完成deque的迭代器的基本操作接口
This commit is contained in:
179
TinySTL/Deque.h
179
TinySTL/Deque.h
@@ -2,37 +2,169 @@
|
|||||||
#define _DEQUE_H_
|
#define _DEQUE_H_
|
||||||
|
|
||||||
#include "Allocator.h"
|
#include "Allocator.h"
|
||||||
|
#include "Iterator.h"
|
||||||
#include "ReverseIterator.h"
|
#include "ReverseIterator.h"
|
||||||
|
|
||||||
namespace TinySTL{
|
namespace TinySTL{
|
||||||
//class of deque iterator
|
template<class T, class Alloc = allocator<T>>
|
||||||
class diter{};
|
class deque;
|
||||||
|
namespace{
|
||||||
|
//class of deque iterator
|
||||||
|
template<class T>
|
||||||
|
class diter :public iterator<bidirectional_iterator_tag, T>{
|
||||||
|
private:
|
||||||
|
typedef TinySTL::deque<T>* 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<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬһ<CDAC><D2BB>Ͱ<EFBFBD><CDB0>
|
||||||
|
++cur_;
|
||||||
|
else{
|
||||||
|
++mapIndex_;
|
||||||
|
cur_ = getBuckHead(mapIndex_);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
diter operator ++(int){
|
||||||
|
auto res = *this;
|
||||||
|
++(*this);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
diter& operator --(){
|
||||||
|
if (cur_ != getBuckHead(mapIndex_))//<2F><>ǰ<EFBFBD><C7B0>ָ<EFBFBD><D6B8>Ͱͷ
|
||||||
|
--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<class T>
|
||||||
|
friend diter<T> operator + (const diter<T>& it, typename diter<T>::difference_type n);
|
||||||
|
template<class T>
|
||||||
|
friend diter<T> operator + (typename diter<T>::difference_type n, const diter<T>& it);
|
||||||
|
template<class T>
|
||||||
|
friend diter<T> operator - (const diter<T>& it, typename diter<T>::difference_type n);
|
||||||
|
template<class T>
|
||||||
|
friend diter<T> operator - (typename diter<T>::difference_type n, const diter<T>& it);
|
||||||
|
template<class T>
|
||||||
|
friend typename diter<T>::difference_type operator - (const diter<T>& it1, const diter<T>& it2);
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
diter<T> operator + (const diter<T>& it, typename diter<T>::difference_type n){//assume n >= 0
|
||||||
|
diter<T> res(it);
|
||||||
|
auto m = res.getBuckTail(res.mapIndex_) - res.cur_;
|
||||||
|
if (n <= m){//ǰ<><C7B0>n<EFBFBD><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬһ<CDAC><D2BB>Ͱ<EFBFBD><CDB0>
|
||||||
|
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<class T>
|
||||||
|
diter<T> operator + (typename diter<T>::difference_type n, const diter<T>& it){
|
||||||
|
return (it + n);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
diter<T> operator - (const diter<T>& it, typename diter<T>::difference_type n){//assume n >= 0
|
||||||
|
diter<T> res(it);
|
||||||
|
auto m = res.cur_ - res.getBuckHead(res.mapIndex_);
|
||||||
|
if (n <= m)//<2F><><EFBFBD><EFBFBD>n<EFBFBD><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬһ<CDAC><D2BB>Ͱ<EFBFBD><CDB0>
|
||||||
|
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<class T>
|
||||||
|
diter<T> operator - (typename diter<T>::difference_type n, const diter<T>& it){
|
||||||
|
return (it - n);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
typename diter<T>::difference_type operator - (const diter<T>& it1, const diter<T>& it2){
|
||||||
|
return typename diter<T>::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
|
//class of deque
|
||||||
template<class T, class Alloc = TinySTL::allocator<T>>
|
template<class T, class Alloc>
|
||||||
class deque{
|
class deque{
|
||||||
|
private:
|
||||||
|
template<class T>
|
||||||
|
friend class diter;
|
||||||
public:
|
public:
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef diter iterator;
|
typedef diter<T> iterator;
|
||||||
typedef const iterator const_iterator;
|
typedef const iterator const_iterator;
|
||||||
typedef reverse_iterator<iterator> reverse_iterator;
|
typedef reverse_iterator<iterator> reverse_iterator;
|
||||||
typedef reverse_iterator<const_iterator> const_reverse_iterator;
|
typedef const reverse_iterator const_reverse_iterator;
|
||||||
typedef T& reference;
|
typedef T& reference;
|
||||||
typedef const reference const_reference;
|
typedef const reference const_reference;
|
||||||
typedef size_t size_type;
|
typedef size_t size_type;
|
||||||
typedef ptrdiff_t difference_type;
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef Alloc allocator_type;
|
||||||
private:
|
private:
|
||||||
typedef Alloc dataAllocator;
|
typedef Alloc dataAllocator;
|
||||||
|
enum class EBucksSize{BUCKSIZE = 64};
|
||||||
T *bucks;
|
private:
|
||||||
|
iterator beg_, end_;
|
||||||
|
size_t mapSize_;
|
||||||
|
T **map_;
|
||||||
public:
|
public:
|
||||||
explicit deque(const allocator_type& alloc = allocator_type());
|
deque();
|
||||||
explicit deque(size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type());
|
explicit deque(size_type n, const value_type& val = value_type());
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
deque(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
|
deque(InputIterator first, InputIterator last);
|
||||||
deque(const deque& x);
|
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= (const deque& x);
|
||||||
deque& operator= (deque&& x);
|
deque& operator= (deque&& x);
|
||||||
@@ -77,6 +209,20 @@ namespace TinySTL{
|
|||||||
iterator erase(iterator first, iterator last);
|
iterator erase(iterator first, iterator last);
|
||||||
void swap(deque& x);
|
void swap(deque& x);
|
||||||
void clear();
|
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:
|
public:
|
||||||
template <class T, class Alloc>
|
template <class T, class Alloc>
|
||||||
friend bool operator== (const deque<T, Alloc>& lhs, const deque<T, Alloc>& rhs);
|
friend bool operator== (const deque<T, Alloc>& lhs, const deque<T, Alloc>& rhs);
|
||||||
@@ -93,5 +239,16 @@ namespace TinySTL{
|
|||||||
template <class T, class Alloc>
|
template <class T, class Alloc>
|
||||||
friend void swap(deque<T, Alloc>& x, deque<T, Alloc>& y);
|
friend void swap(deque<T, Alloc>& x, deque<T, Alloc>& y);
|
||||||
};//end of deque
|
};//end of deque
|
||||||
|
|
||||||
|
template<class T, class Alloc>
|
||||||
|
deque<T, Alloc>::deque()
|
||||||
|
:mapSize_(0), map_(0){}
|
||||||
|
//template<class T, class Alloc>
|
||||||
|
//deque<T, Alloc>::deque(size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type());
|
||||||
|
//template<class T, class Alloc>
|
||||||
|
//template <class InputIterator>
|
||||||
|
//deque<T, Alloc>::deque(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
|
||||||
|
//template<class T, class Alloc>
|
||||||
|
//deque<T, Alloc>::deque(const deque& x);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user