#ifndef DYNAMIC_ARRAY_H__ #define DYNAMIC_ARRAY_H__ #include "Common.h" #include "DynamicArrayImpl.h" namespace Arrays { template class DynamicArray { public: typedef T value_type; typedef T* iterator; typedef const T* const_iterator; typedef T& reference; typedef const T& const_reference; explicit DynamicArray(const size_type sz) : impl_(sz) {} DynamicArray(const DynamicArray& other) : impl_(other.impl_.size_) // may throw an exception { impl_.fill_from(other.impl_); // may throw an exception } DynamicArray& operator=(const DynamicArray& other) { DynamicArray arr_copy(other); // may throw an exception impl_.swap(arr_copy.impl_); // cannot throw an exception return *this; } iterator begin() { return impl_.arr_; } iterator end() { return &impl_.arr_[content()]; } const_iterator begin() const { return const_cast(*this).begin(); } const_iterator end() const { return const_cast(*this).end(); } size_type size() const { return impl_.size_; } size_type content() const { return impl_.content_; } bool empty() const { return content() == 0; } // Unchecked references reference operator[] (const size_type n) { if (n == size()-1) // last element accessed - increase size resize(size()*2); // may throw an exception (see resize()) if (n >= content()) impl_.content_ = n+1; return impl_.arr_[n]; } const_reference operator[] (const size_type n) const { return const_cast(*this)[n]; } // Checked references reference at(const size_type pos) { if (pos >= size()) throw OutOfRange(); return (*this)[pos]; } const_reference at(const size_type pos) const { return const_cast(*this).at(pos); } private: void resize(const size_type new_size) { DynamicArray resized_arr(new_size); // may throw an exception resized_arr.impl_.fill_from(impl_); // may throw an exception impl_.swap(resized_arr.impl_); // cannot throw an exception } private: DynamicArrayImpl impl_; }; } #endif