// Filename:    stl_deque.h// Comment By:  凝霜
// E-mail:      mdl2009@vip.qq.com
// Blog:        http://blog.csdn.net/mdl13412// 如果vector能满足你的需求, 那么就使用vector
// 如果不得不使用deque, 那么在进行一算法(尤其是sort)操作时
// 应该先把deque中的元素复制到vector中
// 执行完算法再复制回去
// 这样的效率往往要高于直接使用算法的效率/*** Copyright (c) 1994* Hewlett-Packard Company** Permission to use, copy, modify, distribute and sell this software* and its documentation for any purpose is hereby granted without fee,* provided that the above copyright notice appear in all copies and* that both that copyright notice and this permission notice appear* in supporting documentation.  Hewlett-Packard Company makes no* representations about the suitability of this software for any* purpose.  It is provided "as is" without express or implied warranty.*** Copyright (c) 1997* Silicon Graphics Computer Systems, Inc.** Permission to use, copy, modify, distribute and sell this software* and its documentation for any purpose is hereby granted without fee,* provided that the above copyright notice appear in all copies and* that both that copyright notice and this permission notice appear* in supporting documentation.  Silicon Graphics makes no* representations about the suitability of this software for any* purpose.  It is provided "as is" without express or implied warranty.*//* NOTE: This is an internal header file, included by other STL headers.*   You should not attempt to use it directly.*/#ifndef __SGI_STL_INTERNAL_DEQUE_H
#define __SGI_STL_INTERNAL_DEQUE_H// 特性:
//   对于任何的非奇异(nonsingular)的迭代器i
//     i.node是map array中的某元素的地址. i.node的内容是一个指向某个结点的头的指针
//     i.first == *(i.node)
//     i.last  == i.first + node_size
//     i.cur是一个指向[i.first, i.last)之间的指针
//       注意: 这意味着i.cur永远是一个可以解引用的指针,
//            即使其是一个指向结尾后元素的迭代器
//
//   起点和终点总是非奇异(nonsingular)的迭代器.
//     注意: 这意味着空deque一定有一个node, 而一个具有N个元素的deque
//          (N是Buffer Size)一定有有两个nodes
//
//   对于除了start.node和finish.node之外的每一个node, 每一个node中的元素
//   都是一个初始化过的对象. 如果start.node == finish.node,
//   那么[start.cur, finish.cur)都是未初始化的空间.
//   否则, [start.cur, start.last)和[finish.first, finish.cur)都是初始化的对象,
//   而[start.first, start.cur)和[finish.cur, finish.last)是未初始化的空间
//
//   [map, map + map_size)是一个合法的非空区间
//   [start.node, finish.node]是内含在[map, map + map_size)区间的合法区间
//   一个在[map, map + map_size)区间内的指针指向一个分配过的node,
//   当且仅当此指针在[start.node, finish.node]区间内// 在前一个版本的deque中, node_size被设定为定植.
// 然而在这个版本中, 用户可以自定义node_size的大小.
// deque有三个模板参数, 第三个参数为size_t类型, 代表每个结点内的元素数目.
// 如果第三个参数被设定为0(默认值), deque使用默认结点大小
//
// 使用不同结点大小的唯一理由是, 你的程序需要不同的效率, 并愿意为此付出代价,
// 例如, 如果你的程序中有许多deque, 但是每个deque都只包含很少的元素,
// 那么你可以使用较小的node_size来进行管理, 但是会对访问操作带来效率损失
//
// 不幸的是, 一些编译器不能正确处理non-type template parameters;
// 如果这样, 在<stl_config.h>会定义__STL_NON_TYPE_TMPL_PARAM_BUG
// 如果你的编译器不幸在列, 你只能使用默认的大小, 而不能更改__STL_BEGIN_NAMESPACE#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1174
#endif// 这个函数是为了防止不同编译器在处理常量表达式时的Bug
// 如果n != 0, 那么就返回n, 表示buffer size为使用者自定义
// 如果n ==0, 就返回默认值表示buffer size,默认值计算方法如下
//    如果sz(元素类型大小sizeof(type))小于512, 返回512 / sz
//    否则返回1
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));
}// 注意这里未继承自std::iterator
#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
template <class T, class Ref, class Ptr, size_t BufSiz>
struct __deque_iterator {typedef __deque_iterator<T, T&, T*, BufSiz>             iterator;typedef __deque_iterator<T, const T&, const T*, BufSiz> const_iterator;static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); }
#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
template <class T, class Ref, class Ptr>
struct __deque_iterator {typedef __deque_iterator<T, T&, T*>             iterator;typedef __deque_iterator<T, const T&, const T*> const_iterator;static size_t buffer_size() {return __deque_buf_size(0, sizeof(T)); }
#endiftypedef random_access_iterator_tag iterator_category;      // STL标准强制要求typedef T value_type;                                      // STL标准强制要求typedef Ptr pointer;                                       // STL标准强制要求typedef Ref reference;                                     // STL标准强制要求typedef size_t size_type;typedef ptrdiff_t difference_type;                         // STL标准强制要求typedef T** map_pointer;typedef __deque_iterator self;// 保存容器中的结点T* cur;       // 指向当前缓冲区中的元素T* first;     // 当前缓冲区的起点T* last;      // 当前缓冲区的终点// 这个是deque内存管理的关键, 其模型如下//
//       ---------------------------------------------
// map-->|   |   |   |   |   |   | ..... |   |   |   |<------------------
//       ---------------------------------------------                  |
//             |                                                        |
//             |                                                        |
//             |   node                                                 |
//             |   缓冲区buffer, 这里实际存储元素                          |
//             |   ---------------------------------------------        |
//             --->|   |   |   |   |   |   | ..... |   |   | X |        |
//                 ---------------------------------------------        |
//                   ↑       ↑                             ↑            |
//             ------        |                             |            |
//             |             |                             |            |
//             |   -----------   ---------------------------            |
//             ----|-----        |                                      |
//                 |    |        |                                      |
//                 |    |        |                                      |
//                 |    |        |                                      |
//              ---------------------------                             |
//              | cur | first | end | map |------------------------------
//              ---------------------------
//              迭代器, 其内部维护着一个缓冲区状态map_pointer node;__deque_iterator(T* x, map_pointer y): cur(x), first(*y), last(*y + buffer_size()), node(y) {}__deque_iterator() : cur(0), first(0), last(0), node(0) {}__deque_iterator(const iterator& x): cur(x.cur), first(x.first), last(x.last), node(x.node) {}reference operator*() const { return *cur; }#ifndef __SGI_STL_NO_ARROW_OPERATOR// 如果编译器支持'->'则重载, 详细见我在<stl_list.h>中的剖析pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */// 判断两个迭代器间的距离difference_type operator-(const self& x) const{return difference_type(buffer_size()) * (node - x.node - 1) +(cur - first) + (x.last - x.cur);}// 下面重载的这些是运算符是让deque从外界看上去维护的是一段连续空间的关键!!!// 前缀自增// 如果当前迭代器指向元素是当前缓冲区的最后一个元素,
// 则将迭代器状态调整为下一个缓冲区的第一个元素// 不是当前缓冲区最后一个元素
//
// 执行前缀自增前的状态
// first          cur                     end
// ↓               ↓                       ↓
// ---------------------------------------------
// |   |   |   |   |   |   | ..... |   |   | X | <----- 当前缓冲区
// ---------------------------------------------
//
// 执行完成后的状态
// first              cur                 end
// ↓                   ↓                   ↓
// ---------------------------------------------
// |   |   |   |   |   |   | ..... |   |   | X | <----- 当前缓冲区
// ---------------------------------------------
//// 当前元素为当前缓冲区的最后一个元素
//
// 执行前缀自增前的状态
// first                              cur end
// ↓                                   ↓   ↓
// ---------------------------------------------
// |   |   |   |   |   |   | ..... |   |   | X | <----- 当前缓冲区
// ---------------------------------------------
//
// 执行完成后的状态
// first                                  end
// ↓                                       ↓
// ---------------------------------------------
// |   |   |   |   |   |   | ..... |   |   | X | <----- 下一缓冲区
// ---------------------------------------------
// ↑
// cur
//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;}// 将迭代器向前移动n个元素, n可以为负//                     operator+=(difference_type n)
//                                   ↓
//                      offset = n + (cur - first)
//                                   |
//                                   |---------- offset > 0 ? &&
//                                   |           移动后是否超出当前缓冲区?
//               ----------------------------
//           No  |                          |  Yes
//               |                          |
//               ↓                          |---------- offset > 0?
//           cur += n;                      |
//                              ----------------------------
//                          Yes |                          | No
//                              |                          |
//                              ↓                          |
//                   计算要向后移动多少个缓冲区                |
//                   node_offset =                         |
//                   offset / difference_type              |
//                   (buffer_size());                      ↓
//                              |           计算要向前移动多少个缓冲区
//                              |           node_offset = -difference_type
//                              |           ((-offset - 1) / buffer_size()) - 1;
//                              |                          |
//                              ----------------------------
//                                           |
//                                           |
//                                           ↓
//                                       调整缓冲区
//                              set_node(node + node_offset);
//                                    计算并调整cur指针self& 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;}self operator+(difference_type n) const{self tmp = *this;// 这里调用了operator +=()可以自动调整指针状态return tmp += n;}// :-), 将n变为-n就可以使用operator +=()了,// 初等数学是神奇的, 还记得我们刚学编程时求绝对值是怎么写的吗? :Pself& 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);}void set_node(map_pointer new_node){node = new_node;first = *new_node;last = first + difference_type(buffer_size());}
};#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION#ifndef __STL_NON_TYPE_TMPL_PARAM_BUGtemplate <class T, class Ref, class Ptr, size_t BufSiz>
inline random_access_iterator_tag
iterator_category(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {return random_access_iterator_tag();
}template <class T, class Ref, class Ptr, size_t BufSiz>
inline T* value_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {return 0;
}template <class T, class Ref, class Ptr, size_t BufSiz>
inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {return 0;
}#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */template <class T, class Ref, class Ptr>
inline random_access_iterator_tag
iterator_category(const __deque_iterator<T, Ref, Ptr>&) {return random_access_iterator_tag();
}template <class T, class Ref, class Ptr>
inline T* value_type(const __deque_iterator<T, Ref, Ptr>&) { return 0; }template <class T, class Ref, class Ptr>
inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr>&) {return 0;
}#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */// 其实剖析到这里就没有什么难的了, deque的运算符才是核心
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */// See __deque_buf_size().  The only reason that the default value is 0
//  is as a workaround for bugs in the way that some compilers handle
//  constant expressions.
template <class T, class Alloc = alloc, size_t BufSiz = 0>
class deque {
public:                         // Basic typestypedef 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
#ifndef __STL_NON_TYPE_TMPL_PARAM_BUGtypedef __deque_iterator<T, T&, T*, BufSiz>              iterator;typedef __deque_iterator<T, const T&, const T&, BufSiz>  const_iterator;
#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */typedef __deque_iterator<T, T&, T*>                      iterator;typedef __deque_iterator<T, const T&, const T*>          const_iterator;
#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */#ifdef __STL_CLASS_PARTIAL_SPECIALIZATIONtypedef reverse_iterator<const_iterator> const_reverse_iterator;typedef reverse_iterator<iterator> reverse_iterator;
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */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;
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */protected:                      // Internal typedefstypedef pointer* map_pointer;// 这个提供STL标准的allocator接口, 见<stl_alloc.h>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));}static size_type initial_map_size() { return 8; }protected:                      // Data membersiterator start;               // 起始缓冲区iterator finish;              // 最后一个缓冲区// 指向map, map是一个连续的空间, 其每个元素都是一个指向缓冲区的指针// 其模型见前面的__deque_iteratormap_pointer map;size_type map_size;   // map容量public:                         // Basic accessorsiterator 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);}// 提供随机访问能力, 其调用的是迭代器重载的operator []// 其实际地址需要进行一些列的计算, 效率有损失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; }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 -size_type size() const { return finish - start;; }size_type max_size() const { return size_type(-1); }// deque为空的时, 只有一个缓冲区bool empty() const { return finish == start; }public:                         // Constructor, destructor.deque(): start(), finish(), map(0), map_size(0){create_map_and_nodes(0);}// 注: commit or rollbackdeque(const deque& x): start(), finish(), map(0), map_size(0){create_map_and_nodes(x.size());__STL_TRY {uninitialized_copy(x.begin(), x.end(), start);  // <stl_uninitialized.h>}__STL_UNWIND(destroy_map_and_nodes());}deque(size_type n, const value_type& value): start(), finish(), map(0), map_size(0){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());}#ifdef __STL_MEMBER_TEMPLATEStemplate <class InputIterator>deque(InputIterator first, InputIterator last): start(), finish(), map(0), map_size(0){range_initialize(first, last, iterator_category(first));}#else /* __STL_MEMBER_TEMPLATES */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());}#endif /* __STL_MEMBER_TEMPLATES */~deque(){destroy(start, finish);     // <stl_construct.h>destroy_map_and_nodes();}deque& operator= (const deque& x){// 其实我觉得把这个操作放在if内效率更高const size_type len = size();if (&x != this) {// 当前容器比x容器拥有元素多, 析构多余元素if (len >= x.size())erase(copy(x.begin(), x.end(), start), finish);// 将x所有超出部分的元素使用insert()追加进去else {const_iterator mid = x.begin() + difference_type(len);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){// STL使用前闭后开的区间, 所以如果还有剩余容量,// 则直接在finish.cur上构造对象即可, 然后更新迭代器if (finish.cur != finish.last - 1) {construct(finish.cur, t);++finish.cur;}// 容量已满就要新申请内存了elsepush_back_aux(t);}void push_front(const value_type& t){if (start.cur != start.first) {construct(start.cur - 1, t);--start.cur;}elsepush_front_aux(t);}void pop_back(){if (finish.cur != finish.first) {--finish.cur;destroy(finish.cur);}elsepop_back_aux();}void pop_front() {if (start.cur != start.last - 1){destroy(start.cur);++start.cur;}elsepop_front_aux();}public:                         // Insert// 在指定位置前插入元素//             insert(iterator position, const value_type& x)
//                                   |
//                                   |---------------- 判断插入位置
//                                   |
//               -----------------------------------------------
// deque.begin() |          deque.emd() |                      |
//               |                      |                      |
//               ↓                      ↓                      |
//         push_front(x);         push_back(x);                |
//                                                             ↓
//                                                 insert_aux(position, x);
//                                                 具体剖析见后面实现iterator insert(iterator position, const value_type& x){// 如果是在deque的最前端插入, 那么直接push_front()即可if (position.cur == start.cur) {push_front(x);return start;}// 如果是在deque的末尾插入, 直接调用push_back()else if (position.cur == finish.cur) {push_back(x);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);}#ifdef __STL_MEMBER_TEMPLATEStemplate <class InputIterator>void insert(iterator pos, InputIterator first, InputIterator last){insert(pos, first, last, iterator_category(first));}#else /* __STL_MEMBER_TEMPLATES */void insert(iterator pos, const value_type* first, const value_type* last);void insert(iterator pos, const_iterator first, const_iterator last);#endif /* __STL_MEMBER_TEMPLATES */// 如果new_size < size(), 那么就析构掉多余的元素,// 否则以x为蓝本进行剩余元素的填充void resize(size_type new_size, const value_type& x){const size_type len = size();if (new_size < len)erase(start + new_size, finish);elseinsert(finish, new_size - len, x);}void resize(size_type new_size) { resize(new_size, value_type()); }public:                         // Eraseiterator erase(iterator pos){iterator next = pos;++next;// 计算待擦除点前的元素个数difference_type index = pos - start;// 判断待擦除结点前后元素的个数, 哪部分少就移动哪部分if (index < (size() >> 1)){// 前面部分的元素少copy_backward(start, pos, next);  // <stl_algobase.h>pop_front();}// 后面部分的元素少else {copy(next, finish, pos);          // <stl_algobase.h>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);#ifdef __STL_MEMBER_TEMPLATEStemplate <class InputIterator>void range_initialize(InputIterator first, InputIterator last,input_iterator_tag);template <class ForwardIterator>void range_initialize(ForwardIterator first, ForwardIterator last,forward_iterator_tag);#endif /* __STL_MEMBER_TEMPLATES */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#ifdef __STL_MEMBER_TEMPLATEStemplate <class InputIterator>void insert(iterator pos, InputIterator first, InputIterator last,input_iterator_tag);template <class ForwardIterator>void insert(iterator pos, ForwardIterator first, ForwardIterator last,forward_iterator_tag);#endif /* __STL_MEMBER_TEMPLATES */iterator insert_aux(iterator pos, const value_type& x);void insert_aux(iterator pos, size_type n, const value_type& x);#ifdef __STL_MEMBER_TEMPLATEStemplate <class ForwardIterator>void insert_aux(iterator pos, ForwardIterator first, ForwardIterator last,size_type n);#else /* __STL_MEMBER_TEMPLATES */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);#endif /* __STL_MEMBER_TEMPLATES */// 在起始缓冲区预留大小为n的空间// 如果缓冲区不足则重新分配iterator reserve_elements_at_front(size_type 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.)void reserve_map_at_back (size_type nodes_to_add = 1){if (nodes_to_add + 1 > map_size - (finish.node - 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());}#ifdef __STL_NON_TYPE_TMPL_PARAM_BUG
public:bool operator==(const deque<T, Alloc, 0>& x) const {return size() == x.size() && equal(begin(), end(), x.begin());}bool operator!=(const deque<T, Alloc, 0>& x) const {return size() != x.size() || !equal(begin(), end(), x.begin());}bool operator<(const deque<T, Alloc, 0>& x) const {return lexicographical_compare(begin(), end(), x.begin(), x.end());}
#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
};// 不进行内联的成员函数// 在指定位置前插入n个值为x的元素//           insert(iterator pos, size_type n, const value_type& x)
//                                   |
//                                   |---------------- 判断插入位置
//                                   |
//               ---------------------------------------------------------
// deque.begin() |                    deque.end() |                      |
//               |                                |                      |
//               ↓                                |                      |
// reserve_elements_at_front(n);                  |                      |
// uninitialized_fill(new_start, start, x);       |                      |
//                                                ↓                      |
//                          reserve_elements_at_back(n);                 |
//                          uninitialized_fill(finish, new_finish, x);   |
//                                                                       ↓
//                                                       insert_aux(pos, n, x);
//                                                       剖析见后面实现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;}elseinsert_aux(pos, n, x);
}// 给不支持成员函数模板的编译器提供支持函数
#ifndef __STL_MEMBER_TEMPLATEStemplate <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));}elseinsert_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));}elseinsert_aux(pos, first, last, n);
}#endif /* __STL_MEMBER_TEMPLATES */// 擦除[first, last)区间的元素//                  erase(iterator first, iterator last)
//                                   |
//                                   |---------------- 是否要删除整个区间?
//                                   |
//               ------------------------------------------
//           Yes |                                        | No
//               |                                        |
//               ↓                                        | --- 判断哪侧元素少
//            clear();                                    ↓
//       -----------------------------------------------------------------
// 左侧少 |                                                         右侧少 |
//       |                                                               |
//       ↓                                                               ↓
//   copy_backward(start, first, last);            copy(last, finish, first);
//   new_start = start + n;                        new_finish = finish - n;
//   析构多余的元素                                  析构多余的元素
//   destroy(start, new_start);                    destroy(new_finish, finish);
//   释放多余内存空间                                释放多余内存空间
//   for (...)                                     for (...)
//      ...                                             ...
//   更新map状态                                    更新map状态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());}// 如果deque本身不为空, 析构所有对象, 并释放掉结尾的内存if (start.node != finish.node) {destroy(start.cur, start.last);destroy(finish.first, finish.cur);data_allocator::deallocate(finish.first, buffer_size());}// 析构所有元素, 但是不释放空间, 因为deque要满足这个前置条件// 具体的细节见本文件开头'特性'elsedestroy(start.cur, finish.cur);finish = start;
}// 创建内部使用的map
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::create_map_and_nodes(size_type num_elements)
{// 需要的结点数, 元素个数 / 每个缓冲区能容纳的元素数 + 1size_type num_nodes = num_elements / buffer_size() + 1;// map要维护的结点, 这里最小的值为8, 见initial_map_size()map_size = max(initial_map_size(), num_nodes + 2);map = map_allocator::allocate(map_size);// 将[nstart, nfinish)区间设置在map的中间,// 这样就能保证前后增长而尽可能减少map的重新分配次数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)*cur = allocate_node();}
#     ifdef  __STL_USE_EXCEPTIONScatch(...) {for (map_pointer n = nstart; n < cur; ++n)deallocate_node(*n);map_allocator::deallocate(map, map_size);throw;}
#     endif /* __STL_USE_EXCEPTIONS */// 维护指针状态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_allocator::deallocate(map, map_size);
}// 分配n个结点, 并以value为蓝本初始化
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::fill_initialize(size_type n,const value_type& value)
{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_EXCEPTIONScatch(...) {for (map_pointer n = start.node; n < cur; ++n)destroy(*n, *n + buffer_size());destroy_map_and_nodes();throw;}
#       endif /* __STL_USE_EXCEPTIONS */
}#ifdef __STL_MEMBER_TEMPLATEStemplate <class T, class Alloc, size_t BufSize>
template <class InputIterator>
void deque<T, Alloc, BufSize>::range_initialize(InputIterator first,InputIterator last,input_iterator_tag) {create_map_and_nodes(0);for ( ; first != last; ++first)push_back(*first);
}template <class T, class Alloc, size_t BufSize>
template <class ForwardIterator>
void deque<T, Alloc, BufSize>::range_initialize(ForwardIterator first,ForwardIterator last,forward_iterator_tag) {size_type n = 0;distance(first, last, n);create_map_and_nodes(n);__STL_TRY {uninitialized_copy(first, last, start);}__STL_UNWIND(destroy_map_and_nodes());
}#endif /* __STL_MEMBER_TEMPLATES */// 仅当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.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;reserve_map_at_front();*(start.node - 1) = allocate_node();__STL_TRY {start.set_node(start.node - 1);start.cur = start.last - 1;construct(start.cur, t_copy);}
#     ifdef __STL_USE_EXCEPTIONScatch(...) {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.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.set_node(start.node + 1);start.cur = start.first;
}#ifdef __STL_MEMBER_TEMPLATES// 将[first, last)区间元素插入到pos前template <class T, class Alloc, size_t BufSize>
template <class InputIterator>
void deque<T, Alloc, BufSize>::insert(iterator pos,InputIterator first, InputIterator last,input_iterator_tag)
{// 由于是Input Iterator, 则使用通用的inserter完成插入操作copy(first, last, inserter(*this, pos));
}template <class T, class Alloc, size_t BufSize>
template <class ForwardIterator>
void deque<T, Alloc, BufSize>::insert(iterator pos,ForwardIterator first,ForwardIterator last,forward_iterator_tag)
{size_type n = 0;distance(first, last, n);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));}elseinsert_aux(pos, first, last, n);
}#endif /* __STL_MEMBER_TEMPLATES */// 在指定位置前插入元素//              insert_aux(iterator pos, const value_type& x)
//                                   |
//                                   |----------- 判断pos前端元素少还是后端元素少
//                                   |
//               -----------------------------------------------
//         前端少 |                                       后端少 |
//               |                                             |
//               ↓                                             |
//           进行相关操作                                   进行相关操作// 下面以pos前面元素少的情形进行说明, 为了简化, 假设操作不会超过一个缓冲区区间
//
// 插入前状态
//           start            pos                                 end
//             ↓               ↓                                   ↓
// ---------------------------------------------------------------------
// |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | X |
// ---------------------------------------------------------------------
//
// 需要进行操作的区间
//                需要拷贝的区间
//                 -------------
//       start     |           |                                  end
//         ↓       ↓           ↓                                   ↓
// ---------------------------------------------------------------------
// |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | X |
// ---------------------------------------------------------------------
//             ↑   ↑       ↑   ↑
//        front1   |       |   |
//                 |       |   |
//            front2       |   |
//                         |   |
//                       pos   |
//                             |
//                          pos1
// 拷贝操作完成后
//
//         这是[front2, pos1)
//             ------------- --------- 这里是给待插入元素预留的空间
//       start |           | |                                    end
//         ↓   ↓           ↓ ↓                                     ↓
// ---------------------------------------------------------------------
// |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   | X |
// ---------------------------------------------------------------------
//         ↑
//   这里存储的是原来的front()
//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;
}// 在pos前插入n个值为x的元素//         insert_aux(iterator pos, size_type n, const value_type& x)
//                                   ↓
//                      elems_before = pos - start;
//                            length = size();
//                                   |
//                                   |---------- elems_before < length / 2 ?
//                                   |           判断哪侧元素少, 就对哪侧进行操作
//               ---------------------------------------
//           Yes |                                     |  No
//               |                                     |
//               ↓                                     ↓
// reserve_elements_at_front(n);          reserve_elements_at_back(n);
// 根据具体情况进行元素的拷贝操作             根据具体情况进行元素的拷贝操作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));}
}#ifdef __STL_MEMBER_TEMPLATES// 供给insert(iterator pos, ForwardIterator first, ForwardIterator last,)
// 处理通用情况
template <class T, class Alloc, size_t BufSize>
template <class ForwardIterator>
void deque<T, Alloc, BufSize>::insert_aux(iterator pos,ForwardIterator first,ForwardIterator 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 {ForwardIterator mid = first;advance(mid, 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 {ForwardIterator mid = first;advance(mid, 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));}
}#else /* __STL_MEMBER_TEMPLATES */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));}
}#endif /* __STL_MEMBER_TEMPLATES */// 在deque前端分配新结点
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::new_elements_at_front(size_type new_elements)
{size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();reserve_map_at_front(new_nodes);size_type i;__STL_TRY {for (i = 1; i <= new_nodes; ++i)*(start.node - i) = allocate_node();}
#       ifdef __STL_USE_EXCEPTIONScatch(...) {for (size_type j = 1; j < i; ++j)deallocate_node(*(start.node - j));throw;}
#       endif /* __STL_USE_EXCEPTIONS */
}// 在deque末尾分配新结点
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_EXCEPTIONScatch(...) {for (size_type j = 1; j < i; ++j)deallocate_node(*(finish.node + j));throw;}
#       endif /* __STL_USE_EXCEPTIONS */
}// 释放[before_start.node, start.node)的结点
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);
}// 释放(finish.node, after_finish.node]的结点
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) {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);elsecopy_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);
}// Nonmember functions.#ifndef __STL_NON_TYPE_TMPL_PARAM_BUGtemplate <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());
}#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */#if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && \!defined(__STL_NON_TYPE_TMPL_PARAM_BUG)template <class T, class Alloc, size_t BufSiz>
inline void swap(deque<T, Alloc, BufSiz>& x, deque<T, Alloc, BufSiz>& y) {x.swap(y);
}#endif#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma reset woff 1174
#endif__STL_END_NAMESPACE#endif /* __SGI_STL_INTERNAL_DEQUE_H */// Local Variables:
// mode:C++
// End:

