zoukankan      html  css  js  c++  java
  • 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;
            }
        }
    }
  • 相关阅读:
    2021NUAA暑假集训 Day3 题解
    2021NUAA暑假集训 Day2 题解
    2021NUAA暑期模拟赛部分题解
    CodeForces 1038D Slime
    UVA 11149 Power of Matrix
    UVA 10655 Contemplation! Algebra
    UVA 10689 Yet another Number Sequence
    HDU 4549 M斐波那契数列
    HDU 4990 Reading comprehension
    CodeForces 450B Jzzhu and Sequences
  • 原文地址:https://www.cnblogs.com/vczf/p/11915644.html
Copyright © 2011-2022 走看看