这篇代码是写给自己看的,所以没什么注释,大家可以去看侯捷先生的《STL 源码剖析》
//mydeque.h
#include"myconstruct.h"
#include"mymemory.h"
using std::max;
using std::copy_backward;
/*deque是双向开头的连续线性空间,它动态地以分段连续空间组合而成,这个表面上deque的迭代器
*支持随机访问,实则是假象,这里是以复杂的迭代器构架来维持此假象,我学习stl deque的目的是
*研究它迭代器的构造,而非实用性;
*/
/*deque采用一块map作为主控,这里的map是一小块连续空间,其中的每个元素都是指针,指向另一块
*连续的线性空间,称为缓冲区,缓冲区是存储主体,允许指定缓冲区的大小,默认情况下为512byte
*/
/*结构 ——————————————————————————
*map 指向一段区域| |node| |
* ——————————————————————————
*每个node指向一片连续空间
*/
//BufSiz为缓冲区的大小,意为BufSiz个元素大小
template<typename T,typename Ref,typename Ptr,size_t BufSiz>
struct __deque_iterator
{
typedef __deque_iterator<T,T&,T*,BufSiz> iterator;
typedef __deque_iterator<T,const T&,const T*> const_iterator;
static size_t buffer_size(){return __deque_buf_size(BufSize,sizeof(T))};
typedef random_iterator_tag iterator_category;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T** map_pointer;
typedef __deque_iterator self;
//保持与容器的联结
T* cur;//所指元素;这里的cur依然保持迭代器特征,如果在最前端,则指向最前端元素,
//如果在最后端指向最后端的下一个元素
T* first;//所指元素所在的缓冲区的头
T* last;//所指元素所在的缓冲区的尾
map_pointer node;//指向这一缓冲区的在map中的节点位置
private:
//辅助函数
void set_node(map_pointer new_node)//切换node
{
node=new_node;
first=*new_node;
last=first+difference_type(buffer_size());
}
public:
/*---------------------重载的操作符-------------------------------------------*/
//必要的操作符
reference operator*() const {return *cur;}
pointer operator->() const {return &(operator*());}
self& operator++()
{++cur;if(cur==last){set_node(node+1);cur=first;} return *this;}
self operator++(int)
{self tmp=*this;++*this;return tmp;}
self& operator--()
{if(cur==first){set_node(node-1);cur=last;} --cur;return *this;}
self operator--(int)
{self tmp=*this;--*this;return tmp;}
//支持随机存取的实现
difference_type operator-(const self& x) const
{return difference_type(buffer_size())*(node-x.node-1) + (cur-first)+(x.last-x.cur);}
self& operator+=(difference_type n);
self operator+(difference_type n) const
{self tmp=*this;return tmp+=n;}
self& operator-=(difference_type n){return *this+=-n;}
self operator-(difference_type n)const {self tmp=*this;return tmp-=n;}
reference operator[](difference_type n)const {return *(*this+n);}
//判断操作符
bool operator==(const self& x) const{return cur==x.cur;}
bool operator!=(const self& x) const {return !(*this==x);}
bool operator<(const self& x)const
{return (node==x.node)?(cur<x.cur):(node<x.node);}
};
//全局函数,如果n不为0,那么返回n;如果n为0,那么使用默认值512byte,返回值为512/sz
inline size_t __deque_buf_size(size_t n,size_t sz)
{
return (n!=0)?n :( (sz<512)?size_t(512/sz):size_t(1));
}
//---------------------------------------------------------------------------
template<typename T,typename Ref,typename Ptr,size_t BufSiz>
typename __deque_iterator<T,Ref,Ptr,BufSiz>::self&
__deque_iterator<T,Ref,Ptr,BufSiz>::operator+=(difference_type n)
{
difference_type offset=n+(cur-first);
if(offset>=0 && offset<difference_type(buffer_size()))
//还在原缓冲区中
cur+=n;
else{
//不在原缓冲区中,此处的计算较复杂
difference_type node_offset=offset>0?offset/difference_type(buffer_size())
:-difference_type((-offset-1)/buffer_size())-1;
set_node(node+node_offset);
cur=first+(offset-node_offset*difference_type(buffer_size()));
}
return *this;
}
//-------------------------------------------------------------------------------------------
template<typename T,typename Alloc=alloc,size_t BufSiz=0>
class deque
{
public:
typedef T value_type;
typedef value_type* pointer;
typedef size_t size_type;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef ptrdiff_t difference_type;
typedef __deque_iterator<T,T&,T*,BufSiz> iterator;
protected:
//元素的指针的指针
typedef pointer* map_pointer;
//Data member
size_type map_size;//map所指区域的大小
map_pointer map;
iterator start;//第一个节点,用iterator包含缓冲区的信息
iterator finish;//last迭代器
protected:
//配置缓冲区中的元素
typedef simple_alloc<value_type,Alloc> data_allocator;
//配置map中的元素,即node
typedef simple_alloc<pointer,Alloc> map_allocator;
public:
deque(int n,const value_type& value)
:map_size(0),start(),finish(),map(0){fill_initialize(n,value);}
iterator begin(){return start;}
iterator end(){return finish;}
size_type buffer_size(){return iterator::buffer_size();}
reference operator[](size_type n){return start[difference_type(n)];}
reference front(){return *start;}
reference back()
{iterator tmp=finish;--tmp;return *tmp;}
size_type size() const {return finish-start;}
size_type max_size() const {return size_type(-1);}//什么意思?
bool empty() const {return finish==start;}
public:
void push_back(const value_type& t);
void push_front(const value_type& t);
void pop_back();
void pop_front();
void clear();//清除元素,最后留一个缓冲区
iterator erase(iterator pos);
iterator insert(iterator position,const value_type& x);
private:
//辅助函数
void fill_initialize(size_type n,const value_type& value);
void create_map_and_node(size_type num_elem);
value_type* allocate_node();//分配一个缓冲区
void deallocate_node(value_type* p);//释放一个缓冲区
void push_back_aux(const value_type& t);
void push_front_aux(const value_type& t);
void pop_back_aux();
void pop_front_aux();
iterator insert_aux(iterator pos,const value_type& x);
//以下三个函数解决:什么时候map需要重新整治?
void reserve_map_at_back(size_type nodes_to_add=1);
void reserve_map_at_front(size_type nodes_to_add=1);
void reallocate_map(size_type nodes_to_add,bool add_at_front);
};
//----------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::fill_initialize(size_type n,const value_type& value)
{
create_map_and_nodes(n);
map_pointer cur;
for(cur=start.node;cur<finish.node;++cur)
uninitialized_fill(*cur,*cur+buffer_size(),value);
//最后一个节点的值设定:
uninitialized_fill(finish.first,finish.cur,value);
}
//------------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
deque<T,Alloc,BufSiz>::value_type* deque<T,Alloc,BufSiz>::allocate_node()
{
return data_allocator::allocate(buffer_size());
}
//--------------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::deallocate_node(value_type* p)
{
data_allocator::deallocate(buffer_size());
}
//------------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::create_map_and_node(size_type num_elem)
{
//需要的map节点数:元素个数/每个缓冲区可容纳的元素数 +1
size_type num_node=num_elem/buffer_size()+1;
//一个map要管理的结点数最少是8个,最多是所需结点数加2,(前后各预留一个)
map_size=max(8,num_node+2);
map=map_allocator::allocate(map_size);
//map配置完毕
//令map从中央开始扩增
map_pointer nstart=map+(map_size-num_node)/2;
map_pointer nfinish=nstart+num_node-1;
map_pointer cur;
try{
//为每个节点配置缓冲区
for(cur=nstart;cur<=nfinish;++cur)
*cur=allocate_node();
}catch(...){
//commit or rollback
for(cur=nstart;cur!=NULL;++cur)
deallocate_node(*cur);
}
start.set_node(nstart);
finish.set_node(nfinish);
start.cur=start.first;
finish.cur=finish.first+num_elem%buffer_size();
}
//-----------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::push_back(const value_type& t)
{
if(finish.cur!=finish.last-1){
//最后缓冲区还有两个以上的备用空间
construct(finish.cur,t);
++finish.cur;
}else{
//只剩一个元素的备用空间
push_back_aux(t);
}
}
//----------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::push_back_aux(const value_type& t)
{
value_type t_copy=t;
reserve_map_at_back();//若符合某种条件则必须重换一个map
*(finish.node+1)=allocate_node();
try{
construct(finish.cur,t_copy);
finish.set_node(finish.node+1);
finish.cur=finish.first;
}catch(...){
finish.set_node(finish.node-1);
finish.cur=finish.last-1;
deallocate_node(*(finish.node+1));
throw;
}
}
//------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::push_front(const value_type& t)
{
if(start.cur!=start.first){
construct(start.cur-1,t);
--finish.cur;
}else{
push_front_aux(t);
}
}
//---------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::push_front_aux(const value_type& t)
{
value_type t_copy=t;
reserve_map_at_front();
*(start.node-1)=allocate_node();
try{
start.set_node(start.node-1);
start.cur=start.last-1;
construct(start.cur,t_copy);
}catch(...){
//commit or rollback
start.set_node(start.node+1);
start.cur=start.first;
deallocate_node(*(start.node-1));
throw;
}
}
//-------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::reserve_map_at_back(size_type nodes_to_add=1)
{
if(nodes_to_add+1>map_size-(finish.node-map)){
//尾部空间不足,需要换一个map
reallocate_map(nodes_to_add,false);
}
}
//----------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::reserve_map_at_front(size_type nodes_to_add=1)
{
if(nodes_to_add>start.node-map){
reallocate_map(nodes_to_add,true);
}
}
//------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::reallocate_map(size_type nodes_to_add,bool add_at_front)
{
size_type old_num_nodes=finish.node-start.node+1;
size_type new_num_nodes=old_num_nodes+nodes_to_add;
map_pointer new_nstart;
if(map_size>2*new_num_nodes){
new_nstart=map+(map_size-new_num_nodes)/2+(add_at_front?nodes_to_add:0);
if(new_nstart<start.node)
copy(start.node,finish.node+1,new_nstart);
else
copy_backward(start.node,finish.node+1,new_nstart+old_num_nodes);
}else{
size_type new_map_size=map_size+max(map_size,nodes_to_add)+2;
//配置新空间
map_pointer new_map=map_allocator::allocate(new_map_size);
new_nstart=new_map+(new_map_size-new_num_nodes)/2+(add_at_front?nodes_to_add:0);
copy(start.node,finish.node+1,new_nstart);
map_allocator::deallocate(map,map_size);
map=new_map;
map_size=new_map_size;
}
start.set_node(new_nstart);
finish.set_node(new_nstart+old_num_nodes-1);
}
//-----------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::pop_back()
{
if(finish.cur!=finish.first){
--finish.cur;
destroy(finish.cur);
}else{
pop_back_aux();
}
}
//---------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::pop_back_aux()
{
deallocate_node(*(finish.node));
finish.set_node(finish.node-1);
finish.cur=finish.last-1;
destroy(finish.cur);
}
//-----------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::pop_front()
{
if(start.cur!=start.last-1){
destroy(start.cur);
++start.cur;
}else{
pop_front_aux();
}
}
//---------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::pop_front_aux()
{
destroy(start.cur);
deallocate_node(*(start.node));
start.set_node(start.node+1);
start.cur=start.first;
}
//-----------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
void deque<T,Alloc,BufSiz>::clear()
{
for(map_pointer node=start.node+1;node<finish.node;++node){
destroy(*node,*node+buffer_size());
deallocate_node(*(node));
}
if(start.node!=finish.node){
destroy(start.cur,start.last);
destroy(finish.first,finish.cur);
deallocate_node(*(finish.node));
}else{//只有一个缓冲区
destroy(start.cur,finish.cur);//析构所有元素
finish=start;
}
}
//-------------------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
typename deque<T,Alloc,BufSiz>::iterator deque<T,Alloc,BufSiz>::erase(iterator pos)
{
iterator next=pos;
++next;
difference_type index=pos-start;
if(index<(size()>>1)){//清除元素之前的元素比较少
copy_backward(start,pos,next);
pop_front();
}else{
copy(next,finish,pos);
pop_back();
}
return start+index;
}
//---------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
typename deque<T,Alloc,BufSiz>::iterator
deque<T,Alloc,BufSiz>::insert(iterator position,const value_type& x)
{
if(position.cur==start.cur){
push_front(x);
return start;
}else if(position.cur==finish.cur){
push_back(x);
iterator tmp=finish;
--tmp;
return tmp;
}else{
return insert_aux(position,x);
}
}
//-----------------------------------------------------------------------------------
template<typename T,typename Alloc,size_t BufSiz>
typename deque<T,Alloc,BufSiz>::iterator
deque<T,Alloc,BufSiz>::insert_aux(iterator pos,const value_type& x)
{
difference_type index=pos-start;
value_type x_copy=x;
if(index<size()/2){
push_front(front());
iterator front1=start;
++front1;
iterator front2=front1;
++front2;
pos=start+index;
iterator pos1=pos;
++pos1;
copy(front2,pos1,front1);
}else{
push_back(back());
iterator back1=finish;
--back1;
iterator back2=back1;
--back2;
pos=start+index;
copy_backward(pos,back2,back1);
}
*pos=x_copy;
return pos;
}