/home/ntakagi/work/STLport-5.1.5/stlport/stl/_list.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_LIST_C
00027 #define _STLP_LIST_C
00028 
00029 #ifndef _STLP_INTERNAL_LIST_H
00030 #  include <stl/_list.h>
00031 #endif
00032 
00033 #ifndef _STLP_CARRAY_H
00034 #  include <stl/_carray.h>
00035 #endif
00036 
00037 #ifndef _STLP_RANGE_ERRORS_H
00038 #  include <stl/_range_errors.h>
00039 #endif
00040 
00041 _STLP_BEGIN_NAMESPACE
00042 
00043 _STLP_MOVE_TO_PRIV_NAMESPACE
00044 
00045 #if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION)
00046 template <class _Dummy>
00047 void _STLP_CALL
00048 _List_global<_Dummy>::_Transfer(_List_node_base* __position,
00049                                 _List_node_base* __first, _List_node_base* __last) {
00050   if (__position != __last) {
00051     // Remove [first, last) from its old position.
00052     __last->_M_prev->_M_next     = __position;
00053     __first->_M_prev->_M_next    = __last;
00054     __position->_M_prev->_M_next = __first;
00055 
00056     // Splice [first, last) into its new position.
00057     _Node_base* __tmp = __position->_M_prev;
00058     __position->_M_prev = __last->_M_prev;
00059     __last->_M_prev     = __first->_M_prev;
00060     __first->_M_prev    = __tmp;
00061   }
00062 }
00063 #endif /* _STLP_EXPOSE_GLOBALS_IMPLEMENTATION */
00064 
00065 template <class _Tp, class _Alloc>
00066 void _List_base<_Tp,_Alloc>::clear() {
00067   _Node* __cur = __STATIC_CAST(_Node*, _M_node._M_data._M_next);
00068   while (__cur != &(_M_node._M_data)) {
00069     _Node* __tmp = __cur;
00070     __cur = __STATIC_CAST(_Node*, __cur->_M_next);
00071     _STLP_STD::_Destroy(&__tmp->_M_data);
00072     this->_M_node.deallocate(__tmp, 1);
00073   }
00074   _M_node._M_data._M_next = &_M_node._M_data;
00075   _M_node._M_data._M_prev = &_M_node._M_data;
00076 }
00077 
00078 #if defined (_STLP_NESTED_TYPE_PARAM_BUG)
00079 #  define size_type size_t
00080 #endif
00081 
00082 #if defined (_STLP_USE_PTR_SPECIALIZATIONS)
00083 #  define list _STLP_PTR_IMPL_NAME(list)
00084 #elif defined (_STLP_DEBUG)
00085 #  define list _STLP_NON_DBG_NAME(list)
00086 #else
00087 _STLP_MOVE_TO_STD_NAMESPACE
00088 #endif
00089 
00090 template <class _Tp, class _Alloc>
00091 void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x) {
00092   iterator __i = begin();
00093   size_type __len = 0;
00094   for ( ; __i != end() && __len < __new_size; ++__i, ++__len);
00095 
00096   if (__len == __new_size)
00097     erase(__i, end());
00098   else // __i == end()
00099     insert(end(), __new_size - __len, __x);
00100 }
00101 
00102 template <class _Tp, class _Alloc>
00103 list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x) {
00104   if (this != &__x) {
00105     iterator __first1 = begin();
00106     iterator __last1 = end();
00107     const_iterator __first2 = __x.begin();
00108     const_iterator __last2 = __x.end();
00109     while (__first1 != __last1 && __first2 != __last2)
00110       *__first1++ = *__first2++;
00111     if (__first2 == __last2)
00112       erase(__first1, __last1);
00113     else
00114       insert(__last1, __first2, __last2);
00115   }
00116   return *this;
00117 }
00118 
00119 template <class _Tp, class _Alloc>
00120 void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) {
00121   iterator __i = begin();
00122   for ( ; __i != end() && __n > 0; ++__i, --__n)
00123     *__i = __val;
00124   if (__n > 0)
00125     insert(end(), __n, __val);
00126   else
00127     erase(__i, end());
00128 }
00129 
00130 #if !defined (list)
00131 _STLP_MOVE_TO_PRIV_NAMESPACE
00132 #endif
00133 
00134 template <class _Tp, class _Alloc, class _Predicate>
00135 void _S_remove_if(list<_Tp, _Alloc>& __that, _Predicate __pred)  {
00136   typedef typename list<_Tp, _Alloc>::iterator _Literator;
00137   _Literator __first = __that.begin();
00138   _Literator __last = __that.end();
00139   while (__first != __last) {
00140     _Literator __next = __first;
00141     ++__next;
00142     if (__pred(*__first)) __that.erase(__first);
00143     __first = __next;
00144   }
00145 }
00146 
00147 template <class _Tp, class _Alloc, class _BinaryPredicate>
00148 void _S_unique(list<_Tp, _Alloc>& __that, _BinaryPredicate __binary_pred) {
00149   typedef typename list<_Tp, _Alloc>::iterator _Literator;
00150   _Literator __first = __that.begin();
00151   _Literator __last = __that.end();
00152   if (__first == __last) return;
00153   _Literator __next = __first;
00154   while (++__next != __last) {
00155     if (__binary_pred(*__first, *__next))
00156       __that.erase(__next);
00157     else
00158       __first = __next;
00159     __next = __first;
00160   }
00161 }
00162 
00163 template <class _Tp, class _Alloc, class _StrictWeakOrdering>
00164 void _S_merge(list<_Tp, _Alloc>& __that, list<_Tp, _Alloc>& __x,
00165               _StrictWeakOrdering __comp) {
00166   typedef typename list<_Tp, _Alloc>::iterator _Literator;
00167   _Literator __first1 = __that.begin();
00168   _Literator __last1 = __that.end();
00169   _Literator __first2 = __x.begin();
00170   _Literator __last2 = __x.end();
00171   if (__that.get_allocator() == __x.get_allocator()) {
00172     while (__first1 != __last1 && __first2 != __last2) {
00173       if (__comp(*__first2, *__first1)) {
00174         _STLP_VERBOSE_ASSERT(!__comp(*__first1, *__first2), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
00175         _Literator __next = __first2;
00176         _List_global_inst::_Transfer(__first1._M_node, __first2._M_node, (++__next)._M_node);
00177         __first2 = __next;
00178       }
00179       else
00180         ++__first1;
00181     }
00182     if (__first2 != __last2)
00183       _List_global_inst::_Transfer(__last1._M_node, __first2._M_node, __last2._M_node);
00184   }
00185   else {
00186     while (__first1 != __last1 && __first2 != __last2) {
00187       if (__comp(*__first2, *__first1)) {
00188         _STLP_VERBOSE_ASSERT(!__comp(*__first1, *__first2), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
00189         __first1 = __that.insert(__first1, *__first2);
00190       }
00191       else
00192         ++__first1;
00193     }
00194     if (__first2 != __last2) {
00195       __that.insert(__first1, __first2, __last2);
00196     }
00197     __x.clear();
00198   }
00199 }
00200 
00201 template <class _Tp, class _Alloc, class _StrictWeakOrdering>
00202 void _S_sort(list<_Tp, _Alloc>& __that, _StrictWeakOrdering __comp) {
00203   // Do nothing if the list has length 0 or 1.
00204   if (__that._M_node._M_data._M_next == &__that._M_node._M_data ||
00205       __that._M_node._M_data._M_next->_M_next == &__that._M_node._M_data)
00206     return;
00207 
00208   list<_Tp, _Alloc> __carry(__that.get_allocator());
00209   const int NB = 64;
00210   _STLP_PRIV _CArray<list<_Tp, _Alloc>, NB> __counter(__carry);
00211   int __fill = 0;
00212   while (!__that.empty()) {
00213     __carry.splice(__carry.begin(), __that, __that.begin());
00214     int __i = 0;
00215     while (__i < __fill && !__counter[__i].empty()) {
00216       _S_merge(__counter[__i], __carry, __comp);
00217       __carry.swap(__counter[__i++]);
00218     }
00219     __carry.swap(__counter[__i]);
00220     if (__i == __fill) {
00221       ++__fill;
00222       if (__fill >= NB) {
00223         //Looks like the list has too many elements to be sorted with this algorithm:
00224         __stl_throw_overflow_error("list::sort");
00225       }
00226     }
00227   }
00228 
00229   for (int __i = 1; __i < __fill; ++__i)
00230     _S_merge(__counter[__i], __counter[__i - 1], __comp);
00231   __that.swap(__counter[__fill - 1]);
00232 }
00233 
00234 #if defined (list)
00235 #  undef list
00236 #endif
00237 
00238 _STLP_MOVE_TO_STD_NAMESPACE
00239 
00240 _STLP_END_NAMESPACE
00241 
00242 #endif /*  _STLP_LIST_C */
00243 
00244 // Local Variables:
00245 // mode:C++
00246 // End:



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