home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / stlport / stl / _deque.c < prev    next >
C/C++ Source or Header  |  2002-02-02  |  24KB  |  677 lines

  1. /*
  2.  *
  3.  *
  4.  * Copyright (c) 1994
  5.  * Hewlett-Packard Company
  6.  *
  7.  * Copyright (c) 1996,1997
  8.  * Silicon Graphics Computer Systems, Inc.
  9.  *
  10.  * Copyright (c) 1997
  11.  * Moscow Center for SPARC Technology
  12.  *
  13.  * Copyright (c) 1999 
  14.  * Boris Fomitchev
  15.  *
  16.  * This material is provided "as is", with absolutely no warranty expressed
  17.  * or implied. Any use is at your own risk.
  18.  *
  19.  * Permission to use or copy this software for any purpose is hereby granted 
  20.  * without fee, provided the above notices are retained on all copies.
  21.  * Permission to modify the code and to distribute modified code is granted,
  22.  * provided the above notices are retained, and a notice that the code was
  23.  * modified is included with the above copyright notice.
  24.  *
  25.  */
  26. #ifndef _STLP_DEQUE_C
  27. # define _STLP_DEQUE_C
  28.  
  29. # ifndef _STLP_INTERNAL_DEQUE_H
  30. #  include <stl/_deque.h>
  31. # endif
  32.  
  33. _STLP_BEGIN_NAMESPACE
  34.  
  35. // Non-inline member functions from _Deque_base.
  36.  
  37. template <class _Tp, class _Alloc >
  38. _Deque_base<_Tp,_Alloc >::~_Deque_base() {
  39.   if (_M_map._M_data) {
  40.     _M_destroy_nodes(_M_start._M_node, this->_M_finish._M_node + 1);
  41.     _M_map.deallocate(_M_map._M_data, _M_map_size._M_data);
  42.   }
  43. }
  44.  
  45. template <class _Tp, class _Alloc >
  46. void
  47. _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
  48. {
  49.   size_t __num_nodes = 
  50.     __num_elements / this->buffer_size() + 1 ;
  51.  
  52.   _M_map_size._M_data = (max)((size_t) _S_initial_map_size, __num_nodes + 2);
  53.   _M_map._M_data = _M_map.allocate(_M_map_size._M_data);
  54.  
  55.   _Tp** __nstart = _M_map._M_data + (_M_map_size._M_data - __num_nodes) / 2;
  56.   _Tp** __nfinish = __nstart + __num_nodes;
  57.     
  58.   _STLP_TRY {
  59.     _M_create_nodes(__nstart, __nfinish);
  60.   }
  61.   _STLP_UNWIND((_M_map.deallocate(_M_map._M_data, _M_map_size._M_data), 
  62.                 _M_map._M_data = 0, _M_map_size._M_data = 0));
  63.   _M_start._M_set_node(__nstart);
  64.   this->_M_finish._M_set_node(__nfinish - 1);
  65.   _M_start._M_cur = _M_start._M_first;
  66.   this->_M_finish._M_cur = this->_M_finish._M_first +
  67.                __num_elements % this->buffer_size();
  68. }
  69.  
  70. template <class _Tp, class _Alloc >
  71. void
  72. _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart,
  73.                                                   _Tp** __nfinish)
  74. {
  75.   _Tp** __cur;
  76.   _STLP_TRY {
  77.     for (__cur = __nstart; __cur < __nfinish; ++__cur)
  78.       *__cur = _M_map_size.allocate(this->buffer_size());
  79.   }
  80.   _STLP_UNWIND(_M_destroy_nodes(__nstart, __cur));
  81. }
  82.  
  83. template <class _Tp, class _Alloc >
  84. void 
  85. _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart,
  86.                                                    _Tp** __nfinish)
  87. {
  88.   for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
  89.     _M_map_size.deallocate(*__n, this->buffer_size());
  90. }
  91.  
  92.  
  93.  
  94. // Non-inline member functions
  95.  
  96. # if defined ( _STLP_NESTED_TYPE_PARAM_BUG )
  97. // qualified references 
  98. #   define __iterator__           _Deque_iterator<_Tp, _Nonconst_traits<_Tp> >
  99. #   define const_iterator         _Deque_iterator<_Tp, _Const_traits<_Tp>  > 
  100. #   define iterator               __iterator__
  101. #   define size_type              size_t
  102. #   define value_type             _Tp
  103. # else
  104. #  define __iterator__           _STLP_TYPENAME_ON_RETURN_TYPE __deque__<_Tp, _Alloc>::iterator
  105. # endif
  106.  
  107. template <class _Tp, class _Alloc >
  108. __deque__<_Tp, _Alloc >&  
  109. __deque__<_Tp, _Alloc >::operator= (const __deque__<_Tp, _Alloc >& __x) {
  110.   const size_type __len = size();
  111.   if (&__x != this) {
  112.     if (__len >= __x.size())
  113.       erase(copy(__x.begin(), __x.end(), this->_M_start), this->_M_finish);
  114.     else {
  115.       const_iterator __mid = __x.begin() + difference_type(__len);
  116.       copy(__x.begin(), __mid, this->_M_start);
  117.       insert(this->_M_finish, __mid, __x.end());
  118.     }
  119.   }
  120.   return *this;
  121. }        
  122.  
  123. template <class _Tp, class _Alloc >
  124. void 
  125. __deque__<_Tp, _Alloc >::_M_fill_insert(iterator __pos,
  126.                          size_type __n, const value_type& __x)
  127. {
  128.   if (__pos._M_cur == this->_M_start._M_cur) {
  129.     iterator __new_start = _M_reserve_elements_at_front(__n);
  130.     _STLP_TRY {
  131.       uninitialized_fill(__new_start, this->_M_start, __x);
  132.     }
  133.     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node));
  134.     this->_M_start = __new_start;
  135.   }
  136.   else if (__pos._M_cur == this->_M_finish._M_cur) {
  137.     iterator __new_finish = _M_reserve_elements_at_back(__n);
  138.     _STLP_TRY {
  139.       uninitialized_fill(this->_M_finish, __new_finish, __x);
  140.     }
  141.     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node+1, __new_finish._M_node+1));
  142.     this->_M_finish = __new_finish;
  143.   }
  144.   else 
  145.     _M_insert_aux(__pos, __n, __x);
  146. }
  147.  
  148. #ifndef _STLP_MEMBER_TEMPLATES  
  149.  
  150. template <class _Tp, class _Alloc >
  151. void __deque__<_Tp, _Alloc>::insert(iterator __pos,
  152.                                            const value_type* __first,
  153.                                            const value_type* __last) {
  154.   size_type __n = __last - __first;
  155.   if (__pos._M_cur == this->_M_start._M_cur) {
  156.     iterator __new_start = _M_reserve_elements_at_front(__n);
  157.     _STLP_TRY {
  158.       uninitialized_copy(__first, __last, __new_start);
  159.     }
  160.     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node));
  161.     this->_M_start = __new_start;
  162.   }
  163.   else if (__pos._M_cur == this->_M_finish._M_cur) {
  164.     iterator __new_finish = _M_reserve_elements_at_back(__n);
  165.     _STLP_TRY {
  166.       uninitialized_copy(__first, __last, this->_M_finish);
  167.     }
  168.     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, 
  169.                                   __new_finish._M_node + 1));
  170.     this->_M_finish = __new_finish;
  171.   }
  172.   else
  173.     _M_insert_aux(__pos, __first, __last, __n);
  174. }
  175.  
  176. template <class _Tp, class _Alloc >
  177. void __deque__<_Tp,_Alloc>::insert(iterator __pos,
  178.                                          const_iterator __first,
  179.                                          const_iterator __last)
  180. {
  181.   size_type __n = __last - __first;
  182.   if (__pos._M_cur == this->_M_start._M_cur) {
  183.     iterator __new_start = _M_reserve_elements_at_front(__n);
  184.     _STLP_TRY {
  185.       uninitialized_copy(__first, __last, __new_start);
  186.     }
  187.     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node));
  188.     this->_M_start = __new_start;
  189.   }
  190.   else if (__pos._M_cur == this->_M_finish._M_cur) {
  191.     iterator __new_finish = _M_reserve_elements_at_back(__n);
  192.     _STLP_TRY {
  193.       uninitialized_copy(__first, __last, this->_M_finish);
  194.     }
  195.     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1,__new_finish._M_node + 1));
  196.     this->_M_finish = __new_finish;
  197.   }
  198.   else
  199.     _M_insert_aux(__pos, __first, __last, __n);
  200. }
  201.  
  202. #endif /* _STLP_MEMBER_TEMPLATES */
  203.  
  204. template <class _Tp, class _Alloc >
  205. __iterator__ 
  206. __deque__<_Tp,_Alloc>::erase(iterator __first, iterator __last)
  207. {
  208.   if (__first == this->_M_start && __last == this->_M_finish) {
  209.     clear();
  210.     return this->_M_finish;
  211.   }
  212.   else {
  213.     difference_type __n = __last - __first;
  214.     difference_type __elems_before = __first - this->_M_start;
  215.     if (__elems_before < difference_type(this->size() - __n) / 2) {
  216.       copy_backward(this->_M_start, __first, __last);
  217.       iterator __new_start = this->_M_start + __n;
  218.       _Destroy(this->_M_start, __new_start);
  219.       this->_M_destroy_nodes(this->_M_start._M_node, __new_start._M_node);
  220.       this->_M_start = __new_start;
  221.     }
  222.     else {
  223.       copy(__last, this->_M_finish, __first);
  224.       iterator __new_finish = this->_M_finish - __n;
  225.       _Destroy(__new_finish, this->_M_finish);
  226.       this->_M_destroy_nodes(__new_finish._M_node + 1, this->_M_finish._M_node + 1);
  227.       this->_M_finish = __new_finish;
  228.     }
  229.     return this->_M_start + __elems_before;
  230.   }
  231. }
  232.  
  233. template <class _Tp, class _Alloc >
  234. void __deque__<_Tp,_Alloc>::clear()
  235. {
  236.   for (_Map_pointer __node = this->_M_start._M_node + 1;
  237.        __node < this->_M_finish._M_node;
  238.        ++__node) {
  239.     _Destroy(*__node, *__node + this->buffer_size());
  240.     this->_M_map_size.deallocate(*__node, this->buffer_size());
  241.   }
  242.  
  243.   if (this->_M_start._M_node != this->_M_finish._M_node) {
  244.     _Destroy(this->_M_start._M_cur, this->_M_start._M_last);
  245.     _Destroy(this->_M_finish._M_first, this->_M_finish._M_cur);
  246.     this->_M_map_size.deallocate(this->_M_finish._M_first, this->buffer_size());
  247.   }
  248.   else
  249.     _Destroy(this->_M_start._M_cur, this->_M_finish._M_cur);
  250.  
  251.   this->_M_finish = this->_M_start;
  252. }
  253.  
  254. // Precondition: this->_M_start and this->_M_finish have already been initialized,
  255. // but none of the deque's elements have yet been constructed.
  256. template <class _Tp, class _Alloc >
  257. void 
  258. __deque__<_Tp,_Alloc>::_M_fill_initialize(const value_type& __val) {
  259.   _Map_pointer __cur;
  260.   _STLP_TRY {
  261.     for (__cur = this->_M_start._M_node; __cur < this->_M_finish._M_node; ++__cur)
  262.       uninitialized_fill(*__cur, *__cur + this->buffer_size(), __val);
  263.     uninitialized_fill(this->_M_finish._M_first, this->_M_finish._M_cur, __val);
  264.   }
  265.   _STLP_UNWIND(_Destroy(this->_M_start, iterator(*__cur, __cur)));
  266. }
  267.  
  268.  
  269. // Called only if this->_M_finish._M_cur == this->_M_finish._M_last - 1.
  270. template <class _Tp, class _Alloc >
  271. void
  272. __deque__<_Tp,_Alloc>::_M_push_back_aux_v(const value_type& __t)
  273. {
  274.   value_type __t_copy = __t;
  275.   _M_reserve_map_at_back();
  276.   *(this->_M_finish._M_node + 1) = this->_M_map_size.allocate(this->buffer_size());
  277.   _STLP_TRY {
  278.     _Construct(this->_M_finish._M_cur, __t_copy);
  279.     this->_M_finish._M_set_node(this->_M_finish._M_node + 1);
  280.     this->_M_finish._M_cur = this->_M_finish._M_first;
  281.   }
  282.   _STLP_UNWIND(this->_M_map_size.deallocate(*(this->_M_finish._M_node + 1), 
  283.                       this->buffer_size()));
  284. }
  285.  
  286. # ifndef _STLP_NO_ANACHRONISMS
  287. // Called only if this->_M_finish._M_cur == this->_M_finish._M_last - 1.
  288. template <class _Tp, class _Alloc >
  289. void
  290. __deque__<_Tp,_Alloc>::_M_push_back_aux()
  291. {
  292.   _M_reserve_map_at_back();
  293.   *(this->_M_finish._M_node + 1) = this->_M_map_size.allocate(this->buffer_size());
  294.   _STLP_TRY {
  295.     _Construct(this->_M_finish._M_cur);
  296.     this->_M_finish._M_set_node(this->_M_finish._M_node + 1);
  297.     this->_M_finish._M_cur = this->_M_finish._M_first;
  298.   }
  299.   _STLP_UNWIND(this->_M_map_size.deallocate(*(this->_M_finish._M_node + 1), 
  300.                       this->buffer_size()));
  301. }
  302. # endif
  303.  
  304. // Called only if this->_M_start._M_cur == this->_M_start._M_first.
  305. template <class _Tp, class _Alloc >
  306. void 
  307. __deque__<_Tp,_Alloc>::_M_push_front_aux_v(const value_type& __t)
  308. {
  309.   value_type __t_copy = __t;
  310.   _M_reserve_map_at_front();
  311.   *(this->_M_start._M_node - 1) = this->_M_map_size.allocate(this->buffer_size());
  312.   _STLP_TRY {
  313.     this->_M_start._M_set_node(this->_M_start._M_node - 1);
  314.     this->_M_start._M_cur = this->_M_start._M_last - 1;
  315.     _Construct(this->_M_start._M_cur, __t_copy);
  316.   }
  317.   _STLP_UNWIND((++this->_M_start, 
  318.         this->_M_map_size.deallocate(*(this->_M_start._M_node - 1), this->buffer_size())));
  319.  
  320.  
  321. # ifndef _STLP_NO_ANACHRONISMS
  322. // Called only if this->_M_start._M_cur == this->_M_start._M_first.
  323. template <class _Tp, class _Alloc >
  324. void 
  325. __deque__<_Tp,_Alloc>::_M_push_front_aux()
  326. {
  327.   _M_reserve_map_at_front();
  328.   *(this->_M_start._M_node - 1) = this->_M_map_size.allocate(this->buffer_size());
  329.   _STLP_TRY {
  330.     this->_M_start._M_set_node(this->_M_start._M_node - 1);
  331.     this->_M_start._M_cur = this->_M_start._M_last - 1;
  332.     _Construct(this->_M_start._M_cur);
  333.   }
  334.   _STLP_UNWIND((++this->_M_start, this->_M_map_size.deallocate(*(this->_M_start._M_node - 1), 
  335.                            this->buffer_size() )));
  336. # endif
  337.  
  338. // Called only if this->_M_finish._M_cur == this->_M_finish._M_first.
  339. template <class _Tp, class _Alloc >
  340. void 
  341. __deque__<_Tp,_Alloc>::_M_pop_back_aux()
  342. {
  343.   this->_M_map_size.deallocate(this->_M_finish._M_first, this->buffer_size());
  344.   this->_M_finish._M_set_node(this->_M_finish._M_node - 1);
  345.   this->_M_finish._M_cur = this->_M_finish._M_last - 1;
  346.   _Destroy(this->_M_finish._M_cur);
  347. }
  348.  
  349. // Called only if this->_M_start._M_cur == this->_M_start._M_last - 1.  Note that 
  350. // if the deque has at least one element (a precondition for this member 
  351. // function), and if this->_M_start._M_cur == this->_M_start._M_last, then the deque 
  352. // must have at least two nodes.
  353. template <class _Tp, class _Alloc >
  354. void 
  355. __deque__<_Tp,_Alloc>::_M_pop_front_aux()
  356. {
  357.   _Destroy(this->_M_start._M_cur);
  358.   this->_M_map_size.deallocate(this->_M_start._M_first, this->buffer_size());
  359.   this->_M_start._M_set_node(this->_M_start._M_node + 1);
  360.   this->_M_start._M_cur = this->_M_start._M_first;
  361. }      
  362.  
  363.  
  364.  
  365. template <class _Tp, class _Alloc >
  366. __iterator__
  367. __deque__<_Tp,_Alloc>::_M_insert_aux_prepare(iterator __pos) {
  368.   difference_type __index = __pos - this->_M_start;
  369.   if (__index < difference_type(size() / 2)) {
  370.     push_front(front());
  371.     iterator __front1 = this->_M_start;
  372.     ++__front1;
  373.     iterator __front2 = __front1;
  374.     ++__front2;
  375.     __pos = this->_M_start + __index;
  376.     iterator __pos1 = __pos;
  377.     ++__pos1;
  378.     copy(__front2, __pos1, __front1);
  379.   }
  380.   else {
  381.     push_back(back());
  382.     iterator __back1 = this->_M_finish;
  383.     --__back1;
  384.     iterator __back2 = __back1;
  385.     --__back2;
  386.     __pos = this->_M_start + __index;
  387.     copy_backward(__pos, __back2, __back1);
  388.   }
  389.   return __pos;
  390. }
  391.  
  392. template <class _Tp, class _Alloc >
  393. __iterator__
  394. __deque__<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
  395.                      const value_type& __x) {
  396.   value_type __x_copy = __x;
  397.   _STLP_MPWFIX_TRY        //*TY 06/01/2000 - mpw forget to call dtor on __x_copy without this try block
  398.   __pos = _M_insert_aux_prepare(__pos);
  399.   *__pos = __x_copy;
  400.   return __pos;
  401.   _STLP_MPWFIX_CATCH        //*TY 06/01/2000 - 
  402. }
  403.  
  404. template <class _Tp, class _Alloc >
  405. __iterator__
  406. __deque__<_Tp,_Alloc>::_M_insert_aux(iterator __pos)
  407. {
  408.   __pos = _M_insert_aux_prepare(__pos);
  409.   *__pos = value_type();
  410.   return __pos;
  411. }
  412.  
  413. template <class _Tp, class _Alloc >
  414. void
  415. __deque__<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
  416.                                            size_type __n,
  417.                                            const value_type& __x)
  418. {
  419.   const difference_type __elems_before = __pos - this->_M_start;
  420.   size_type __length = this->size();
  421.   value_type __x_copy = __x;
  422.   if (__elems_before < difference_type(__length / 2)) {
  423.     iterator __new_start = _M_reserve_elements_at_front(__n);
  424.     iterator __old_start = this->_M_start;
  425.     __pos = this->_M_start + __elems_before;
  426.     _STLP_TRY {
  427.       if (__elems_before >= difference_type(__n)) {
  428.         iterator __start_n = this->_M_start + difference_type(__n);
  429.         uninitialized_copy(this->_M_start, __start_n, __new_start);
  430.         this->_M_start = __new_start;
  431.         copy(__start_n, __pos, __old_start);
  432.         fill(__pos - difference_type(__n), __pos, __x_copy);
  433.       }
  434.       else {
  435.         __uninitialized_copy_fill(this->_M_start, __pos, __new_start, 
  436.                               this->_M_start, __x_copy);
  437.         this->_M_start = __new_start;
  438.         fill(__old_start, __pos, __x_copy);
  439.       }
  440.     }
  441.     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node));
  442.   }
  443.   else {
  444.     iterator __new_finish = _M_reserve_elements_at_back(__n);
  445.     iterator __old_finish = this->_M_finish;
  446.     const difference_type __elems_after = 
  447.       difference_type(__length) - __elems_before;
  448.     __pos = this->_M_finish - __elems_after;
  449.     _STLP_TRY {
  450.       if (__elems_after > difference_type(__n)) {
  451.         iterator __finish_n = this->_M_finish - difference_type(__n);
  452.         uninitialized_copy(__finish_n, this->_M_finish, this->_M_finish);
  453.         this->_M_finish = __new_finish;
  454.         copy_backward(__pos, __finish_n, __old_finish);
  455.         fill(__pos, __pos + difference_type(__n), __x_copy);
  456.       }
  457.       else {
  458.         __uninitialized_fill_copy(this->_M_finish, __pos + difference_type(__n),
  459.                                   __x_copy, __pos, this->_M_finish);
  460.         this->_M_finish = __new_finish;
  461.         fill(__pos, __old_finish, __x_copy);
  462.       }
  463.     }
  464.     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1));
  465.   }
  466. }
  467.  
  468. #ifndef _STLP_MEMBER_TEMPLATES 
  469. template <class _Tp, class _Alloc >
  470. void 
  471. __deque__<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
  472.                                            const value_type* __first,
  473.                                            const value_type* __last,
  474.                                            size_type __n)
  475. {
  476.  
  477.   const difference_type __elemsbefore = __pos - this->_M_start;
  478.   size_type __length = size();
  479.   if (__elemsbefore < difference_type(__length / 2)) {
  480.     iterator __new_start = _M_reserve_elements_at_front(__n);
  481.     iterator __old_start = this->_M_start;
  482.     __pos = this->_M_start + __elemsbefore;
  483.     _STLP_TRY {
  484.       if (__elemsbefore >= difference_type(__n)) {
  485.         iterator __start_n = this->_M_start + difference_type(__n);
  486.         uninitialized_copy(this->_M_start, __start_n, __new_start);
  487.         this->_M_start = __new_start;
  488.         copy(__start_n, __pos, __old_start);
  489.         copy(__first, __last, __pos - difference_type(__n));
  490.       }
  491.       else {
  492.         const value_type* __mid = 
  493.       __first + (difference_type(__n) - __elemsbefore);
  494.         __uninitialized_copy_copy(this->_M_start, __pos, __first, __mid,
  495.                                   __new_start, _IsPODType());
  496.         this->_M_start = __new_start;
  497.         copy(__mid, __last, __old_start);
  498.       }
  499.     }
  500.     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node));
  501.   }
  502.   else {
  503.     iterator __new_finish = _M_reserve_elements_at_back(__n);
  504.     iterator __old_finish = this->_M_finish;
  505.     const difference_type __elemsafter = 
  506.       difference_type(__length) - __elemsbefore;
  507.     __pos = this->_M_finish - __elemsafter;
  508.     _STLP_TRY {
  509.       if (__elemsafter > difference_type(__n)) {
  510.         iterator __finish_n = this->_M_finish - difference_type(__n);
  511.         uninitialized_copy(__finish_n, this->_M_finish, this->_M_finish);
  512.         this->_M_finish = __new_finish;
  513.         copy_backward(__pos, __finish_n, __old_finish);
  514.         copy(__first, __last, __pos);
  515.       }
  516.       else {
  517.         const value_type* __mid = __first + __elemsafter;
  518.         __uninitialized_copy_copy(__mid, __last, __pos, this->_M_finish, this->_M_finish, _IsPODType());
  519.         this->_M_finish = __new_finish;
  520.         copy(__first, __mid, __pos);
  521.       }
  522.     }
  523.     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1));
  524.   }
  525. }
  526.  
  527. template <class _Tp, class _Alloc >
  528. void
  529. __deque__<_Tp,_Alloc>::_M_insert_aux(iterator __pos,
  530.                                            const_iterator __first,
  531.                                            const_iterator __last,
  532.                                            size_type __n)
  533. {
  534.   const difference_type __elemsbefore = __pos - this->_M_start;
  535.   size_type __length = size();
  536.   if (__elemsbefore < difference_type(__length / 2)) {
  537.     iterator __new_start = _M_reserve_elements_at_front(__n);
  538.     iterator __old_start = this->_M_start;
  539.     __pos = this->_M_start + __elemsbefore;
  540.     _STLP_TRY {
  541.       if (__elemsbefore >= difference_type(__n)) {
  542.         iterator __start_n = this->_M_start + __n;
  543.         uninitialized_copy(this->_M_start, __start_n, __new_start);
  544.         this->_M_start = __new_start;
  545.         copy(__start_n, __pos, __old_start);
  546.         copy(__first, __last, __pos - difference_type(__n));
  547.       }
  548.       else {
  549.         const_iterator __mid = __first + (__n - __elemsbefore);
  550.         __uninitialized_copy_copy(this->_M_start, __pos, __first, __mid,
  551.                                   __new_start, _IsPODType());
  552.         this->_M_start = __new_start;
  553.         copy(__mid, __last, __old_start);
  554.       }
  555.     }
  556.     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node));
  557.   }
  558.   else {
  559.     iterator __new_finish = _M_reserve_elements_at_back(__n);
  560.     iterator __old_finish = this->_M_finish;
  561.     const difference_type __elemsafter = __length - __elemsbefore;
  562.     __pos = this->_M_finish - __elemsafter;
  563.     _STLP_TRY {
  564.       if (__elemsafter > difference_type(__n)) {
  565.         iterator __finish_n = this->_M_finish - difference_type(__n);
  566.         uninitialized_copy(__finish_n, this->_M_finish, this->_M_finish);
  567.         this->_M_finish = __new_finish;
  568.         copy_backward(__pos, __finish_n, __old_finish);
  569.         copy(__first, __last, __pos);
  570.       }
  571.       else {
  572.         const_iterator __mid = __first + __elemsafter;
  573.         __uninitialized_copy_copy(__mid, __last, __pos, this->_M_finish, this->_M_finish, _IsPODType());
  574.         this->_M_finish = __new_finish;
  575.         copy(__first, __mid, __pos);
  576.       }
  577.     }
  578.     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1));
  579.   }
  580. }
  581.  
  582. #endif /* _STLP_MEMBER_TEMPLATES */
  583.  
  584. template <class _Tp, class _Alloc >
  585. void 
  586. __deque__<_Tp,_Alloc>::_M_new_elements_at_front(size_type __new_elems)
  587. {
  588.   size_type __new_nodes
  589.       = (__new_elems + this->buffer_size() - 1) / this->buffer_size();
  590.   _M_reserve_map_at_front(__new_nodes);
  591.   size_type __i =1;
  592.   _STLP_TRY {
  593.     for (; __i <= __new_nodes; ++__i)
  594.       *(this->_M_start._M_node - __i) = this->_M_map_size.allocate(this->buffer_size());
  595.   }
  596. #       ifdef _STLP_USE_EXCEPTIONS
  597.   catch(...) {
  598.     for (size_type __j = 1; __j < __i; ++__j)
  599.       this->_M_map_size.deallocate(*(this->_M_start._M_node - __j), this->buffer_size());
  600.     throw;
  601.   }
  602. #       endif /* _STLP_USE_EXCEPTIONS */
  603. }
  604.  
  605. template <class _Tp, class _Alloc >
  606. void 
  607. __deque__<_Tp,_Alloc>::_M_new_elements_at_back(size_type __new_elems)
  608. {
  609.   size_type __new_nodes
  610.       = (__new_elems + this->buffer_size() - 1) / this->buffer_size();
  611.   _M_reserve_map_at_back(__new_nodes);
  612.   size_type __i = 1;
  613.   _STLP_TRY {
  614.     for (; __i <= __new_nodes; ++__i)
  615.       *(this->_M_finish._M_node + __i) = this->_M_map_size.allocate(this->buffer_size());
  616.   }
  617. #       ifdef _STLP_USE_EXCEPTIONS
  618.   catch(...) {
  619.     for (size_type __j = 1; __j < __i; ++__j)
  620.       this->_M_map_size.deallocate(*(this->_M_finish._M_node + __j), this->buffer_size());
  621.     throw;
  622.   }
  623. #       endif /* _STLP_USE_EXCEPTIONS */
  624. }
  625.  
  626. template <class _Tp, class _Alloc >
  627. void 
  628. __deque__<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add,
  629.                                               bool __add_at_front)
  630. {
  631.   size_type __old_num_nodes = this->_M_finish._M_node - this->_M_start._M_node + 1;
  632.   size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
  633.  
  634.   _Map_pointer __new_nstart;
  635.   if (this->_M_map_size._M_data > 2 * __new_num_nodes) {
  636.     __new_nstart = this->_M_map._M_data + (this->_M_map_size._M_data - __new_num_nodes) / 2 
  637.                      + (__add_at_front ? __nodes_to_add : 0);
  638.     if (__new_nstart < this->_M_start._M_node)
  639.       copy(this->_M_start._M_node, this->_M_finish._M_node + 1, __new_nstart);
  640.     else
  641.       copy_backward(this->_M_start._M_node, this->_M_finish._M_node + 1, 
  642.                     __new_nstart + __old_num_nodes);
  643.   }
  644.   else {
  645.     size_type __new_map_size = 
  646.       this->_M_map_size._M_data + (max)((size_t)this->_M_map_size._M_data, __nodes_to_add) + 2;
  647.  
  648.     _Map_pointer __new_map = this->_M_map.allocate(__new_map_size);
  649.     __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
  650.                          + (__add_at_front ? __nodes_to_add : 0);
  651.     copy(this->_M_start._M_node, this->_M_finish._M_node + 1, __new_nstart);
  652.     this->_M_map.deallocate(this->_M_map._M_data, this->_M_map_size._M_data);
  653.  
  654.     this->_M_map._M_data = __new_map;
  655.     this->_M_map_size._M_data = __new_map_size;
  656.   }
  657.  
  658.   this->_M_start._M_set_node(__new_nstart);
  659.   this->_M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
  660. }
  661.  
  662. _STLP_END_NAMESPACE
  663.  
  664. # undef __iterator__
  665. # undef iterator
  666. # undef const_iterator
  667. # undef size_type
  668. # undef value_type
  669.  
  670. #endif /*  _STLP_DEQUE_C */
  671.  
  672. // Local Variables:
  673. // mode:C++
  674. // End:
  675.