// Vector.h // // A class vector similar to the STL container vector. // Version 1.2 // // New in this version: // copy constructor, assignment operator, destructor // // Included from earlier versions: // vector(), vector(n), vector(init_list), ~vector() // size(), indexing operator // iterators, constant iterators // begin, end, cbegin, cend // erase, insert (memory but not time efficient) #ifndef _Vector_h_ #define _Vector_h_ #include #include namespace CS142 { template class vector { public: typedef T * iterator; typedef const T * const_iterator; vector() : buffer_(nullptr), size_(0) {} explicit vector(int n); vector(std::initializer_list init_list); vector(const vector & v); ~vector() { delete [] buffer_; } int size() const { return size_; } T & operator[](int i) { return buffer_[i]; } const T & operator[](int i) const { return buffer_[i]; } vector & operator=(const vector & v); iterator begin() { return buffer_; } const_iterator begin() const { return buffer_; } const_iterator cbegin() const { return buffer_; } iterator end() { return buffer_ + size_; } const_iterator end() const { return buffer_ + size_; } const_iterator cend() const { return buffer_ + size_; } iterator erase(const_iterator itr); iterator insert(const_iterator itr, const T & e); private: T * buffer_; // points to a dynamically allocated array that // contains the vector elements int size_; // the number of elements in the vector (and the size of // the buffer) }; template vector::vector(int n) { if (n == 0) { buffer_ = nullptr; size_ = 0; } else { buffer_ = new T[n]{}; size_ = n; } } template vector::vector(std::initializer_list init_list) { if (init_list.size() == 0) { buffer_ = nullptr; size_ = 0; } else { buffer_ = new T[init_list.size()]; std::copy(init_list.begin(), init_list.end(), buffer_); size_ = init_list.size(); } } template typename vector::iterator vector::erase( vector::const_iterator const_itr) { if (size_ == 1) { delete [] buffer_; buffer_ = nullptr; size_ = 0; return end(); } else { T * new_buffer = new T[size_ - 1]; iterator new_itr = std::copy(cbegin(), const_itr, new_buffer); std::copy(const_itr + 1, cend(), new_itr); delete [] buffer_; buffer_ = new_buffer; --size_; return new_itr; } } template typename vector::iterator vector::insert( vector::const_iterator const_itr, const T & e) { T * new_buffer = new T[size_ + 1]; iterator new_itr = std::copy(cbegin(), const_itr, new_buffer); *new_itr = e; std::copy(const_itr, cend(), new_itr + 1); delete [] buffer_; buffer_ = new_buffer; ++size_; return new_itr; } template vector::vector(const vector& v) { if (v.size() == 0) { buffer_ = nullptr; size_ = 0; } else { buffer_ = new T[v.size()]; std::copy(v.begin(), v.end(), buffer_); size_ = v.size(); } } template vector& vector::operator=(const vector& v) { // Note: The current buffer of the receiver won't be // deallocated until a new buffer has been successfully // allocated and filled with a copy of v's buffer. This // prevents problems in case the allocation fails or the // calling function did "v = v". if (v.size() == 0) { delete [] buffer_; buffer_ = nullptr; size_ = 0; } else { T * new_buffer = new T[v.size()]; std::copy(v.begin(), v.end(), new_buffer); delete [] buffer_; buffer_ = new_buffer; size_ = v.size(); } return *this; } } // namespace CS142 #endif