//
template <class T, class Alloc = alloc, size_t BufSiz = 0>
class deque {
public: // Basic types
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
public: // Iterators
typedef __deque_iterator<T, T&, T*, BufSiz> iterator;
typedef __deque_iterator<T, const T&, const T&, BufSiz> const_iterator;
typedef reverse_iterator<const_iterator, value_type, const_reference,
difference_type>
const_reverse_iterator;
typedef reverse_iterator<iterator, value_type, reference, difference_type>
reverse_iterator;
protected: // Internal typedefs
typedef pointer* map_pointer;
typedef simple_alloc<value_type, Alloc> data_allocator;
typedef simple_alloc<pointer, Alloc> map_allocator;
static size_type buffer_size() {
return __deque_buf_size(BufSiz, sizeof(value_type));
}
//一个map最少要管理8个节点,在产生deque结构时用到
//create_map_and_nodes()函数中:map_size = max(initial_map_size(), num_nodes + 2);
//map_size 是map要的节点数,num_nodes 客户需求的节点数,详看create_map_and_nodes()函数
static size_type initial_map_size() { return 8; }
protected: // Data members
//看图4.4-2
//start对应第一个缓冲区,start.node指向已经在使用的第一个map节点
//finish对应最后一个缓冲区,finish.node指向已经在使用的最后一个map节点
//如果map只有一个节点在使用,则start.node==finish.node,但start不一定等finish
//start是否等于finish,要看start.cur是否等于finish.cur (迭代器重载==)
iterator start;
iterator finish;
map_pointer map;
size_type map_size;
public: // Basic accessors
iterator begin() { return start; }
iterator end() { return finish; }
const_iterator begin() const { return start; }
const_iterator end() const { return finish; }
reverse_iterator rbegin() { return reverse_iterator(finish); }
reverse_iterator rend() { return reverse_iterator(start); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(finish);
}
const_reverse_iterator rend() const {
return const_reverse_iterator(start);
}
reference operator[](size_type n) { return start[difference_type(n)]; }
const_reference operator[](size_type n) const {
return start[difference_type(n)];
}
reference front() { return *start; }
//如图4.4-3,finish.cur指向的备用空间,最后一个元素在cur的前一个
//所以--tmp(调用重载,看__deque_iterator),cur会前移一位,*tmp会返回*cur
//tmp是finish的拷贝,所以tmp的cur改变,并不影响finish的cur
reference back() {
iterator tmp = finish;
--tmp;
return *tmp;
}
const_reference front() const { return *start; }
const_reference back() const {
const_iterator tmp = finish;
--tmp;
return *tmp;
}
//调用迭代器的重载operator-(const self& x)
size_type size() const { return finish - start;; }
size_type max_size() const { return size_type(-1); }
//调用迭代器的重载operator==(const self& x)判断finish.cur==start.cur
bool empty() const { return finish == start; }
public: // Constructor, destructor.
deque()
: start(), finish(), map(0), map_size(0)
{
//构建了一个有8个map节点,一个缓冲区的deque
//start.node==finish.node且start.cur==finish.cur
create_map_and_nodes(0);
}
deque(const deque& x)
: start(), finish(), map(0), map_size(0)
{
//配置好deque整个结构(只差数据没填入)
create_map_and_nodes(x.size());
__STL_TRY{
//填充数据,p70-1
uninitialized_copy(x.begin(), x.end(), start);
}
__STL_UNWIND(destroy_map_and_nodes());
}
deque(size_type n, const value_type& value)
: start(), finish(), map(0), map_size(0)
{
//传入元素个数和初值,构建好deque
fill_initialize(n, value);
}
deque(int n, const value_type& value)
: start(), finish(), map(0), map_size(0)
{
fill_initialize(n, value);
}
deque(long n, const value_type& value)
: start(), finish(), map(0), map_size(0)
{
fill_initialize(n, value);
}
explicit deque(size_type n)
: start(), finish(), map(0), map_size(0)
{
fill_initialize(n, value_type());
}
deque(const value_type* first, const value_type* last)
: start(), finish(), map(0), map_size(0)
{
create_map_and_nodes(last - first);
__STL_TRY{
uninitialized_copy(first, last, start);
}
__STL_UNWIND(destroy_map_and_nodes());
}
deque(const_iterator first, const_iterator last)
: start(), finish(), map(0), map_size(0)
{
create_map_and_nodes(last - first);
__STL_TRY{
uninitialized_copy(first, last, start);
}
__STL_UNWIND(destroy_map_and_nodes());
}
~deque() {
//销毁掉所有元素 @
destroy(start, finish);
//销毁掉map所有节点和所有缓冲区
destroy_map_and_nodes();
}
deque& operator= (const deque& x) {
const size_type len = size();
if (&x != this) {
if (len >= x.size())
//copy详见stl_algobase.h p315-1
//把x的元素全部copy过来,并把原deque后面多余的移除掉
erase(copy(x.begin(), x.end(), start), finish);
else {
const_iterator mid = x.begin() + difference_type(len);
//把x的前len个元素copy过来,再把后面的元素用插入的方式移进
copy(x.begin(), mid, start);
insert(finish, mid, x.end());
}
}
return *this;
}
void swap(deque& x) {
__STD::swap(start, x.start);
__STD::swap(finish, x.finish);
__STD::swap(map, x.map);
__STD::swap(map_size, x.map_size);
}
public: // push_* and pop_*
void push_back(const value_type& t) {
if (finish.cur != finish.last - 1) {
//当前缓冲区备用空间>=2
//finish.cur指向最后一个元素的尾地址(第一个备用空间首地址),finish.last指向缓冲区末尾地址
//详见stl_construct.h
construct(finish.cur, t);
++finish.cur;
}
else
//当前缓冲区剩最后一个备用空间,插入后,要增加一个缓冲区
push_back_aux(t);
}
void push_front(const value_type& t) {
if (start.cur != start.first) {
construct(start.cur - 1, t);
--start.cur;
}
else
//要向前加缓冲区
push_front_aux(t);
}
void pop_back() {
//start.cur指向第一个元素首址,finish.cur指向最后一个元素尾地址
if (finish.cur != finish.first) {
--finish.cur;
destroy(finish.cur);
}
else
//尾端缓冲区一个元素都没有,全都是备用空间
pop_back_aux();
}
void pop_front() {
if (start.cur != start.last - 1) {
destroy(start.cur);
++start.cur;
}
else
//前端缓冲区只有一个元素
pop_front_aux();
}
public: // 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);
//因为finish.cur指向第一个备用(最后元素尾地址),要返回插入的元素,所以--tmp
iterator tmp = finish;
--tmp;
return tmp;
}
else {
//中间插入
return insert_aux(position, x);
}
}
iterator insert(iterator position) { return insert(position, value_type()); }
void insert(iterator pos, size_type n, const value_type& x);
void insert(iterator pos, int n, const value_type& x) {
insert(pos, (size_type)n, x);
}
void insert(iterator pos, long n, const value_type& x) {
insert(pos, (size_type)n, x);
}
void insert(iterator pos, const value_type* first, const value_type* last);
void insert(iterator pos, const_iterator first, const_iterator last);
void resize(size_type new_size, const value_type& x) {
const size_type len = size();
if (new_size < len)
erase(start + new_size, finish);
else
insert(finish, new_size - len, x);
}
void resize(size_type new_size) { resize(new_size, value_type()); }
public: // 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;
}
iterator erase(iterator first, iterator last);
void clear();
protected: // Internal construction/destruction
void create_map_and_nodes(size_type num_elements);
void destroy_map_and_nodes();
void fill_initialize(size_type n, const value_type& value);
protected: // Internal push_* and pop_*
void push_back_aux(const value_type& t);
void push_front_aux(const value_type& t);
void pop_back_aux();
void pop_front_aux();
protected: // Internal insert functions
iterator insert_aux(iterator pos, const value_type& x);
void insert_aux(iterator pos, size_type n, const value_type& x);
void insert_aux(iterator pos,
const value_type* first, const value_type* last,
size_type n);
void insert_aux(iterator pos, const_iterator first, const_iterator last,
size_type n);
iterator reserve_elements_at_front(size_type n) {
//在前端预留出n个元素空间
size_type vacancies = start.cur - start.first;
if (n > vacancies)
//备用空间不够,要添加缓冲区,预留出空间
new_elements_at_front(n - vacancies);
return start - difference_type(n);
}
iterator reserve_elements_at_back(size_type n) {
size_type vacancies = (finish.last - finish.cur) - 1;
if (n > vacancies)
new_elements_at_back(n - vacancies);
return finish + difference_type(n);
}
void new_elements_at_front(size_type new_elements);
void new_elements_at_back(size_type new_elements);
void destroy_nodes_at_front(iterator before_start);
void destroy_nodes_at_back(iterator after_finish);
protected: // Allocation of map and nodes
// Makes sure the map has space for new nodes. Does not actually
// add the nodes. Can invalidate map pointers. (And consequently,
// deque iterators.)
//如果map尾端的备用节点不够,则重配置一个更大的
void reserve_map_at_back(size_type nodes_to_add = 1) {
if (nodes_to_add + 1 > map_size - (finish.node - map))
//如果符合条件,配置一个更大的map,只是改变map,其他不变(缓冲区和迭代器)
reallocate_map(nodes_to_add, false);
}
void reserve_map_at_front(size_type nodes_to_add = 1) {
if (nodes_to_add > start.node - map)
reallocate_map(nodes_to_add, true);
}
void reallocate_map(size_type nodes_to_add, bool add_at_front);
pointer allocate_node() { return data_allocator::allocate(buffer_size()); }
void deallocate_node(pointer n) {
data_allocator::deallocate(n, buffer_size());
}
};
// Non-inline member functions
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert(iterator pos,
size_type n, const value_type& x) {
if (pos.cur == start.cur) {
iterator new_start = reserve_elements_at_front(n);
uninitialized_fill(new_start, start, x);
start = new_start;
}
else if (pos.cur == finish.cur) {
iterator new_finish = reserve_elements_at_back(n);
uninitialized_fill(finish, new_finish, x);
finish = new_finish;
}
else
insert_aux(pos, n, x);
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert(iterator pos,
const value_type* first,
const value_type* last) {
size_type n = last - first;
if (pos.cur == start.cur) {
iterator new_start = reserve_elements_at_front(n);
__STL_TRY{
uninitialized_copy(first, last, new_start);
start = new_start;
}
__STL_UNWIND(destroy_nodes_at_front(new_start));
}
else if (pos.cur == finish.cur) {
iterator new_finish = reserve_elements_at_back(n);
__STL_TRY{
uninitialized_copy(first, last, finish);
finish = new_finish;
}
__STL_UNWIND(destroy_nodes_at_back(new_finish));
}
else
insert_aux(pos, first, last, n);
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert(iterator pos,
const_iterator first,
const_iterator last)
{
size_type n = last - first;
if (pos.cur == start.cur) {
iterator new_start = reserve_elements_at_front(n);
__STL_TRY{
uninitialized_copy(first, last, new_start);
start = new_start;
}
__STL_UNWIND(destroy_nodes_at_front(new_start));
}
else if (pos.cur == finish.cur) {
iterator new_finish = reserve_elements_at_back(n);
__STL_TRY{
uninitialized_copy(first, last, finish);
finish = new_finish;
}
__STL_UNWIND(destroy_nodes_at_back(new_finish));
}
else
insert_aux(pos, first, last, n);
}
template <class T, class Alloc, size_t BufSize>
deque<T, Alloc, BufSize>::iterator
deque<T, Alloc, BufSize>::erase(iterator first, iterator last) {
if (first == start && last == finish) {
clear();
return finish;
}
else {
difference_type n = last - first;
difference_type elems_before = first - start;
if (elems_before < (size() - n) / 2) {
copy_backward(start, first, last);
iterator new_start = start + n;
destroy(start, new_start);
for (map_pointer cur = start.node; cur < new_start.node; ++cur)
data_allocator::deallocate(*cur, buffer_size());
start = new_start;
}
else {
copy(last, finish, first);
iterator new_finish = finish - n;
destroy(new_finish, finish);
for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur)
data_allocator::deallocate(*cur, buffer_size());
finish = new_finish;
}
return start + elems_before;
}
}
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;
}
//传入元素个数,配置好deque整个结构(只差数据没填入)
//配置好map_size、map、start、finish,
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::create_map_and_nodes(size_type num_elements) {
//num_elements:deque需要的元素个数
// buffer_size()缓冲区元素个数,因为除会把余数忽略,所以要多加一个节点存余的,例:10/8,需要两个节点存
//如果刚好整除,则多配一个节点
size_type num_nodes = num_elements / buffer_size() + 1;
//num_nodes + 2:在需要的节点数上前后预留一个,以便扩充时用
//initial_map_size()这里为8
//map_size :要给map分配的节点数
//一个map最少要管理8个节点,所以map_size 选择比较大的值
map_size = max(initial_map_size(), num_nodes + 2);
//配置出一个具有map_size 节点的map
map = map_allocator::allocate(map_size);
//假设这里map已经全部配置好,则(实际这里map节点都还没用)
//nstart 指向有指向缓冲区的第一个map节点(即已经在使用的第一个map节点)
//nfinish 指向有指向缓冲区的最后一个map节点(即已经在使用的最后一个map节点)
//map_size - num_nodes得到备用空间个数,再除2,把备用空间分成两份
// 前后个一份备用空间
map_pointer nstart = map + (map_size - num_nodes) / 2;
map_pointer nfinish = nstart + num_nodes - 1;
map_pointer cur;
__STL_TRY{
for (cur = nstart; cur <= nfinish; ++cur)
//为map节点配置缓冲区,每个map节点都指向缓冲区首地址
// 返回缓冲区首地址赋给map节点
*cur = allocate_node();
}
# ifdef __STL_USE_EXCEPTIONS
catch (...) {
// 如果不是全部成功,则都销毁掉
for (map_pointer n = nstart; n < cur; ++n)
//销毁缓冲区
deallocate_node(*n);
//销毁map
map_allocator::deallocate(map, map_size);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
//配置start、finish迭代器,
// 迭代器内cur、first、last、node的配置
//finish.cur指向的最后一个元素的下一个
start.set_node(nstart);
finish.set_node(nfinish);
start.cur = start.first;
finish.cur = finish.first + num_elements % buffer_size();
}
// This is only used as a cleanup function in catch clauses.
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::destroy_map_and_nodes() {
for (map_pointer cur = start.node; cur <= finish.node; ++cur)
//遍历销毁点所有元素
deallocate_node(*cur);
//销毁掉所有map节点
map_allocator::deallocate(map, map_size);
}
//传入元素个数和初值,构建好deque
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::fill_initialize(size_type n,
const value_type& value) {
//配置好deque整个结构(只差数据没填入)
create_map_and_nodes(n);
map_pointer cur;
__STL_TRY{
for (cur = start.node; cur < finish.node; ++cur)
//填入数据
uninitialized_fill(*cur, *cur + buffer_size(), value);
// 最后一个缓冲区可能有备用空间,不必填入
uninitialized_fill(finish.first, finish.cur, value);
}
# ifdef __STL_USE_EXCEPTIONS
catch (...) {
for (map_pointer n = start.node; n < cur; ++n)
destroy(*n, *n + buffer_size());
destroy_map_and_nodes();
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
// Called only if 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;
//如果条件需要,要配置一个更大的map
reserve_map_at_back();
//配置一个新的缓冲区
*(finish.node + 1) = allocate_node();
__STL_TRY{
//这里的finish.cur还是指向要加元素的缓冲区
construct(finish.cur, t_copy);
//调整finish,让其指向新的缓冲区
finish.set_node(finish.node + 1);
finish.cur = finish.first;
}
__STL_UNWIND(deallocate_node(*(finish.node + 1)));
}
// 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;
//如果条件需要,要配置一个更大的map
reserve_map_at_front();
//配置一个新的缓冲区
*(start.node - 1) = allocate_node();
__STL_TRY{
//调整start,让其指向新的缓冲区
start.set_node(start.node - 1);
start.cur = start.last - 1;
//填值
construct(start.cur, t_copy);
}
# ifdef __STL_USE_EXCEPTIONS
catch (...) {
start.set_node(start.node + 1);
start.cur = start.first;
deallocate_node(*(start.node - 1));
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
// Called only if finish.cur == finish.first.
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::pop_back_aux() {
//销毁缓冲区
deallocate_node(finish.first);
//调整finish
finish.set_node(finish.node - 1);
finish.cur = finish.last - 1;
//销毁元素
destroy(finish.cur);
}
// Called only if start.cur == start.last - 1. Note that if the deque
// has at least one element (a necessary precondition for this member
// function), and if start.cur == start.last, then the deque must have
// at least two nodes.
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::pop_front_aux() {
//销毁元素
destroy(start.cur);
//销毁缓冲区
deallocate_node(start.first);
//调整start
start.set_node(start.node + 1);
start.cur = start.first;
}
//在pos位置插入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) {
//插入点比较靠近头部
//先在前端插入一个front(),扩展空间
push_front(front());
iterator front1 = start;
++front1;
iterator front2 = front1;
++front2;
pos = start + index;
iterator pos1 = pos;
++pos1;
//除了第一个元素,所以在pos之前(包括pos)都前移一个位置
copy(front2, pos1, front1);
}
else {
//插入点比较靠近尾部
//先在尾端插入一个back(),扩展空间
push_back(back());
iterator back1 = finish;
--back1;
iterator back2 = back1;
--back2;
pos = start + index;
//除了最后元素,所以在pos之后(包括pos)都后移一个位置
copy_backward(pos, back2, back1);
}
//在pos位置填入新值
*pos = x_copy;
return pos;
}
//在pos位置插入n个x
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
size_type n, const value_type& x) {
const difference_type elems_before = pos - start;
size_type length = size();
value_type x_copy = x;
if (elems_before < length / 2) {
//插入点比较靠近头部
//预留出空间,如果需要,要增加缓冲区
iterator new_start = reserve_elements_at_front(n);
iterator old_start = start;
pos = start + elems_before;
__STL_TRY{
if (elems_before >= difference_type(n)) {
//@
iterator start_n = start + difference_type(n);
uninitialized_copy(start, start_n, new_start);
start = new_start;
copy(start_n, pos, old_start);
fill(pos - difference_type(n), pos, x_copy);
}
else {
__uninitialized_copy_fill(start, pos, new_start, start, x_copy);
start = new_start;
fill(old_start, pos, x_copy);
}
}
__STL_UNWIND(destroy_nodes_at_front(new_start));
}
else {
//插入点比较靠近尾部
//预留出空间,如果需要,要增加缓冲区
iterator new_finish = reserve_elements_at_back(n);
iterator old_finish = finish;
const difference_type elems_after = difference_type(length) - elems_before;
pos = finish - elems_after;
__STL_TRY{
if (elems_after > difference_type(n)) {
iterator finish_n = finish - difference_type(n);
uninitialized_copy(finish_n, finish, finish);
finish = new_finish;
copy_backward(pos, finish_n, old_finish);
fill(pos, pos + difference_type(n), x_copy);
}
else {
__uninitialized_fill_copy(finish, pos + difference_type(n),
x_copy,
pos, finish);
finish = new_finish;
fill(pos, old_finish, x_copy);
}
}
__STL_UNWIND(destroy_nodes_at_back(new_finish));
}
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
const value_type* first,
const value_type* last,
size_type n)
{
const difference_type elems_before = pos - start;
size_type length = size();
if (elems_before < length / 2) {
iterator new_start = reserve_elements_at_front(n);
iterator old_start = start;
pos = start + elems_before;
__STL_TRY{
if (elems_before >= difference_type(n)) {
iterator start_n = start + difference_type(n);
uninitialized_copy(start, start_n, new_start);
start = new_start;
copy(start_n, pos, old_start);
copy(first, last, pos - difference_type(n));
}
else {
const value_type* mid = first + (difference_type(n) - elems_before);
__uninitialized_copy_copy(start, pos, first, mid, new_start);
start = new_start;
copy(mid, last, old_start);
}
}
__STL_UNWIND(destroy_nodes_at_front(new_start));
}
else {
iterator new_finish = reserve_elements_at_back(n);
iterator old_finish = finish;
const difference_type elems_after = difference_type(length) - elems_before;
pos = finish - elems_after;
__STL_TRY{
if (elems_after > difference_type(n)) {
iterator finish_n = finish - difference_type(n);
uninitialized_copy(finish_n, finish, finish);
finish = new_finish;
copy_backward(pos, finish_n, old_finish);
copy(first, last, pos);
}
else {
const value_type* mid = first + elems_after;
__uninitialized_copy_copy(mid, last, pos, finish, finish);
finish = new_finish;
copy(first, mid, pos);
}
}
__STL_UNWIND(destroy_nodes_at_back(new_finish));
}
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
const_iterator first,
const_iterator last,
size_type n)
{
const difference_type elems_before = pos - start;
size_type length = size();
if (elems_before < length / 2) {
iterator new_start = reserve_elements_at_front(n);
iterator old_start = start;
pos = start + elems_before;
__STL_TRY{
if (elems_before >= n) {
iterator start_n = start + n;
uninitialized_copy(start, start_n, new_start);
start = new_start;
copy(start_n, pos, old_start);
copy(first, last, pos - difference_type(n));
}
else {
const_iterator mid = first + (n - elems_before);
__uninitialized_copy_copy(start, pos, first, mid, new_start);
start = new_start;
copy(mid, last, old_start);
}
}
__STL_UNWIND(destroy_nodes_at_front(new_start));
}
else {
iterator new_finish = reserve_elements_at_back(n);
iterator old_finish = finish;
const difference_type elems_after = length - elems_before;
pos = finish - elems_after;
__STL_TRY{
if (elems_after > n) {
iterator finish_n = finish - difference_type(n);
uninitialized_copy(finish_n, finish, finish);
finish = new_finish;
copy_backward(pos, finish_n, old_finish);
copy(first, last, pos);
}
else {
const_iterator mid = first + elems_after;
__uninitialized_copy_copy(mid, last, pos, finish, finish);
finish = new_finish;
copy(first, mid, pos);
}
}
__STL_UNWIND(destroy_nodes_at_back(new_finish));
}
}
//但缓冲区的备用节点不够需求时,会调用,
//通过增加缓冲区,预留出new_elements个元素备用空间
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::new_elements_at_front(size_type new_elements) {
//new_elements:要在前端预留的元素个数
//new_nodes要预留的缓冲区个数
size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
//如果map的前端备用节点不够,则调整(把后端备用节点调到前端)或增加map前端的备用节点
reserve_map_at_front(new_nodes);
size_type i;
__STL_TRY{
for (i = 1; i <= new_nodes; ++i)
//分配缓冲区,map预留节点指向预留缓冲区
*(start.node - i) = allocate_node();
}
# ifdef __STL_USE_EXCEPTIONS
catch (...) {
for (size_type j = 1; j < i; ++j)
deallocate_node(*(start.node - j));
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::new_elements_at_back(size_type new_elements) {
size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
reserve_map_at_back(new_nodes);
size_type i;
__STL_TRY{
for (i = 1; i <= new_nodes; ++i)
*(finish.node + i) = allocate_node();
}
# ifdef __STL_USE_EXCEPTIONS
catch (...) {
for (size_type j = 1; j < i; ++j)
deallocate_node(*(finish.node + j));
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::destroy_nodes_at_front(iterator before_start) {
for (map_pointer n = before_start.node; n < start.node; ++n)
deallocate_node(*n);
}
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::destroy_nodes_at_back(iterator after_finish) {
for (map_pointer n = after_finish.node; n > finish.node; --n)
deallocate_node(*n);
}
//map某一端的备用节点不够用,扩展或调整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 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) {
//map的大小大于需求的两倍,只是调整一下map,并没有重换,比如两端一端节点过多,一端很少
//保持元素在中央
new_nstart = map + (map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0);
if (new_nstart < start.node)
//finish.node指向最后一个元素的首址,copy作用区间[start.node, finish.node + 1),所以要+1
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使用
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
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);
}
// Nonmember functions.
template <class T, class Alloc, size_t BufSiz>
bool operator==(const deque<T, Alloc, BufSiz>& x,
const deque<T, Alloc, BufSiz>& y) {
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}
template <class T, class Alloc, size_t BufSiz>
bool operator<(const deque<T, Alloc, BufSiz>& x,
const deque<T, Alloc, BufSiz>& y) {
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
STL源码剖析-----deque
最新推荐文章于 2021-12-13 20:49:54 发布