# STL（六）：deque

deque 是双端队列。也就是，方便在队头和队尾插入数据的队列。

## 数据结构

deque的数据组织是这样的：

deque 主要是维护好中控器和数据的关系。

deque 还是比较复杂的，实现的代码超千行了。

## 迭代器

template<typename T, typename Ref, typename Ptr, size_t Buff_size>
struct _deque_iterator
{
typedef _deque_iterator<T, T&, T*, Buff_size> iterator;
typedef _deque_iterator<T, const T&, const T*, Buff_size> const_iterator;
typedef _deque_iterator self;

static size_t buffer_size()
{
return _deque_buf_size(Buff_size, sizeof(T) );
}

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 random_access_iterator_tag iterator_category;

pointer curr;
pointer first;
pointer last;
map_pointer node;

void set_node(map_pointer new_node)
{
node = new_node;
first = *node;
last = first + buffer_size();
}
//-----------------function -------------
_deque_iterator() : curr(0), first(0), last(0), node(0) {}
_deque_iterator(pointer x, map_pointer y): node(y), first(*y), last(*y + buffer_size()), curr(x) {}
_deque_iterator(const iterator& x): curr(x.curr), first(x.first), last(x.last), node(x.node) {}

...
}


difference_type operator - (const self& x) const
{
//这个计算公式非常巧妙，值得推敲一番
return difference_type( (node-x.node-1)*buffer_size() + (curr - first) + (x.last - x.curr) );
}
self& operator += (difference_type dist)
{
difference_type offset = dist + (curr - first);
if(offset >=0 && offset < difference_type(buffer_size() ))
curr += dist;
else
{
//这个计算公式.....有点厉害，我承认我写的代码是垃圾=_=
difference_type node_offset = offset >0 ? offset / difference_type(buffer_size() )
: -difference_type( (-offset - 1)/buffer_size()) -1;
set_node(node + node_offset);
curr = first + (offset - node_offset * difference_type(buffer_size()) );
}
return *this;
}

## 一些默认的行为

deque 的声明如下：

template<typename T, typename Alloc = alloc, size_t Buff_size = 0>
class deque;


/** _deque_buf_size 决定缓冲区大小的函数
@param n 模板中的参数
@param sz sizeof(T)
*/
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) );
}

–END–