diff --git a/TinySTL/Deque.h b/TinySTL/Deque.h index 8dd7cb0..d98ec12 100644 --- a/TinySTL/Deque.h +++ b/TinySTL/Deque.h @@ -9,16 +9,16 @@ namespace TinySTL{ template> class deque; - namespace{ + namespace Detail{ //class of deque iterator template class dq_iter :public iterator{ private: template - friend class deque; + friend class ::TinySTL::deque; private: //typedef TinySTL::deque* cntrPtr; - typedef const TinySTL::deque* cntrPtr; + typedef const ::TinySTL::deque* cntrPtr; size_t mapIndex_; T *cur_; cntrPtr container_; @@ -28,75 +28,22 @@ namespace TinySTL{ :mapIndex_(index), cur_(ptr), container_(container){} dq_iter(const dq_iter& it) :mapIndex_(it.mapIndex_), cur_(it.cur_), container_(it.container_){} - dq_iter& operator = (const dq_iter& it){ - if (this != &it){ - mapIndex_ = it.mapIndex_; - cur_ = it.cur_; - container_ = it.container_; - } - return *this; - } - void swap(dq_iter& it){ - TinySTL::swap(mapIndex_, it.mapIndex_); - TinySTL::swap(cur_, it.cur_); - //TinySTL::swap(container_, it.container_); - } + dq_iter& operator = (const dq_iter& it); + void swap(dq_iter& it); reference operator *(){ return *cur_; } const reference operator *()const{ return *cur_; } pointer operator ->(){ return &(operator*()); } const pointer operator ->()const{ return &(operator*()); } - dq_iter& operator ++(){ - if (cur_ != getBuckTail(mapIndex_))//+1后还在同一个桶里 - ++cur_; - else if(mapIndex_ + 1 < container_->mapSize_){//+1后还在同一个map里 - ++mapIndex_; - cur_ = getBuckHead(mapIndex_); - }else{//+1后跳出了map - mapIndex_ = container_->mapSize_; - //cur_ = container_->map_[mapIndex_] + getBuckSize();//指向map_[mapSize_-1]的尾的下一个位置 - cur_ = container_->map_[mapIndex_]; - } - return *this; - } - dq_iter operator ++(int){ - auto res = *this; - ++(*this); - return res; - } - dq_iter& operator --(){ - if (cur_ != getBuckHead(mapIndex_))//当前不指向桶头 - --cur_; - else if(mapIndex_ - 1 >= 0){//-1后还在map里面 - --mapIndex_; - cur_ = getBuckTail(mapIndex_); - }else{ - mapIndex_ = 0; - cur_ = container_->map_[mapIndex_];//指向map_[0]的头 - } - return *this; - } - dq_iter operator --(int){ - auto res = *this; - --(*this); - return res; - } - bool operator ==(const dq_iter& it)const{ - return ((mapIndex_ == it.mapIndex_) && - (cur_ == it.cur_) && (container_ == it.container_)); - } - bool operator !=(const dq_iter& it)const{ - return !(*this == it); - } + dq_iter& operator ++(); + dq_iter operator ++(int); + dq_iter& operator --(); + dq_iter operator --(int); + bool operator ==(const dq_iter& it)const; + bool operator !=(const dq_iter& it)const; private: - T *getBuckTail(size_t mapIndex)const{ - return container_->map_[mapIndex] + (container_->getBuckSize() - 1); - } - T *getBuckHead(size_t mapIndex)const{ - return container_->map_[mapIndex]; - } - size_t getBuckSize()const{ - return container_->getBuckSize(); - } + T *getBuckTail(size_t mapIndex)const; + T *getBuckHead(size_t mapIndex)const; + size_t getBuckSize()const; public: template friend dq_iter operator + (const dq_iter& it, typename dq_iter::difference_type n); @@ -111,66 +58,18 @@ namespace TinySTL{ template friend void swap(dq_iter& lhs, dq_iter& rhs); }; - template - dq_iter operator + (const dq_iter& it, typename dq_iter::difference_type n){//assume n >= 0 - dq_iter res(it); - auto m = res.getBuckTail(res.mapIndex_) - res.cur_; - if (n <= m){//前进n步仍在同一个桶中 - res.cur_ += n; - } - else{ - n = n - m; - res.mapIndex_ += (n / it.getBuckSize() + 1); - auto p = res.getBuckHead(res.mapIndex_); - auto x = n % it.getBuckSize() - 1; - res.cur_ = p + x; - } - return res; - } - template - dq_iter operator + (typename dq_iter::difference_type n, const dq_iter& it){ - return (it + n); - } - template - dq_iter operator - (const dq_iter& it, typename dq_iter::difference_type n){//assume n >= 0 - dq_iter 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.getBuckSize() + 1); - res.cur_ = res.getBuckTail(res.mapIndex_) - (n % res.getBuckSize() - 1); - } - return res; - } - template - dq_iter operator - (typename dq_iter::difference_type n, const dq_iter& it){ - return (it - n); - } - template - typename dq_iter::difference_type operator - (const dq_iter& it1, const dq_iter& it2){ - if (it1.container_ == it2.container_ && it1.container_ == 0) - return 0; - return typename dq_iter::difference_type(it1.getBuckSize()) * (it1.mapIndex_ - it2.mapIndex_ - 1) - + (it1.cur_ - it1.getBuckHead(it1.mapIndex_)) + (it2.getBuckTail(it2.mapIndex_) - it2.cur_) + 1; - } - template - void swap(dq_iter& lhs, dq_iter& rhs){ - lhs.swap(rhs); - } - } + }// end of Detail namespace //class of deque template class deque{ private: template - friend class dq_iter; + friend class ::TinySTL::Detail::dq_iter; public: typedef T value_type; - typedef dq_iter iterator; - typedef dq_iter const_iterator; + typedef Detail::dq_iter iterator; + typedef Detail::dq_iter const_iterator; typedef T& reference; typedef const reference const_reference; typedef size_t size_type; @@ -190,97 +89,43 @@ namespace TinySTL{ deque(InputIterator first, InputIterator last); deque(const deque& x); - ~deque(){ - for (int i = 0; i != mapSize_; ++i){ - for (auto p = map_[i] + 0; !p && p != map_[i] + getBuckSize(); ++p) - dataAllocator::destroy(p); - if (!map_[i]) - dataAllocator::deallocate(map_[i], getBuckSize()); - } - delete[] map_; - } + ~deque(); deque& operator= (const deque& x); deque& operator= (deque&& x); - iterator begin(){ return beg_; } - iterator end(){ return end_; } - //迭代器设计失误,会使下面两个函数丧失const特性,暂时没有效解决办法故只能先这样妥协 - iterator begin()const{ return beg_; } - iterator end()const{ return end_; } + iterator begin(); + iterator end(); + iterator begin()const; + iterator end()const; public: size_type size() const{ return end() - begin(); } bool empty() const{ return begin() == end(); } - reference operator[] (size_type n){ return *(begin() + n); } - reference front(){ return *begin(); } - reference back(){ return *(end() - 1); } - //由于const迭代器的设计失误故以下三个const函数会丧失const特性 - const_reference operator[] (size_type n) const{ return *(begin() + n); } - const_reference front() const{ return *begin(); } - const_reference back() const{ return *(end() - 1); } + reference operator[] (size_type n); + reference front(); + reference back(); + const_reference operator[] (size_type n) const; + const_reference front() const; + const_reference back() const; void push_back(const value_type& val); void push_front(const value_type& val); void pop_back(); void pop_front(); void swap(deque& x); - void clear(){ - /*for (int i = 0; i != mapSize_; ++i) - if (!map_[i]) - dataAllocator::destroy(map_[i], map_[i] + getBuckSize());*/ - for (auto i = 0; i != mapSize_; ++i){ - for (auto p = map_[i] + 0; !p && p != map_[i] + getBuckSize(); ++p) - dataAllocator::destroy(p); - } - mapSize_ = 0; - beg_.mapIndex_ = end_.mapIndex_ = mapSize_ / 2; - beg_.cur_ = end_.cur_ = map_[mapSize_ / 2]; - } + void clear(); private: - T *getANewBuck(){ - return dataAllocator::allocate(getBuckSize()); - } - T** getANewMap(const size_t size){ - T **map = new T*[size]; - for (int i = 0; i != size; ++i) - map[i] = getANewBuck(); - return map; - } - size_t getNewMapSize(const size_t size){ - return (size == 0 ? 2 : size * 2); - } - size_t getBuckSize()const{ - return (size_t)EBucksSize::BUCKSIZE; - } - void init(){ - mapSize_ = 2; - map_ = getANewMap(mapSize_); - beg_.container_ = end_.container_ = this; - beg_.mapIndex_ = end_.mapIndex_ = mapSize_ - 1; - beg_.cur_ = end_.cur_ = map_[mapSize_ - 1]; - } - bool back_full()const{ - return map_[mapSize_ - 1] && (map_[mapSize_]) == end().cur_; - } - bool front_full()const{ - return map_[0] && map_[0] == begin().cur_; - } - void deque_aux(size_t n, const value_type& val, std::true_type){ - int i = 0; - for (; i != n / 2; ++i) - (*this).push_front(val); - for (; i != n; ++i) - (*this).push_back(val); - } + T *getANewBuck(); + T** getANewMap(const size_t size); + size_t getNewMapSize(const size_t size); + size_t getBuckSize()const; + void init(); + bool back_full()const; + bool front_full()const; + void deque_aux(size_t n, const value_type& val, std::true_type); template - void deque_aux(Iterator first, Iterator last, std::false_type){ - difference_type mid = (last - first) / 2; - for (auto it = first + mid; it != first - 1; --it) - (*this).push_front(*it); - for (auto it = first + mid + 1; it != last; ++it) - (*this).push_back(*it); - } + void deque_aux(Iterator first, Iterator last, std::false_type); void reallocateAndCopy(); public: template @@ -290,117 +135,7 @@ 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()){ - deque(); - deque_aux(n, val, typename std::is_integral::type()); - } - template - template - deque::deque(InputIterator first, InputIterator last){ - deque(); - deque_aux(first, last, typename std::is_integral::type()); - } - template - deque::deque(const deque& x){ - mapSize_ = x.mapSize_; - map_ = getANewMap(mapSize_); - for (int i = 0; i + x.beg_.mapIndex_ != x.mapSize_; ++i) - for (int j = 0; j != getBuckSize(); ++j) - map_[x.beg_.mapIndex_ + i][j] = x.map_[x.beg_.mapIndex_ + i][j]; - beg_.mapIndex_ = x.beg_.mapIndex_; - end_.mapIndex_ = x.end_.mapIndex_; - beg_.cur_ = map_[beg_.mapIndex_] + (x.beg_.cur_ - x.map_[x.beg_.mapIndex_]); - end_.cur_ = map_[end_.mapIndex_] + (x.end_.cur_ - x.map_[x.end_.mapIndex_]); - beg_.container_ = end_.container_ = this; - } - template - void deque::reallocateAndCopy(){ - auto newMapSize = getNewMapSize(mapSize_); - T** newMap = getANewMap(newMapSize); - size_t startIndex = newMapSize / 4; - for (int i = 0; i + beg_.mapIndex_ != mapSize_; ++i) - for (int j = 0; j != getBuckSize(); ++j) - newMap[startIndex + i][j] = map_[beg_.mapIndex_ + i][j]; - - size_t n = beg_.cur_ - map_[beg_.mapIndex_]; - auto size = this->size(); - auto b = beg_, e = end_; - clear(); - mapSize_ = newMapSize; - map_ = newMap; - beg_ = iterator(startIndex, newMap[startIndex] + n, this); - end_ = beg_ + size; - - } - template - void deque::push_back(const value_type& val){ - if (empty()){ - init(); - } - else if (back_full()){ - reallocateAndCopy(); - } - //*end_ = val; - //bug fix - //2015.01.02 - TinySTL::construct(end_.cur_, val); - ++end_; - } - template - void deque::push_front(const value_type& val){ - if (empty()){ - init(); - } - else if (front_full()){ - reallocateAndCopy(); - } - --beg_; - //*beg_ = val; - //bug fix - //2015.01.02 - TinySTL::construct(beg_.cur_, val); - } - template - void deque::pop_front(){ - dataAllocator::destroy(beg_.cur_); - ++beg_; - } - template - void deque::pop_back(){ - --end_; - dataAllocator::destroy(end_.cur_); - } - template - void deque::swap(deque& x){ - TinySTL::swap(mapSize_, x.mapSize_); - TinySTL::swap(map_, x.map_); - beg_.swap(x.beg_); - end_.swap(x.end_); - } - - template - bool operator== (const deque& lhs, const deque& rhs){ - auto cit1 = lhs.begin(), cit2 = rhs.begin(); - for (; cit1 != lhs.end() && cit2 != rhs.end(); ++cit1, ++cit2){ - if (*cit1 != *cit2) - return false; - } - if (cit1 == lhs.end() && cit2 == rhs.end()) - return true; - return false; - } - template - bool operator!= (const deque& lhs, const deque& rhs){ - return !(lhs == rhs); - } - template - void swap(deque& x, deque& y){ - x.swap(y); - } } + +#include "Detail\Deque.impl.h" #endif \ No newline at end of file diff --git a/TinySTL/Detail/Deque.impl.h b/TinySTL/Detail/Deque.impl.h new file mode 100644 index 0000000..ef5d05a --- /dev/null +++ b/TinySTL/Detail/Deque.impl.h @@ -0,0 +1,354 @@ +#ifndef _DEQUE_IMPL_H_ +#define _DEQUE_IMPL_H_ + +namespace TinySTL{ + namespace Detail{ + template + dq_iter& dq_iter::operator ++(){ + if (cur_ != getBuckTail(mapIndex_))//+1后还在同一个桶里 + ++cur_; + else if (mapIndex_ + 1 < container_->mapSize_){//+1后还在同一个map里 + ++mapIndex_; + cur_ = getBuckHead(mapIndex_); + } + else{//+1后跳出了map + mapIndex_ = container_->mapSize_; + //cur_ = container_->map_[mapIndex_] + getBuckSize();//指向map_[mapSize_-1]的尾的下一个位置 + cur_ = container_->map_[mapIndex_]; + } + return *this; + } + template + dq_iter dq_iter::operator ++(int){ + auto res = *this; + ++(*this); + return res; + } + template + dq_iter& dq_iter::operator --(){ + if (cur_ != getBuckHead(mapIndex_))//当前不指向桶头 + --cur_; + else if (mapIndex_ - 1 >= 0){//-1后还在map里面 + --mapIndex_; + cur_ = getBuckTail(mapIndex_); + } + else{ + mapIndex_ = 0; + cur_ = container_->map_[mapIndex_];//指向map_[0]的头 + } + return *this; + } + template + dq_iter dq_iter::operator --(int){ + auto res = *this; + --(*this); + return res; + } + template + bool dq_iter::operator ==(const dq_iter& it)const{ + return ((mapIndex_ == it.mapIndex_) && + (cur_ == it.cur_) && (container_ == it.container_)); + } + template + bool dq_iter::operator !=(const dq_iter& it)const{ + return !(*this == it); + } + template + dq_iter& dq_iter::operator = (const dq_iter& it){ + if (this != &it){ + mapIndex_ = it.mapIndex_; + cur_ = it.cur_; + container_ = it.container_; + } + return *this; + } + template + void dq_iter::swap(dq_iter& it){ + TinySTL::swap(mapIndex_, it.mapIndex_); + TinySTL::swap(cur_, it.cur_); + //TinySTL::swap(container_, it.container_); + } + template + dq_iter operator + (const dq_iter& it, typename dq_iter::difference_type n){//assume n >= 0 + dq_iter res(it); + auto m = res.getBuckTail(res.mapIndex_) - res.cur_; + if (n <= m){//前进n步仍在同一个桶中 + res.cur_ += n; + } + else{ + n = n - m; + res.mapIndex_ += (n / it.getBuckSize() + 1); + auto p = res.getBuckHead(res.mapIndex_); + auto x = n % it.getBuckSize() - 1; + res.cur_ = p + x; + } + return res; + } + template + dq_iter operator + (typename dq_iter::difference_type n, const dq_iter& it){ + return (it + n); + } + template + dq_iter operator - (const dq_iter& it, typename dq_iter::difference_type n){//assume n >= 0 + dq_iter 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.getBuckSize() + 1); + res.cur_ = res.getBuckTail(res.mapIndex_) - (n % res.getBuckSize() - 1); + } + return res; + } + template + dq_iter operator - (typename dq_iter::difference_type n, const dq_iter& it){ + return (it - n); + } + template + typename dq_iter::difference_type operator - (const dq_iter& it1, const dq_iter& it2){ + if (it1.container_ == it2.container_ && it1.container_ == 0) + return 0; + return typename dq_iter::difference_type(it1.getBuckSize()) * (it1.mapIndex_ - it2.mapIndex_ - 1) + + (it1.cur_ - it1.getBuckHead(it1.mapIndex_)) + (it2.getBuckTail(it2.mapIndex_) - it2.cur_) + 1; + } + template + void swap(dq_iter& lhs, dq_iter& rhs){ + lhs.swap(rhs); + } + template + T *dq_iter::getBuckTail(size_t mapIndex)const{ + return container_->map_[mapIndex] + (container_->getBuckSize() - 1); + } + template + T *dq_iter::getBuckHead(size_t mapIndex)const{ + return container_->map_[mapIndex]; + } + template + size_t dq_iter::getBuckSize()const{ + return container_->getBuckSize(); + } + }//end of Detail namespace + + template + bool deque::back_full()const{ + return map_[mapSize_ - 1] && (map_[mapSize_]) == end().cur_; + } + template + bool deque::front_full()const{ + return map_[0] && map_[0] == begin().cur_; + } + template + void deque::deque_aux(size_t n, const value_type& val, std::true_type){ + int i = 0; + for (; i != n / 2; ++i) + (*this).push_front(val); + for (; i != n; ++i) + (*this).push_back(val); + } + template + template + void deque::deque_aux(Iterator first, Iterator last, std::false_type){ + difference_type mid = (last - first) / 2; + for (auto it = first + mid; it != first - 1; --it) + (*this).push_front(*it); + for (auto it = first + mid + 1; it != last; ++it) + (*this).push_back(*it); + } + template + void deque::init(){ + mapSize_ = 2; + map_ = getANewMap(mapSize_); + beg_.container_ = end_.container_ = this; + beg_.mapIndex_ = end_.mapIndex_ = mapSize_ - 1; + beg_.cur_ = end_.cur_ = map_[mapSize_ - 1]; + } + template + T *deque::getANewBuck(){ + return dataAllocator::allocate(getBuckSize()); + } + template + T** deque::getANewMap(const size_t size){ + T **map = new T*[size]; + for (int i = 0; i != size; ++i) + map[i] = getANewBuck(); + return map; + } + template + size_t deque::getNewMapSize(const size_t size){ + return (size == 0 ? 2 : size * 2); + } + template + size_t deque::getBuckSize()const{ + return (size_t)EBucksSize::BUCKSIZE; + } + template + void deque::clear(){ + /*for (int i = 0; i != mapSize_; ++i) + if (!map_[i]) + dataAllocator::destroy(map_[i], map_[i] + getBuckSize());*/ + for (auto i = 0; i != mapSize_; ++i){ + for (auto p = map_[i] + 0; !p && p != map_[i] + getBuckSize(); ++p) + dataAllocator::destroy(p); + } + mapSize_ = 0; + beg_.mapIndex_ = end_.mapIndex_ = mapSize_ / 2; + beg_.cur_ = end_.cur_ = map_[mapSize_ / 2]; + } + template + typename deque::reference deque::operator[] (size_type n){ + return *(begin() + n); + } + template + typename deque::reference deque::front(){ + return *begin(); + } + template + typename deque::reference deque::back(){ + return *(end() - 1); + } + //由于const迭代器的设计失误故以下三个const函数会丧失const特性 + template + typename deque::const_reference deque::operator[] (size_type n) const{ + return *(begin() + n); + } + template + typename deque::const_reference deque::front() const{ + return *begin(); + } + template + typename deque::const_reference deque::back() const{ + return *(end() - 1); + } + template + typename deque::iterator deque::begin(){ return beg_; } + template + typename deque::iterator deque::end(){ return end_; } + //迭代器设计失误,会使下面两个函数丧失const特性,暂时没有效解决办法故只能先这样妥协 + template + typename deque::iterator deque::begin()const{ return beg_; } + template + typename deque::iterator deque::end()const{ return end_; } + template + deque::~deque(){ + for (int i = 0; i != mapSize_; ++i){ + for (auto p = map_[i] + 0; !p && p != map_[i] + getBuckSize(); ++p) + dataAllocator::destroy(p); + if (!map_[i]) + dataAllocator::deallocate(map_[i], getBuckSize()); + } + delete[] map_; + } + template + deque::deque() + :mapSize_(0), map_(0){} + template + deque::deque(size_type n, const value_type& val = value_type()){ + deque(); + deque_aux(n, val, typename std::is_integral::type()); + } + template + template + deque::deque(InputIterator first, InputIterator last){ + deque(); + deque_aux(first, last, typename std::is_integral::type()); + } + template + deque::deque(const deque& x){ + mapSize_ = x.mapSize_; + map_ = getANewMap(mapSize_); + for (int i = 0; i + x.beg_.mapIndex_ != x.mapSize_; ++i) + for (int j = 0; j != getBuckSize(); ++j) + map_[x.beg_.mapIndex_ + i][j] = x.map_[x.beg_.mapIndex_ + i][j]; + beg_.mapIndex_ = x.beg_.mapIndex_; + end_.mapIndex_ = x.end_.mapIndex_; + beg_.cur_ = map_[beg_.mapIndex_] + (x.beg_.cur_ - x.map_[x.beg_.mapIndex_]); + end_.cur_ = map_[end_.mapIndex_] + (x.end_.cur_ - x.map_[x.end_.mapIndex_]); + beg_.container_ = end_.container_ = this; + } + template + void deque::reallocateAndCopy(){ + auto newMapSize = getNewMapSize(mapSize_); + T** newMap = getANewMap(newMapSize); + size_t startIndex = newMapSize / 4; + for (int i = 0; i + beg_.mapIndex_ != mapSize_; ++i) + for (int j = 0; j != getBuckSize(); ++j) + newMap[startIndex + i][j] = map_[beg_.mapIndex_ + i][j]; + + size_t n = beg_.cur_ - map_[beg_.mapIndex_]; + auto size = this->size(); + auto b = beg_, e = end_; + clear(); + mapSize_ = newMapSize; + map_ = newMap; + beg_ = iterator(startIndex, newMap[startIndex] + n, this); + end_ = beg_ + size; + + } + template + void deque::push_back(const value_type& val){ + if (empty()){ + init(); + } + else if (back_full()){ + reallocateAndCopy(); + } + //*end_ = val; + //bug fix + //2015.01.02 + TinySTL::construct(end_.cur_, val); + ++end_; + } + template + void deque::push_front(const value_type& val){ + if (empty()){ + init(); + } + else if (front_full()){ + reallocateAndCopy(); + } + --beg_; + //*beg_ = val; + //bug fix + //2015.01.02 + TinySTL::construct(beg_.cur_, val); + } + template + void deque::pop_front(){ + dataAllocator::destroy(beg_.cur_); + ++beg_; + } + template + void deque::pop_back(){ + --end_; + dataAllocator::destroy(end_.cur_); + } + template + void deque::swap(deque& x){ + TinySTL::swap(mapSize_, x.mapSize_); + TinySTL::swap(map_, x.map_); + beg_.swap(x.beg_); + end_.swap(x.end_); + } + + template + bool operator== (const deque& lhs, const deque& rhs){ + auto cit1 = lhs.begin(), cit2 = rhs.begin(); + for (; cit1 != lhs.end() && cit2 != rhs.end(); ++cit1, ++cit2){ + if (*cit1 != *cit2) + return false; + } + if (cit1 == lhs.end() && cit2 == rhs.end()) + return true; + return false; + } + template + bool operator!= (const deque& lhs, const deque& rhs){ + return !(lhs == rhs); + } + template + void swap(deque& x, deque& y){ + x.swap(y); + } +} +#endif \ No newline at end of file