• 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;
            }
        }
    }
  • 相关阅读:
    ElasticSearch6学习(1)-安装Elasticsearch
    Ubuntu 18.04 安装java8
    windows10 php7安装mongodb 扩展
    https加密解密过程详解
    Beanstalkd,zeromq,rabbitmq的区别
    PHP中的++和--
    win10 git bash 闪退
    谈下WebSocket介绍,与Socket的区别
    Bridge桥接模式(结构型模式)
    Apater适配器模式(结构型模式)
  • 原文地址:https://www.cnblogs.com/vczf/p/11915644.html
Copyright © 2020-2023  润新知