《STL源码剖析》-- stl_deque.h相关推荐

  1. 《STL源码剖析》学习-- 1.9-- 可能令你困惑的C++语法1

    最近在看侯捷的<STL源码剖析>,虽然感觉自己c++看得比较深一点,还是感觉还多东西不是那么明白,这里将一些细小的东西或者概念记录一下. 有些东西是根据<C++编程思想>理解的 ...

  2. STL源码剖析——P142关于list::sort函数

    在list容器中,由于容器自身组织数据的特殊性,所以list提供了自己的排序函数list::sort, 并且实现得相当巧妙,不过<STL源码剖析>的原文中,我有些许疑问,对于该排序算法,侯 ...

  3. STL源码剖析 stack 栈 概述->(使用deque双端队列 / list链表)作为stack的底层容器

    Stack是一种先进后出的数据结构,他只有一个出口 stack允许 新增元素.移除元素.取得最顶端的元素,但是无法获得stack的内部数据,因此satck没有遍历行为 Stack定义的完整列表 (双端 ...

  4. STL源码剖析 __type_traits

    traits编程 弥补了C++本身的不足 STL只对迭代器进行规范制定出了iterator_traits,SGI在此基础上进一步扩展,产生了__type_traits 双下划线的含义是这个是SGI内部 ...

  5. STL源码剖析 空间配置器 查漏补缺

    ptrdiff_t含义 减去两个指针的结果的带符号整数类型 ptrdiff_t (Type support) - C 中文开发手册 - 开发者手册 - 云+社区 - 腾讯云 std::set_new_ ...

  6. 《STL源码剖析》笔记——allocator

    六大组件间关系 部分STL文件包含关系 allocator包含于中: 实际实现于三个文件 : 1.stl_construct.h :对象的构造和析构 2.stl_alloc.h空间配置和释放 3.st ...

  7. STL源码剖析之配接器

    adapter(配接器)在STL组件的灵活组合运用上,扮演者转换器的角色.adapter来源于一种适配器模式,其功能是:将一个class接口转换为另一个class的接口,使得原本因接口不兼容而不能合作 ...

  8. 【STL源码剖析】list模拟实现 | 适配器实现反向迭代器【超详细的底层算法解释】

    今天博主继续带来STL源码剖析专栏的第三篇博客了! 今天带来list的模拟实现! 话不多说,直接进入我们今天的内容! 前言 那么这里博主先安利一下一些干货满满的专栏啦! 手撕数据结构https://b ...

  9. STL(C++标准库,体系结构及其内核分析)(STL源码剖析)(更新完毕)

    文章目录 介绍 Level 0:使用C++标准库 0 STL六大部件 0.1 六大部件之间的关系 0.2 复杂度 0.3 容器是前闭后开(左闭右开)区间 1 容器的结构与分类 1.1 使用容器Arra ...

  10. STL源码剖析学习七:stack和queue

    STL源码剖析学习七:stack和queue stack是一种先进后出的数据结构,只有一个出口. 允许新增.删除.获取最顶端的元素,没有任何办法可以存取其他元素,不允许有遍历行为. 缺省情况下用deq ...

最新文章

  1. 2012.3.17庆祝我的博客创建!名字是web-sheena
  2. 有始有终,设计一个结构合理的下载模块
  3. IO流之过滤流介绍:
  4. 逆向去除winrar广告
  5. Andriod中的两种自定义颜色选择器
  6. php面向对象公共类,PHP面向对象(一):类与类的实例化
  7. UE4如何贴混合贴图_UE4[蓝图]动态积雪材质的实现(一)
  8. vue --- vue中的几个钩子属性
  9. linux操作系统中查看网络信息的命令,Linux查看系统信息命令盘点
  10. 怎么从PDF中提取图片?教你简单的提取方法
  11. 中国将在未来几十年主导电动汽车市场
  12. matlab的方法定义变量,Matlab定义变量的操作步骤
  13. MySQL实验7存储过程_mySQL 教程 第7章 存储过程和函数
  14. 在matlab设置三角波,matlab 中repeating sequence中怎样设置20khz三角波
  15. 床上用品四件套家居纺织品网站模板
  16. 补天漏洞平台为什么能吸引众多白帽和企业?
  17. 【详解】机器学习库-Matplotlib+Numpy+Pandas
  18. 【Centos7 NTP 服务器和客户端配置(含离线状态) 附赠手动配置系统时间】
  19. 无题(2011.10.26)
  20. 【TARS】TarsWeb 说明

热门文章

  1. 每日算法(四十三)-java为了更改的规划城市,需要统计楼栋数目信息。
  2. 将树莓派变成行车记录仪
  3. tableau连接不上oracle,Oracle
  4. File Provider
  5. 耳机不分主从是什么意思_音质出色,降噪服众,千元机档位王者南卡A1主动降噪耳机深度评测...
  6. UI自动化测试框架-从入门到精通
  7. nrf51822 52832学习汇总
  8. 牛客网SQL大厂面试真题(二)
  9. Elasticsearch 如何实现时间差查询?
  10. 前端培训教程JavaScript