STL实现01---vector

/***************************************
 * 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;
        }
    }
}
原文地址:https://www.cnblogs.com/vczf/p/11915644.html