stl_list.h

00001 /*
00002  *
00003  * Copyright (c) 1994
00004  * Hewlett-Packard Company
00005  *
00006  * Permission to use, copy, modify, distribute and sell this software
00007  * and its documentation for any purpose is hereby granted without fee,
00008  * provided that the above copyright notice appear in all copies and
00009  * that both that copyright notice and this permission notice appear
00010  * in supporting documentation.  Hewlett-Packard Company makes no
00011  * representations about the suitability of this software for any
00012  * purpose.  It is provided "as is" without express or implied warranty.
00013  *
00014  *
00015  * Copyright (c) 1996,1997
00016  * Silicon Graphics Computer Systems, Inc.
00017  *
00018  * Permission to use, copy, modify, distribute and sell this software
00019  * and its documentation for any purpose is hereby granted without fee,
00020  * provided that the above copyright notice appear in all copies and
00021  * that both that copyright notice and this permission notice appear
00022  * in supporting documentation.  Silicon Graphics makes no
00023  * representations about the suitability of this software for any
00024  * purpose.  It is provided "as is" without express or implied warranty.
00025  */
00026 
00027 /* NOTE: This is an internal header file, included by other STL headers.
00028  *   You should not attempt to use it directly.
00029  */
00030 
00031 #ifndef __SGI_STL_INTERNAL_LIST_H
00032 #define __SGI_STL_INTERNAL_LIST_H
00033 
00034 #include <concept_checks.h>
00035 
00036 __STL_BEGIN_NAMESPACE
00037 
00038 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
00039 #pragma set woff 1174
00040 #pragma set woff 1375
00041 #endif
00042 
00043 struct _List_node_base {
00044   _List_node_base* _M_next;
00045   _List_node_base* _M_prev;
00046 };
00047 
00048 template <class _Tp>
00049 struct _List_node : public _List_node_base {
00050   _Tp _M_data;
00051 };
00052 
00053 struct _List_iterator_base {
00054   typedef size_t                     size_type;
00055   typedef ptrdiff_t                  difference_type;
00056   typedef bidirectional_iterator_tag iterator_category;
00057 
00058   _List_node_base* _M_node;
00059 
00060   _List_iterator_base(_List_node_base* __x) : _M_node(__x) {}
00061   _List_iterator_base() {}
00062 
00063   void _M_incr() { _M_node = _M_node->_M_next; }
00064   void _M_decr() { _M_node = _M_node->_M_prev; }
00065 
00066   bool operator==(const _List_iterator_base& __x) const {
00067     return _M_node == __x._M_node;
00068   }
00069   bool operator!=(const _List_iterator_base& __x) const {
00070     return _M_node != __x._M_node;
00071   }
00072 };  
00073 
00074 template<class _Tp, class _Ref, class _Ptr>
00075 struct _List_iterator : public _List_iterator_base {
00076   typedef _List_iterator<_Tp,_Tp&,_Tp*>             iterator;
00077   typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
00078   typedef _List_iterator<_Tp,_Ref,_Ptr>             _Self;
00079 
00080   typedef _Tp value_type;
00081   typedef _Ptr pointer;
00082   typedef _Ref reference;
00083   typedef _List_node<_Tp> _Node;
00084 
00085   _List_iterator(_Node* __x) : _List_iterator_base(__x) {}
00086   _List_iterator() {}
00087   _List_iterator(const iterator& __x) : _List_iterator_base(__x._M_node) {}
00088 
00089   reference operator*() const { return ((_Node*) _M_node)->_M_data; }
00090 
00091 #ifndef __SGI_STL_NO_ARROW_OPERATOR
00092   pointer operator->() const { return &(operator*()); }
00093 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
00094 
00095   _Self& operator++() { 
00096     this->_M_incr();
00097     return *this;
00098   }
00099   _Self operator++(int) { 
00100     _Self __tmp = *this;
00101     this->_M_incr();
00102     return __tmp;
00103   }
00104   _Self& operator--() { 
00105     this->_M_decr();
00106     return *this;
00107   }
00108   _Self operator--(int) { 
00109     _Self __tmp = *this;
00110     this->_M_decr();
00111     return __tmp;
00112   }
00113 };
00114 
00115 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
00116 
00117 inline bidirectional_iterator_tag
00118 iterator_category(const _List_iterator_base&)
00119 {
00120   return bidirectional_iterator_tag();
00121 }
00122 
00123 template <class _Tp, class _Ref, class _Ptr>
00124 inline _Tp*
00125 value_type(const _List_iterator<_Tp, _Ref, _Ptr>&)
00126 {
00127   return 0;
00128 }
00129 
00130 inline ptrdiff_t*
00131 distance_type(const _List_iterator_base&)
00132 {
00133   return 0;
00134 }
00135 
00136 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
00137 
00138 
00139 // Base class that encapsulates details of allocators.  Three cases:
00140 // an ordinary standard-conforming allocator, a standard-conforming
00141 // allocator with no non-static data, and an SGI-style allocator.
00142 // This complexity is necessary only because we're worrying about backward
00143 // compatibility and because we want to avoid wasting storage on an 
00144 // allocator instance if it isn't necessary.
00145 
00146 #ifdef __STL_USE_STD_ALLOCATORS
00147 
00148 // Base for general standard-conforming allocators.
00149 template <class _Tp, class _Allocator, bool _IsStatic>
00150 class _List_alloc_base {
00151 public:
00152   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
00153           allocator_type;
00154   allocator_type get_allocator() const { return _Node_allocator; }
00155 
00156   _List_alloc_base(const allocator_type& __a) : _Node_allocator(__a) {}
00157 
00158 protected:
00159   _List_node<_Tp>* _M_get_node()
00160    { return _Node_allocator.allocate(1); }
00161   void _M_put_node(_List_node<_Tp>* __p)
00162     { _Node_allocator.deallocate(__p, 1); }
00163 
00164 protected:
00165   typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type
00166            _Node_allocator;
00167   _List_node<_Tp>* _M_node;
00168 };
00169 
00170 // Specialization for instanceless allocators.
00171 
00172 template <class _Tp, class _Allocator>
00173 class _List_alloc_base<_Tp, _Allocator, true> {
00174 public:
00175   typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
00176           allocator_type;
00177   allocator_type get_allocator() const { return allocator_type(); }
00178 
00179   _List_alloc_base(const allocator_type&) {}
00180 
00181 protected:
00182   typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type
00183           _Alloc_type;
00184   _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); }
00185   void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
00186 
00187 protected:
00188   _List_node<_Tp>* _M_node;
00189 };
00190 
00191 template <class _Tp, class _Alloc>
00192 class _List_base 
00193   : public _List_alloc_base<_Tp, _Alloc,
00194                             _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00195 {
00196 public:
00197   typedef _List_alloc_base<_Tp, _Alloc,
00198                            _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
00199           _Base; 
00200   typedef typename _Base::allocator_type allocator_type;
00201 
00202   _List_base(const allocator_type& __a) : _Base(__a) {
00203     _M_node = _M_get_node();
00204     _M_node->_M_next = _M_node;
00205     _M_node->_M_prev = _M_node;
00206   }
00207   ~_List_base() {
00208     clear();
00209     _M_put_node(_M_node);
00210   }
00211 
00212   void clear();
00213 };
00214 
00215 #else /* __STL_USE_STD_ALLOCATORS */
00216 
00217 template <class _Tp, class _Alloc>
00218 class _List_base 
00219 {
00220 public:
00221   typedef _Alloc allocator_type;
00222   allocator_type get_allocator() const { return allocator_type(); }
00223 
00224   _List_base(const allocator_type&) {
00225     _M_node = _M_get_node();
00226     _M_node->_M_next = _M_node;
00227     _M_node->_M_prev = _M_node;
00228   }
00229   ~_List_base() {
00230     clear();
00231     _M_put_node(_M_node);
00232   }
00233 
00234   void clear();
00235 
00236 protected:
00237   typedef simple_alloc<_List_node<_Tp>, _Alloc> _Alloc_type;
00238   _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); }
00239   void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } 
00240 
00241 protected:
00242   _List_node<_Tp>* _M_node;
00243 };
00244 
00245 #endif /* __STL_USE_STD_ALLOCATORS */
00246 
00247 template <class _Tp, class _Alloc>
00248 void 
00249 _List_base<_Tp,_Alloc>::clear() 
00250 {
00251   _List_node<_Tp>* __cur = (_List_node<_Tp>*) _M_node->_M_next;
00252   while (__cur != _M_node) {
00253     _List_node<_Tp>* __tmp = __cur;
00254     __cur = (_List_node<_Tp>*) __cur->_M_next;
00255     _Destroy(&__tmp->_M_data);
00256     _M_put_node(__tmp);
00257   }
00258   _M_node->_M_next = _M_node;
00259   _M_node->_M_prev = _M_node;
00260 }
00261 
00262 template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
00263 class list : protected _List_base<_Tp, _Alloc> {
00264   // requirements:
00265 
00266   __STL_CLASS_REQUIRES(_Tp, _Assignable);
00267 
00268   typedef _List_base<_Tp, _Alloc> _Base;
00269 protected:
00270   typedef void* _Void_pointer;
00271 
00272 public:      
00273   typedef _Tp value_type;
00274   typedef value_type* pointer;
00275   typedef const value_type* const_pointer;
00276   typedef value_type& reference;
00277   typedef const value_type& const_reference;
00278   typedef _List_node<_Tp> _Node;
00279   typedef size_t size_type;
00280   typedef ptrdiff_t difference_type;
00281 
00282   typedef typename _Base::allocator_type allocator_type;
00283   allocator_type get_allocator() const { return _Base::get_allocator(); }
00284 
00285 public:
00286   typedef _List_iterator<_Tp,_Tp&,_Tp*>             iterator;
00287   typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
00288 
00289 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
00290   typedef reverse_iterator<const_iterator> const_reverse_iterator;
00291   typedef reverse_iterator<iterator>       reverse_iterator;
00292 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
00293   typedef reverse_bidirectional_iterator<const_iterator,value_type,
00294                                          const_reference,difference_type>
00295           const_reverse_iterator;
00296   typedef reverse_bidirectional_iterator<iterator,value_type,reference,
00297                                          difference_type>
00298           reverse_iterator; 
00299 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
00300 
00301 protected:
00302 #ifdef __STL_HAS_NAMESPACES
00303   using _Base::_M_node;
00304   using _Base::_M_put_node;
00305   using _Base::_M_get_node;
00306 #endif /* __STL_HAS_NAMESPACES */
00307 
00308 protected:
00309   _Node* _M_create_node(const _Tp& __x)
00310   {
00311     _Node* __p = _M_get_node();
00312     __STL_TRY {
00313       _Construct(&__p->_M_data, __x);
00314     }
00315     __STL_UNWIND(_M_put_node(__p));
00316     return __p;
00317   }
00318 
00319   _Node* _M_create_node()
00320   {
00321     _Node* __p = _M_get_node();
00322     __STL_TRY {
00323       _Construct(&__p->_M_data);
00324     }
00325     __STL_UNWIND(_M_put_node(__p));
00326     return __p;
00327   }
00328 
00329 public:
00330   explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {}
00331 
00332   iterator begin()             { return (_Node*)(_M_node->_M_next); }
00333   const_iterator begin() const { return (_Node*)(_M_node->_M_next); }
00334 
00335   iterator end()             { return _M_node; }
00336   const_iterator end() const { return _M_node; }
00337 
00338   reverse_iterator rbegin() 
00339     { return reverse_iterator(end()); }
00340   const_reverse_iterator rbegin() const 
00341     { return const_reverse_iterator(end()); }
00342 
00343   reverse_iterator rend()
00344     { return reverse_iterator(begin()); }
00345   const_reverse_iterator rend() const
00346     { return const_reverse_iterator(begin()); }
00347 
00348   bool empty() const { return _M_node->_M_next == _M_node; }
00349   size_type size() const {
00350     size_type __result = 0;
00351     distance(begin(), end(), __result);
00352     return __result;
00353   }
00354   size_type max_size() const { return size_type(-1); }
00355 
00356   reference front() { return *begin(); }
00357   const_reference front() const { return *begin(); }
00358   reference back() { return *(--end()); }
00359   const_reference back() const { return *(--end()); }
00360 
00361   void swap(list<_Tp, _Alloc>& __x) { __STD::swap(_M_node, __x._M_node); }
00362 
00363   iterator insert(iterator __position, const _Tp& __x) {
00364     _Node* __tmp = _M_create_node(__x);
00365     __tmp->_M_next = __position._M_node;
00366     __tmp->_M_prev = __position._M_node->_M_prev;
00367     __position._M_node->_M_prev->_M_next = __tmp;
00368     __position._M_node->_M_prev = __tmp;
00369     return __tmp;
00370   }
00371   iterator insert(iterator __position) { return insert(__position, _Tp()); }
00372 #ifdef __STL_MEMBER_TEMPLATES
00373   // Check whether it's an integral type.  If so, it's not an iterator.
00374 
00375   template<class _Integer>
00376   void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
00377                           __true_type) {
00378     _M_fill_insert(__pos, (size_type) __n, (_Tp) __x);
00379   }
00380 
00381   template <class _InputIterator>
00382   void _M_insert_dispatch(iterator __pos,
00383                           _InputIterator __first, _InputIterator __last,
00384                           __false_type);
00385 
00386   template <class _InputIterator>
00387   void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
00388     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00389     _M_insert_dispatch(__pos, __first, __last, _Integral());
00390   }
00391 
00392 #else /* __STL_MEMBER_TEMPLATES */
00393   void insert(iterator __position, const _Tp* __first, const _Tp* __last);
00394   void insert(iterator __position,
00395               const_iterator __first, const_iterator __last);
00396 #endif /* __STL_MEMBER_TEMPLATES */
00397   void insert(iterator __pos, size_type __n, const _Tp& __x)
00398     { _M_fill_insert(__pos, __n, __x); }
00399   void _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x); 
00400 
00401   void push_front(const _Tp& __x) { insert(begin(), __x); }
00402   void push_front() {insert(begin());}
00403   void push_back(const _Tp& __x) { insert(end(), __x); }
00404   void push_back() {insert(end());}
00405 
00406   iterator erase(iterator __position) {
00407     _List_node_base* __next_node = __position._M_node->_M_next;
00408     _List_node_base* __prev_node = __position._M_node->_M_prev;
00409     _Node* __n = (_Node*) __position._M_node;
00410     __prev_node->_M_next = __next_node;
00411     __next_node->_M_prev = __prev_node;
00412     _Destroy(&__n->_M_data);
00413     _M_put_node(__n);
00414     return iterator((_Node*) __next_node);
00415   }
00416   iterator erase(iterator __first, iterator __last);
00417   void clear() { _Base::clear(); }
00418 
00419   void resize(size_type __new_size, const _Tp& __x);
00420   void resize(size_type __new_size) { this->resize(__new_size, _Tp()); }
00421 
00422   void pop_front() { erase(begin()); }
00423   void pop_back() { 
00424     iterator __tmp = end();
00425     erase(--__tmp);
00426   }
00427   list(size_type __n, const _Tp& __value,
00428        const allocator_type& __a = allocator_type())
00429     : _Base(__a)
00430     { insert(begin(), __n, __value); }
00431   explicit list(size_type __n)
00432     : _Base(allocator_type())
00433     { insert(begin(), __n, _Tp()); }
00434 
00435 #ifdef __STL_MEMBER_TEMPLATES
00436 
00437   // We don't need any dispatching tricks here, because insert does all of
00438   // that anyway.  
00439   template <class _InputIterator>
00440   list(_InputIterator __first, _InputIterator __last,
00441        const allocator_type& __a = allocator_type())
00442     : _Base(__a)
00443     { insert(begin(), __first, __last); }
00444 
00445 #else /* __STL_MEMBER_TEMPLATES */
00446 
00447   list(const _Tp* __first, const _Tp* __last,
00448        const allocator_type& __a = allocator_type())
00449     : _Base(__a)
00450     { this->insert(begin(), __first, __last); }
00451   list(const_iterator __first, const_iterator __last,
00452        const allocator_type& __a = allocator_type())
00453     : _Base(__a)
00454     { this->insert(begin(), __first, __last); }
00455 
00456 #endif /* __STL_MEMBER_TEMPLATES */
00457   list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator())
00458     { insert(begin(), __x.begin(), __x.end()); }
00459 
00460   ~list() { }
00461 
00462   list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x);
00463 
00464 public:
00465   // assign(), a generalized assignment member function.  Two
00466   // versions: one that takes a count, and one that takes a range.
00467   // The range version is a member template, so we dispatch on whether
00468   // or not the type is an integer.
00469 
00470   void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
00471 
00472   void _M_fill_assign(size_type __n, const _Tp& __val);
00473 
00474 #ifdef __STL_MEMBER_TEMPLATES
00475 
00476   template <class _InputIterator>
00477   void assign(_InputIterator __first, _InputIterator __last) {
00478     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00479     _M_assign_dispatch(__first, __last, _Integral());
00480   }
00481 
00482   template <class _Integer>
00483   void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
00484     { _M_fill_assign((size_type) __n, (_Tp) __val); }
00485 
00486   template <class _InputIterator>
00487   void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
00488                           __false_type);
00489 
00490 #endif /* __STL_MEMBER_TEMPLATES */
00491 
00492 protected:
00493   void transfer(iterator __position, iterator __first, iterator __last) {
00494     if (__position != __last) {
00495       // Remove [first, last) from its old position.
00496       __last._M_node->_M_prev->_M_next     = __position._M_node;
00497       __first._M_node->_M_prev->_M_next    = __last._M_node;
00498       __position._M_node->_M_prev->_M_next = __first._M_node; 
00499 
00500       // Splice [first, last) into its new position.
00501       _List_node_base* __tmp      = __position._M_node->_M_prev;
00502       __position._M_node->_M_prev = __last._M_node->_M_prev;
00503       __last._M_node->_M_prev     = __first._M_node->_M_prev; 
00504       __first._M_node->_M_prev    = __tmp;
00505     }
00506   }
00507 
00508 public:
00509   void splice(iterator __position, list& __x) {
00510     if (!__x.empty()) 
00511       this->transfer(__position, __x.begin(), __x.end());
00512   }
00513   void splice(iterator __position, list&, iterator __i) {
00514     iterator __j = __i;
00515     ++__j;
00516     if (__position == __i || __position == __j) return;
00517     this->transfer(__position, __i, __j);
00518   }
00519   void splice(iterator __position, list&, iterator __first, iterator __last) {
00520     if (__first != __last) 
00521       this->transfer(__position, __first, __last);
00522   }
00523   void remove(const _Tp& __value);
00524   void unique();
00525   void merge(list& __x);
00526   void reverse();
00527   void sort();
00528 
00529 #ifdef __STL_MEMBER_TEMPLATES
00530   template <class _Predicate> void remove_if(_Predicate);
00531   template <class _BinaryPredicate> void unique(_BinaryPredicate);
00532   template <class _StrictWeakOrdering> void merge(list&, _StrictWeakOrdering);
00533   template <class _StrictWeakOrdering> void sort(_StrictWeakOrdering);
00534 #endif /* __STL_MEMBER_TEMPLATES */
00535 };
00536 
00537 template <class _Tp, class _Alloc>
00538 inline bool 
00539 operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
00540 {
00541   typedef typename list<_Tp,_Alloc>::const_iterator const_iterator;
00542   const_iterator __end1 = __x.end();
00543   const_iterator __end2 = __y.end();
00544 
00545   const_iterator __i1 = __x.begin();
00546   const_iterator __i2 = __y.begin();
00547   while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
00548     ++__i1;
00549     ++__i2;
00550   }
00551   return __i1 == __end1 && __i2 == __end2;
00552 }
00553 
00554 template <class _Tp, class _Alloc>
00555 inline bool operator<(const list<_Tp,_Alloc>& __x,
00556                       const list<_Tp,_Alloc>& __y)
00557 {
00558   return lexicographical_compare(__x.begin(), __x.end(),
00559                                  __y.begin(), __y.end());
00560 }
00561 
00562 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
00563 
00564 template <class _Tp, class _Alloc>
00565 inline bool operator!=(const list<_Tp,_Alloc>& __x,
00566                        const list<_Tp,_Alloc>& __y) {
00567   return !(__x == __y);
00568 }
00569 
00570 template <class _Tp, class _Alloc>
00571 inline bool operator>(const list<_Tp,_Alloc>& __x,
00572                       const list<_Tp,_Alloc>& __y) {
00573   return __y < __x;
00574 }
00575 
00576 template <class _Tp, class _Alloc>
00577 inline bool operator<=(const list<_Tp,_Alloc>& __x,
00578                        const list<_Tp,_Alloc>& __y) {
00579   return !(__y < __x);
00580 }
00581 
00582 template <class _Tp, class _Alloc>
00583 inline bool operator>=(const list<_Tp,_Alloc>& __x,
00584                        const list<_Tp,_Alloc>& __y) {
00585   return !(__x < __y);
00586 }
00587 
00588 template <class _Tp, class _Alloc>
00589 inline void 
00590 swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
00591 {
00592   __x.swap(__y);
00593 }
00594 
00595 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
00596 
00597 #ifdef __STL_MEMBER_TEMPLATES
00598 
00599 template <class _Tp, class _Alloc> template <class _InputIter>
00600 void 
00601 list<_Tp, _Alloc>::_M_insert_dispatch(iterator __position,
00602                                       _InputIter __first, _InputIter __last,
00603                                       __false_type)
00604 {
00605   for ( ; __first != __last; ++__first)
00606     insert(__position, *__first);
00607 }
00608 
00609 #else /* __STL_MEMBER_TEMPLATES */
00610 
00611 template <class _Tp, class _Alloc>
00612 void 
00613 list<_Tp, _Alloc>::insert(iterator __position, 
00614                           const _Tp* __first, const _Tp* __last)
00615 {
00616   for ( ; __first != __last; ++__first)
00617     insert(__position, *__first);
00618 }
00619 
00620 template <class _Tp, class _Alloc>
00621 void 
00622 list<_Tp, _Alloc>::insert(iterator __position,
00623                          const_iterator __first, const_iterator __last)
00624 {
00625   for ( ; __first != __last; ++__first)
00626     insert(__position, *__first);
00627 }
00628 
00629 #endif /* __STL_MEMBER_TEMPLATES */
00630 
00631 template <class _Tp, class _Alloc>
00632 void 
00633 list<_Tp, _Alloc>::_M_fill_insert(iterator __position,
00634                                   size_type __n, const _Tp& __x)
00635 {
00636   for ( ; __n > 0; --__n)
00637     insert(__position, __x);
00638 }
00639 
00640 template <class _Tp, class _Alloc>
00641 typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first, 
00642                                                              iterator __last)
00643 {
00644   while (__first != __last)
00645     erase(__first++);
00646   return __last;
00647 }
00648 
00649 template <class _Tp, class _Alloc>
00650 void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x)
00651 {
00652   iterator __i = begin();
00653   size_type __len = 0;
00654   for ( ; __i != end() && __len < __new_size; ++__i, ++__len)
00655     ;
00656   if (__len == __new_size)
00657     erase(__i, end());
00658   else                          // __i == end()
00659     insert(end(), __new_size - __len, __x);
00660 }
00661 
00662 template <class _Tp, class _Alloc>
00663 list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x)
00664 {
00665   if (this != &__x) {
00666     iterator __first1 = begin();
00667     iterator __last1 = end();
00668     const_iterator __first2 = __x.begin();
00669     const_iterator __last2 = __x.end();
00670     while (__first1 != __last1 && __first2 != __last2) 
00671       *__first1++ = *__first2++;
00672     if (__first2 == __last2)
00673       erase(__first1, __last1);
00674     else
00675       insert(__last1, __first2, __last2);
00676   }
00677   return *this;
00678 }
00679 
00680 template <class _Tp, class _Alloc>
00681 void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) {
00682   iterator __i = begin();
00683   for ( ; __i != end() && __n > 0; ++__i, --__n)
00684     *__i = __val;
00685   if (__n > 0)
00686     insert(end(), __n, __val);
00687   else
00688     erase(__i, end());
00689 }
00690 
00691 #ifdef __STL_MEMBER_TEMPLATES
00692 
00693 template <class _Tp, class _Alloc> template <class _InputIter>
00694 void
00695 list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2,
00696                                       __false_type)
00697 {
00698   iterator __first1 = begin();
00699   iterator __last1 = end();
00700   for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
00701     *__first1 = *__first2;
00702   if (__first2 == __last2)
00703     erase(__first1, __last1);
00704   else
00705     insert(__last1, __first2, __last2);
00706 }
00707 
00708 #endif /* __STL_MEMBER_TEMPLATES */
00709 
00710 template <class _Tp, class _Alloc>
00711 void list<_Tp, _Alloc>::remove(const _Tp& __value)
00712 {
00713   iterator __first = begin();
00714   iterator __last = end();
00715   while (__first != __last) {
00716     iterator __next = __first;
00717     ++__next;
00718     if (*__first == __value) erase(__first);
00719     __first = __next;
00720   }
00721 }
00722 
00723 template <class _Tp, class _Alloc>
00724 void list<_Tp, _Alloc>::unique()
00725 {
00726   iterator __first = begin();
00727   iterator __last = end();
00728   if (__first == __last) return;
00729   iterator __next = __first;
00730   while (++__next != __last) {
00731     if (*__first == *__next)
00732       erase(__next);
00733     else
00734       __first = __next;
00735     __next = __first;
00736   }
00737 }
00738 
00739 template <class _Tp, class _Alloc>
00740 void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x)
00741 {
00742   iterator __first1 = begin();
00743   iterator __last1 = end();
00744   iterator __first2 = __x.begin();
00745   iterator __last2 = __x.end();
00746   while (__first1 != __last1 && __first2 != __last2)
00747     if (*__first2 < *__first1) {
00748       iterator __next = __first2;
00749       transfer(__first1, __first2, ++__next);
00750       __first2 = __next;
00751     }
00752     else
00753       ++__first1;
00754   if (__first2 != __last2) transfer(__last1, __first2, __last2);
00755 }
00756 
00757 inline void __List_base_reverse(_List_node_base* __p)
00758 {
00759   _List_node_base* __tmp = __p;
00760   do {
00761     __STD::swap(__tmp->_M_next, __tmp->_M_prev);
00762     __tmp = __tmp->_M_prev;     // Old next node is now prev.
00763   } while (__tmp != __p);
00764 }
00765 
00766 template <class _Tp, class _Alloc>
00767 inline void list<_Tp, _Alloc>::reverse() 
00768 {
00769   __List_base_reverse(this->_M_node);
00770 }    
00771 
00772 template <class _Tp, class _Alloc>
00773 void list<_Tp, _Alloc>::sort()
00774 {
00775   // Do nothing if the list has length 0 or 1.
00776   if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
00777     list<_Tp, _Alloc> __carry;
00778     list<_Tp, _Alloc> __counter[64];
00779     int __fill = 0;
00780     while (!empty()) {
00781       __carry.splice(__carry.begin(), *this, begin());
00782       int __i = 0;
00783       while(__i < __fill && !__counter[__i].empty()) {
00784         __counter[__i].merge(__carry);
00785         __carry.swap(__counter[__i++]);
00786       }
00787       __carry.swap(__counter[__i]);         
00788       if (__i == __fill) ++__fill;
00789     } 
00790 
00791     for (int __i = 1; __i < __fill; ++__i)
00792       __counter[__i].merge(__counter[__i-1]);
00793     swap(__counter[__fill-1]);
00794   }
00795 }
00796 
00797 #ifdef __STL_MEMBER_TEMPLATES
00798 
00799 template <class _Tp, class _Alloc> template <class _Predicate>
00800 void list<_Tp, _Alloc>::remove_if(_Predicate __pred)
00801 {
00802   iterator __first = begin();
00803   iterator __last = end();
00804   while (__first != __last) {
00805     iterator __next = __first;
00806     ++__next;
00807     if (__pred(*__first)) erase(__first);
00808     __first = __next;
00809   }
00810 }
00811 
00812 template <class _Tp, class _Alloc> template <class _BinaryPredicate>
00813 void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
00814 {
00815   iterator __first = begin();
00816   iterator __last = end();
00817   if (__first == __last) return;
00818   iterator __next = __first;
00819   while (++__next != __last) {
00820     if (__binary_pred(*__first, *__next))
00821       erase(__next);
00822     else
00823       __first = __next;
00824     __next = __first;
00825   }
00826 }
00827 
00828 template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
00829 void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x,
00830                               _StrictWeakOrdering __comp)
00831 {
00832   iterator __first1 = begin();
00833   iterator __last1 = end();
00834   iterator __first2 = __x.begin();
00835   iterator __last2 = __x.end();
00836   while (__first1 != __last1 && __first2 != __last2)
00837     if (__comp(*__first2, *__first1)) {
00838       iterator __next = __first2;
00839       transfer(__first1, __first2, ++__next);
00840       __first2 = __next;
00841     }
00842     else
00843       ++__first1;
00844   if (__first2 != __last2) transfer(__last1, __first2, __last2);
00845 }
00846 
00847 template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
00848 void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp)
00849 {
00850   // Do nothing if the list has length 0 or 1.
00851   if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
00852     list<_Tp, _Alloc> __carry;
00853     list<_Tp, _Alloc> __counter[64];
00854     int __fill = 0;
00855     while (!empty()) {
00856       __carry.splice(__carry.begin(), *this, begin());
00857       int __i = 0;
00858       while(__i < __fill && !__counter[__i].empty()) {
00859         __counter[__i].merge(__carry, __comp);
00860         __carry.swap(__counter[__i++]);
00861       }
00862       __carry.swap(__counter[__i]);         
00863       if (__i == __fill) ++__fill;
00864     } 
00865 
00866     for (int __i = 1; __i < __fill; ++__i) 
00867       __counter[__i].merge(__counter[__i-1], __comp);
00868     swap(__counter[__fill-1]);
00869   }
00870 }
00871 
00872 #endif /* __STL_MEMBER_TEMPLATES */
00873 
00874 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
00875 #pragma reset woff 1174
00876 #pragma reset woff 1375
00877 #endif
00878 
00879 __STL_END_NAMESPACE 
00880 
00881 #endif /* __SGI_STL_INTERNAL_LIST_H */
00882 
00883 // Local Variables:
00884 // mode:C++
00885 // End:

Generated on Mon Jun 5 10:20:44 2006 for Intelligence.kdevelop by  doxygen 1.4.6