手写的奇怪vector

手写了一个动态申请内存的数组,更准确的说是一个本来应该是块链,最后由于太耗时间了变成数组的东西。
由于太懒了,编译需要用c++11或以上。
两个参数分别是元素类型和块大小S。申请内存以块为单位,很明显如果块大小是\(O(n)\)那么就是数组,如果块大小是\(O(1)\)那么就是链表。
各种操作的复杂度跟数组没啥区别,有可能乘上一个\(O(n/S)\),毕竟我太懒了。
重载了许多构造函数,重载了迭代器,应该可以支持大部分stl算法,冒号遍历应该也没有问题。

结果慢的飞起,被vector卡爆了,目前还不知有个毛用。
有bug吗?我也不知道,暂且可以过一些题。
曾经有过内存泄漏的bug,不过现在应该不会了。

namespace container{
    template<class T,size_t BLOCK_SIZE>
    class myarray{
        struct period{
            T* a;
            period* ne=NULL;
            period(){
                //slow but safe
                a=new T[BLOCK_SIZE]();
            }
            period(const T &v){
                a=new T[BLOCK_SIZE](v);
            }
            ~period(){
                delete []a;
            }
        };
        period *Be;
        size_t Sz;
        class iterator{
            period *ip;
            size_t pos;
            myarray *po;
        public:
            typedef random_access_iterator_tag iterator_category;
            typedef T value_type;
            typedef T* pointer;
            typedef T& reference;
            typedef ptrdiff_t difference_type;
            iterator():ip(nullptr),pos(0),po(nullptr){
            }
            iterator(const iterator &it){
                (*this)=it;
            }
            iterator(period * const &ip,const size_t &pos,myarray * const &po):ip(ip),pos(pos),po(po){
            }
            bool operator !=(const iterator &it) const{
                return ip!=it.ip||pos!=it.pos;
            }
            bool operator ==(const iterator &it) const{
                return ip==it.ip&&pos==it.pos;
            }
            iterator operator ++(){
                if (++pos==BLOCK_SIZE&&ip->ne!=NULL){
                    ip=ip->ne;
                    pos=0;
                }
                return *this;
            }
            const iterator operator ++(int){
                iterator tmp(*this);
                if (++pos==BLOCK_SIZE&&ip->ne!=NULL){
                    ip=ip->ne;
                    pos=0;
                }
                return tmp;
            }
            iterator operator --(){
                if (pos){
                    --pos;
                    return (*this);
                }
                period *tBe=po->Be;
                while (tBe->ne!=ip) tBe=tBe->ne;
                ip=tBe;
                pos=BLOCK_SIZE-1;
                return (*this);
            }
            const iterator operator --(int){
                iterator tmp(*this);
                if (pos){
                    --pos;
                    return tmp;
                }
                period *tBe=po->Be;
                while (tBe->ne!=ip) tBe=tBe->ne;
                ip=tBe;
                pos=BLOCK_SIZE-1;
                return tmp;
            }
            iterator operator +(const size_t &len) const{
                //ip!=NULL BUG
                if (BLOCK_SIZE>pos+len) return iterator(ip,pos+len,po);
                size_t tmp=len-(BLOCK_SIZE-1-pos);
                if (ip->ne==NULL) return iterator(ip,BLOCK_SIZE,po);
                period *tip=ip->ne;
                while (tmp>BLOCK_SIZE){
                    if (tip->ne==NULL) return iterator(tip,BLOCK_SIZE,po);
                    tip=tip->ne;
                    tmp-=BLOCK_SIZE;
                }
                return iterator(tip,tmp-1,po);
            }
            iterator operator +=(const size_t &len){
                return ((*this)=(*this)+len);
            }
            size_t operator -(const iterator &it) const{
                //only
                if (ip==it.ip) return pos-it.pos;
                period *tmp=it.ip->ne;
                size_t ret=BLOCK_SIZE-it.pos;
                while (tmp!=ip){
                    ret+=BLOCK_SIZE;
                    tmp=tmp->ne;
                }
                return ret+pos;
            }
            iterator operator -(const size_t &len) const{
                return (po->begin()+((*this)-(po->begin())-len));
            }
            iterator operator -=(const size_t &len){
                return ((*this)=(*this)-len);
            }
            bool operator <(const iterator &it) const{
                //same father
                return ((*this)-po->begin())<(it-(po->begin()));
            }
            bool operator <=(const iterator &it) const{
                //same father
                return ((*this)-po->begin())<=(it-(po->begin()));
            }
            T & operator *() const{
                return ip->a[pos];
            }
        };
    public:
        typedef T value_type;
        typedef T& reference;
        typedef const T& const_reference;
        typedef size_t size_type;
        myarray(){
            Be=NULL;
            Sz=0;
        }
        myarray(const size_t &sz){
            construct(sz);
        }
        myarray(const size_t &sz,const T &v){
            construct(sz,v);
        }
        ~myarray(){
            myfree(Be);
        }
        myarray(const myarray &rhs){
            if (this==&rhs) return;
            construct(rhs.size());
            auto j=begin();
            for (auto it=rhs.begin(); it!=rhs.end(); ++it) *(j++)=(*it);
        }
        myarray(const initializer_list<T> &args){
            construct(args.size());
            auto j=begin();
            for (auto it=args.begin(); it!=args.end(); ++it) *(j++)=(*it);
        }
        myarray& operator =(const myarray &rhs){
            if (this==&rhs) return (*this);
            myfree(Be);
            construct(rhs.size());
            auto j=begin();
            for (auto it=rhs.begin(); it!=rhs.end(); ++it) *(j++)=(*it);
            return *this;
        }
        void myfree(period * const &Be){
            period *tBe=Be,*tmp;
            while (tBe!=NULL){
                tmp=tBe->ne;
                delete tBe;
                tBe=tmp;
            }
        }
        void construct(const size_t &sz){
            Be=new period();//slow but safe
            Sz=sz;
            size_t tSz=sz;
            period *tBe=Be;
            while (tSz>BLOCK_SIZE){
                tBe=(tBe->ne=new period);
                tSz-=BLOCK_SIZE;
            }
        }
        void construct(const size_t &sz,const T &v){
            Be=new period(v);
            Sz=sz;
            size_t tSz=sz;
            period *tBe=Be;
            while (tSz>BLOCK_SIZE){
                tBe=(tBe->ne=new period);
                tSz-=BLOCK_SIZE;
            }
        }
        iterator begin() const{
            return iterator(Be,0,(myarray*)this);
        }
        iterator end() const{
            //Slow And Dangerous
            if (Be==NULL) return iterator(NULL,0,(myarray*)this);
            period *tBe=Be;
            while (tBe->ne!=NULL) tBe=tBe->ne;
            return iterator(tBe,((int)Sz-1)%(int)BLOCK_SIZE+1,(myarray*)this);
        }
        void push_back(const T &v){
            if (Be==NULL){
                Be=new period;
                Be->a[Sz++]=v;
                return;
            }
            period *tBe=Be;
            while (tBe->ne!=NULL) tBe=tBe->ne;
            size_t tSz=(Sz++)%BLOCK_SIZE;
            if (tSz==0) tBe=(tBe->ne=new period);
            tBe->a[tSz]=v;
        }
        void pop_back(){
            if ((--Sz)%BLOCK_SIZE) return;
            if (Sz==0){
                delete Be;
                Be=NULL;
                return;
            }
            period *tBe=Be;
            while (tBe->ne->ne!=NULL) tBe=tBe->ne;
            delete tBe->ne;
            tBe->ne=NULL;
        }
        T& operator [](const size_t &pos) const{
            size_t tpos=pos;
            for (period* i=Be; i!=NULL; i=i->ne)
                if (tpos<BLOCK_SIZE) return i->a[tpos];
                else tpos-=BLOCK_SIZE;
            throw;
        }
        T& front() const{
            //unusual
            return Be->a[0];
        }
        T& back() const{
            return *(--end());
        }
        size_t size() const{
            return Sz;
        }
        bool empty() const{
            return Sz==0;
        }
        void swap(myarray &arr){
            std::swap(Be,arr.Be);
            std::swap(Sz,arr.Sz);
        }
        template<class U>
        struct iterator_traits{
            typedef typename U::value_type value_type;
            typedef typename U::iterator_category iterator_category;
            typedef typename U::difference_type difference_type;
            typedef typename U::pointer pointer;
            typedef typename U::reference reference;
        };
    };
}
template<class T=int,size_t BLOCK_SIZE=32>
using arr=container::myarray<T,BLOCK_SIZE>;
posted @ 2019-03-17 13:48  Yuhuger  阅读(304)  评论(1编辑  收藏  举报