_list.h

00001 /*
00002  *
00003  * Copyright (c) 1994
00004  * Hewlett-Packard Company
00005  *
00006  * Copyright (c) 1996,1997
00007  * Silicon Graphics Computer Systems, Inc.
00008  *
00009  * Copyright (c) 1997
00010  * Moscow Center for SPARC Technology
00011  *
00012  * Copyright (c) 1999 
00013  * Boris Fomitchev
00014  *
00015  * This material is provided "as is", with absolutely no warranty expressed
00016  * or implied. Any use is at your own risk.
00017  *
00018  * Permission to use or copy this software for any purpose is hereby granted 
00019  * without fee, provided the above notices are retained on all copies.
00020  * Permission to modify the code and to distribute modified code is granted,
00021  * provided the above notices are retained, and a notice that the code was
00022  * modified is included with the above copyright notice.
00023  *
00024  */
00025 
00026 /* NOTE: This is an internal header file, included by other STL headers.
00027  *   You should not attempt to use it directly.
00028  */
00029 
00030 #ifndef _STLP_INTERNAL_LIST_H
00031 #define _STLP_INTERNAL_LIST_H
00032 
00033 # ifndef _STLP_INTERNAL_ALGOBASE_H
00034 #  include <stl/_algobase.h>
00035 # endif
00036 
00037 # ifndef _STLP_INTERNAL_ALLOC_H
00038 #  include <stl/_alloc.h>
00039 # endif
00040 
00041 # ifndef _STLP_INTERNAL_ITERATOR_H
00042 #  include <stl/_iterator.h>
00043 # endif
00044 
00045 # ifndef _STLP_INTERNAL_CONSTRUCT_H
00046 #  include <stl/_construct.h>
00047 # endif
00048 
00049 # ifndef _STLP_INTERNAL_FUNCTION_BASE_H
00050 #  include <stl/_function_base.h>
00051 # endif
00052 
00053 _STLP_BEGIN_NAMESPACE
00054 
00055 # undef list
00056 # define  list  __WORKAROUND_DBG_RENAME(list)
00057 
00058 struct _List_node_base {
00059   _List_node_base* _M_next;
00060   _List_node_base* _M_prev;
00061 };
00062 
00063 template <class _Dummy>
00064 class _List_global {
00065 public:
00066   typedef _List_node_base _Node;
00067   static void  _STLP_CALL _Transfer(_List_node_base* __position, 
00068                                     _List_node_base* __first, _List_node_base* __last);
00069 };
00070 
00071 # if defined (_STLP_USE_TEMPLATE_EXPORT) 
00072 _STLP_EXPORT_TEMPLATE_CLASS _List_global<bool>;
00073 # endif
00074 typedef _List_global<bool> _List_global_inst;
00075 
00076 template <class _Tp>
00077 struct _List_node : public _List_node_base {
00078   _Tp _M_data;
00079   __TRIVIAL_STUFF(_List_node)
00080 };
00081 
00082 struct _List_iterator_base {
00083   typedef size_t                     size_type;
00084   typedef ptrdiff_t                  difference_type;
00085   typedef bidirectional_iterator_tag iterator_category;
00086 
00087   _List_node_base* _M_node;
00088 
00089   _List_iterator_base(_List_node_base* __x) : _M_node(__x) {}
00090   _List_iterator_base() {}
00091 
00092   void _M_incr() { _M_node = _M_node->_M_next; }
00093   void _M_decr() { _M_node = _M_node->_M_prev; }
00094   bool operator==(const _List_iterator_base& __y ) const { 
00095     return _M_node == __y._M_node; 
00096   }
00097   bool operator!=(const _List_iterator_base& __y ) const { 
00098     return _M_node != __y._M_node; 
00099   }
00100 };  
00101 
00102 
00103 
00104 
00105 template<class _Tp, class _Traits>
00106 struct _List_iterator : public _List_iterator_base {
00107   typedef _Tp value_type;
00108   typedef typename _Traits::pointer    pointer;
00109   typedef typename _Traits::reference  reference;
00110 
00111   typedef _List_iterator<_Tp, _Nonconst_traits<_Tp> > iterator;
00112   typedef _List_iterator<_Tp, _Const_traits<_Tp> >    const_iterator;
00113   typedef _List_iterator<_Tp, _Traits>                       _Self;
00114 
00115   typedef bidirectional_iterator_tag iterator_category;
00116   typedef _List_node<_Tp> _Node;
00117   typedef size_t size_type;
00118   typedef ptrdiff_t difference_type;
00119 
00120   _List_iterator(_Node* __x) : _List_iterator_base(__x) {}
00121   _List_iterator() {}
00122   _List_iterator(const iterator& __x) :  _List_iterator_base(__x._M_node) {}
00123 
00124   reference operator*() const { return ((_Node*)_M_node)->_M_data; }
00125 
00126   _STLP_DEFINE_ARROW_OPERATOR
00127 
00128   _Self& operator++() { 
00129     this->_M_incr();
00130     return *this;
00131   }
00132   _Self operator++(int) { 
00133     _Self __tmp = *this;
00134     this->_M_incr();
00135     return __tmp;
00136   }
00137   _Self& operator--() { 
00138     this->_M_decr();
00139     return *this;
00140   }
00141   _Self operator--(int) { 
00142     _Self __tmp = *this;
00143     this->_M_decr();
00144     return __tmp;
00145   }
00146 };
00147 
00148 
00149 #ifdef _STLP_USE_OLD_HP_ITERATOR_QUERIES
00150 template <class _Tp, class _Traits>
00151 inline _Tp* value_type(const _List_iterator<_Tp, _Traits>&) { return 0; }
00152 inline bidirectional_iterator_tag iterator_category(const _List_iterator_base&) { return bidirectional_iterator_tag();}
00153 inline ptrdiff_t* distance_type(const _List_iterator_base&) { return 0; }
00154 #endif
00155 
00156 
00157 // Base class that encapsulates details of allocators and helps 
00158 // to simplify EH
00159 
00160 template <class _Tp, class _Alloc>
00161 class _List_base 
00162 {
00163 protected:
00164   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00165   typedef _List_node<_Tp> _Node;
00166   typedef typename _Alloc_traits<_Node, _Alloc>::allocator_type
00167            _Node_allocator_type;
00168 public:
00169   typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type
00170           allocator_type;
00171 
00172   allocator_type get_allocator() const { 
00173     return _STLP_CONVERT_ALLOCATOR((const _Node_allocator_type&)_M_node, _Tp);
00174   }
00175 
00176   _List_base(const allocator_type& __a) : _M_node(_STLP_CONVERT_ALLOCATOR(__a, _Node), (_Node*)0) {
00177     _Node* __n = _M_node.allocate(1);
00178     __n->_M_next = __n;
00179     __n->_M_prev = __n;
00180     _M_node._M_data = __n;
00181   }
00182   ~_List_base() {
00183     clear();
00184     _M_node.deallocate(_M_node._M_data, 1);
00185   }
00186 
00187   void clear();
00188 
00189 public:
00190   _STLP_alloc_proxy<_Node*, _Node, _Node_allocator_type>  _M_node;
00191 };
00192 
00193 template <class _Tp, _STLP_DEFAULT_ALLOCATOR_SELECT(_Tp) >
00194 class list;
00195 
00196 // helper functions to reduce code duplication
00197 template <class _Tp, class _Alloc, class _Predicate> 
00198 void _S_remove_if(list<_Tp, _Alloc>& __that, _Predicate __pred);
00199 
00200 template <class _Tp, class _Alloc, class _BinaryPredicate>
00201 void _S_unique(list<_Tp, _Alloc>& __that, _BinaryPredicate __binary_pred);
00202 
00203 template <class _Tp, class _Alloc, class _StrictWeakOrdering>
00204 void _S_merge(list<_Tp, _Alloc>& __that, list<_Tp, _Alloc>& __x,
00205               _StrictWeakOrdering __comp);
00206 
00207 template <class _Tp, class _Alloc, class _StrictWeakOrdering>
00208 void _S_sort(list<_Tp, _Alloc>& __that, _StrictWeakOrdering __comp);
00209 
00210 template <class _Tp, class _Alloc>
00211 class list : public _List_base<_Tp, _Alloc> {
00212   typedef _List_base<_Tp, _Alloc> _Base;
00213   typedef list<_Tp, _Alloc> _Self;
00214 public:      
00215   typedef _Tp value_type;
00216   typedef value_type* pointer;
00217   typedef const value_type* const_pointer;
00218   typedef value_type& reference;
00219   typedef const value_type& const_reference;
00220   typedef _List_node<_Tp> _Node;
00221   typedef size_t size_type;
00222   typedef ptrdiff_t difference_type;
00223   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00224   typedef typename _Base::allocator_type allocator_type;
00225   typedef bidirectional_iterator_tag _Iterator_category;
00226 
00227 public:
00228   typedef _List_iterator<_Tp, _Nonconst_traits<_Tp> > iterator;
00229   typedef _List_iterator<_Tp, _Const_traits<_Tp> >    const_iterator;
00230   _STLP_DECLARE_BIDIRECTIONAL_REVERSE_ITERATORS;
00231 
00232 protected:
00233   _Node* _M_create_node(const _Tp& __x)
00234   {
00235     _Node* __p = this->_M_node.allocate(1);
00236     _STLP_TRY {
00237       _Construct(&__p->_M_data, __x);
00238     }
00239     _STLP_UNWIND(this->_M_node.deallocate(__p, 1));
00240     return __p;
00241   }
00242 
00243   _Node* _M_create_node()
00244   {
00245     _Node* __p = this->_M_node.allocate(1);
00246     _STLP_TRY {
00247       _Construct(&__p->_M_data);
00248     }
00249     _STLP_UNWIND(this->_M_node.deallocate(__p, 1));
00250     return __p;
00251   }
00252 
00253 public:
00254 # if !(defined(__MRC__)||defined(__SC__))
00255   explicit
00256 # endif
00257   list(const allocator_type& __a = allocator_type()) :
00258     _List_base<_Tp, _Alloc>(__a) {}
00259 
00260   iterator begin()             { return iterator((_Node*)(this->_M_node._M_data->_M_next)); }
00261   const_iterator begin() const { return const_iterator((_Node*)(this->_M_node._M_data->_M_next)); }
00262 
00263   iterator end()             { return this->_M_node._M_data; }
00264   const_iterator end() const { return this->_M_node._M_data; }
00265 
00266   reverse_iterator rbegin() 
00267     { return reverse_iterator(end()); }
00268   const_reverse_iterator rbegin() const 
00269     { return const_reverse_iterator(end()); }
00270 
00271   reverse_iterator rend()
00272     { return reverse_iterator(begin()); }
00273   const_reverse_iterator rend() const
00274     { return const_reverse_iterator(begin()); }
00275 
00276   bool empty() const { return this->_M_node._M_data->_M_next == this->_M_node._M_data; }
00277   size_type size() const {
00278     size_type __result = distance(begin(), end());
00279     return __result;
00280   }
00281   size_type max_size() const { return size_type(-1); }
00282 
00283   reference front() { return *begin(); }
00284   const_reference front() const { return *begin(); }
00285   reference back() { return *(--end()); }
00286   const_reference back() const { return *(--end()); }
00287 
00288   void swap(list<_Tp, _Alloc>& __x) {
00289     _STLP_STD::swap(this->_M_node, __x._M_node); 
00290   }
00291 
00292   iterator insert(iterator __position, const _Tp& __x) {
00293 
00294     _Node* __tmp = _M_create_node(__x);
00295     _List_node_base* __n = __position._M_node;
00296     _List_node_base* __p = __n->_M_prev;
00297     __tmp->_M_next = __n;
00298     __tmp->_M_prev = __p;
00299     __p->_M_next = __tmp;
00300     __n->_M_prev = __tmp;
00301     return __tmp;
00302   }
00303 
00304 #ifdef _STLP_MEMBER_TEMPLATES
00305   template <class _InputIterator>
00306   void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
00307     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00308     _M_insert_dispatch(__pos, __first, __last, _Integral());
00309   }
00310   // Check whether it's an integral type.  If so, it's not an iterator.
00311   template<class _Integer>
00312   void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
00313                           const __true_type&) {
00314     _M_fill_insert(__pos, (size_type) __n, (_Tp) __x);
00315   }
00316   template <class _InputIter>
00317   void 
00318   _M_insert_dispatch(iterator __position,
00319                      _InputIter __first, _InputIter __last,
00320                      const __false_type&) 
00321 #else /* _STLP_MEMBER_TEMPLATES */
00322   void insert(iterator __position, const _Tp* __first, const _Tp* __last) {
00323     for ( ; __first != __last; ++__first)
00324       insert(__position, *__first);
00325   }
00326   void insert(iterator __position, const_iterator __first, const_iterator __last)
00327 #endif /* _STLP_MEMBER_TEMPLATES */
00328   {
00329     for ( ; __first != __last; ++__first)
00330       insert(__position, *__first);
00331   }
00332   void insert(iterator __pos, size_type __n, const _Tp& __x) { _M_fill_insert(__pos, __n, __x); }
00333   
00334   void _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x) {
00335     for ( ; __n > 0; --__n)
00336       insert(__pos, __x);
00337   } 
00338   void push_front(const _Tp& __x) { insert(begin(), __x); }
00339   void push_back(const _Tp& __x) { insert(end(), __x); }
00340 
00341 # ifndef _STLP_NO_ANACHRONISMS
00342   iterator insert(iterator __position) { return insert(__position, _Tp()); }
00343   void push_front() {insert(begin());}
00344   void push_back() {insert(end());}
00345 # endif
00346 
00347   iterator erase(iterator __position) {
00348     _List_node_base* __next_node = __position._M_node->_M_next;
00349     _List_node_base* __prev_node = __position._M_node->_M_prev;
00350     _Node* __n = (_Node*) __position._M_node;
00351     __prev_node->_M_next = __next_node;
00352     __next_node->_M_prev = __prev_node;
00353     _Destroy(&__n->_M_data);
00354     this->_M_node.deallocate(__n, 1);
00355     return iterator((_Node*)__next_node);
00356     }
00357   
00358   iterator erase(iterator __first, iterator __last) {
00359     while (__first != __last)
00360       erase(__first++);
00361     return __last;
00362   }
00363 
00364   void resize(size_type __new_size, const _Tp& __x);
00365   void resize(size_type __new_size) { this->resize(__new_size, _Tp()); }
00366 
00367   void pop_front() { erase(begin()); }
00368   void pop_back() { 
00369     iterator __tmp = end();
00370     erase(--__tmp);
00371   }
00372   list(size_type __n, const _Tp& __value,
00373        const allocator_type& __a = allocator_type())
00374     : _List_base<_Tp, _Alloc>(__a)
00375     { this->insert(begin(), __n, __value); }
00376   explicit list(size_type __n)
00377     : _List_base<_Tp, _Alloc>(allocator_type())
00378     { this->insert(begin(), __n, _Tp()); }
00379 
00380 #ifdef _STLP_MEMBER_TEMPLATES
00381   // We don't need any dispatching tricks here, because insert does all of
00382   // that anyway.
00383 # ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS
00384   template <class _InputIterator>
00385   list(_InputIterator __first, _InputIterator __last)
00386     : _List_base<_Tp, _Alloc>(allocator_type())
00387   { insert(begin(), __first, __last); }
00388 # endif  
00389   template <class _InputIterator>
00390   list(_InputIterator __first, _InputIterator __last,
00391        const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL)
00392     : _List_base<_Tp, _Alloc>(__a)
00393   { insert(begin(), __first, __last); }
00394   
00395 #else /* _STLP_MEMBER_TEMPLATES */
00396 
00397   list(const _Tp* __first, const _Tp* __last,
00398        const allocator_type& __a = allocator_type())
00399     : _List_base<_Tp, _Alloc>(__a)
00400     { insert(begin(), __first, __last); }
00401   list(const_iterator __first, const_iterator __last,
00402        const allocator_type& __a = allocator_type())
00403     : _List_base<_Tp, _Alloc>(__a)
00404     { insert(begin(), __first, __last); }
00405 
00406 #endif /* _STLP_MEMBER_TEMPLATES */
00407   list(const list<_Tp, _Alloc>& __x) : _List_base<_Tp, _Alloc>(__x.get_allocator())
00408     { insert(begin(), __x.begin(), __x.end()); }
00409 
00410   ~list() { }
00411 
00412   list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x);
00413 
00414 public:
00415   // assign(), a generalized assignment member function.  Two
00416   // versions: one that takes a count, and one that takes a range.
00417   // The range version is a member template, so we dispatch on whether
00418   // or not the type is an integer.
00419 
00420   void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
00421 
00422   void _M_fill_assign(size_type __n, const _Tp& __val);
00423 
00424 #ifdef _STLP_MEMBER_TEMPLATES
00425 
00426   template <class _InputIterator>
00427   void assign(_InputIterator __first, _InputIterator __last) {
00428     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00429     _M_assign_dispatch(__first, __last, _Integral());
00430   }
00431 
00432   template <class _Integer>
00433   void _M_assign_dispatch(_Integer __n, _Integer __val, const __true_type&)
00434     { assign((size_type) __n, (_Tp) __val); }
00435 
00436   template <class _InputIterator>
00437   void _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2,
00438                           const __false_type&) {
00439     iterator __first1 = begin();
00440     iterator __last1 = end();
00441     for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
00442       *__first1 = *__first2;
00443     if (__first2 == __last2)
00444       erase(__first1, __last1);
00445     else
00446       insert(__last1, __first2, __last2);
00447   }
00448 
00449 #endif /* _STLP_MEMBER_TEMPLATES */
00450 
00451 public:
00452   void splice(iterator __position, _Self& __x) {
00453     if (!__x.empty()) 
00454       _List_global_inst::_Transfer(__position._M_node, __x.begin()._M_node, __x.end()._M_node);
00455   }
00456   void splice(iterator __position, _Self&, iterator __i) {
00457     iterator __j = __i;
00458     ++__j;
00459     if (__position == __i || __position == __j) return;
00460     _List_global_inst::_Transfer(__position._M_node, __i._M_node, __j._M_node);
00461   }
00462   void splice(iterator __position, _Self&, iterator __first, iterator __last) {
00463     if (__first != __last) 
00464       _List_global_inst::_Transfer(__position._M_node, __first._M_node, __last._M_node);
00465   }
00466 
00467   void remove(const _Tp& __value) {
00468     iterator __first = begin();
00469     iterator __last = end();
00470     while (__first != __last) {
00471       iterator __next = __first;
00472       ++__next;
00473       if (__value == *__first) erase(__first);
00474       __first = __next;
00475     }
00476   }
00477   
00478   void unique() {
00479     _S_unique(*this, equal_to<_Tp>());
00480   }
00481   
00482   void merge(_Self& __x) {
00483     _S_merge(*this, __x, less<_Tp>());
00484   }
00485 
00486   void reverse() {
00487     _List_node_base* __p = this->_M_node._M_data;
00488     _List_node_base* __tmp = __p;
00489     do {
00490       _STLP_STD::swap(__tmp->_M_next, __tmp->_M_prev);
00491       __tmp = __tmp->_M_prev;     // Old next node is now prev.
00492     } while (__tmp != __p);
00493   }    
00494   
00495   void sort() {
00496     _S_sort(*this, less<_Tp>());
00497   }
00498 
00499 #ifdef _STLP_MEMBER_TEMPLATES
00500   template <class _Predicate> void remove_if(_Predicate __pred)  {
00501     _S_remove_if(*this, __pred);
00502   }
00503   template <class _BinaryPredicate>
00504     void unique(_BinaryPredicate __binary_pred) {
00505     _S_unique(*this, __binary_pred);
00506   }
00507 
00508   template <class _StrictWeakOrdering>
00509     void merge(list<_Tp, _Alloc>& __x,
00510           _StrictWeakOrdering __comp) {
00511     _S_merge(*this, __x, __comp);
00512   }
00513 
00514   template <class _StrictWeakOrdering>
00515     void sort(_StrictWeakOrdering __comp) {
00516     _S_sort(*this, __comp);
00517   }
00518 #endif /* _STLP_MEMBER_TEMPLATES */
00519 
00520 };
00521 
00522 template <class _Tp, class _Alloc>
00523 _STLP_INLINE_LOOP bool  _STLP_CALL
00524 operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
00525 {
00526   typedef typename list<_Tp,_Alloc>::const_iterator const_iterator;
00527   const_iterator __end1 = __x.end();
00528   const_iterator __end2 = __y.end();
00529 
00530   const_iterator __i1 = __x.begin();
00531   const_iterator __i2 = __y.begin();
00532   while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
00533     ++__i1;
00534     ++__i2;
00535   }
00536   return __i1 == __end1 && __i2 == __end2;
00537 }
00538 
00539 template <class _Tp, class _Alloc>
00540 inline bool  _STLP_CALL operator<(const list<_Tp,_Alloc>& __x,
00541                                   const list<_Tp,_Alloc>& __y)
00542 {
00543   return lexicographical_compare(__x.begin(), __x.end(),
00544                                  __y.begin(), __y.end());
00545 }
00546 
00547 # define _STLP_TEMPLATE_CONTAINER list<_Tp, _Alloc>
00548 # define _STLP_TEMPLATE_HEADER    template <class _Tp, class _Alloc>
00549 _STLP_RELOPS_OPERATORS(_STLP_TEMPLATE_HEADER, _STLP_TEMPLATE_CONTAINER)
00550 # undef _STLP_TEMPLATE_CONTAINER
00551 # undef _STLP_TEMPLATE_HEADER
00552 
00553 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
00554 
00555 template <class _Tp, class _Alloc>
00556 inline void _STLP_CALL 
00557 swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
00558 {
00559   __x.swap(__y);
00560 }
00561 
00562 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
00563 
00564 _STLP_END_NAMESPACE 
00565 
00566 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
00567 #  include <stl/_list.c>
00568 # endif
00569 
00570 // do a cleanup
00571 # undef list
00572 # define __list__ __FULL_NAME(list)
00573 
00574 #if defined (_STLP_DEBUG)
00575 # include <stl/debug/_list.h>
00576 #endif
00577 
00578 #if defined (_STLP_USE_WRAPPER_FOR_ALLOC_PARAM)
00579 # include <stl/wrappers/_list.h>
00580 #endif
00581 
00582 #endif /* _STLP_INTERNAL_LIST_H */
00583 
00584 // Local Variables:
00585 // mode:C++
00586 // End:

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