zoukankan      html  css  js  c++  java
  • STL-Deque 源码剖析

       1 G++ 2.91.57,cygnuscygwin-b20includeg++stl_deque.h 完整列表
       2 /*
       3  *
       4  * Copyright (c) 1994
       5  * Hewlett-Packard Company
       6  *
       7  * Permission to use, copy, modify, distribute and sell this software
       8  * and its documentation for any purpose is hereby granted without fee,
       9  * provided that the above copyright notice appear in all copies and
      10  * that both that copyright notice and this permission notice appear
      11  * in supporting documentation.  Hewlett-Packard Company makes no
      12  * representations about the suitability of this software for any
      13  * purpose.  It is provided "as is" without express or implied warranty.
      14  *
      15  *
      16  * Copyright (c) 1997
      17  * Silicon Graphics Computer Systems, Inc.
      18  *
      19  * Permission to use, copy, modify, distribute and sell this software
      20  * and its documentation for any purpose is hereby granted without fee,
      21  * provided that the above copyright notice appear in all copies and
      22  * that both that copyright notice and this permission notice appear
      23  * in supporting documentation.  Silicon Graphics makes no
      24  * representations about the suitability of this software for any
      25  * purpose.  It is provided "as is" without express or implied warranty.
      26  */
      27 
      28 /* NOTE: This is an internal header file, included by other STL headers.
      29  *   You should not attempt to use it directly.
      30  */
      31 
      32 #ifndef __SGI_STL_INTERNAL_DEQUE_H
      33 #define __SGI_STL_INTERNAL_DEQUE_H
      34 
      35 /* Class 的恆長特性(invariants):
      36  *  對於任何 nonsingular iterator I:
      37  *    i.node 是 map array 中的某個元素的位址。
      38  *      i.node 所指內容則是一個指標,指向某個節點(緩衝區)的頭。
      39  *    i.first == *(i.node) 
      40  *    i.last  == i.first + node_size(也就是 buffer_size())
      41  *    i.cur 是一個指標,指向範圍 [i.first, i.last) 之間。注意:
      42  *      這意味 i.cur 永遠是一個 dereferenceable pointer,
      43  *      縱使 i 是一個 past-the-end iterator.
      44  *  Start 和 Finish 總是 nonsingular iterators。注意:這意味
      45  *    empty deque 一定會有一個node,而一個具有N個元素的deque,
      46  *    (N 表示緩衝區大小),一定會有兩個nodes。
      47  *  對於start.node 和finish.node 以外的每一個node,其中的每一個元素
      48  *    都是一個經過初始化的物件。如果 start.node == finish.node,
      49  *    那麼 [start.cur, finish.cur) 都是經過初始化的物件,而該範圍以外
      50  *    元素則是未經初始化的空間。否則,[start.cur, start.last) 和
      51  *    [finish.first, finish.cur) 是經過初始化的物件,而
      52  *    [start.first, start.cur) 和 [finish.cur, finish.last)
      53  *    則是未經初始化的空間
      54  *  [map, map + map_size) 是一個有效的,non-empty 的範圍。  
      55  *  [start.node, finish.node] 是一個有效的範圍,內含於 
      56  *    [map, map + map_size) 之內。  
      57  *  範圍 [map, map + map_size) 內的任何一個指標會指向一個經過配置的
      58  *    node — 若且唯若該指標在範圍 [start.node, finish.node] 之內。
      59  */
      60 
      61 /*
      62  * 在前一版的deque中,node_size 由編譯器定死。這個版本允許使用者選擇節點 
      63  * (node)的大小。Deque 有三個 template 參數,其中第三個是一個型別為 size_t 
      64  * 的數值,代表每個節點(node)內含的元素個數。如果第三個 template 參數為0
      65  * (那是預設值),deque 就使用預設的節點大小。
      66  *
      67  * 使用不同的節點大小的唯一理由是,或許你的程式需要不同的效率並願意付出其他方
      68  * 面的代價。例如,假設你的程式內含許多deques,每一個都只內含一些元素,那麼
      69  * 你可以使用較小的 nodes 來節省記憶體(或許會因此犧牲速度)。
      70  *
      71  * 不幸的是,某些編譯器面對 non-type template 參數會有問題。stl_config.h 之
      72  * 中為此定義了一個 __STL_NON_TYPE_TMPL_PARAM_BUG。如果你的編譯器正是如
      73  * 此,你就無法使用不同的節點大小,你必須使用預設大小。
      74 */
      75 
      76 __STL_BEGIN_NAMESPACE 
      77 
      78 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
      79 #pragma set woff 1174
      80 #endif
      81 
      82 // 注意:下面這個函式是七拼八湊的產品,只是為了閃避數家編譯器在處理常數算式
      83 // (constant expressions)時的臭蟲。
      84 // 如果 n 不為 0,傳回 n,表示 buffer size 由使用者自定。
      85 // 如果 n 為 0,表示buffer size 使用預設值,那麼
      86 //   如果 sz(元素大小,sizeof(value_type))小於 512,傳回 512/sz,
      87 //   如果 sz 不小於 512,傳回 1。
      88 inline size_t __deque_buf_size(size_t n, size_t sz)
      89 {
      90   return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1));
      91 }
      92 
      93 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
      94 template <class T, class Ref, class Ptr, size_t BufSiz>
      95 struct __deque_iterator {     // 未繼承 std::iterator
      96   typedef __deque_iterator<T, T&, T*, BufSiz>      iterator;
      97   typedef __deque_iterator<T, const T&, const T*, BufSiz> const_iterator;
      98   static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); }
      99 #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
     100 template <class T, class Ref, class Ptr>
     101 struct __deque_iterator {     // 未繼承 std::iterator
     102   typedef __deque_iterator<T, T&, T*>             iterator;
     103   typedef __deque_iterator<T, const T&, const T*> const_iterator;
     104   static size_t buffer_size() {return __deque_buf_size(0, sizeof(T)); }
     105 #endif
     106 
     107   // 未繼承 std::iterator,所以必須自行撰寫五個必要的迭代器相應型別
     108   typedef random_access_iterator_tag iterator_category; // (1)
     109   typedef T value_type;                 // (2)
     110   typedef Ptr pointer;                 // (3)
     111   typedef Ref reference;                 // (4)
     112   typedef size_t size_type;
     113   typedef ptrdiff_t difference_type;     // (5)
     114   typedef T** map_pointer;
     115 
     116   typedef __deque_iterator self;
     117 
     118   // 保持與容器的聯結
     119   T* cur;    // 此迭代器所指之緩衝區中的現行(current)元素
     120   T* first;    // 此迭代器所指之緩衝區的頭
     121   T* last;    // 此迭代器所指之緩衝區的尾(含備用空間)
     122   map_pointer node;
     123 
     124   __deque_iterator(T* x, map_pointer y) 
     125     : cur(x), first(*y), last(*y + buffer_size()), node(y) {}
     126   __deque_iterator() : cur(0), first(0), last(0), node(0) {}
     127   __deque_iterator(const iterator& x)
     128     : cur(x.cur), first(x.first), last(x.last), node(x.node) {}
     129 
     130 
     131 // 以下各個多載化運算子是 __deque_iterator<> 成功運作的關鍵。
     132 
     133   reference operator*() const { return *cur; }
     134 #ifndef __SGI_STL_NO_ARROW_OPERATOR
     135   pointer operator->() const { return &(operator*()); }
     136 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
     137 
     138   difference_type operator-(const self& x) const {
     139     return difference_type(buffer_size()) * (node - x.node - 1) +
     140       (cur - first) + (x.last - x.cur);
     141   }
     142   
     143   // 參考 More Effective C++, item6: Distinguish between prefix and
     144   // postfix forms of increment and decrement operators.
     145   self& operator++() {
     146     ++cur;                // 切換至下一個元素。
     147     if (cur == last) {        // 如果已達所在緩衝區的尾端,
     148       set_node(node + 1);    // 就切換至下一個節點(亦即緩衝區)
     149       cur = first;            //   的第一個元素。
     150     }
     151     return *this; 
     152   }
     153   self operator++(int)  {
     154     self tmp = *this;
     155     ++*this;
     156     return tmp;
     157   }
     158   self& operator--() {
     159     if (cur == first) {    // 如果已達所在緩衝區的頭端,
     160       set_node(node - 1);    // 就切換至前一個節點(亦即緩衝區)
     161       cur = last;            //   的最後一個元素。
     162     }
     163     --cur;                // 切換至前一個元素。
     164     return *this;
     165   }
     166   self operator--(int) {
     167     self tmp = *this;
     168     --*this;
     169     return tmp;
     170   }
     171 
     172   self& operator+=(difference_type n) {
     173     difference_type offset = n + (cur - first);
     174     if (offset >= 0 && offset < difference_type(buffer_size()))
     175       // 目標位置在同一緩衝區內
     176       cur += n;
     177     else {
     178       // 目標位置不在同一緩衝區內
     179       difference_type node_offset =
     180         offset > 0 ? offset / difference_type(buffer_size())
     181                    : -difference_type((-offset - 1) / buffer_size()) - 1;
     182       // 切換至正確的節點(亦即緩衝區)
     183       set_node(node + node_offset);
     184       // 切換至正確的元素
     185       cur = first + (offset - node_offset * difference_type(buffer_size()));
     186     }
     187     return *this;
     188   }
     189 
     190   // 參考 More Effective C++, item22: Consider using op= instead of  
     191   // stand-alone op.
     192   self operator+(difference_type n) const {
     193     self tmp = *this;
     194     return tmp += n; // 喚起operator+=
     195   }
     196 
     197   self& operator-=(difference_type n) { return *this += -n; }
     198   // 以上利用operator+= 來完成 operator-=
     199 
     200   // 參考 More Effective C++, item22: Consider using op= instead of  
     201   // stand-alone op.
     202   self operator-(difference_type n) const {
     203     self tmp = *this;
     204     return tmp -= n; // 喚起operator-=
     205   }
     206 
     207   reference operator[](difference_type n) const { return *(*this + n); }
     208   // 以上喚起operator*, operator+
     209 
     210   bool operator==(const self& x) const { return cur == x.cur; }
     211   bool operator!=(const self& x) const { return !(*this == x); }
     212   bool operator<(const self& x) const {
     213     return (node == x.node) ? (cur < x.cur) : (node < x.node);
     214   }
     215 
     216   void set_node(map_pointer new_node) {
     217     node = new_node;
     218     first = *new_node;
     219     last = first + difference_type(buffer_size());
     220   }
     221 };
     222 
     223 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
     224 // 編譯器不支援 partial specialization 時,才需以下定義
     225 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
     226 
     227 template <class T, class Ref, class Ptr, size_t BufSiz>
     228 inline random_access_iterator_tag
     229 iterator_category(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {
     230   return random_access_iterator_tag();
     231 }
     232 
     233 template <class T, class Ref, class Ptr, size_t BufSiz>
     234 inline T* value_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {
     235   return 0;
     236 }
     237 
     238 template <class T, class Ref, class Ptr, size_t BufSiz>
     239 inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {
     240   return 0;
     241 }
     242 
     243 #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
     244 
     245 template <class T, class Ref, class Ptr>
     246 inline random_access_iterator_tag
     247 iterator_category(const __deque_iterator<T, Ref, Ptr>&) {
     248   return random_access_iterator_tag();
     249 }
     250 
     251 template <class T, class Ref, class Ptr>
     252 inline T* value_type(const __deque_iterator<T, Ref, Ptr>&) { return 0; }
     253 
     254 template <class T, class Ref, class Ptr>
     255 inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr>&) {
     256   return 0;
     257 }
     258 
     259 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
     260 // 編譯器不支援 partial specialization 時,才需以上定義
     261 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
     262 
     263 // 見 __deque_buf_size()。BufSize 預設值為 0 的唯一理由是為了閃避某些
     264 //  編譯器在處理常數算式(constant expressions)時的臭蟲。
     265 // 預設使用 alloc 為配置器
     266 template <class T, class Alloc = alloc, size_t BufSiz = 0> 
     267 class deque {
     268 public:                         // Basic types
     269   typedef T value_type;
     270   typedef value_type* pointer;
     271   typedef const value_type* const_pointer;
     272   typedef value_type& reference;
     273   typedef const value_type& const_reference;
     274   typedef size_t size_type;
     275   typedef ptrdiff_t difference_type;
     276 
     277 public:                         // Iterators
     278 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
     279   typedef __deque_iterator<T, T&, T*, BufSiz>              iterator;
     280   typedef __deque_iterator<T, const T&, const T&, BufSiz>  const_iterator;
     281 #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
     282   typedef __deque_iterator<T, T&, T*>                      iterator;
     283   typedef __deque_iterator<T, const T&, const T*>          const_iterator;
     284 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
     285 
     286 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
     287   typedef reverse_iterator<const_iterator> const_reverse_iterator;
     288   typedef reverse_iterator<iterator> reverse_iterator;
     289 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
     290   typedef reverse_iterator<const_iterator, value_type, const_reference, 
     291                            difference_type>  
     292           const_reverse_iterator;
     293   typedef reverse_iterator<iterator, value_type, reference, difference_type>
     294           reverse_iterator; 
     295 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
     296 
     297 protected:                      // Internal typedefs
     298   // 元素的指標的指標(pointer of pointer of T)
     299   typedef pointer* map_pointer;    
     300   // 專屬之空間配置器,每次配置一個元素大小
     301   typedef simple_alloc<value_type, Alloc> data_allocator;
     302   // 專屬之空間配置器,每次配置一個指標大小
     303   typedef simple_alloc<pointer, Alloc> map_allocator;
     304 
     305   static size_type buffer_size() {
     306     return __deque_buf_size(BufSiz, sizeof(value_type));
     307   }
     308   static size_type initial_map_size() { return 8; }
     309 
     310 protected:                      // Data members
     311   iterator start;        // 表現第一個節點。
     312   iterator finish;    // 表現最後一個節點。
     313 
     314   map_pointer map;    // 指向map,map是塊連續空間,
     315                           // 其內的每個元素都是一個指標(稱為節點),指向一塊緩衝區。
     316   size_type map_size;    // map內可容納多少指標。
     317 
     318 public:                         // Basic accessors
     319   iterator begin() { return start; }
     320   iterator end() { return finish; }
     321   const_iterator begin() const { return start; }
     322   const_iterator end() const { return finish; }
     323 
     324   reverse_iterator rbegin() { return reverse_iterator(finish); }
     325   reverse_iterator rend() { return reverse_iterator(start); }
     326   const_reverse_iterator rbegin() const {
     327     return const_reverse_iterator(finish);
     328   }
     329   const_reverse_iterator rend() const {
     330     return const_reverse_iterator(start);
     331   }
     332 
     333   reference operator[](size_type n) {
     334     return start[difference_type(n)]; // 喚起 __deque_iterator<>::operator[]
     335   }
     336   const_reference operator[](size_type n) const {
     337     return start[difference_type(n)];
     338   }
     339 
     340   reference front() { return *start; } // 喚起 __deque_iterator<>::operator*
     341   reference back() {
     342     iterator tmp = finish;    
     343     --tmp;    // 喚起 __deque_iterator<>::operator--
     344     return *tmp;     // 喚起 __deque_iterator<>::operator*
     345     // 以上三行何不改為:return *(finish-1);
     346     // 因為 __deque_iterator<> 沒有為 (finish-1) 定義運算子。待查!
     347   }
     348   const_reference front() const { return *start; }
     349   const_reference back() const {
     350     const_iterator tmp = finish;
     351     --tmp;
     352     return *tmp;
     353   }
     354 
     355   // 下行最後有兩個 ‘;’,雖奇怪但合乎語法。
     356   size_type size() const { return finish - start;; } 
     357   // 以上喚起iterator::operator-
     358   size_type max_size() const { return size_type(-1); }
     359   bool empty() const { return finish == start; }
     360 
     361 public:                         // Constructor, destructor.
     362   deque()
     363     : start(), finish(), map(0), map_size(0)
     364     // 以上 start() 和 finish() 喚起 iterator(亦即 __deque_iterator)
     365     // 的 default ctor,於是令其 cur, first, last, node 皆為0。
     366   {
     367     create_map_and_nodes(0);
     368   }
     369 
     370   deque(const deque& x)
     371     : start(), finish(), map(0), map_size(0)
     372   {
     373     create_map_and_nodes(x.size());
     374     __STL_TRY {
     375       uninitialized_copy(x.begin(), x.end(), start);
     376     }
     377     __STL_UNWIND(destroy_map_and_nodes());
     378   }
     379 
     380   deque(size_type n, const value_type& value)
     381     : start(), finish(), map(0), map_size(0)
     382   {
     383     fill_initialize(n, value);
     384   }
     385 
     386   deque(int n, const value_type& value)
     387     : start(), finish(), map(0), map_size(0)
     388   {
     389     fill_initialize(n, value);
     390   }
     391  
     392   deque(long n, const value_type& value)
     393     : start(), finish(), map(0), map_size(0)
     394   {
     395     fill_initialize(n, value);
     396   }
     397 
     398   explicit deque(size_type n)
     399     : start(), finish(), map(0), map_size(0)
     400   {
     401     fill_initialize(n, value_type());
     402   }
     403 
     404 #ifdef __STL_MEMBER_TEMPLATES
     405 
     406   template <class InputIterator>
     407   deque(InputIterator first, InputIterator last)
     408     : start(), finish(), map(0), map_size(0)
     409   {
     410     range_initialize(first, last, iterator_category(first));
     411   }
     412 
     413 #else /* __STL_MEMBER_TEMPLATES */
     414 
     415   deque(const value_type* first, const value_type* last)
     416     : start(), finish(), map(0), map_size(0)
     417   {
     418     create_map_and_nodes(last - first);
     419     __STL_TRY {
     420       uninitialized_copy(first, last, start);
     421     }
     422     __STL_UNWIND(destroy_map_and_nodes());
     423   }
     424 
     425   deque(const_iterator first, const_iterator last)
     426     : start(), finish(), map(0), map_size(0)
     427   {
     428     create_map_and_nodes(last - first);
     429     __STL_TRY {
     430       uninitialized_copy(first, last, start);
     431     }
     432     __STL_UNWIND(destroy_map_and_nodes());
     433   }
     434 
     435 #endif /* __STL_MEMBER_TEMPLATES */
     436 
     437   ~deque() {
     438     destroy(start, finish);
     439     destroy_map_and_nodes();
     440   }
     441 
     442   deque& operator= (const deque& x) {
     443     const size_type len = size();
     444     if (&x != this) {
     445       if (len >= x.size())
     446         erase(copy(x.begin(), x.end(), start), finish);
     447       else {
     448         const_iterator mid = x.begin() + difference_type(len);
     449         copy(x.begin(), mid, start);
     450         insert(finish, mid, x.end());
     451       }
     452     }
     453     return *this;
     454   }        
     455 
     456   void swap(deque& x) {
     457     __STD::swap(start, x.start);
     458     __STD::swap(finish, x.finish);
     459     __STD::swap(map, x.map);
     460     __STD::swap(map_size, x.map_size);
     461   }
     462 
     463 public:                         // push_* and pop_*
     464   
     465   void push_back(const value_type& t) {
     466     if (finish.cur != finish.last - 1) { 
     467       // 最後緩衝區尚有一個以上的備用空間
     468       construct(finish.cur, t);    // 直接在備用空間上建構元素
     469       ++finish.cur;    // 調整最後緩衝區的使用狀態
     470     }
     471     else  // 最後緩衝區已無(或只剩一個)元素備用空間。
     472       push_back_aux(t);
     473   }
     474 
     475   void push_front(const value_type& t) {
     476     if (start.cur != start.first) {     // 第一緩衝區尚有備用空間
     477       construct(start.cur - 1, t);     // 直接在備用空間上建構元素
     478       --start.cur;        // 調整第一緩衝區的使用狀態
     479     }
     480     else // 第一緩衝區已無備用空間
     481       push_front_aux(t);
     482   }
     483 
     484   void pop_back() {
     485     if (finish.cur != finish.first) {
     486       // 最後緩衝區有一個(或更多)元素
     487 
     488       --finish.cur;        // 調整指標,相當於排除了最後元素
     489       destroy(finish.cur);    // 將最後元素解構
     490     }
     491     else
     492       // 最後緩衝區沒有任何元素
     493       pop_back_aux();        // 這裡將進行緩衝區的釋放工作
     494   }
     495 
     496   void pop_front() {
     497     if (start.cur != start.last - 1) {
     498       // 第一緩衝區有一個(或更多)元素
     499       destroy(start.cur);    // 將第一元素解構
     500       ++start.cur;            // 調整指標,相當於排除了第一元素
     501     }
     502     else 
     503       // 第一緩衝區僅有一個元素
     504       pop_front_aux();        // 這裡將進行緩衝區的釋放工作
     505   }
     506 
     507 public:                         // Insert
     508 
     509   // 在position 處安插一個元素,其值為 x
     510   iterator insert(iterator position, const value_type& x) {
     511     if (position.cur == start.cur) {    // 如果安插點是deque 最前端
     512       push_front(x);                // 交給push_front 去做
     513       return start;
     514     }
     515     else if (position.cur == finish.cur) { // 如果安插點是deque 最尾端
     516       push_back(x);                      // 交給push_back 去做
     517       iterator tmp = finish;
     518       --tmp;
     519       return tmp;
     520     }
     521     else {
     522       return insert_aux(position, x);         // 交給 insert_aux 去做
     523     }
     524   }
     525 
     526   iterator insert(iterator position) { return insert(position, value_type()); }
     527 
     528   void insert(iterator pos, size_type n, const value_type& x); 
     529 
     530   void insert(iterator pos, int n, const value_type& x) {
     531     insert(pos, (size_type) n, x);
     532   }
     533   void insert(iterator pos, long n, const value_type& x) {
     534     insert(pos, (size_type) n, x);
     535   }
     536 
     537 #ifdef __STL_MEMBER_TEMPLATES  
     538 
     539   template <class InputIterator>
     540   void insert(iterator pos, InputIterator first, InputIterator last) {
     541     insert(pos, first, last, iterator_category(first));
     542   }
     543 
     544 #else /* __STL_MEMBER_TEMPLATES */
     545 
     546   void insert(iterator pos, const value_type* first, const value_type* last);
     547   void insert(iterator pos, const_iterator first, const_iterator last);
     548 
     549 #endif /* __STL_MEMBER_TEMPLATES */
     550 
     551   void resize(size_type new_size, const value_type& x) {
     552     const size_type len = size();
     553     if (new_size < len) 
     554       erase(start + new_size, finish);
     555     else
     556       insert(finish, new_size - len, x);
     557   }
     558 
     559   void resize(size_type new_size) { resize(new_size, value_type()); }
     560 
     561 public:                         // Erase
     562   // 清除 pos 所指的元素。pos 為清除點。
     563   iterator erase(iterator pos) {
     564     iterator next = pos;
     565     ++next;
     566     difference_type index = pos - start;    // 清除點之前的元素個數
     567     if (index < (size() >> 1)) {            // 如果清除點之前的元素比較少,
     568       copy_backward(start, pos, next);    // 就搬移清除點之前的元素
     569       pop_front();                // 搬移完畢,最前一個元素贅餘,去除之
     570     }
     571     else {                    // 清除點之後的元素比較少,
     572       copy(next, finish, pos);    // 就搬移清除點之後的元素
     573       pop_back();                // 搬移完畢,最後一個元素贅餘,去除之
     574     }
     575     return start + index;
     576   }
     577 
     578   iterator erase(iterator first, iterator last);
     579   void clear(); 
     580 
     581 protected:                        // Internal construction/destruction
     582 
     583   void create_map_and_nodes(size_type num_elements);
     584   void destroy_map_and_nodes();
     585   void fill_initialize(size_type n, const value_type& value);
     586 
     587 #ifdef __STL_MEMBER_TEMPLATES  
     588 
     589   template <class InputIterator>
     590   void range_initialize(InputIterator first, InputIterator last,
     591                         input_iterator_tag);
     592 
     593   template <class ForwardIterator>
     594   void range_initialize(ForwardIterator first, ForwardIterator last,
     595                         forward_iterator_tag);
     596 
     597 #endif /* __STL_MEMBER_TEMPLATES */
     598 
     599 protected:                        // Internal push_* and pop_*
     600 
     601   void push_back_aux(const value_type& t);
     602   void push_front_aux(const value_type& t);
     603   void pop_back_aux();
     604   void pop_front_aux();
     605 
     606 protected:                        // Internal insert functions
     607 
     608 #ifdef __STL_MEMBER_TEMPLATES  
     609 
     610   template <class InputIterator>
     611   void insert(iterator pos, InputIterator first, InputIterator last,
     612               input_iterator_tag);
     613 
     614   template <class ForwardIterator>
     615   void insert(iterator pos, ForwardIterator first, ForwardIterator last,
     616               forward_iterator_tag);
     617 
     618 #endif /* __STL_MEMBER_TEMPLATES */
     619 
     620   iterator insert_aux(iterator pos, const value_type& x);
     621   void insert_aux(iterator pos, size_type n, const value_type& x);
     622 
     623 #ifdef __STL_MEMBER_TEMPLATES  
     624 
     625   template <class ForwardIterator>
     626   void insert_aux(iterator pos, ForwardIterator first, ForwardIterator last,
     627                   size_type n);
     628 
     629 #else /* __STL_MEMBER_TEMPLATES */
     630   
     631   void insert_aux(iterator pos,
     632                   const value_type* first, const value_type* last,
     633                   size_type n);
     634 
     635   void insert_aux(iterator pos, const_iterator first, const_iterator last,
     636                   size_type n);
     637  
     638 #endif /* __STL_MEMBER_TEMPLATES */
     639 
     640   iterator reserve_elements_at_front(size_type n) {
     641     size_type vacancies = start.cur - start.first;
     642     if (n > vacancies) 
     643       new_elements_at_front(n - vacancies);
     644     return start - difference_type(n);
     645   }
     646 
     647   iterator reserve_elements_at_back(size_type n) {
     648     size_type vacancies = (finish.last - finish.cur) - 1;
     649     if (n > vacancies)
     650       new_elements_at_back(n - vacancies);
     651     return finish + difference_type(n);
     652   }
     653 
     654   void new_elements_at_front(size_type new_elements);
     655   void new_elements_at_back(size_type new_elements);
     656 
     657   void destroy_nodes_at_front(iterator before_start);
     658   void destroy_nodes_at_back(iterator after_finish);
     659 
     660 protected:                      // Allocation of map and nodes
     661 
     662   // Makes sure the map has space for new nodes.  Does not actually
     663   //  add the nodes.  Can invalidate map pointers.  (And consequently, 
     664   //  deque iterators.)
     665 
     666   void reserve_map_at_back (size_type nodes_to_add = 1) {
     667     if (nodes_to_add + 1 > map_size - (finish.node - map))
     668       // 如果 map 尾端的節點備用空間不足
     669       // 符合以上條件則必須重換一個map(配置更大的,拷貝原來的,釋放原來的)
     670       reallocate_map(nodes_to_add, false); 
     671   }
     672 
     673   void reserve_map_at_front (size_type nodes_to_add = 1) {
     674     if (nodes_to_add > start.node - map)
     675       // 如果 map 前端的節點備用空間不足
     676       // 符合以上條件則必須重換一個map(配置更大的,拷貝原來的,釋放原來的)
     677       reallocate_map(nodes_to_add, true);    
     678   }
     679 
     680   void reallocate_map(size_type nodes_to_add, bool add_at_front);
     681 
     682   pointer allocate_node() { return data_allocator::allocate(buffer_size()); }
     683   void deallocate_node(pointer n) {
     684     data_allocator::deallocate(n, buffer_size());
     685   }
     686 
     687 #ifdef __STL_NON_TYPE_TMPL_PARAM_BUG
     688 public:
     689   bool operator==(const deque<T, Alloc, 0>& x) const {
     690     return size() == x.size() && equal(begin(), end(), x.begin());
     691   }
     692   bool operator!=(const deque<T, Alloc, 0>& x) const {
     693     return size() != x.size() || !equal(begin(), end(), x.begin());
     694   }
     695   bool operator<(const deque<T, Alloc, 0>& x) const {
     696     return lexicographical_compare(begin(), end(), x.begin(), x.end());
     697   }
     698 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
     699 };
     700 
     701 // Non-inline member functions
     702 
     703 template <class T, class Alloc, size_t BufSize>
     704 void deque<T, Alloc, BufSize>::insert(iterator pos,
     705                                       size_type n, const value_type& x) {
     706   if (pos.cur == start.cur) {
     707     iterator new_start = reserve_elements_at_front(n);
     708     uninitialized_fill(new_start, start, x);
     709     start = new_start;
     710   }
     711   else if (pos.cur == finish.cur) {
     712     iterator new_finish = reserve_elements_at_back(n);
     713     uninitialized_fill(finish, new_finish, x);
     714     finish = new_finish;
     715   }
     716   else 
     717     insert_aux(pos, n, x);
     718 }
     719 
     720 #ifndef __STL_MEMBER_TEMPLATES  
     721 
     722 template <class T, class Alloc, size_t BufSize>
     723 void deque<T, Alloc, BufSize>::insert(iterator pos,
     724                                       const value_type* first,
     725                                       const value_type* last) {
     726   size_type n = last - first;
     727   if (pos.cur == start.cur) {
     728     iterator new_start = reserve_elements_at_front(n);
     729     __STL_TRY {
     730       uninitialized_copy(first, last, new_start);
     731       start = new_start;
     732     }
     733     __STL_UNWIND(destroy_nodes_at_front(new_start));
     734   }
     735   else if (pos.cur == finish.cur) {
     736     iterator new_finish = reserve_elements_at_back(n);
     737     __STL_TRY {
     738       uninitialized_copy(first, last, finish);
     739       finish = new_finish;
     740     }
     741     __STL_UNWIND(destroy_nodes_at_back(new_finish));
     742   }
     743   else
     744     insert_aux(pos, first, last, n);
     745 }
     746 
     747 template <class T, class Alloc, size_t BufSize>
     748 void deque<T, Alloc, BufSize>::insert(iterator pos,
     749                                       const_iterator first,
     750                                       const_iterator last)
     751 {
     752   size_type n = last - first;
     753   if (pos.cur == start.cur) {
     754     iterator new_start = reserve_elements_at_front(n);
     755     __STL_TRY {
     756       uninitialized_copy(first, last, new_start);
     757       start = new_start;
     758     }
     759     __STL_UNWIND(destroy_nodes_at_front(new_start));
     760   }
     761   else if (pos.cur == finish.cur) {
     762     iterator new_finish = reserve_elements_at_back(n);
     763     __STL_TRY {
     764       uninitialized_copy(first, last, finish);
     765       finish = new_finish;
     766     }
     767     __STL_UNWIND(destroy_nodes_at_back(new_finish));
     768   }
     769   else
     770     insert_aux(pos, first, last, n);
     771 }
     772 
     773 #endif /* __STL_MEMBER_TEMPLATES */
     774 
     775 template <class T, class Alloc, size_t BufSize>
     776 deque<T, Alloc, BufSize>::iterator 
     777 deque<T, Alloc, BufSize>::erase(iterator first, iterator last) {
     778   if (first == start && last == finish) { // 如果清除區間就是整個 deque
     779     clear();                            // 直接呼叫 clear() 即可
     780     return finish;
     781   }
     782   else {
     783     difference_type n = last - first;            // 清除區間的長度
     784     difference_type elems_before = first - start;    // 清除區間前方的元素個數
     785     if (elems_before < (size() - n) / 2) {        // 如果前方的元素比較少,
     786       copy_backward(start, first, last);        // 向後搬移前方元素(覆蓋清除區間)
     787       iterator new_start = start + n;            // 標記 deque 的新起點
     788       destroy(start, new_start);                // 搬移完畢,將贅餘的元素解構
     789       // 以下將贅餘的緩衝區釋放
     790       for (map_pointer cur = start.node; cur < new_start.node; ++cur)
     791         data_allocator::deallocate(*cur, buffer_size());
     792       start = new_start;    // 設定 deque 的新起點
     793     }
     794     else {    // 如果清除區間後方的元素比較少
     795       copy(last, finish, first);            // 向前搬移後方元素(覆蓋清除區間)
     796       iterator new_finish = finish - n;    // 標記 deque 的新尾點
     797       destroy(new_finish, finish);        // 搬移完畢,將贅餘的元素解構
     798       // 以下將贅餘的緩衝區釋放
     799       for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur)
     800         data_allocator::deallocate(*cur, buffer_size());
     801       finish = new_finish;    // 設定 deque 的新尾點
     802     }
     803     return start + elems_before;
     804   }
     805 }
     806 
     807 // 注意,最終需要保留一個緩衝區。這是deque 的策略,也是deque 的初始狀態。
     808 template <class T, class Alloc, size_t BufSize>
     809 void deque<T, Alloc, BufSize>::clear() {
     810   // 以下針對頭尾以外的每一個緩衝區(它們一定都是飽滿的)
     811   for (map_pointer node = start.node + 1; node < finish.node; ++node) {
     812     // 將緩衝區內的所有元素解構。注意,呼叫的是destroy() 第二版本,見2.2.3節
     813     destroy(*node, *node + buffer_size());
     814     // 釋放緩衝區記憶體
     815     data_allocator::deallocate(*node, buffer_size());
     816   }
     817 
     818   if (start.node != finish.node) {    // 至少有頭尾兩個緩衝區
     819     destroy(start.cur, start.last);    // 將頭緩衝區的目前所有元素解構
     820     destroy(finish.first, finish.cur); // 將尾緩衝區的目前所有元素解構
     821     // 以下釋放尾緩衝區。注意,頭緩衝區保留。
     822     data_allocator::deallocate(finish.first, buffer_size());
     823   }
     824   else    // 只有一個緩衝區
     825     destroy(start.cur, finish.cur);    // 將此唯一緩衝區內的所有元素解構
     826     // 注意,並不釋放緩衝區空間。這唯一的緩衝區將保留。
     827 
     828   finish = start;    // 調整狀態
     829 }
     830 
     831 template <class T, class Alloc, size_t BufSize>
     832 void deque<T, Alloc, BufSize>::create_map_and_nodes(size_type num_elements) {
     833   // 需要節點數=(元素個數/每個緩衝區可容納的元素個數)+1
     834   // 如果剛好整除,會多配一個節點。
     835   size_type num_nodes = num_elements / buffer_size() + 1;
     836 
     837   // 一個 map 要管理幾個節點。最少8個,最多是 “所需節點數加2”
     838   // (前後各預留一個,擴充時可用)。
     839   map_size = max(initial_map_size(), num_nodes + 2);
     840   map = map_allocator::allocate(map_size);
     841   // 以上配置出一個 “具有 map_size個節點” 的map。
     842 
     843   // 以下令nstart和nfinish指向map所擁有之全部節點的最中央區段。
     844   // 保持在最中央,可使頭尾兩端的擴充能量一樣大。每個節點可對應一個緩衝區。
     845   map_pointer nstart = map + (map_size - num_nodes) / 2;
     846   map_pointer nfinish = nstart + num_nodes - 1;
     847     
     848   map_pointer cur;
     849   __STL_TRY {
     850     // 為map內的每個現用節點配置緩衝區。所有緩衝區加起來就是deque的空間
     851    // (最後一個緩衝區可能留有一些餘裕)。
     852     for (cur = nstart; cur <= nfinish; ++cur)
     853       *cur = allocate_node();
     854   }
     855 #     ifdef  __STL_USE_EXCEPTIONS 
     856   catch(...) {
     857     // "commit or rollback" 語意:若非全部成功,就一個不留。
     858     for (map_pointer n = nstart; n < cur; ++n)
     859       deallocate_node(*n);
     860     map_allocator::deallocate(map, map_size);
     861     throw;
     862   }
     863 #     endif /* __STL_USE_EXCEPTIONS */
     864 
     865   // 為deque內的兩個迭代器start和end 設定正確的內容。
     866   start.set_node(nstart);
     867   finish.set_node(nfinish);
     868   start.cur = start.first;        // first, cur都是public
     869   finish.cur = finish.first + num_elements % buffer_size();
     870   // 前面說過,如果剛好整除,會多配一個節點。
     871   // 此時即令cur指向這多配的一個節點(所對映之緩衝區)的起頭處。
     872 }
     873 
     874 // This is only used as a cleanup function in catch clauses.
     875 template <class T, class Alloc, size_t BufSize>
     876 void deque<T, Alloc, BufSize>::destroy_map_and_nodes() {
     877   for (map_pointer cur = start.node; cur <= finish.node; ++cur)
     878     deallocate_node(*cur);
     879   map_allocator::deallocate(map, map_size);
     880 }
     881   
     882 
     883 template <class T, class Alloc, size_t BufSize>
     884 void deque<T, Alloc, BufSize>::fill_initialize(size_type n,
     885                                                const value_type& value) {
     886   create_map_and_nodes(n);     // 把deque的結構都產生並安排好
     887   map_pointer cur;
     888   __STL_TRY {
     889     // 為每個節點的緩衝區設定初值
     890     for (cur = start.node; cur < finish.node; ++cur)
     891       uninitialized_fill(*cur, *cur + buffer_size(), value);
     892     // 最後一個節點的設定稍有不同(因為尾端可能有備用空間,不必設初值)
     893     uninitialized_fill(finish.first, finish.cur, value);
     894   }
     895 #       ifdef __STL_USE_EXCEPTIONS
     896   catch(...) {
     897     // "commit or rollback" 語意:若非全部成功,就一個不留。
     898     for (map_pointer n = start.node; n < cur; ++n)
     899       destroy(*n, *n + buffer_size());
     900     destroy_map_and_nodes();
     901     throw;
     902   }
     903 #       endif /* __STL_USE_EXCEPTIONS */
     904 }
     905 
     906 #ifdef __STL_MEMBER_TEMPLATES  
     907 
     908 template <class T, class Alloc, size_t BufSize>
     909 template <class InputIterator>
     910 void deque<T, Alloc, BufSize>::range_initialize(InputIterator first,
     911                                                 InputIterator last,
     912                                                 input_iterator_tag) {
     913   create_map_and_nodes(0);
     914   for ( ; first != last; ++first)
     915     push_back(*first);
     916 }
     917 
     918 template <class T, class Alloc, size_t BufSize>
     919 template <class ForwardIterator>
     920 void deque<T, Alloc, BufSize>::range_initialize(ForwardIterator first,
     921                                                 ForwardIterator last,
     922                                                 forward_iterator_tag) {
     923   size_type n = 0;
     924   distance(first, last, n);
     925   create_map_and_nodes(n);
     926   __STL_TRY {
     927     uninitialized_copy(first, last, start);
     928   }
     929   __STL_UNWIND(destroy_map_and_nodes());
     930 }
     931 
     932 #endif /* __STL_MEMBER_TEMPLATES */
     933 
     934 // 只有當 finish.cur == finish.last – 1 時才會被呼叫。
     935 // 也就是說只有當最後一個緩衝區只剩一個備用元素空間時才會被呼叫。
     936 template <class T, class Alloc, size_t BufSize>
     937 void deque<T, Alloc, BufSize>::push_back_aux(const value_type& t) {
     938   value_type t_copy = t;
     939   reserve_map_at_back();        //  若符合某種條件則必須重換一個map
     940   *(finish.node + 1) = allocate_node();    // 配置一個新節點(緩衝區)
     941   __STL_TRY {
     942     construct(finish.cur, t_copy);        // 針對標的元素設值
     943     finish.set_node(finish.node + 1);    // 改變finish,令其指向新節點
     944     finish.cur = finish.first;            // 設定 finish 的狀態
     945   }
     946   __STL_UNWIND(deallocate_node(*(finish.node + 1)));
     947 }
     948 
     949 // 只有當start.cur == start.first時才會被呼叫。
     950 // 也就是說只有當第一個緩衝區沒有任何備用元素時才會被呼叫。
     951 template <class T, class Alloc, size_t BufSize>
     952 void deque<T, Alloc, BufSize>::push_front_aux(const value_type& t) {
     953   value_type t_copy = t;
     954   reserve_map_at_front();        //  若符合某種條件則必須重換一個map
     955   *(start.node - 1) = allocate_node();    // 配置一個新節點(緩衝區)
     956   __STL_TRY {
     957     start.set_node(start.node - 1);        // 改變start,令其指向新節點
     958     start.cur = start.last - 1;            // 設定 start的狀態
     959     construct(start.cur, t_copy);        // 針對標的元素設值
     960   }
     961 #     ifdef __STL_USE_EXCEPTIONS
     962   catch(...) {
     963     // "commit or rollback" 語意:若非全部成功,就一個不留。
     964     start.set_node(start.node + 1);
     965     start.cur = start.first;
     966     deallocate_node(*(start.node - 1));
     967     throw;
     968   }
     969 #     endif /* __STL_USE_EXCEPTIONS */
     970 } 
     971 
     972 // 只有當finish.cur == finish.first時才會被呼叫。
     973 template <class T, class Alloc, size_t BufSize>
     974 void deque<T, Alloc, BufSize>::pop_back_aux() {
     975   deallocate_node(finish.first);    // 釋放最後一個緩衝區
     976   finish.set_node(finish.node - 1);    // 調整 finish 的狀態,使指向
     977   finish.cur = finish.last - 1;        //  上一個緩衝區的最後一個元素
     978   destroy(finish.cur);                // 將該元素解構。
     979 }
     980 
     981 // 只有當start.cur == start.last - 1時才會被呼叫。
     982 template <class T, class Alloc, size_t BufSize>
     983 void deque<T, Alloc, BufSize>::pop_front_aux() {
     984   destroy(start.cur);                // 將第一緩衝區的第一個元素解構。
     985   deallocate_node(start.first);        // 釋放第一緩衝區。
     986   start.set_node(start.node + 1);    // 調整 start 的狀態,使指向
     987   start.cur = start.first;            //  下一個緩衝區的第一個元素。
     988 }      
     989 
     990 #ifdef __STL_MEMBER_TEMPLATES  
     991 
     992 template <class T, class Alloc, size_t BufSize>
     993 template <class InputIterator>
     994 void deque<T, Alloc, BufSize>::insert(iterator pos,
     995                                       InputIterator first, InputIterator last,
     996                                       input_iterator_tag) {
     997   copy(first, last, inserter(*this, pos));
     998 }
     999 
    1000 template <class T, class Alloc, size_t BufSize>
    1001 template <class ForwardIterator>
    1002 void deque<T, Alloc, BufSize>::insert(iterator pos,
    1003                                       ForwardIterator first,
    1004                                       ForwardIterator last,
    1005                                       forward_iterator_tag) {
    1006   size_type n = 0;
    1007   distance(first, last, n);
    1008   if (pos.cur == start.cur) {
    1009     iterator new_start = reserve_elements_at_front(n);
    1010     __STL_TRY {
    1011       uninitialized_copy(first, last, new_start);
    1012       start = new_start;
    1013     }
    1014     __STL_UNWIND(destroy_nodes_at_front(new_start));
    1015   }
    1016   else if (pos.cur == finish.cur) {
    1017     iterator new_finish = reserve_elements_at_back(n);
    1018     __STL_TRY {
    1019       uninitialized_copy(first, last, finish);
    1020       finish = new_finish;
    1021     }
    1022     __STL_UNWIND(destroy_nodes_at_back(new_finish));
    1023   }
    1024   else
    1025     insert_aux(pos, first, last, n);
    1026 }
    1027 
    1028 #endif /* __STL_MEMBER_TEMPLATES */
    1029 
    1030 template <class T, class Alloc, size_t BufSize>
    1031 typename deque<T, Alloc, BufSize>::iterator
    1032 deque<T, Alloc, BufSize>::insert_aux(iterator pos, const value_type& x) {
    1033   difference_type index = pos - start;    // 安插點之前的元素個數
    1034   value_type x_copy = x;
    1035   if (index < size() / 2) {            // 如果安插點之前的元素個數比較少
    1036     push_front(front());            // 在最前端加入與第一元素同值的元素。
    1037     iterator front1 = start;        // 以下標示記號,然後進行元素搬移...
    1038     ++front1;
    1039     iterator front2 = front1;
    1040     ++front2;
    1041     pos = start + index;
    1042     iterator pos1 = pos;
    1043     ++pos1;
    1044     copy(front2, pos1, front1);        // 元素搬移
    1045   }
    1046   else {                        // 安插點之後的元素個數比較少
    1047     push_back(back());            // 在最尾端加入與最後元素同值的元素。
    1048     iterator back1 = finish;    // 以下標示記號,然後進行元素搬移...
    1049     --back1;
    1050     iterator back2 = back1;
    1051     --back2;
    1052     pos = start + index;
    1053     copy_backward(pos, back2, back1);    // 元素搬移
    1054   }
    1055   *pos = x_copy;    // 在安插點上設定新值
    1056   return pos;
    1057 }
    1058 
    1059 template <class T, class Alloc, size_t BufSize>
    1060 void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
    1061                                           size_type n, const value_type& x) {
    1062   const difference_type elems_before = pos - start;
    1063   size_type length = size();
    1064   value_type x_copy = x;
    1065   if (elems_before < length / 2) {
    1066     iterator new_start = reserve_elements_at_front(n);
    1067     iterator old_start = start;
    1068     pos = start + elems_before;
    1069     __STL_TRY {
    1070       if (elems_before >= difference_type(n)) {
    1071         iterator start_n = start + difference_type(n);
    1072         uninitialized_copy(start, start_n, new_start);
    1073         start = new_start;
    1074         copy(start_n, pos, old_start);
    1075         fill(pos - difference_type(n), pos, x_copy);
    1076       }
    1077       else {
    1078         __uninitialized_copy_fill(start, pos, new_start, start, x_copy);
    1079         start = new_start;
    1080         fill(old_start, pos, x_copy);
    1081       }
    1082     }
    1083     __STL_UNWIND(destroy_nodes_at_front(new_start));
    1084   }
    1085   else {
    1086     iterator new_finish = reserve_elements_at_back(n);
    1087     iterator old_finish = finish;
    1088     const difference_type elems_after = difference_type(length) - elems_before;
    1089     pos = finish - elems_after;
    1090     __STL_TRY {
    1091       if (elems_after > difference_type(n)) {
    1092         iterator finish_n = finish - difference_type(n);
    1093         uninitialized_copy(finish_n, finish, finish);
    1094         finish = new_finish;
    1095         copy_backward(pos, finish_n, old_finish);
    1096         fill(pos, pos + difference_type(n), x_copy);
    1097       }
    1098       else {
    1099         __uninitialized_fill_copy(finish, pos + difference_type(n),
    1100                                   x_copy,
    1101                                   pos, finish);
    1102         finish = new_finish;
    1103         fill(pos, old_finish, x_copy);
    1104       }
    1105     }
    1106     __STL_UNWIND(destroy_nodes_at_back(new_finish));
    1107   }
    1108 }
    1109 
    1110 #ifdef __STL_MEMBER_TEMPLATES  
    1111 
    1112 template <class T, class Alloc, size_t BufSize>
    1113 template <class ForwardIterator>
    1114 void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
    1115                                           ForwardIterator first,
    1116                                           ForwardIterator last,
    1117                                           size_type n)
    1118 {
    1119   const difference_type elems_before = pos - start;
    1120   size_type length = size();
    1121   if (elems_before < length / 2) {
    1122     iterator new_start = reserve_elements_at_front(n);
    1123     iterator old_start = start;
    1124     pos = start + elems_before;
    1125     __STL_TRY {
    1126       if (elems_before >= difference_type(n)) {
    1127         iterator start_n = start + difference_type(n); 
    1128         uninitialized_copy(start, start_n, new_start);
    1129         start = new_start;
    1130         copy(start_n, pos, old_start);
    1131         copy(first, last, pos - difference_type(n));
    1132       }
    1133       else {
    1134         ForwardIterator mid = first;
    1135         advance(mid, difference_type(n) - elems_before);
    1136         __uninitialized_copy_copy(start, pos, first, mid, new_start);
    1137         start = new_start;
    1138         copy(mid, last, old_start);
    1139       }
    1140     }
    1141     __STL_UNWIND(destroy_nodes_at_front(new_start));
    1142   }
    1143   else {
    1144     iterator new_finish = reserve_elements_at_back(n);
    1145     iterator old_finish = finish;
    1146     const difference_type elems_after = difference_type(length) - elems_before;
    1147     pos = finish - elems_after;
    1148     __STL_TRY {
    1149       if (elems_after > difference_type(n)) {
    1150         iterator finish_n = finish - difference_type(n);
    1151         uninitialized_copy(finish_n, finish, finish);
    1152         finish = new_finish;
    1153         copy_backward(pos, finish_n, old_finish);
    1154         copy(first, last, pos);
    1155       }
    1156       else {
    1157         ForwardIterator mid = first;
    1158         advance(mid, elems_after);
    1159         __uninitialized_copy_copy(mid, last, pos, finish, finish);
    1160         finish = new_finish;
    1161         copy(first, mid, pos);
    1162       }
    1163     }
    1164     __STL_UNWIND(destroy_nodes_at_back(new_finish));
    1165   }
    1166 }
    1167 
    1168 #else /* __STL_MEMBER_TEMPLATES */
    1169 
    1170 template <class T, class Alloc, size_t BufSize>
    1171 void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
    1172                                           const value_type* first,
    1173                                           const value_type* last,
    1174                                           size_type n)
    1175 {
    1176   const difference_type elems_before = pos - start;
    1177   size_type length = size();
    1178   if (elems_before < length / 2) {
    1179     iterator new_start = reserve_elements_at_front(n);
    1180     iterator old_start = start;
    1181     pos = start + elems_before;
    1182     __STL_TRY {
    1183       if (elems_before >= difference_type(n)) {
    1184         iterator start_n = start + difference_type(n);
    1185         uninitialized_copy(start, start_n, new_start);
    1186         start = new_start;
    1187         copy(start_n, pos, old_start);
    1188         copy(first, last, pos - difference_type(n));
    1189       }
    1190       else {
    1191         const value_type* mid = first + (difference_type(n) - elems_before);
    1192         __uninitialized_copy_copy(start, pos, first, mid, new_start);
    1193         start = new_start;
    1194         copy(mid, last, old_start);
    1195       }
    1196     }
    1197     __STL_UNWIND(destroy_nodes_at_front(new_start));
    1198   }
    1199   else {
    1200     iterator new_finish = reserve_elements_at_back(n);
    1201     iterator old_finish = finish;
    1202     const difference_type elems_after = difference_type(length) - elems_before;
    1203     pos = finish - elems_after;
    1204     __STL_TRY {
    1205       if (elems_after > difference_type(n)) {
    1206         iterator finish_n = finish - difference_type(n);
    1207         uninitialized_copy(finish_n, finish, finish);
    1208         finish = new_finish;
    1209         copy_backward(pos, finish_n, old_finish);
    1210         copy(first, last, pos);
    1211       }
    1212       else {
    1213         const value_type* mid = first + elems_after;
    1214         __uninitialized_copy_copy(mid, last, pos, finish, finish);
    1215         finish = new_finish;
    1216         copy(first, mid, pos);
    1217       }
    1218     }
    1219     __STL_UNWIND(destroy_nodes_at_back(new_finish));
    1220   }
    1221 }
    1222 
    1223 template <class T, class Alloc, size_t BufSize>
    1224 void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
    1225                                           const_iterator first,
    1226                                           const_iterator last,
    1227                                           size_type n)
    1228 {
    1229   const difference_type elems_before = pos - start;
    1230   size_type length = size();
    1231   if (elems_before < length / 2) {
    1232     iterator new_start = reserve_elements_at_front(n);
    1233     iterator old_start = start;
    1234     pos = start + elems_before;
    1235     __STL_TRY {
    1236       if (elems_before >= n) {
    1237         iterator start_n = start + n;
    1238         uninitialized_copy(start, start_n, new_start);
    1239         start = new_start;
    1240         copy(start_n, pos, old_start);
    1241         copy(first, last, pos - difference_type(n));
    1242       }
    1243       else {
    1244         const_iterator mid = first + (n - elems_before);
    1245         __uninitialized_copy_copy(start, pos, first, mid, new_start);
    1246         start = new_start;
    1247         copy(mid, last, old_start);
    1248       }
    1249     }
    1250     __STL_UNWIND(destroy_nodes_at_front(new_start));
    1251   }
    1252   else {
    1253     iterator new_finish = reserve_elements_at_back(n);
    1254     iterator old_finish = finish;
    1255     const difference_type elems_after = length - elems_before;
    1256     pos = finish - elems_after;
    1257     __STL_TRY {
    1258       if (elems_after > n) {
    1259         iterator finish_n = finish - difference_type(n);
    1260         uninitialized_copy(finish_n, finish, finish);
    1261         finish = new_finish;
    1262         copy_backward(pos, finish_n, old_finish);
    1263         copy(first, last, pos);
    1264       }
    1265       else {
    1266         const_iterator mid = first + elems_after;
    1267         __uninitialized_copy_copy(mid, last, pos, finish, finish);
    1268         finish = new_finish;
    1269         copy(first, mid, pos);
    1270       }
    1271     }
    1272     __STL_UNWIND(destroy_nodes_at_back(new_finish));
    1273   }
    1274 }
    1275 
    1276 #endif /* __STL_MEMBER_TEMPLATES */
    1277 
    1278 template <class T, class Alloc, size_t BufSize>
    1279 void deque<T, Alloc, BufSize>::new_elements_at_front(size_type new_elements) {
    1280   size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
    1281   reserve_map_at_front(new_nodes);
    1282   size_type i;
    1283   __STL_TRY {
    1284     for (i = 1; i <= new_nodes; ++i)
    1285       *(start.node - i) = allocate_node();
    1286   }
    1287 #       ifdef __STL_USE_EXCEPTIONS
    1288   catch(...) {
    1289     for (size_type j = 1; j < i; ++j)
    1290       deallocate_node(*(start.node - j));      
    1291     throw;
    1292   }
    1293 #       endif /* __STL_USE_EXCEPTIONS */
    1294 }
    1295 
    1296 template <class T, class Alloc, size_t BufSize>
    1297 void deque<T, Alloc, BufSize>::new_elements_at_back(size_type new_elements) {
    1298   size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
    1299   reserve_map_at_back(new_nodes);
    1300   size_type i;
    1301   __STL_TRY {
    1302     for (i = 1; i <= new_nodes; ++i)
    1303       *(finish.node + i) = allocate_node();
    1304   }
    1305 #       ifdef __STL_USE_EXCEPTIONS
    1306   catch(...) {
    1307     for (size_type j = 1; j < i; ++j)
    1308       deallocate_node(*(finish.node + j));      
    1309     throw;
    1310   }
    1311 #       endif /* __STL_USE_EXCEPTIONS */
    1312 }
    1313 
    1314 template <class T, class Alloc, size_t BufSize>
    1315 void deque<T, Alloc, BufSize>::destroy_nodes_at_front(iterator before_start) {
    1316   for (map_pointer n = before_start.node; n < start.node; ++n)
    1317     deallocate_node(*n);
    1318 }
    1319 
    1320 template <class T, class Alloc, size_t BufSize>
    1321 void deque<T, Alloc, BufSize>::destroy_nodes_at_back(iterator after_finish) {
    1322   for (map_pointer n = after_finish.node; n > finish.node; --n)
    1323     deallocate_node(*n);
    1324 }
    1325 
    1326 template <class T, class Alloc, size_t BufSize>
    1327 void deque<T, Alloc, BufSize>::reallocate_map(size_type nodes_to_add,
    1328                                               bool add_at_front) {
    1329   size_type old_num_nodes = finish.node - start.node + 1;
    1330   size_type new_num_nodes = old_num_nodes + nodes_to_add;
    1331 
    1332   map_pointer new_nstart;
    1333   if (map_size > 2 * new_num_nodes) {
    1334     new_nstart = map + (map_size - new_num_nodes) / 2 
    1335                      + (add_at_front ? nodes_to_add : 0);
    1336     if (new_nstart < start.node)
    1337       copy(start.node, finish.node + 1, new_nstart);
    1338     else
    1339       copy_backward(start.node, finish.node + 1, new_nstart + old_num_nodes);
    1340   }
    1341   else {
    1342     size_type new_map_size = map_size + max(map_size, nodes_to_add) + 2;
    1343     // 配置一塊空間,準備給新map使用。
    1344     map_pointer new_map = map_allocator::allocate(new_map_size);
    1345     new_nstart = new_map + (new_map_size - new_num_nodes) / 2
    1346                          + (add_at_front ? nodes_to_add : 0);
    1347     // 把原map 內容拷貝過來。
    1348     copy(start.node, finish.node + 1, new_nstart);
    1349     // 釋放原map
    1350     map_allocator::deallocate(map, map_size);
    1351     // 設定新map的起始位址與大小
    1352     map = new_map;
    1353     map_size = new_map_size;
    1354   }
    1355 
    1356   // 重新設定迭代器 start 和 finish
    1357   start.set_node(new_nstart);
    1358   finish.set_node(new_nstart + old_num_nodes - 1);
    1359 }
    1360 
    1361 
    1362 // Nonmember functions.
    1363 
    1364 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
    1365 
    1366 template <class T, class Alloc, size_t BufSiz>
    1367 bool operator==(const deque<T, Alloc, BufSiz>& x,
    1368                 const deque<T, Alloc, BufSiz>& y) {
    1369   return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
    1370 }
    1371 
    1372 template <class T, class Alloc, size_t BufSiz>
    1373 bool operator<(const deque<T, Alloc, BufSiz>& x,
    1374                const deque<T, Alloc, BufSiz>& y) {
    1375   return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
    1376 }
    1377 
    1378 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
    1379 
    1380 #if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && 
    1381     !defined(__STL_NON_TYPE_TMPL_PARAM_BUG)
    1382 
    1383 template <class T, class Alloc, size_t BufSiz>
    1384 inline void swap(deque<T, Alloc, BufSiz>& x, deque<T, Alloc, BufSiz>& y) {
    1385   x.swap(y);
    1386 }
    1387 
    1388 #endif
    1389 
    1390 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
    1391 #pragma reset woff 1174
    1392 #endif
    1393           
    1394 __STL_END_NAMESPACE 
    1395   
    1396 #endif /* __SGI_STL_INTERNAL_DEQUE_H */
    1397 
    1398 // Local Variables:
    1399 // mode:C++
    1400 // End:
  • 相关阅读:
    如何通过CSS3实现背景图片色彩的梯度渐变
    提升网站页面打开速度的12个建议
    DIV+CSS高手必知的15个CSS常识
    飞机订票-1注册用户脚本
    需求不明的测试
    职业发展-外包公司考虑项
    Linux-Apache+Mysql+PHP+PHPWind(重点Apache+PHP集成环境)
    LR11-更改licence
    Linux-服务排查
    C语言-删除重复字符
  • 原文地址:https://www.cnblogs.com/xxiaoye/p/3964309.html
Copyright © 2011-2022 走看看