/home/ntakagi/work/STLport-5.1.5/stlport/stl/_deque.c

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Copyright (c) 1994
00005  * Hewlett-Packard Company
00006  *
00007  * Copyright (c) 1996,1997
00008  * Silicon Graphics Computer Systems, Inc.
00009  *
00010  * Copyright (c) 1997
00011  * Moscow Center for SPARC Technology
00012  *
00013  * Copyright (c) 1999
00014  * Boris Fomitchev
00015  *
00016  * This material is provided "as is", with absolutely no warranty expressed
00017  * or implied. Any use is at your own risk.
00018  *
00019  * Permission to use or copy this software for any purpose is hereby granted
00020  * without fee, provided the above notices are retained on all copies.
00021  * Permission to modify the code and to distribute modified code is granted,
00022  * provided the above notices are retained, and a notice that the code was
00023  * modified is included with the above copyright notice.
00024  *
00025  */
00026 #ifndef _STLP_DEQUE_C
00027 #define _STLP_DEQUE_C
00028 
00029 #ifndef _STLP_INTERNAL_DEQUE_H
00030 #  include <stl/_deque.h>
00031 #endif
00032 
00033 _STLP_BEGIN_NAMESPACE
00034 
00035 _STLP_MOVE_TO_PRIV_NAMESPACE
00036 
00037 // Non-inline member functions from _Deque_base.
00038 
00039 template <class _Tp, class _Alloc >
00040 _Deque_base<_Tp,_Alloc >::~_Deque_base() {
00041   if (_M_map._M_data) {
00042     _M_destroy_nodes(_M_start._M_node, this->_M_finish._M_node + 1);
00043     _M_map.deallocate(_M_map._M_data, _M_map_size._M_data);
00044   }
00045 }
00046 
00047 template <class _Tp, class _Alloc >
00048 void _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements) {
00049   size_t __num_nodes = __num_elements / this->buffer_size() + 1 ;
00050 
00051   _M_map_size._M_data = (max)((size_t) _S_initial_map_size, __num_nodes + 2);
00052   _M_map._M_data = _M_map.allocate(_M_map_size._M_data);
00053 
00054   _Tp** __nstart = _M_map._M_data + (_M_map_size._M_data - __num_nodes) / 2;
00055   _Tp** __nfinish = __nstart + __num_nodes;
00056 
00057   _STLP_TRY {
00058     _M_create_nodes(__nstart, __nfinish);
00059   }
00060   _STLP_UNWIND((_M_map.deallocate(_M_map._M_data, _M_map_size._M_data),
00061                 _M_map._M_data = 0, _M_map_size._M_data = 0))
00062   _M_start._M_set_node(__nstart);
00063   this->_M_finish._M_set_node(__nfinish - 1);
00064   _M_start._M_cur = _M_start._M_first;
00065   this->_M_finish._M_cur = this->_M_finish._M_first + __num_elements % this->buffer_size();
00066 }
00067 
00068 template <class _Tp, class _Alloc >
00069 void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart,
00070                                               _Tp** __nfinish) {
00071   _Tp** __cur = __nstart;
00072   _STLP_TRY {
00073     for (; __cur < __nfinish; ++__cur)
00074       *__cur = _M_map_size.allocate(this->buffer_size());
00075   }
00076   _STLP_UNWIND(_M_destroy_nodes(__nstart, __cur))
00077 }
00078 
00079 template <class _Tp, class _Alloc >
00080 void _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart,
00081                                                _Tp** __nfinish) {
00082   for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
00083     _M_map_size.deallocate(*__n, this->buffer_size());
00084 }
00085 
00086 #if defined (_STLP_USE_PTR_SPECIALIZATIONS)
00087 #  define deque _STLP_PTR_IMPL_NAME(deque)
00088 #elif defined (_STLP_DEBUG)
00089 #  define deque _STLP_NON_DBG_NAME(deque)
00090 #else
00091 _STLP_MOVE_TO_STD_NAMESPACE
00092 #endif
00093 
00094 #if defined (_STLP_NESTED_TYPE_PARAM_BUG)
00095 // qualified references
00096 #  define __iterator__   _Deque_iterator<_Tp, _Nonconst_traits<_Tp> >
00097 #  define const_iterator _Deque_iterator<_Tp, _Const_traits<_Tp>  >
00098 #  define iterator       __iterator__
00099 #  define size_type      size_t
00100 #  define value_type     _Tp
00101 #else
00102 #  define __iterator__   _STLP_TYPENAME_ON_RETURN_TYPE deque<_Tp, _Alloc>::iterator
00103 #endif
00104 
00105 template <class _Tp, class _Alloc >
00106 deque<_Tp, _Alloc >&
00107 deque<_Tp, _Alloc >::operator= (const deque<_Tp, _Alloc >& __x) {
00108   const size_type __len = size();
00109   if (&__x != this) {
00110     if (__len >= __x.size())
00111       erase(copy(__x.begin(), __x.end(), this->_M_start), this->_M_finish);
00112     else {
00113       const_iterator __mid = __x.begin() + difference_type(__len);
00114       copy(__x.begin(), __mid, this->_M_start);
00115       insert(this->_M_finish, __mid, __x.end());
00116     }
00117   }
00118   return *this;
00119 }
00120 
00121 template <class _Tp, class _Alloc >
00122 void deque<_Tp, _Alloc >::_M_fill_insert(iterator __pos,
00123                                          size_type __n, const value_type& __x) {
00124   if (__pos._M_cur == this->_M_start._M_cur) {
00125     iterator __new_start = _M_reserve_elements_at_front(__n);
00126     _STLP_TRY {
00127       uninitialized_fill(__new_start, this->_M_start, __x);
00128     }
00129     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
00130     this->_M_start = __new_start;
00131   }
00132   else if (__pos._M_cur == this->_M_finish._M_cur) {
00133     iterator __new_finish = _M_reserve_elements_at_back(__n);
00134     _STLP_TRY {
00135       uninitialized_fill(this->_M_finish, __new_finish, __x);
00136     }
00137     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node+1, __new_finish._M_node+1))
00138     this->_M_finish = __new_finish;
00139   }
00140   else
00141     _M_fill_insert_aux(__pos, __n, __x, _Movable());
00142 }
00143 
00144 #if !defined (_STLP_MEMBER_TEMPLATES)
00145 
00146 template <class _Tp, class _Alloc >
00147 void deque<_Tp, _Alloc>::insert(iterator __pos,
00148                                 const value_type* __first, const value_type* __last) {
00149   size_type __n = __last - __first;
00150   if (__pos._M_cur == this->_M_start._M_cur) {
00151     iterator __new_start = _M_reserve_elements_at_front(__n);
00152     _STLP_TRY {
00153       _STLP_PRIV __ucopy(__first, __last, __new_start);
00154     }
00155     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
00156     this->_M_start = __new_start;
00157   }
00158   else if (__pos._M_cur == this->_M_finish._M_cur) {
00159     iterator __new_finish = _M_reserve_elements_at_back(__n);
00160     _STLP_TRY {
00161       _STLP_PRIV __ucopy(__first, __last, this->_M_finish);
00162     }
00163     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1,
00164                                         __new_finish._M_node + 1))
00165     this->_M_finish = __new_finish;
00166   }
00167   else
00168     _M_insert_range_aux(__pos, __first, __last, __n, _Movable());
00169 }
00170 
00171 template <class _Tp, class _Alloc >
00172 void deque<_Tp,_Alloc>::insert(iterator __pos,
00173                                const_iterator __first, const_iterator __last) {
00174   size_type __n = __last - __first;
00175   if (__pos._M_cur == this->_M_start._M_cur) {
00176     iterator __new_start = _M_reserve_elements_at_front(__n);
00177     _STLP_TRY {
00178       _STLP_PRIV __ucopy(__first, __last, __new_start);
00179     }
00180     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
00181     this->_M_start = __new_start;
00182   }
00183   else if (__pos._M_cur == this->_M_finish._M_cur) {
00184     iterator __new_finish = _M_reserve_elements_at_back(__n);
00185     _STLP_TRY {
00186       _STLP_PRIV __ucopy(__first, __last, this->_M_finish);
00187     }
00188     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1,
00189                                         __new_finish._M_node + 1))
00190     this->_M_finish = __new_finish;
00191   }
00192   else
00193     _M_insert_range_aux(__pos, __first, __last, __n, _Movable());
00194 }
00195 
00196 #endif /* _STLP_MEMBER_TEMPLATES */
00197 
00198 template <class _Tp, class _Alloc >
00199 __iterator__ deque<_Tp,_Alloc>::_M_erase(iterator __pos,
00200                                          const __true_type& /*_Movable*/) {
00201   difference_type __index = __pos - this->_M_start;
00202   if (size_type(__index) < this->size() >> 1) {
00203     //We move the start of the deque one position to the right
00204     //starting from the rightmost element to move.
00205     iterator __src = __pos, __dst = __pos;
00206     _STLP_STD::_Destroy(&(*__dst));
00207     if (__src != this->_M_start) {
00208       for (--__src; __dst != this->_M_start; --__src, --__dst) {
00209         _STLP_STD::_Move_Construct(&(*__dst), *__src);
00210         _STLP_STD::_Destroy_Moved(&(*__src));
00211       }
00212     }
00213     _M_pop_front_aux();
00214   }
00215   else {
00216     iterator __src = __pos, __dst = __pos;
00217     _STLP_STD::_Destroy(&(*__dst));
00218     for (++__src; __src != this->_M_finish; ++__src, ++__dst) {
00219       _STLP_STD::_Move_Construct(&(*__dst), *__src);
00220       _STLP_STD::_Destroy_Moved(&(*__src));
00221     }
00222     //Duplication of the pop_back code without the destroy which has already been done:
00223     if (this->_M_finish._M_cur != this->_M_finish._M_first) {
00224       --this->_M_finish._M_cur;
00225     }
00226     else {
00227       _M_pop_back_aux();
00228     }
00229   }
00230   return this->_M_start + __index;
00231 }
00232 
00233 template <class _Tp, class _Alloc >
00234 __iterator__ deque<_Tp,_Alloc>::_M_erase(iterator __pos,
00235                                          const __false_type& /*_Movable*/) {
00236   iterator __next = __pos;
00237   ++__next;
00238   difference_type __index = __pos - this->_M_start;
00239   if (size_type(__index) < this->size() >> 1) {
00240     copy_backward(this->_M_start, __pos, __next);
00241     pop_front();
00242   }
00243   else {
00244     copy(__next, this->_M_finish, __pos);
00245     pop_back();
00246   }
00247   return this->_M_start + __index;
00248 }
00249 
00250 template <class _Tp, class _Alloc >
00251 __iterator__ deque<_Tp,_Alloc>::_M_erase(iterator __first, iterator __last,
00252                                          const __true_type& /*_Movable*/) {
00253   difference_type __n = __last - __first;
00254   difference_type __elems_before = __first - this->_M_start;
00255   if (__elems_before <= difference_type(this->size() - __n) / 2) {
00256     iterator __src = __first, __dst = __last;
00257     if (__src != this->_M_start) {
00258       for (--__src, --__dst; (__src >= this->_M_start) && (__dst >= __first); --__src, --__dst) {
00259         _STLP_STD::_Destroy(&(*__dst));
00260         _STLP_STD::_Move_Construct(&(*__dst), *__src);
00261       }
00262       if (__dst >= __first) {
00263         //There are more elements to erase than elements to move
00264         _STLP_STD::_Destroy_Range(__first, ++__dst);
00265         _STLP_STD::_Destroy_Moved_Range(this->_M_start, __first);
00266       }
00267       else {
00268         //There are more elements to move than elements to erase
00269         for (; __src >= this->_M_start; --__src, --__dst) {
00270           _STLP_STD::_Destroy_Moved(&(*__dst));
00271           _STLP_STD::_Move_Construct(&(*__dst), *__src);
00272         }
00273         _STLP_STD::_Destroy_Moved_Range(this->_M_start, ++__dst);
00274       }
00275     }
00276     else {
00277       _STLP_STD::_Destroy_Range(this->_M_start, __last);
00278     }
00279     iterator __new_start = this->_M_start + __n;
00280     this->_M_destroy_nodes(this->_M_start._M_node, __new_start._M_node);
00281     this->_M_start = __new_start;
00282   }
00283   else {
00284     if (__last != this->_M_finish) {
00285       iterator __src = __last, __dst = __first;
00286       for (; (__src != this->_M_finish) && (__dst != __last); ++__src, ++__dst) {
00287         _STLP_STD::_Destroy(&(*__dst));
00288         _STLP_STD::_Move_Construct(&(*__dst), *__src);
00289       }
00290       if (__dst != __last) {
00291         //There are more elements to erase than elements to move
00292         _STLP_STD::_Destroy_Range(__dst, __last);
00293         _STLP_STD::_Destroy_Moved_Range(__last, this->_M_finish);
00294       }
00295       else {
00296         //There are more elements to move than elements to erase
00297         for (; __src != this->_M_finish; ++__src, ++__dst) {
00298           _STLP_STD::_Destroy_Moved(&(*__dst));
00299           _STLP_STD::_Move_Construct(&(*__dst), *__src);
00300         }
00301         _STLP_STD::_Destroy_Moved_Range(__dst, this->_M_finish);
00302       }
00303     }
00304     else {
00305       _STLP_STD::_Destroy_Range(__first, this->_M_finish);
00306     }
00307     iterator __new_finish = this->_M_finish - __n;
00308     this->_M_destroy_nodes(__new_finish._M_node + 1, this->_M_finish._M_node + 1);
00309     this->_M_finish = __new_finish;
00310   }
00311   return this->_M_start + __elems_before;
00312 }
00313 
00314 template <class _Tp, class _Alloc >
00315 __iterator__ deque<_Tp,_Alloc>::_M_erase(iterator __first, iterator __last,
00316                                          const __false_type& /*_Movable*/) {
00317   difference_type __n = __last - __first;
00318   difference_type __elems_before = __first - this->_M_start;
00319   if (__elems_before <= difference_type(this->size() - __n) / 2) {
00320     copy_backward(this->_M_start, __first, __last);
00321     iterator __new_start = this->_M_start + __n;
00322     _STLP_STD::_Destroy_Range(this->_M_start, __new_start);
00323     this->_M_destroy_nodes(this->_M_start._M_node, __new_start._M_node);
00324     this->_M_start = __new_start;
00325   }
00326   else {
00327     copy(__last, this->_M_finish, __first);
00328     iterator __new_finish = this->_M_finish - __n;
00329     _STLP_STD::_Destroy_Range(__new_finish, this->_M_finish);
00330     this->_M_destroy_nodes(__new_finish._M_node + 1, this->_M_finish._M_node + 1);
00331     this->_M_finish = __new_finish;
00332   }
00333   return this->_M_start + __elems_before;
00334 }
00335 
00336 template <class _Tp, class _Alloc >
00337 void deque<_Tp,_Alloc>::clear() {
00338   for (_Map_pointer __node = this->_M_start._M_node + 1;
00339        __node < this->_M_finish._M_node;
00340        ++__node) {
00341     _STLP_STD::_Destroy_Range(*__node, *__node + this->buffer_size());
00342     this->_M_map_size.deallocate(*__node, this->buffer_size());
00343   }
00344 
00345   if (this->_M_start._M_node != this->_M_finish._M_node) {
00346     _STLP_STD::_Destroy_Range(this->_M_start._M_cur, this->_M_start._M_last);
00347     _STLP_STD::_Destroy_Range(this->_M_finish._M_first, this->_M_finish._M_cur);
00348     this->_M_map_size.deallocate(this->_M_finish._M_first, this->buffer_size());
00349   }
00350   else
00351     _STLP_STD::_Destroy_Range(this->_M_start._M_cur, this->_M_finish._M_cur);
00352 
00353   this->_M_finish = this->_M_start;
00354 }
00355 
00356 // Precondition: this->_M_start and this->_M_finish have already been initialized,
00357 // but none of the deque's elements have yet been constructed.
00358 template <class _Tp, class _Alloc >
00359 void deque<_Tp,_Alloc>::_M_fill_initialize(const value_type& __val,
00360                                            const __false_type& /*_TrivialInit*/) {
00361   _Map_pointer __cur = this->_M_start._M_node;
00362   _STLP_TRY {
00363     for (; __cur < this->_M_finish._M_node; ++__cur)
00364       uninitialized_fill(*__cur, *__cur + this->buffer_size(), __val);
00365     uninitialized_fill(this->_M_finish._M_first, this->_M_finish._M_cur, __val);
00366   }
00367   _STLP_UNWIND(_STLP_STD::_Destroy_Range(this->_M_start, iterator(*__cur, __cur)))
00368 }
00369 
00370 
00371 // Called only if this->_M_finish._M_cur == this->_M_finish._M_last - 1.
00372 template <class _Tp, class _Alloc >
00373 void deque<_Tp,_Alloc>::_M_push_back_aux_v(const value_type& __t) {
00374   _M_reserve_map_at_back();
00375   *(this->_M_finish._M_node + 1) = this->_M_map_size.allocate(this->buffer_size());
00376   _STLP_TRY {
00377     _Copy_Construct(this->_M_finish._M_cur, __t);
00378     this->_M_finish._M_set_node(this->_M_finish._M_node + 1);
00379     this->_M_finish._M_cur = this->_M_finish._M_first;
00380   }
00381   _STLP_UNWIND(this->_M_map_size.deallocate(*(this->_M_finish._M_node + 1),
00382                                             this->buffer_size()))
00383 }
00384 
00385 #if defined(_STLP_DONT_SUP_DFLT_PARAM) && !defined(_STLP_NO_ANACHRONISMS)
00386 // Called only if this->_M_finish._M_cur == this->_M_finish._M_last - 1.
00387 template <class _Tp, class _Alloc >
00388 void deque<_Tp,_Alloc>::_M_push_back_aux() {
00389   _M_reserve_map_at_back();
00390   *(this->_M_finish._M_node + 1) = this->_M_map_size.allocate(this->buffer_size());
00391   _STLP_TRY {
00392     _STLP_STD::_Construct(this->_M_finish._M_cur);
00393     this->_M_finish._M_set_node(this->_M_finish._M_node + 1);
00394     this->_M_finish._M_cur = this->_M_finish._M_first;
00395   }
00396   _STLP_UNWIND(this->_M_map_size.deallocate(*(this->_M_finish._M_node + 1),
00397                                             this->buffer_size()))
00398 }
00399 #endif /*_STLP_DONT_SUP_DFLT_PARAM && !_STLP_NO_ANACHRONISMS*/
00400 
00401 // Called only if this->_M_start._M_cur == this->_M_start._M_first.
00402 template <class _Tp, class _Alloc >
00403 void deque<_Tp,_Alloc>::_M_push_front_aux_v(const value_type& __t) {
00404   _M_reserve_map_at_front();
00405   *(this->_M_start._M_node - 1) = this->_M_map_size.allocate(this->buffer_size());
00406   _STLP_TRY {
00407     this->_M_start._M_set_node(this->_M_start._M_node - 1);
00408     this->_M_start._M_cur = this->_M_start._M_last - 1;
00409     _Copy_Construct(this->_M_start._M_cur, __t);
00410   }
00411   _STLP_UNWIND((++this->_M_start,
00412                 this->_M_map_size.deallocate(*(this->_M_start._M_node - 1), this->buffer_size())))
00413 }
00414 
00415 
00416 #if defined (_STLP_DONT_SUP_DFLT_PARAM) && !defined (_STLP_NO_ANACHRONISMS)
00417 // Called only if this->_M_start._M_cur == this->_M_start._M_first.
00418 template <class _Tp, class _Alloc >
00419 void deque<_Tp,_Alloc>::_M_push_front_aux() {
00420   _M_reserve_map_at_front();
00421   *(this->_M_start._M_node - 1) = this->_M_map_size.allocate(this->buffer_size());
00422   _STLP_TRY {
00423     this->_M_start._M_set_node(this->_M_start._M_node - 1);
00424     this->_M_start._M_cur = this->_M_start._M_last - 1;
00425     _STLP_STD::_Construct(this->_M_start._M_cur);
00426   }
00427   _STLP_UNWIND((++this->_M_start, this->_M_map_size.deallocate(*(this->_M_start._M_node - 1),
00428                                                                this->buffer_size())))
00429 }
00430 #endif /*_STLP_DONT_SUP_DFLT_PARAM && !_STLP_NO_ANACHRONISMS*/
00431 
00432 // Called only if this->_M_finish._M_cur == this->_M_finish._M_first.
00433 template <class _Tp, class _Alloc >
00434 void deque<_Tp,_Alloc>::_M_pop_back_aux() {
00435   this->_M_map_size.deallocate(this->_M_finish._M_first, this->buffer_size());
00436   this->_M_finish._M_set_node(this->_M_finish._M_node - 1);
00437   this->_M_finish._M_cur = this->_M_finish._M_last - 1;
00438 }
00439 
00440 // Note that if the deque has at least one element (a precondition for this member
00441 // function), and if this->_M_start._M_cur == this->_M_start._M_last, then the deque
00442 // must have at least two nodes.
00443 template <class _Tp, class _Alloc >
00444 void deque<_Tp,_Alloc>::_M_pop_front_aux() {
00445   if (this->_M_start._M_cur != this->_M_start._M_last - 1)
00446     ++this->_M_start._M_cur;
00447   else {
00448     this->_M_map_size.deallocate(this->_M_start._M_first, this->buffer_size());
00449     this->_M_start._M_set_node(this->_M_start._M_node + 1);
00450     this->_M_start._M_cur = this->_M_start._M_first;
00451   }
00452 }
00453 
00454 template <class _Tp, class _Alloc >
00455 __iterator__ deque<_Tp,_Alloc>::_M_fill_insert_aux(iterator __pos, size_type __n,
00456                                                    const value_type& __x,
00457                                                    const __true_type& /*_Movable*/) {
00458   const difference_type __elems_before = __pos - this->_M_start;
00459   size_type __length = this->size();
00460   value_type __x_copy = __x;
00461   if (__elems_before <= difference_type(__length / 2)) {
00462     iterator __new_start = _M_reserve_elements_at_front(__n);
00463     __pos = this->_M_start + __elems_before;
00464     _STLP_TRY {
00465       iterator __dst = __new_start;
00466       iterator __src = this->_M_start;
00467       for (; __src != __pos; ++__dst, ++__src) {
00468         _STLP_STD::_Move_Construct(&(*__dst), *__src);
00469         _STLP_STD::_Destroy_Moved(&(*__src));
00470       }
00471       this->_M_start = __new_start;
00472       uninitialized_fill(__dst, __src, __x_copy);
00473       __pos = __dst;
00474     }
00475     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
00476   }
00477   else {
00478     iterator __new_finish = _M_reserve_elements_at_back(__n);
00479     const difference_type __elems_after = difference_type(__length) - __elems_before;
00480     __pos = this->_M_finish - __elems_after;
00481     _STLP_TRY {
00482       iterator __dst = __new_finish;
00483       iterator __src = this->_M_finish;
00484       for (--__src, --__dst; __src >= __pos; --__src, --__dst) {
00485         _STLP_STD::_Move_Construct(&(*__dst), *__src);
00486         _STLP_STD::_Destroy_Moved(&(*__src));
00487       }
00488       this->_M_finish = __new_finish;
00489       uninitialized_fill(__pos, __pos + __n, __x_copy);
00490     }
00491     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1))
00492   }
00493   return __pos;
00494 }
00495 
00496 template <class _Tp, class _Alloc >
00497 __iterator__ deque<_Tp,_Alloc>::_M_fill_insert_aux(iterator __pos, size_type __n,
00498                                                    const value_type& __x,
00499                                                    const __false_type& /*_Movable*/) {
00500   const difference_type __elems_before = __pos - this->_M_start;
00501   size_type __length = this->size();
00502   value_type __x_copy = __x;
00503   if (__elems_before <= difference_type(__length / 2)) {
00504     iterator __new_start = _M_reserve_elements_at_front(__n);
00505     iterator __old_start = this->_M_start;
00506     __pos = this->_M_start + __elems_before;
00507     _STLP_TRY {
00508       if (__elems_before >= difference_type(__n)) {
00509         iterator __start_n = this->_M_start + difference_type(__n);
00510         _STLP_PRIV __ucopy(this->_M_start, __start_n, __new_start);
00511         this->_M_start = __new_start;
00512         copy(__start_n, __pos, __old_start);
00513         fill(__pos - difference_type(__n), __pos, __x_copy);
00514         __pos -= difference_type(__n);
00515       }
00516       else {
00517         _STLP_PRIV __uninitialized_copy_fill(this->_M_start, __pos, __new_start,
00518                                              this->_M_start, __x_copy);
00519         this->_M_start = __new_start;
00520         fill(__old_start, __pos, __x_copy);
00521       }
00522     }
00523     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
00524   }
00525   else {
00526     iterator __new_finish = _M_reserve_elements_at_back(__n);
00527     iterator __old_finish = this->_M_finish;
00528     const difference_type __elems_after =
00529       difference_type(__length) - __elems_before;
00530     __pos = this->_M_finish - __elems_after;
00531     _STLP_TRY {
00532       if (__elems_after > difference_type(__n)) {
00533         iterator __finish_n = this->_M_finish - difference_type(__n);
00534         _STLP_PRIV __ucopy(__finish_n, this->_M_finish, this->_M_finish);
00535         this->_M_finish = __new_finish;
00536         copy_backward(__pos, __finish_n, __old_finish);
00537         fill(__pos, __pos + difference_type(__n), __x_copy);
00538       }
00539       else {
00540         _STLP_PRIV __uninitialized_fill_copy(this->_M_finish, __pos + difference_type(__n),
00541                                              __x_copy, __pos, this->_M_finish);
00542         this->_M_finish = __new_finish;
00543         fill(__pos, __old_finish, __x_copy);
00544       }
00545     }
00546     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1))
00547   }
00548   return __pos;
00549 }
00550 
00551 #if !defined (_STLP_MEMBER_TEMPLATES)
00552 template <class _Tp, class _Alloc >
00553 void deque<_Tp,_Alloc>::_M_insert_range_aux(iterator __pos,
00554                                             const value_type* __first, const value_type* __last,
00555                                             size_type __n, const __true_type& /*_Movable*/) {
00556   const difference_type __elems_before = __pos - this->_M_start;
00557   size_type __length = size();
00558   if (__elems_before <= difference_type(__length / 2)) {
00559     iterator __new_start = _M_reserve_elements_at_front(__n);
00560     __pos = this->_M_start + __elems_before;
00561     _STLP_TRY {
00562       iterator __dst = __new_start;
00563       iterator __src = this->_M_start;
00564       for (; __src != __pos; ++__dst, ++__src) {
00565         _STLP_STD::_Move_Construct(&(*__dst), *__src);
00566         _STLP_STD::_Destroy_Moved(&(*__src));
00567       }
00568       this->_M_start = __new_start;
00569       _STLP_PRIV __ucopy(__first, __last, __dst);
00570     }
00571     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
00572   }
00573   else {
00574     iterator __new_finish = _M_reserve_elements_at_back(__n);
00575     const difference_type __elems_after = difference_type(__length) - __elems_before;
00576     __pos = this->_M_finish - __elems_after;
00577     _STLP_TRY {
00578       iterator __dst = __new_finish;
00579       iterator __src = this->_M_finish;
00580       for (--__src, --__dst; __src >= __pos; --__src, --__dst) {
00581         _STLP_STD::_Move_Construct(&(*__dst), *__src);
00582         _STLP_STD::_Destroy_Moved(&(*__src));
00583       }
00584       this->_M_finish = __new_finish;
00585       _STLP_PRIV __ucopy(__first, __last, __pos);
00586     }
00587     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1))
00588   }
00589 }
00590 
00591 template <class _Tp, class _Alloc >
00592 void deque<_Tp,_Alloc>::_M_insert_range_aux(iterator __pos,
00593                                             const value_type* __first, const value_type* __last,
00594                                             size_type __n, const __false_type& /*_Movable*/) {
00595   const difference_type __elems_before = __pos - this->_M_start;
00596   size_type __length = size();
00597   if (__elems_before <= difference_type(__length / 2)) {
00598     iterator __new_start = _M_reserve_elements_at_front(__n);
00599     iterator __old_start = this->_M_start;
00600     __pos = this->_M_start + __elems_before;
00601     _STLP_TRY {
00602       if (__elems_before >= difference_type(__n)) {
00603         iterator __start_n = this->_M_start + difference_type(__n);
00604         _STLP_PRIV __ucopy(this->_M_start, __start_n, __new_start);
00605         this->_M_start = __new_start;
00606         copy(__start_n, __pos, __old_start);
00607         copy(__first, __last, __pos - difference_type(__n));
00608       }
00609       else {
00610         const value_type* __mid = __first + (difference_type(__n) - __elems_before);
00611         __uninitialized_copy_copy(this->_M_start, __pos, __first, __mid, __new_start);
00612         this->_M_start = __new_start;
00613         copy(__mid, __last, __old_start);
00614       }
00615     }
00616     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
00617   }
00618   else {
00619     iterator __new_finish = _M_reserve_elements_at_back(__n);
00620     iterator __old_finish = this->_M_finish;
00621     const difference_type __elems_after =
00622       difference_type(__length) - __elems_before;
00623     __pos = this->_M_finish - __elems_after;
00624     _STLP_TRY {
00625 
00626       if (__elems_after > difference_type(__n)) {
00627         iterator __finish_n = this->_M_finish - difference_type(__n);
00628         _STLP_PRIV __ucopy(__finish_n, this->_M_finish, this->_M_finish);
00629         this->_M_finish = __new_finish;
00630         copy_backward(__pos, __finish_n, __old_finish);
00631         copy(__first, __last, __pos);
00632       }
00633       else {
00634         const value_type* __mid = __first + __elems_after;
00635         __uninitialized_copy_copy(__mid, __last, __pos, this->_M_finish, this->_M_finish);
00636         this->_M_finish = __new_finish;
00637         copy(__first, __mid, __pos);
00638       }
00639     }
00640     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1))
00641   }
00642 }
00643 
00644 template <class _Tp, class _Alloc >
00645 void deque<_Tp,_Alloc>::_M_insert_range_aux(iterator __pos,
00646                                             const_iterator __first, const_iterator __last,
00647                                             size_type __n, const __true_type& /*_Movable*/) {
00648   const difference_type __elems_before = __pos - this->_M_start;
00649   size_type __length = size();
00650   if (__elems_before <= difference_type(__length / 2)) {
00651     iterator __new_start = _M_reserve_elements_at_front(__n);
00652     __pos = this->_M_start + __elems_before;
00653     _STLP_TRY {
00654       iterator __dst = __new_start;
00655       iterator __src = this->_M_start;
00656       for (; __src != __pos; ++__dst, ++__src) {
00657         _STLP_STD::_Move_Construct(&(*__dst), *__src);
00658         _STLP_STD::_Destroy_Moved(&(*__src));
00659       }
00660       this->_M_start = __new_start;
00661       _STLP_PRIV __ucopy(__first, __last, __dst);
00662     }
00663     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
00664   }
00665   else {
00666     iterator __new_finish = _M_reserve_elements_at_back(__n);
00667     const difference_type __elems_after = difference_type(__length) - __elems_before;
00668     __pos = this->_M_finish - __elems_after;
00669     _STLP_TRY {
00670       iterator __dst = __new_finish;
00671       iterator __src = this->_M_finish;
00672       for (--__src, --__dst; __src >= __pos; --__src, --__dst) {
00673         _STLP_STD::_Move_Construct(&(*__dst), *__src);
00674         _STLP_STD::_Destroy_Moved(&(*__src));
00675       }
00676       this->_M_finish = __new_finish;
00677       _STLP_PRIV __ucopy(__first, __last, __pos);
00678     }
00679     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1))
00680   }
00681 }
00682 
00683 template <class _Tp, class _Alloc >
00684 void deque<_Tp,_Alloc>::_M_insert_range_aux(iterator __pos,
00685                                             const_iterator __first, const_iterator __last,
00686                                             size_type __n, const __false_type& /*_Movable*/) {
00687   const difference_type __elems_before = __pos - this->_M_start;
00688   size_type __length = size();
00689   if (__elems_before < difference_type(__length / 2)) {
00690     iterator __new_start = _M_reserve_elements_at_front(__n);
00691     iterator __old_start = this->_M_start;
00692     __pos = this->_M_start + __elems_before;
00693     _STLP_TRY {
00694       if (__elems_before >= difference_type(__n)) {
00695         iterator __start_n = this->_M_start + __n;
00696         _STLP_PRIV __ucopy(this->_M_start, __start_n, __new_start);
00697         this->_M_start = __new_start;
00698         copy(__start_n, __pos, __old_start);
00699         copy(__first, __last, __pos - difference_type(__n));
00700       }
00701       else {
00702         const_iterator __mid = __first + (__n - __elems_before);
00703         __uninitialized_copy_copy(this->_M_start, __pos, __first, __mid, __new_start);
00704         this->_M_start = __new_start;
00705         copy(__mid, __last, __old_start);
00706       }
00707     }
00708     _STLP_UNWIND(this->_M_destroy_nodes(__new_start._M_node, this->_M_start._M_node))
00709   }
00710   else {
00711     iterator __new_finish = _M_reserve_elements_at_back(__n);
00712     iterator __old_finish = this->_M_finish;
00713     const difference_type __elems_after = __length - __elems_before;
00714     __pos = this->_M_finish - __elems_after;
00715     _STLP_TRY {
00716       if (__elems_after > difference_type(__n)) {
00717         iterator __finish_n = this->_M_finish - difference_type(__n);
00718         _STLP_PRIV __ucopy(__finish_n, this->_M_finish, this->_M_finish);
00719         this->_M_finish = __new_finish;
00720         copy_backward(__pos, __finish_n, __old_finish);
00721         copy(__first, __last, __pos);
00722       }
00723       else {
00724         const_iterator __mid = __first + __elems_after;
00725         __uninitialized_copy_copy(__mid, __last, __pos, this->_M_finish, this->_M_finish);
00726         this->_M_finish = __new_finish;
00727         copy(__first, __mid, __pos);
00728       }
00729     }
00730     _STLP_UNWIND(this->_M_destroy_nodes(this->_M_finish._M_node + 1, __new_finish._M_node + 1))
00731   }
00732 }
00733 #endif /* _STLP_MEMBER_TEMPLATES */
00734 
00735 template <class _Tp, class _Alloc >
00736 void deque<_Tp,_Alloc>::_M_new_elements_at_front(size_type __new_elems) {
00737   size_type __new_nodes
00738       = (__new_elems + this->buffer_size() - 1) / this->buffer_size();
00739   _M_reserve_map_at_front(__new_nodes);
00740   size_type __i = 1;
00741   _STLP_TRY {
00742     for (; __i <= __new_nodes; ++__i)
00743       *(this->_M_start._M_node - __i) = this->_M_map_size.allocate(this->buffer_size());
00744   }
00745   _STLP_UNWIND(for (size_type __j = 1; __j < __i; ++__j)
00746                  this->_M_map_size.deallocate(*(this->_M_start._M_node - __j), this->buffer_size()))
00747 }
00748 
00749 template <class _Tp, class _Alloc >
00750 void deque<_Tp,_Alloc>::_M_new_elements_at_back(size_type __new_elems) {
00751   size_type __new_nodes
00752       = (__new_elems + this->buffer_size() - 1) / this->buffer_size();
00753   _M_reserve_map_at_back(__new_nodes);
00754   size_type __i = 1;
00755   _STLP_TRY {
00756     for (; __i <= __new_nodes; ++__i)
00757       *(this->_M_finish._M_node + __i) = this->_M_map_size.allocate(this->buffer_size());
00758   }
00759   _STLP_UNWIND(for (size_type __j = 1; __j < __i; ++__j)
00760                  this->_M_map_size.deallocate(*(this->_M_finish._M_node + __j), this->buffer_size()))
00761 }
00762 
00763 template <class _Tp, class _Alloc >
00764 void deque<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add,
00765                                           bool __add_at_front) {
00766   size_type __old_num_nodes = this->_M_finish._M_node - this->_M_start._M_node + 1;
00767   size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
00768 
00769   _Map_pointer __new_nstart;
00770   if (this->_M_map_size._M_data > 2 * __new_num_nodes) {
00771     __new_nstart = this->_M_map._M_data + (this->_M_map_size._M_data - __new_num_nodes) / 2
00772                      + (__add_at_front ? __nodes_to_add : 0);
00773     if (__new_nstart < this->_M_start._M_node)
00774       copy(this->_M_start._M_node, this->_M_finish._M_node + 1, __new_nstart);
00775     else
00776       copy_backward(this->_M_start._M_node, this->_M_finish._M_node + 1,
00777                     __new_nstart + __old_num_nodes);
00778   }
00779   else {
00780     size_type __new_map_size =
00781       this->_M_map_size._M_data + (max)((size_t)this->_M_map_size._M_data, __nodes_to_add) + 2;
00782 
00783     _Map_pointer __new_map = this->_M_map.allocate(__new_map_size);
00784     __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
00785                          + (__add_at_front ? __nodes_to_add : 0);
00786     copy(this->_M_start._M_node, this->_M_finish._M_node + 1, __new_nstart);
00787     this->_M_map.deallocate(this->_M_map._M_data, this->_M_map_size._M_data);
00788 
00789     this->_M_map._M_data = __new_map;
00790     this->_M_map_size._M_data = __new_map_size;
00791   }
00792 
00793   this->_M_start._M_set_node(__new_nstart);
00794   this->_M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
00795 }
00796 
00797 #if defined (deque)
00798 #  undef deque
00799 _STLP_MOVE_TO_STD_NAMESPACE
00800 #endif
00801 
00802 _STLP_END_NAMESPACE
00803 
00804 #undef __iterator__
00805 #undef iterator
00806 #undef const_iterator
00807 #undef size_type
00808 #undef value_type
00809 
00810 #endif /*  _STLP_DEQUE_C */
00811 
00812 // Local Variables:
00813 // mode:C++
00814 // End:



Generated on Mon Mar 10 15:32:20 2008 by  doxygen 1.5.1