From 3e70e8db2636b9f85737f3173ddc173f56a9e3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=99=93=E8=88=AA?= <1210603696@qq.com> Date: Thu, 16 Oct 2014 11:19:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90deque=E7=9A=84=E8=BF=AD?= =?UTF-8?q?=E4=BB=A3=E5=99=A8=E7=9A=84=E5=9F=BA=E6=9C=AC=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TinySTL/Deque.h | 179 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 168 insertions(+), 11 deletions(-) diff --git a/TinySTL/Deque.h b/TinySTL/Deque.h index a398d14..8408bc8 100644 --- a/TinySTL/Deque.h +++ b/TinySTL/Deque.h @@ -2,37 +2,169 @@ #define _DEQUE_H_ #include "Allocator.h" +#include "Iterator.h" #include "ReverseIterator.h" namespace TinySTL{ - //class of deque iterator - class diter{}; + template> + class deque; + namespace{ + //class of deque iterator + template + class diter :public iterator{ + private: + typedef TinySTL::deque* cntrPtr; + size_t mapIndex_; + T *cur_; + cntrPtr container_; + public: + diter() :mapIndex_(-1), cur_(0), container_(0){} + diter(size_t index, T *ptr, cntrPtr container) + :mapIndex_(index), cur_(ptr), container_(container){} + diter(const diter& it) + :mapIndex_(it.mapIndex_), cur_(it.cur_), container_(it.container_){} + diter& operator = (const diter& it){ + if (this != it){ + mapIndex_ = it->mapIndex_; + cur_ = it->cur_; + container_ = it->container_; + } + return *this; + } + reference operator *(){ return *cur_; } + pointer operator ->(){ return &(operator*()); } + diter& operator ++(){ + if (cur_ != getBuckTail(mapIndex_))//+1后还在同一个桶里 + ++cur_; + else{ + ++mapIndex_; + cur_ = getBuckHead(mapIndex_); + } + return *this; + } + diter operator ++(int){ + auto res = *this; + ++(*this); + return res; + } + diter& operator --(){ + if (cur_ != getBuckHead(mapIndex_))//当前不指向桶头 + --cur_; + else{ + --mapIndex_; + cur_ = getBuckTail(mapIndex_); + } + return *this; + } + diter operator --(int){ + auto res = *this; + --(*this); + return res; + } + bool operator ==(const diter& it)const{ + return ((mapIndex_ == it.mapIndex_) && + (cur_ == it.cur_) && (container_ == it.container_)); + } + bool operator !=(const diter& it)const{ + return !(*this == it); + } + private: + T *getBuckTail(size_t mapIndex)const{ + return container_[mapIndex] + container_->getBuckSize() - 1; + } + T *getBuckHead(size_t mapIndex)const{ + return container_->map_[mapIndex]; + } + public: + template + friend diter operator + (const diter& it, typename diter::difference_type n); + template + friend diter operator + (typename diter::difference_type n, const diter& it); + template + friend diter operator - (const diter& it, typename diter::difference_type n); + template + friend diter operator - (typename diter::difference_type n, const diter& it); + template + friend typename diter::difference_type operator - (const diter& it1, const diter& it2); + }; + template + diter operator + (const diter& it, typename diter::difference_type n){//assume n >= 0 + diter res(it); + auto m = res.getBuckTail(res.mapIndex_) - res.cur_; + if (n <= m){//前进n步仍在同一个桶中 + res.cur_ += n; + } + else{ + n = n - m; + res.mapIndex_ += n / res.container_->getBuckSize(); + res.cur_ = res.getBuckHead(res.mapIndex_) + n % res.container_->getBuckSize(); + } + return res; + } + template + diter operator + (typename diter::difference_type n, const diter& it){ + return (it + n); + } + template + diter operator - (const diter& it, typename diter::difference_type n){//assume n >= 0 + diter res(it); + auto m = res.cur_ - res.getBuckHead(res.mapIndex_); + if (n <= m)//后退n步还在同一个桶中 + res.cur_ -= n; + else{ + n = n - m; + res.mapIndex_ -= n / res.container_->getBuckSize(); + res.cur_ = res.getBuckTail(res.mapIndex_) - n % res.container_->getBuckSize(); + } + return res; + } + template + diter operator - (typename diter::difference_type n, const diter& it){ + return (it - n); + } + template + typename diter::difference_type operator - (const diter& it1, const diter& it2){ + return typename diter::difference_type(it1.container_->getBuckSize()) * (it1.mapIndex_ - it2.mapIndex_ - 1) + + (it1.cur_ - it1.getBuckHead(it1.mapIndex_)) + (it2.getBuckTail(it2.mapIndex_) - it2.cur_); + } + } //class of deque - template> + template class deque{ + private: + template + friend class diter; public: typedef T value_type; - typedef diter iterator; + typedef diter iterator; typedef const iterator const_iterator; typedef reverse_iterator reverse_iterator; - typedef reverse_iterator const_reverse_iterator; + typedef const reverse_iterator const_reverse_iterator; typedef T& reference; typedef const reference const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; + typedef Alloc allocator_type; private: typedef Alloc dataAllocator; - - T *bucks; + enum class EBucksSize{BUCKSIZE = 64}; + private: + iterator beg_, end_; + size_t mapSize_; + T **map_; public: - explicit deque(const allocator_type& alloc = allocator_type()); - explicit deque(size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type()); + deque(); + explicit deque(size_type n, const value_type& val = value_type()); template - deque(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); + deque(InputIterator first, InputIterator last); deque(const deque& x); - ~deque(); + ~deque(){ + for (int i = 0; i != mapSize_; ++i) + delete[] map_[i]; + delete[] map_; + } deque& operator= (const deque& x); deque& operator= (deque&& x); @@ -77,6 +209,20 @@ namespace TinySTL{ iterator erase(iterator first, iterator last); void swap(deque& x); void clear(); + private: + T *getABuck(){ + return new T[getBuckSize()]; + } + T** getANewMap(const size_t size){ + mapSize_ = getNewMapSize(size); + return new T*[mapSize_](0); + } + size_t getNewMapSize(const size_t size){ + return (size == 0 ? 1 : size * 1.5); + } + size_t getBuckSize()const{ + return EBucksSize::BUCKSIZE; + } public: template friend bool operator== (const deque& lhs, const deque& rhs); @@ -93,5 +239,16 @@ namespace TinySTL{ template friend void swap(deque& x, deque& y); };//end of deque + + template + deque::deque() + :mapSize_(0), map_(0){} + //template + //deque::deque(size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type()); + //template + //template + //deque::deque(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); + //template + //deque::deque(const deque& x); } #endif \ No newline at end of file