/*************************************** * Description:vector实现 * Create:2019/11/22 * Author:zhangfeng * History: * 2019-11-22 搭建基本框架和实现基本功能 * 2019-11-27 添加了元素访问 * 2019-11-28 添加了容量相关 * reserve涉及到元素的拷贝复制,有性能的开销 * 2019-11-29 补齐元素修改器 * *************************************/ #include <memory> #include <iostream> #include <algorithm> #include <cstddef> template<class T, class Alloc=std::allocator<T>> class mVector { public: typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type* iterator; typedef const value_type* const_iterator; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; public: mVector() : _start(0), _finish(0), _end_of_storage(0) {} mVector(size_type n); mVector(size_type n, const T& value); //复制构造函数 mVector( const mVector& other ); mVector& operator=(const mVector& rhs); ~mVector(); iterator begin() { return _start; } const_iterator begin() const { return _start; } iterator end() { return _finish; } const_iterator end() const { return _finish; } //容量 bool empty() const { return begin() == end(); } size_type max_size() const { return size_type(-1) / sizeof(T); } void reserve(size_type new_cap); size_type size() const { return size_type(end() - begin()); } size_type capacity() const { return size_type(_end_of_storage - begin()); } //修改器 void clear(); void push_back( const T& value ); void pop_back(); void swap(mVector & value); iterator erase(iterator pos); iterator erase(iterator first, iterator last); iterator insert( iterator pos, const T& value ); void insert( iterator pos, size_type count, const T& value ); void resize( size_type count, T value = T() ){ if(count < size()) { erase(begin() + count, end()); }else{ insert(end(), count - size(), value); } } //元素访问 reference at(size_type pos); reference operator[](size_type pos) { return *(begin() + pos); } const_reference operator[](size_type pos) const { return *(begin() + pos); } reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(end() - 1); } const_reference back() const { return *(end() - 1); } protected: iterator _start; //使用起始空间 iterator _finish; //使用结束空间 iterator _end_of_storage; //实际空间尾 Alloc _alloc; protected: void _insert_aux(iterator _position, const T& _x); //对象析构 void _destroy(iterator _first, iterator _last); }; template<class T, class Alloc> mVector<T, Alloc>::mVector(size_type n) : _start(0), _finish(0), _end_of_storage(0) { _start = _alloc.allocate(n); _finish = _start; _end_of_storage = _start + n; } template<class T, class Alloc> mVector<T, Alloc>::mVector(size_type n, const T& value) : _start(0), _finish(0), _end_of_storage(0) { _start = _alloc.allocate(n); std::uninitialized_fill_n(_start, n, value); _finish = _end_of_storage = _start + n; } template<class T, class Alloc> mVector<T, Alloc>::mVector( const mVector& other ) : _start(0), _finish(0), _end_of_storage(0) { std::cout << "mVector copy construct ..." << std::endl; _start = _alloc.allocate(other.size()); _finish = _end_of_storage = std::uninitialized_copy(other.begin(), other.end(), _start); } template<class T, class Alloc> mVector<T, Alloc> &mVector<T, Alloc>::operator=(const mVector& rhs) { if(&rhs != this){ std::cout << "mVector operator= ..." << std::endl; size_type _len = rhs.size(); if(_len > capacity()){ iterator _new_start = _alloc.allocate(rhs.size()); iterator _new_finish = std::uninitialized_copy(rhs.begin(), rhs.end(), _new_start); _destroy(_start, _finish); //释放内存 _alloc.deallocate(_start, _end_of_storage-_start); _start = _new_start; _end_of_storage = _new_start + _len; } else if( _len <= size()) { iterator i = std::copy(rhs.begin(), rhs.end(), begin()); _destroy(i, _finish); } else { std::copy(rhs.begin(), rhs.begin() + size(), begin()); std::uninitialized_copy(rhs.begin() + size(), rhs.end(), _finish); } _finish = _start + _len; } return *this; } template<class T, class Alloc> mVector<T, Alloc>::~mVector() { std::cout << "~mVector" << std::endl; _destroy(_start, _finish); //释放内存 _alloc.deallocate(_start, _end_of_storage-_start); _start = _finish = _end_of_storage = NULL; } template<class T, class Alloc> void mVector<T, Alloc>::_destroy(iterator _first, iterator _last) { for(; _first != _last; _first++){ _alloc.destroy(_first); } } template<class T, class Alloc> void mVector<T, Alloc>::_insert_aux(iterator _position, const T& _x) { if(_finish != _end_of_storage){ _alloc.construct(_finish, *(_finish - 1)); ++_finish; T _x_copy = _x; std::copy_backward(_position, _finish - 2, _finish -1); *_position = _x_copy; }else{ const size_type _old_size = size(); const size_type _len = _old_size != 0 ? 2 * _old_size : 1; iterator _new_start = _alloc.allocate(_len); iterator _new_finish = _new_start; try{ // 复制来自范围 [_start, _position) 的元素到始于 _new_start 的未初始化内存 _new_finish = std::uninitialized_copy(_start, _position, _new_start); _alloc.construct(_new_finish, _x); ++_new_finish; _new_finish = std::uninitialized_copy(_position, _finish, _new_finish); }catch(...){ _destroy(_new_start, _new_finish); _alloc.deallocate(_new_start, _len); } _destroy(_start, _finish); _alloc.deallocate(_start, _end_of_storage - _start); _start = _new_start; _finish = _new_finish; _end_of_storage = _new_start + _len; } } template<class T, class Alloc> void mVector<T, Alloc>::push_back( const T& value ) { if(_finish != _end_of_storage) { _alloc.construct(_finish, value); ++_finish; }else{ _insert_aux(_finish, value); } } template<class T, class Alloc> void mVector<T, Alloc>::pop_back() { if(_start != _finish) { --_finish; _alloc.destroy(_finish); } } template<class T, class Alloc> void mVector<T, Alloc>::swap(mVector & value) { std::swap(_start, value._start); std::swap(_finish, value._finish); std::swap(_end_of_storage, value._end_of_storage); } template<class T, class Alloc> typename mVector<T, Alloc>::reference mVector<T, Alloc>::at(size_type pos) { if(pos >= size() || pos < 0) throw std::range_error("vector"); return (*this)[pos]; } template<class T, class Alloc> void mVector<T, Alloc>::reserve(size_type new_cap) { if(capacity() < new_cap){ const size_type _old_size = size(); iterator _new_start = _alloc.allocate(new_cap); try { std::uninitialized_copy(_start, _finish, _new_start); }catch(...){ _alloc.deallocate(_new_start, new_cap); } _destroy(_start, _finish); _alloc.deallocate(_start, _end_of_storage - _start); _start = _new_start; _finish = _start + _old_size; _end_of_storage = _start + new_cap; } } template<class T, class Alloc> typename mVector<T, Alloc>::iterator mVector<T, Alloc>::erase(iterator pos) { if ( pos+1 != end()) { std::copy( pos+1, _finish, pos); } --_finish; _alloc.destroy(_finish); return pos; } template<class T, class Alloc> typename mVector<T, Alloc>::iterator mVector<T, Alloc>::erase(iterator first, iterator last) { iterator it = std::copy(last, _finish, first); _destroy(it, _finish); _finish = _finish - (last - first); return first; } template<class T, class Alloc> typename mVector<T, Alloc>::iterator mVector<T, Alloc>::insert( iterator pos, const T& value ) { size_type _n = pos -begin(); insert(pos, 1, value); return begin() + _n; } template<class T, class Alloc> void mVector<T, Alloc>::insert( iterator pos, size_type count, const T& value ) { if (count != 0) { //备用空间大于新增元素个数 if( size_type(_end_of_storage - _finish) >= count) { T _x_copy = value; //计算pos之后元素个数 const size_type _elems_after = _finish - pos; iterator _old_finish = _finish; if (_elems_after > count) { std::uninitialized_copy(_finish - count, _finish, _finish); _finish += count; std::copy_backward(pos, _old_finish - count, _old_finish); std::fill(pos, pos + count, _x_copy); }else{ std::uninitialized_fill_n(_finish, count-_elems_after, _x_copy); _finish += count - _elems_after; std::uninitialized_copy(pos, _old_finish, _finish); _finish += _elems_after; std::fill(pos, _old_finish, _x_copy); } }else{ //空间不足,需要申请空间 const size_type __old_size = size(); const size_type __len = __old_size + std::max(__old_size, count); iterator __new_start = _alloc.allocate(__len); iterator __new_finish = __new_start; try{ __new_finish = std::uninitialized_copy(_start, pos, __new_start); std::uninitialized_fill_n(__new_finish, count, value); __new_finish = std::uninitialized_copy(pos, _finish, __new_finish + count); }catch(...){ _destroy(__new_start, __new_finish); _alloc.deallocate(__new_start, __len); } _destroy(_start, _finish); _alloc.deallocate(_start, _end_of_storage - _start); _start = __new_start; _finish = __new_finish; _end_of_storage = _start + __len; } } }