xref: /openbsd-src/gnu/lib/libstdc++/libstdc++/include/bits/list.tcc (revision 19731d4f8b8a37c0f0786969cd7fb2f87d5c0b74)
103a78d15Sespie // List implementation (out of line) -*- C++ -*-
203a78d15Sespie 
303a78d15Sespie // Copyright (C) 2001, 2002 Free Software Foundation, Inc.
403a78d15Sespie //
503a78d15Sespie // This file is part of the GNU ISO C++ Library.  This library is free
603a78d15Sespie // software; you can redistribute it and/or modify it under the
703a78d15Sespie // terms of the GNU General Public License as published by the
803a78d15Sespie // Free Software Foundation; either version 2, or (at your option)
903a78d15Sespie // any later version.
1003a78d15Sespie 
1103a78d15Sespie // This library is distributed in the hope that it will be useful,
1203a78d15Sespie // but WITHOUT ANY WARRANTY; without even the implied warranty of
1303a78d15Sespie // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1403a78d15Sespie // GNU General Public License for more details.
1503a78d15Sespie 
1603a78d15Sespie // You should have received a copy of the GNU General Public License along
1703a78d15Sespie // with this library; see the file COPYING.  If not, write to the Free
1803a78d15Sespie // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
1903a78d15Sespie // USA.
2003a78d15Sespie 
2103a78d15Sespie // As a special exception, you may use this file as part of a free software
2203a78d15Sespie // library without restriction.  Specifically, if other files instantiate
2303a78d15Sespie // templates or use macros or inline functions from this file, or you compile
2403a78d15Sespie // this file and link it with other files to produce an executable, this
2503a78d15Sespie // file does not by itself cause the resulting executable to be covered by
2603a78d15Sespie // the GNU General Public License.  This exception does not however
2703a78d15Sespie // invalidate any other reasons why the executable file might be covered by
2803a78d15Sespie // the GNU General Public License.
2903a78d15Sespie 
3003a78d15Sespie /*
3103a78d15Sespie  *
3203a78d15Sespie  * Copyright (c) 1994
3303a78d15Sespie  * Hewlett-Packard Company
3403a78d15Sespie  *
3503a78d15Sespie  * Permission to use, copy, modify, distribute and sell this software
3603a78d15Sespie  * and its documentation for any purpose is hereby granted without fee,
3703a78d15Sespie  * provided that the above copyright notice appear in all copies and
3803a78d15Sespie  * that both that copyright notice and this permission notice appear
3903a78d15Sespie  * in supporting documentation.  Hewlett-Packard Company makes no
4003a78d15Sespie  * representations about the suitability of this software for any
4103a78d15Sespie  * purpose.  It is provided "as is" without express or implied warranty.
4203a78d15Sespie  *
4303a78d15Sespie  *
4403a78d15Sespie  * Copyright (c) 1996,1997
4503a78d15Sespie  * Silicon Graphics Computer Systems, Inc.
4603a78d15Sespie  *
4703a78d15Sespie  * Permission to use, copy, modify, distribute and sell this software
4803a78d15Sespie  * and its documentation for any purpose is hereby granted without fee,
4903a78d15Sespie  * provided that the above copyright notice appear in all copies and
5003a78d15Sespie  * that both that copyright notice and this permission notice appear
5103a78d15Sespie  * in supporting documentation.  Silicon Graphics makes no
5203a78d15Sespie  * representations about the suitability of this software for any
5303a78d15Sespie  * purpose.  It is provided "as is" without express or implied warranty.
5403a78d15Sespie  */
5503a78d15Sespie 
5603a78d15Sespie /** @file list.tcc
5703a78d15Sespie  *  This is an internal header file, included by other library headers.
5803a78d15Sespie  *  You should not attempt to use it directly.
5903a78d15Sespie  */
6003a78d15Sespie 
6103a78d15Sespie #ifndef __GLIBCPP_INTERNAL_LIST_TCC
6203a78d15Sespie #define __GLIBCPP_INTERNAL_LIST_TCC
6303a78d15Sespie 
6403a78d15Sespie namespace std
6503a78d15Sespie {
6603a78d15Sespie   template<typename _Tp, typename _Alloc>
6703a78d15Sespie     void
6803a78d15Sespie     _List_base<_Tp,_Alloc>::
__clear()6903a78d15Sespie     __clear()
7003a78d15Sespie     {
7103a78d15Sespie       typedef _List_node<_Tp>  _Node;
7203a78d15Sespie       _Node* __cur = static_cast<_Node*>(_M_node->_M_next);
7303a78d15Sespie       while (__cur != _M_node)
7403a78d15Sespie       {
7503a78d15Sespie         _Node* __tmp = __cur;
7603a78d15Sespie         __cur = static_cast<_Node*>(__cur->_M_next);
7703a78d15Sespie         _Destroy(&__tmp->_M_data);
7803a78d15Sespie         _M_put_node(__tmp);
7903a78d15Sespie       }
8003a78d15Sespie       _M_node->_M_next = _M_node;
8103a78d15Sespie       _M_node->_M_prev = _M_node;
8203a78d15Sespie     }
8303a78d15Sespie 
8403a78d15Sespie   template<typename _Tp, typename _Alloc>
8503a78d15Sespie     typename list<_Tp,_Alloc>::iterator
8603a78d15Sespie     list<_Tp,_Alloc>::
insert(iterator __position,const value_type & __x)8703a78d15Sespie     insert(iterator __position, const value_type& __x)
8803a78d15Sespie     {
8903a78d15Sespie       _Node* __tmp = _M_create_node(__x);
9003a78d15Sespie       __tmp->_M_next = __position._M_node;
9103a78d15Sespie       __tmp->_M_prev = __position._M_node->_M_prev;
9203a78d15Sespie       __position._M_node->_M_prev->_M_next = __tmp;
9303a78d15Sespie       __position._M_node->_M_prev = __tmp;
9403a78d15Sespie       return __tmp;
9503a78d15Sespie     }
9603a78d15Sespie 
9703a78d15Sespie   template<typename _Tp, typename _Alloc>
9803a78d15Sespie     typename list<_Tp,_Alloc>::iterator
9903a78d15Sespie     list<_Tp,_Alloc>::
erase(iterator __position)10003a78d15Sespie     erase(iterator __position)
10103a78d15Sespie     {
10203a78d15Sespie       _List_node_base* __next_node = __position._M_node->_M_next;
10303a78d15Sespie       _List_node_base* __prev_node = __position._M_node->_M_prev;
10403a78d15Sespie       _Node* __n = static_cast<_Node*>(__position._M_node);
10503a78d15Sespie       __prev_node->_M_next = __next_node;
10603a78d15Sespie       __next_node->_M_prev = __prev_node;
10703a78d15Sespie       _Destroy(&__n->_M_data);
10803a78d15Sespie       _M_put_node(__n);
10903a78d15Sespie       return iterator(static_cast<_Node*>(__next_node));
11003a78d15Sespie     }
11103a78d15Sespie 
11203a78d15Sespie   template<typename _Tp, typename _Alloc>
11303a78d15Sespie     void
11403a78d15Sespie     list<_Tp,_Alloc>::
resize(size_type __new_size,const value_type & __x)11503a78d15Sespie     resize(size_type __new_size, const value_type& __x)
11603a78d15Sespie     {
11703a78d15Sespie       iterator __i = begin();
11803a78d15Sespie       size_type __len = 0;
11903a78d15Sespie       for ( ; __i != end() && __len < __new_size; ++__i, ++__len)
12003a78d15Sespie         ;
12103a78d15Sespie       if (__len == __new_size)
12203a78d15Sespie         erase(__i, end());
12303a78d15Sespie       else                          // __i == end()
12403a78d15Sespie         insert(end(), __new_size - __len, __x);
12503a78d15Sespie     }
12603a78d15Sespie 
12703a78d15Sespie   template<typename _Tp, typename _Alloc>
12803a78d15Sespie     list<_Tp,_Alloc>&
12903a78d15Sespie     list<_Tp,_Alloc>::
operator =(const list & __x)13003a78d15Sespie     operator=(const list& __x)
13103a78d15Sespie     {
13203a78d15Sespie       if (this != &__x)
13303a78d15Sespie       {
13403a78d15Sespie         iterator __first1 = begin();
13503a78d15Sespie         iterator __last1 = end();
13603a78d15Sespie         const_iterator __first2 = __x.begin();
13703a78d15Sespie         const_iterator __last2 = __x.end();
13803a78d15Sespie         while (__first1 != __last1 && __first2 != __last2)
13903a78d15Sespie           *__first1++ = *__first2++;
14003a78d15Sespie         if (__first2 == __last2)
14103a78d15Sespie           erase(__first1, __last1);
14203a78d15Sespie         else
14303a78d15Sespie           insert(__last1, __first2, __last2);
14403a78d15Sespie       }
14503a78d15Sespie       return *this;
14603a78d15Sespie     }
14703a78d15Sespie 
14803a78d15Sespie   template<typename _Tp, typename _Alloc>
14903a78d15Sespie     void
15003a78d15Sespie     list<_Tp,_Alloc>::
_M_fill_assign(size_type __n,const value_type & __val)15103a78d15Sespie     _M_fill_assign(size_type __n, const value_type& __val)
15203a78d15Sespie     {
15303a78d15Sespie       iterator __i = begin();
15403a78d15Sespie       for ( ; __i != end() && __n > 0; ++__i, --__n)
15503a78d15Sespie         *__i = __val;
15603a78d15Sespie       if (__n > 0)
15703a78d15Sespie         insert(end(), __n, __val);
15803a78d15Sespie       else
15903a78d15Sespie         erase(__i, end());
16003a78d15Sespie     }
16103a78d15Sespie 
16203a78d15Sespie   template<typename _Tp, typename _Alloc>
16303a78d15Sespie     template <typename _InputIter>
16403a78d15Sespie       void
16503a78d15Sespie       list<_Tp,_Alloc>::
_M_assign_dispatch(_InputIter __first2,_InputIter __last2,__false_type)16603a78d15Sespie       _M_assign_dispatch(_InputIter __first2, _InputIter __last2, __false_type)
16703a78d15Sespie       {
16803a78d15Sespie         iterator __first1 = begin();
16903a78d15Sespie         iterator __last1 = end();
17003a78d15Sespie         for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
17103a78d15Sespie           *__first1 = *__first2;
17203a78d15Sespie         if (__first2 == __last2)
17303a78d15Sespie           erase(__first1, __last1);
17403a78d15Sespie         else
17503a78d15Sespie           insert(__last1, __first2, __last2);
17603a78d15Sespie       }
17703a78d15Sespie 
17803a78d15Sespie   template<typename _Tp, typename _Alloc>
17903a78d15Sespie     void
18003a78d15Sespie     list<_Tp,_Alloc>::
remove(const value_type & __value)18103a78d15Sespie     remove(const value_type& __value)
18203a78d15Sespie     {
18303a78d15Sespie       iterator __first = begin();
18403a78d15Sespie       iterator __last = end();
18503a78d15Sespie       while (__first != __last)
18603a78d15Sespie       {
18703a78d15Sespie         iterator __next = __first;
18803a78d15Sespie         ++__next;
18903a78d15Sespie         if (*__first == __value)
19003a78d15Sespie           erase(__first);
19103a78d15Sespie         __first = __next;
19203a78d15Sespie       }
19303a78d15Sespie     }
19403a78d15Sespie 
19503a78d15Sespie   template<typename _Tp, typename _Alloc>
19603a78d15Sespie     void
19703a78d15Sespie     list<_Tp,_Alloc>::
unique()19803a78d15Sespie     unique()
19903a78d15Sespie     {
20003a78d15Sespie       iterator __first = begin();
20103a78d15Sespie       iterator __last = end();
20203a78d15Sespie       if (__first == __last) return;
20303a78d15Sespie       iterator __next = __first;
20403a78d15Sespie       while (++__next != __last)
20503a78d15Sespie       {
20603a78d15Sespie         if (*__first == *__next)
20703a78d15Sespie           erase(__next);
20803a78d15Sespie         else
20903a78d15Sespie           __first = __next;
21003a78d15Sespie         __next = __first;
21103a78d15Sespie       }
21203a78d15Sespie     }
21303a78d15Sespie 
21403a78d15Sespie   template<typename _Tp, typename _Alloc>
21503a78d15Sespie     void
21603a78d15Sespie     list<_Tp,_Alloc>::
merge(list & __x)21703a78d15Sespie     merge(list& __x)
21803a78d15Sespie     {
219*19731d4fSespie       // _GLIBCXX_RESOLVE_LIB_DEFECTS
220*19731d4fSespie       // 300. list::merge() specification incomplete
221*19731d4fSespie       if (this != &__x)
222*19731d4fSespie 	{
22303a78d15Sespie 	  iterator __first1 = begin();
22403a78d15Sespie 	  iterator __last1 = end();
22503a78d15Sespie 	  iterator __first2 = __x.begin();
22603a78d15Sespie 	  iterator __last2 = __x.end();
22703a78d15Sespie 	  while (__first1 != __last1 && __first2 != __last2)
22803a78d15Sespie 	    if (*__first2 < *__first1)
22903a78d15Sespie 	      {
23003a78d15Sespie 		iterator __next = __first2;
23103a78d15Sespie 		_M_transfer(__first1, __first2, ++__next);
23203a78d15Sespie 		__first2 = __next;
23303a78d15Sespie 	      }
23403a78d15Sespie 	    else
23503a78d15Sespie 	      ++__first1;
23603a78d15Sespie 	  if (__first2 != __last2)
23703a78d15Sespie 	    _M_transfer(__last1, __first2, __last2);
23803a78d15Sespie 	}
239*19731d4fSespie     }
24003a78d15Sespie 
24103a78d15Sespie   // FIXME put this somewhere else
24203a78d15Sespie   inline void
__List_base_reverse(_List_node_base * __p)24303a78d15Sespie   __List_base_reverse(_List_node_base* __p)
24403a78d15Sespie   {
24503a78d15Sespie     _List_node_base* __tmp = __p;
24603a78d15Sespie     do {
24703a78d15Sespie       std::swap(__tmp->_M_next, __tmp->_M_prev);
24803a78d15Sespie       __tmp = __tmp->_M_prev;     // Old next node is now prev.
24903a78d15Sespie     } while (__tmp != __p);
25003a78d15Sespie   }
25103a78d15Sespie 
25203a78d15Sespie   template<typename _Tp, typename _Alloc>
25303a78d15Sespie     void
25403a78d15Sespie     list<_Tp,_Alloc>::
sort()25503a78d15Sespie     sort()
25603a78d15Sespie     {
25703a78d15Sespie       // Do nothing if the list has length 0 or 1.
25803a78d15Sespie       if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node)
25903a78d15Sespie       {
26003a78d15Sespie         list __carry;
26103a78d15Sespie         list __counter[64];
26203a78d15Sespie         int __fill = 0;
26303a78d15Sespie         while (!empty())
26403a78d15Sespie         {
26503a78d15Sespie           __carry.splice(__carry.begin(), *this, begin());
26603a78d15Sespie           int __i = 0;
26703a78d15Sespie           while(__i < __fill && !__counter[__i].empty())
26803a78d15Sespie           {
26903a78d15Sespie             __counter[__i].merge(__carry);
27003a78d15Sespie             __carry.swap(__counter[__i++]);
27103a78d15Sespie           }
27203a78d15Sespie           __carry.swap(__counter[__i]);
27303a78d15Sespie           if (__i == __fill) ++__fill;
27403a78d15Sespie         }
27503a78d15Sespie 
27603a78d15Sespie         for (int __i = 1; __i < __fill; ++__i)
27703a78d15Sespie           __counter[__i].merge(__counter[__i-1]);
27803a78d15Sespie         swap(__counter[__fill-1]);
27903a78d15Sespie       }
28003a78d15Sespie     }
28103a78d15Sespie 
28203a78d15Sespie   template<typename _Tp, typename _Alloc>
28303a78d15Sespie     template <typename _Predicate>
28403a78d15Sespie       void
28503a78d15Sespie       list<_Tp,_Alloc>::
remove_if(_Predicate __pred)28603a78d15Sespie       remove_if(_Predicate __pred)
28703a78d15Sespie       {
28803a78d15Sespie         iterator __first = begin();
28903a78d15Sespie         iterator __last = end();
29003a78d15Sespie         while (__first != __last)
29103a78d15Sespie         {
29203a78d15Sespie           iterator __next = __first;
29303a78d15Sespie           ++__next;
29403a78d15Sespie           if (__pred(*__first)) erase(__first);
29503a78d15Sespie           __first = __next;
29603a78d15Sespie         }
29703a78d15Sespie       }
29803a78d15Sespie 
29903a78d15Sespie   template<typename _Tp, typename _Alloc>
30003a78d15Sespie     template <typename _BinaryPredicate>
30103a78d15Sespie       void
30203a78d15Sespie       list<_Tp,_Alloc>::
unique(_BinaryPredicate __binary_pred)30303a78d15Sespie       unique(_BinaryPredicate __binary_pred)
30403a78d15Sespie       {
30503a78d15Sespie         iterator __first = begin();
30603a78d15Sespie         iterator __last = end();
30703a78d15Sespie         if (__first == __last) return;
30803a78d15Sespie         iterator __next = __first;
30903a78d15Sespie         while (++__next != __last)
31003a78d15Sespie         {
31103a78d15Sespie           if (__binary_pred(*__first, *__next))
31203a78d15Sespie             erase(__next);
31303a78d15Sespie           else
31403a78d15Sespie             __first = __next;
31503a78d15Sespie           __next = __first;
31603a78d15Sespie         }
31703a78d15Sespie       }
31803a78d15Sespie 
31903a78d15Sespie   template<typename _Tp, typename _Alloc>
32003a78d15Sespie     template <typename _StrictWeakOrdering>
32103a78d15Sespie       void
32203a78d15Sespie       list<_Tp,_Alloc>::
merge(list & __x,_StrictWeakOrdering __comp)32303a78d15Sespie       merge(list& __x, _StrictWeakOrdering __comp)
32403a78d15Sespie       {
325*19731d4fSespie 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
326*19731d4fSespie 	// 300. list::merge() specification incomplete
327*19731d4fSespie 	if (this != &__x)
328*19731d4fSespie 	  {
32903a78d15Sespie 	    iterator __first1 = begin();
33003a78d15Sespie 	    iterator __last1 = end();
33103a78d15Sespie 	    iterator __first2 = __x.begin();
33203a78d15Sespie 	    iterator __last2 = __x.end();
33303a78d15Sespie 	    while (__first1 != __last1 && __first2 != __last2)
33403a78d15Sespie 	      if (__comp(*__first2, *__first1))
33503a78d15Sespie 		{
33603a78d15Sespie 		  iterator __next = __first2;
33703a78d15Sespie 		  _M_transfer(__first1, __first2, ++__next);
33803a78d15Sespie 		  __first2 = __next;
33903a78d15Sespie 		}
34003a78d15Sespie 	      else
34103a78d15Sespie 		++__first1;
34203a78d15Sespie 	    if (__first2 != __last2) _M_transfer(__last1, __first2, __last2);
34303a78d15Sespie 	  }
344*19731d4fSespie       }
34503a78d15Sespie 
34603a78d15Sespie   template<typename _Tp, typename _Alloc>
34703a78d15Sespie     template <typename _StrictWeakOrdering>
34803a78d15Sespie     void
34903a78d15Sespie     list<_Tp,_Alloc>::
sort(_StrictWeakOrdering __comp)35003a78d15Sespie     sort(_StrictWeakOrdering __comp)
35103a78d15Sespie     {
35203a78d15Sespie       // Do nothing if the list has length 0 or 1.
35303a78d15Sespie       if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node)
35403a78d15Sespie       {
35503a78d15Sespie         list __carry;
35603a78d15Sespie         list __counter[64];
35703a78d15Sespie         int __fill = 0;
35803a78d15Sespie         while (!empty())
35903a78d15Sespie         {
36003a78d15Sespie           __carry.splice(__carry.begin(), *this, begin());
36103a78d15Sespie           int __i = 0;
36203a78d15Sespie           while(__i < __fill && !__counter[__i].empty())
36303a78d15Sespie           {
36403a78d15Sespie             __counter[__i].merge(__carry, __comp);
36503a78d15Sespie             __carry.swap(__counter[__i++]);
36603a78d15Sespie           }
36703a78d15Sespie           __carry.swap(__counter[__i]);
36803a78d15Sespie           if (__i == __fill) ++__fill;
36903a78d15Sespie         }
37003a78d15Sespie 
37103a78d15Sespie         for (int __i = 1; __i < __fill; ++__i)
37203a78d15Sespie           __counter[__i].merge(__counter[__i-1], __comp);
37303a78d15Sespie         swap(__counter[__fill-1]);
37403a78d15Sespie       }
37503a78d15Sespie     }
37603a78d15Sespie } // namespace std
37703a78d15Sespie 
37803a78d15Sespie #endif /* __GLIBCPP_INTERNAL_LIST_TCC */
379