首页 > 代码库 > STL-Deque 源码剖析

STL-Deque 源码剖析

   1 G++ 2.91.57,cygnus\cygwin-b20\include\g++\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   else1025     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>::iterator1032 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_EXCEPTIONS1288   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_EXCEPTIONS1306   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     else1339       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) / 21346                          + (add_at_front ? nodes_to_add : 0);1347     // 把原map 內容拷貝過來。1348     copy(start.node, finish.node + 1, new_nstart);1349     // 釋放原map1350     map_allocator::deallocate(map, map_size);1351     // 設定新map的起始位址與大小1352     map = new_map;1353     map_size = new_map_size;1354   }1355 1356   // 重新設定迭代器 start 和 finish1357   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_BUG1365 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 #endif1389 1390 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)1391 #pragma reset woff 11741392 #endif1393           1394 __STL_END_NAMESPACE 1395   1396 #endif /* __SGI_STL_INTERNAL_DEQUE_H */1397 1398 // Local Variables:1399 // mode:C++1400 // End:

 

STL-Deque 源码剖析