void push_back(const value_type& t)
{
// 最后缓冲区尚有两个(含)以上的元素备用空间
if (finish.cur != finish.last - 1)
{
construct(finish.cur, t); // 直接在备用空间上构造元素
++finish.cur; // 调整最后缓冲区的使用状态
}
// 容量已满就要新申请内存了
else
push_back_aux(t);
}
// 只有当finish.cur == finish.last - 1 时才会被调用
// 也就是说,只有当最后一个缓冲区只剩下一个备用元素空间时才会被调用
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::push_back_aux(const value_type& t)
{
value_type t_copy = t;
reserve_map_at_back();
*(finish.node + 1) = allocate_node(); // 配置一个新节点(缓冲区)
__STL_TRY
{
construct(finish.cur, t_copy); // 针对标的元素设值
finish.set_node(finish.node + 1); // 改变finish,令其指向新节点
finish.cur = finish.first; // 设定finish的状态
}
__STL_UNWIND(deallocate_node(*(finish.node + 1)));
}
void reserve_map_at_back (size_type nodes_to_add = 1)
{
// l= map + map_size ==最后的node之后一个越界的node
// l-finish.node -1 == 剩下的node个数
// nodes_to_add > l - finish.node -1 不需要重新分配内存
if(nodes_to_add + 1 > map_size - (finish.node - map))
reallocate_map(nodes_to_add,false);//false表示在尾部重分配
}
//reallocate_map
template<class T,class Alloc,size_t BufSize>
void deque<T,Alloc,BufSize>::reallocate_map(size_type nodes_to_add, bool add_at_front)
{
size_type ole_num_nodes = finish.node - start.node + 1;
size_type new_num_nodes = ole_num_nodes + nodes_to_add;
map_pointer new_nstart;//T**类型
if(map_size > 2 * new_num_nodes)
{
//node内存数量是 两倍的 新的node数量 时调用, 头尾总是pop时,会剩余大量node
/*
最后要使头尾剩下的可分配(未使用)的node数量一样
如果add_at_front = true new_nstart会多一个node节点
如果add_at_front = false new_nfinish会多一个node节点
说到底 这个reallocate函数并不添加node,他的使命是确保有足够的
nodes给前面的aux函数使用
*/
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 + ole_num_nodes);
}
else
{
//剩下的没有两倍就 重新分配一块nodes内存
//新的缓存区起码要留map_size+2 的大小
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 + ole_num_nodes);
}
void push_front(const value_type& t)
{
if (start.cur != start.first) // 第一缓冲区尚有备用空间
{
construct(start.cur - 1, t); // 直接在备用空间上构造元素
--start.cur; // 调整第一缓冲区的使用状态
}
else // 第一缓冲区已无备用空间
push_front_aux(t);
}
// Called only if start.cur == start.first.
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::push_front_aux(const value_type& t)
{
value_type t_copy = t;
reserve_map_at_front();
*(start.node - 1) = allocate_node();
__STL_TRY
{
start.set_node(start.node - 1); // 改变start,令其指向新节点
start.cur = start.last - 1; // 设定start的状态
construct(start.cur, t_copy); // 针对标的元素设值
}
catch(...)
{
start.set_node(start.node + 1);
start.cur = start.first;
deallocate_node(*(start.node - 1));
throw;
}
}
pop_back和pop_front函数讲解:
//pop_back
void pop_back()
{
if(finish.cur != finish.first)
{
--finish.cur;
destroy(finish.cur);
}
else
pop_back_aux();
}
//pop_back_aux
template<class T,class Alloc,size_t BufSize>
void deque<T,Alloc,BufSize>::pop_back_aux()
{
//释放finish的缓存,使finish指向前一个node末尾
//deallocate_node(pointer n){ data_allocator::deallocate(n,buffer_size());}
deallocate_node(finish.first);
finish.set_node(finish.node - 1);
finish.cur = finish.last -1;
destroy(finish.cur);
}
//pop_front
void pop_front()
{
if(start.cur != start.last -1 )
{
destroy(start.cur)
++start.cur;
}
else
pop_front_aux();
}
//pop_front_aux
template<class T,class Alloc,size_t BufSize>
void deque<T,Alloc,BufSize>::pop_front_aux()
{
destroy(start.cur);
deallocate_node(start.first);
start.set_node(start.node +1);
start.cur = start.first;
}
clear函数讲解:
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::clear()
{
// 以下针对头尾以外的每一个缓冲区
for (map_pointer node = start.node + 1; node < finish.node; ++node)
{
// 将缓冲区内的所有元素析构
destroy(*node, *node + buffer_size());
// 释放缓冲区内存
data_allocator::deallocate(*node, buffer_size());
}
if (start.node != finish.node) // 至少有头尾两个缓冲区
{
destroy(start.cur, start.last); // 将头缓冲区的目前所有元素析构
destroy(finish.first, finish.cur); // 将尾缓冲区的目前所有元素析构
// 以下释放尾缓冲区。注意:头缓冲区保留
data_allocator::deallocate(finish.first, buffer_size());
}
else // 只有一个缓冲区
destroy(start.cur, finish.cur); // 将此唯一缓冲区内的所有元素析构
// 注意:并不释放缓冲区空间,这唯一的缓冲区将保留
finish = start; // 调整状态
}
erase函数讲解:
iterator 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;
}
insert相关函数:
iterator 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 <class T, class Alloc, size_t BufSize>
typename deque<T, Alloc, BufSize>::iterator
deque<T, Alloc, BufSize>::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;
}
deque完结!