xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/list.tcc (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj // List implementation (out of line) -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2001-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj /*
26*38fd1498Szrj  *
27*38fd1498Szrj  * Copyright (c) 1994
28*38fd1498Szrj  * Hewlett-Packard Company
29*38fd1498Szrj  *
30*38fd1498Szrj  * Permission to use, copy, modify, distribute and sell this software
31*38fd1498Szrj  * and its documentation for any purpose is hereby granted without fee,
32*38fd1498Szrj  * provided that the above copyright notice appear in all copies and
33*38fd1498Szrj  * that both that copyright notice and this permission notice appear
34*38fd1498Szrj  * in supporting documentation.  Hewlett-Packard Company makes no
35*38fd1498Szrj  * representations about the suitability of this software for any
36*38fd1498Szrj  * purpose.  It is provided "as is" without express or implied warranty.
37*38fd1498Szrj  *
38*38fd1498Szrj  *
39*38fd1498Szrj  * Copyright (c) 1996,1997
40*38fd1498Szrj  * Silicon Graphics Computer Systems, Inc.
41*38fd1498Szrj  *
42*38fd1498Szrj  * Permission to use, copy, modify, distribute and sell this software
43*38fd1498Szrj  * and its documentation for any purpose is hereby granted without fee,
44*38fd1498Szrj  * provided that the above copyright notice appear in all copies and
45*38fd1498Szrj  * that both that copyright notice and this permission notice appear
46*38fd1498Szrj  * in supporting documentation.  Silicon Graphics makes no
47*38fd1498Szrj  * representations about the suitability of this software for any
48*38fd1498Szrj  * purpose.  It is provided "as is" without express or implied warranty.
49*38fd1498Szrj  */
50*38fd1498Szrj 
51*38fd1498Szrj /** @file bits/list.tcc
52*38fd1498Szrj  *  This is an internal header file, included by other library headers.
53*38fd1498Szrj  *  Do not attempt to use it directly. @headername{list}
54*38fd1498Szrj  */
55*38fd1498Szrj 
56*38fd1498Szrj #ifndef _LIST_TCC
57*38fd1498Szrj #define _LIST_TCC 1
58*38fd1498Szrj 
59*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
60*38fd1498Szrj {
61*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
62*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
63*38fd1498Szrj 
64*38fd1498Szrj   template<typename _Tp, typename _Alloc>
65*38fd1498Szrj     void
66*38fd1498Szrj     _List_base<_Tp, _Alloc>::
_M_clear()67*38fd1498Szrj     _M_clear() _GLIBCXX_NOEXCEPT
68*38fd1498Szrj     {
69*38fd1498Szrj       typedef _List_node<_Tp>  _Node;
70*38fd1498Szrj       __detail::_List_node_base* __cur = _M_impl._M_node._M_next;
71*38fd1498Szrj       while (__cur != &_M_impl._M_node)
72*38fd1498Szrj 	{
73*38fd1498Szrj 	  _Node* __tmp = static_cast<_Node*>(__cur);
74*38fd1498Szrj 	  __cur = __tmp->_M_next;
75*38fd1498Szrj 	  _Tp* __val = __tmp->_M_valptr();
76*38fd1498Szrj #if __cplusplus >= 201103L
77*38fd1498Szrj 	  _Node_alloc_traits::destroy(_M_get_Node_allocator(), __val);
78*38fd1498Szrj #else
79*38fd1498Szrj 	  _Tp_alloc_type(_M_get_Node_allocator()).destroy(__val);
80*38fd1498Szrj #endif
81*38fd1498Szrj 	  _M_put_node(__tmp);
82*38fd1498Szrj 	}
83*38fd1498Szrj     }
84*38fd1498Szrj 
85*38fd1498Szrj #if __cplusplus >= 201103L
86*38fd1498Szrj   template<typename _Tp, typename _Alloc>
87*38fd1498Szrj     template<typename... _Args>
88*38fd1498Szrj       typename list<_Tp, _Alloc>::iterator
89*38fd1498Szrj       list<_Tp, _Alloc>::
emplace(const_iterator __position,_Args &&...__args)90*38fd1498Szrj       emplace(const_iterator __position, _Args&&... __args)
91*38fd1498Szrj       {
92*38fd1498Szrj 	_Node* __tmp = _M_create_node(std::forward<_Args>(__args)...);
93*38fd1498Szrj 	__tmp->_M_hook(__position._M_const_cast()._M_node);
94*38fd1498Szrj 	this->_M_inc_size(1);
95*38fd1498Szrj 	return iterator(__tmp);
96*38fd1498Szrj       }
97*38fd1498Szrj #endif
98*38fd1498Szrj 
99*38fd1498Szrj   template<typename _Tp, typename _Alloc>
100*38fd1498Szrj     typename list<_Tp, _Alloc>::iterator
101*38fd1498Szrj     list<_Tp, _Alloc>::
102*38fd1498Szrj #if __cplusplus >= 201103L
insert(const_iterator __position,const value_type & __x)103*38fd1498Szrj     insert(const_iterator __position, const value_type& __x)
104*38fd1498Szrj #else
105*38fd1498Szrj     insert(iterator __position, const value_type& __x)
106*38fd1498Szrj #endif
107*38fd1498Szrj     {
108*38fd1498Szrj       _Node* __tmp = _M_create_node(__x);
109*38fd1498Szrj       __tmp->_M_hook(__position._M_const_cast()._M_node);
110*38fd1498Szrj       this->_M_inc_size(1);
111*38fd1498Szrj       return iterator(__tmp);
112*38fd1498Szrj     }
113*38fd1498Szrj 
114*38fd1498Szrj #if __cplusplus >= 201103L
115*38fd1498Szrj   template<typename _Tp, typename _Alloc>
116*38fd1498Szrj     typename list<_Tp, _Alloc>::iterator
117*38fd1498Szrj     list<_Tp, _Alloc>::
insert(const_iterator __position,size_type __n,const value_type & __x)118*38fd1498Szrj     insert(const_iterator __position, size_type __n, const value_type& __x)
119*38fd1498Szrj     {
120*38fd1498Szrj       if (__n)
121*38fd1498Szrj 	{
122*38fd1498Szrj 	  list __tmp(__n, __x, get_allocator());
123*38fd1498Szrj 	  iterator __it = __tmp.begin();
124*38fd1498Szrj 	  splice(__position, __tmp);
125*38fd1498Szrj 	  return __it;
126*38fd1498Szrj 	}
127*38fd1498Szrj       return __position._M_const_cast();
128*38fd1498Szrj     }
129*38fd1498Szrj 
130*38fd1498Szrj   template<typename _Tp, typename _Alloc>
131*38fd1498Szrj     template<typename _InputIterator, typename>
132*38fd1498Szrj       typename list<_Tp, _Alloc>::iterator
133*38fd1498Szrj       list<_Tp, _Alloc>::
insert(const_iterator __position,_InputIterator __first,_InputIterator __last)134*38fd1498Szrj       insert(const_iterator __position, _InputIterator __first,
135*38fd1498Szrj 	     _InputIterator __last)
136*38fd1498Szrj       {
137*38fd1498Szrj 	list __tmp(__first, __last, get_allocator());
138*38fd1498Szrj 	if (!__tmp.empty())
139*38fd1498Szrj 	  {
140*38fd1498Szrj 	    iterator __it = __tmp.begin();
141*38fd1498Szrj 	    splice(__position, __tmp);
142*38fd1498Szrj 	    return __it;
143*38fd1498Szrj 	  }
144*38fd1498Szrj 	return __position._M_const_cast();
145*38fd1498Szrj       }
146*38fd1498Szrj #endif
147*38fd1498Szrj 
148*38fd1498Szrj   template<typename _Tp, typename _Alloc>
149*38fd1498Szrj     typename list<_Tp, _Alloc>::iterator
150*38fd1498Szrj     list<_Tp, _Alloc>::
151*38fd1498Szrj #if __cplusplus >= 201103L
erase(const_iterator __position)152*38fd1498Szrj     erase(const_iterator __position) noexcept
153*38fd1498Szrj #else
154*38fd1498Szrj     erase(iterator __position)
155*38fd1498Szrj #endif
156*38fd1498Szrj     {
157*38fd1498Szrj       iterator __ret = iterator(__position._M_node->_M_next);
158*38fd1498Szrj       _M_erase(__position._M_const_cast());
159*38fd1498Szrj       return __ret;
160*38fd1498Szrj     }
161*38fd1498Szrj 
162*38fd1498Szrj   // Return a const_iterator indicating the position to start inserting or
163*38fd1498Szrj   // erasing elements (depending whether the list is growing or shrinking),
164*38fd1498Szrj   // and set __new_size to the number of new elements that must be appended.
165*38fd1498Szrj   // Equivalent to the following, but performed optimally:
166*38fd1498Szrj   // if (__new_size < size()) {
167*38fd1498Szrj   //   __new_size = 0;
168*38fd1498Szrj   //   return std::next(begin(), __new_size);
169*38fd1498Szrj   // } else {
170*38fd1498Szrj   //   __newsize -= size();
171*38fd1498Szrj   //   return end();
172*38fd1498Szrj   // }
173*38fd1498Szrj   template<typename _Tp, typename _Alloc>
174*38fd1498Szrj     typename list<_Tp, _Alloc>::const_iterator
175*38fd1498Szrj     list<_Tp, _Alloc>::
_M_resize_pos(size_type & __new_size) const176*38fd1498Szrj     _M_resize_pos(size_type& __new_size) const
177*38fd1498Szrj     {
178*38fd1498Szrj       const_iterator __i;
179*38fd1498Szrj #if _GLIBCXX_USE_CXX11_ABI
180*38fd1498Szrj       const size_type __len = size();
181*38fd1498Szrj       if (__new_size < __len)
182*38fd1498Szrj 	{
183*38fd1498Szrj 	  if (__new_size <= __len / 2)
184*38fd1498Szrj 	    {
185*38fd1498Szrj 	      __i = begin();
186*38fd1498Szrj 	      std::advance(__i, __new_size);
187*38fd1498Szrj 	    }
188*38fd1498Szrj 	  else
189*38fd1498Szrj 	    {
190*38fd1498Szrj 	      __i = end();
191*38fd1498Szrj 	      ptrdiff_t __num_erase = __len - __new_size;
192*38fd1498Szrj 	      std::advance(__i, -__num_erase);
193*38fd1498Szrj 	    }
194*38fd1498Szrj 	  __new_size = 0;
195*38fd1498Szrj 	  return __i;
196*38fd1498Szrj 	}
197*38fd1498Szrj       else
198*38fd1498Szrj 	__i = end();
199*38fd1498Szrj #else
200*38fd1498Szrj       size_type __len = 0;
201*38fd1498Szrj       for (__i = begin(); __i != end() && __len < __new_size; ++__i, ++__len)
202*38fd1498Szrj         ;
203*38fd1498Szrj #endif
204*38fd1498Szrj       __new_size -= __len;
205*38fd1498Szrj       return __i;
206*38fd1498Szrj     }
207*38fd1498Szrj 
208*38fd1498Szrj #if __cplusplus >= 201103L
209*38fd1498Szrj   template<typename _Tp, typename _Alloc>
210*38fd1498Szrj     void
211*38fd1498Szrj     list<_Tp, _Alloc>::
_M_default_append(size_type __n)212*38fd1498Szrj     _M_default_append(size_type __n)
213*38fd1498Szrj     {
214*38fd1498Szrj       size_type __i = 0;
215*38fd1498Szrj       __try
216*38fd1498Szrj 	{
217*38fd1498Szrj 	  for (; __i < __n; ++__i)
218*38fd1498Szrj 	    emplace_back();
219*38fd1498Szrj 	}
220*38fd1498Szrj       __catch(...)
221*38fd1498Szrj 	{
222*38fd1498Szrj 	  for (; __i; --__i)
223*38fd1498Szrj 	    pop_back();
224*38fd1498Szrj 	  __throw_exception_again;
225*38fd1498Szrj 	}
226*38fd1498Szrj     }
227*38fd1498Szrj 
228*38fd1498Szrj   template<typename _Tp, typename _Alloc>
229*38fd1498Szrj     void
230*38fd1498Szrj     list<_Tp, _Alloc>::
resize(size_type __new_size)231*38fd1498Szrj     resize(size_type __new_size)
232*38fd1498Szrj     {
233*38fd1498Szrj       const_iterator __i = _M_resize_pos(__new_size);
234*38fd1498Szrj       if (__new_size)
235*38fd1498Szrj 	_M_default_append(__new_size);
236*38fd1498Szrj       else
237*38fd1498Szrj         erase(__i, end());
238*38fd1498Szrj     }
239*38fd1498Szrj 
240*38fd1498Szrj   template<typename _Tp, typename _Alloc>
241*38fd1498Szrj     void
242*38fd1498Szrj     list<_Tp, _Alloc>::
resize(size_type __new_size,const value_type & __x)243*38fd1498Szrj     resize(size_type __new_size, const value_type& __x)
244*38fd1498Szrj     {
245*38fd1498Szrj       const_iterator __i = _M_resize_pos(__new_size);
246*38fd1498Szrj       if (__new_size)
247*38fd1498Szrj         insert(end(), __new_size, __x);
248*38fd1498Szrj       else
249*38fd1498Szrj         erase(__i, end());
250*38fd1498Szrj     }
251*38fd1498Szrj #else
252*38fd1498Szrj   template<typename _Tp, typename _Alloc>
253*38fd1498Szrj     void
254*38fd1498Szrj     list<_Tp, _Alloc>::
resize(size_type __new_size,value_type __x)255*38fd1498Szrj     resize(size_type __new_size, value_type __x)
256*38fd1498Szrj     {
257*38fd1498Szrj       const_iterator __i = _M_resize_pos(__new_size);
258*38fd1498Szrj       if (__new_size)
259*38fd1498Szrj         insert(end(), __new_size, __x);
260*38fd1498Szrj       else
261*38fd1498Szrj         erase(__i._M_const_cast(), end());
262*38fd1498Szrj     }
263*38fd1498Szrj #endif
264*38fd1498Szrj 
265*38fd1498Szrj   template<typename _Tp, typename _Alloc>
266*38fd1498Szrj     list<_Tp, _Alloc>&
267*38fd1498Szrj     list<_Tp, _Alloc>::
operator =(const list & __x)268*38fd1498Szrj     operator=(const list& __x)
269*38fd1498Szrj     {
270*38fd1498Szrj       if (this != std::__addressof(__x))
271*38fd1498Szrj 	{
272*38fd1498Szrj #if __cplusplus >= 201103L
273*38fd1498Szrj 	  if (_Node_alloc_traits::_S_propagate_on_copy_assign())
274*38fd1498Szrj 	    {
275*38fd1498Szrj               auto& __this_alloc = this->_M_get_Node_allocator();
276*38fd1498Szrj               auto& __that_alloc = __x._M_get_Node_allocator();
277*38fd1498Szrj               if (!_Node_alloc_traits::_S_always_equal()
278*38fd1498Szrj 	          && __this_alloc != __that_alloc)
279*38fd1498Szrj 	        {
280*38fd1498Szrj 		  // replacement allocator cannot free existing storage
281*38fd1498Szrj 		  clear();
282*38fd1498Szrj 		}
283*38fd1498Szrj 	      std::__alloc_on_copy(__this_alloc, __that_alloc);
284*38fd1498Szrj             }
285*38fd1498Szrj #endif
286*38fd1498Szrj 	  _M_assign_dispatch(__x.begin(), __x.end(), __false_type());
287*38fd1498Szrj 	}
288*38fd1498Szrj       return *this;
289*38fd1498Szrj     }
290*38fd1498Szrj 
291*38fd1498Szrj   template<typename _Tp, typename _Alloc>
292*38fd1498Szrj     void
293*38fd1498Szrj     list<_Tp, _Alloc>::
_M_fill_assign(size_type __n,const value_type & __val)294*38fd1498Szrj     _M_fill_assign(size_type __n, const value_type& __val)
295*38fd1498Szrj     {
296*38fd1498Szrj       iterator __i = begin();
297*38fd1498Szrj       for (; __i != end() && __n > 0; ++__i, --__n)
298*38fd1498Szrj         *__i = __val;
299*38fd1498Szrj       if (__n > 0)
300*38fd1498Szrj         insert(end(), __n, __val);
301*38fd1498Szrj       else
302*38fd1498Szrj         erase(__i, end());
303*38fd1498Szrj     }
304*38fd1498Szrj 
305*38fd1498Szrj   template<typename _Tp, typename _Alloc>
306*38fd1498Szrj     template <typename _InputIterator>
307*38fd1498Szrj       void
308*38fd1498Szrj       list<_Tp, _Alloc>::
_M_assign_dispatch(_InputIterator __first2,_InputIterator __last2,__false_type)309*38fd1498Szrj       _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2,
310*38fd1498Szrj 			 __false_type)
311*38fd1498Szrj       {
312*38fd1498Szrj         iterator __first1 = begin();
313*38fd1498Szrj         iterator __last1 = end();
314*38fd1498Szrj         for (; __first1 != __last1 && __first2 != __last2;
315*38fd1498Szrj 	     ++__first1, ++__first2)
316*38fd1498Szrj           *__first1 = *__first2;
317*38fd1498Szrj         if (__first2 == __last2)
318*38fd1498Szrj           erase(__first1, __last1);
319*38fd1498Szrj         else
320*38fd1498Szrj           insert(__last1, __first2, __last2);
321*38fd1498Szrj       }
322*38fd1498Szrj 
323*38fd1498Szrj   template<typename _Tp, typename _Alloc>
324*38fd1498Szrj     void
325*38fd1498Szrj     list<_Tp, _Alloc>::
remove(const value_type & __value)326*38fd1498Szrj     remove(const value_type& __value)
327*38fd1498Szrj     {
328*38fd1498Szrj       iterator __first = begin();
329*38fd1498Szrj       iterator __last = end();
330*38fd1498Szrj       iterator __extra = __last;
331*38fd1498Szrj       while (__first != __last)
332*38fd1498Szrj 	{
333*38fd1498Szrj 	  iterator __next = __first;
334*38fd1498Szrj 	  ++__next;
335*38fd1498Szrj 	  if (*__first == __value)
336*38fd1498Szrj 	    {
337*38fd1498Szrj 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
338*38fd1498Szrj 	      // 526. Is it undefined if a function in the standard changes
339*38fd1498Szrj 	      // in parameters?
340*38fd1498Szrj 	      if (std::__addressof(*__first) != std::__addressof(__value))
341*38fd1498Szrj 		_M_erase(__first);
342*38fd1498Szrj 	      else
343*38fd1498Szrj 		__extra = __first;
344*38fd1498Szrj 	    }
345*38fd1498Szrj 	  __first = __next;
346*38fd1498Szrj 	}
347*38fd1498Szrj       if (__extra != __last)
348*38fd1498Szrj 	_M_erase(__extra);
349*38fd1498Szrj     }
350*38fd1498Szrj 
351*38fd1498Szrj   template<typename _Tp, typename _Alloc>
352*38fd1498Szrj     void
353*38fd1498Szrj     list<_Tp, _Alloc>::
unique()354*38fd1498Szrj     unique()
355*38fd1498Szrj     {
356*38fd1498Szrj       iterator __first = begin();
357*38fd1498Szrj       iterator __last = end();
358*38fd1498Szrj       if (__first == __last)
359*38fd1498Szrj 	return;
360*38fd1498Szrj       iterator __next = __first;
361*38fd1498Szrj       while (++__next != __last)
362*38fd1498Szrj 	{
363*38fd1498Szrj 	  if (*__first == *__next)
364*38fd1498Szrj 	    _M_erase(__next);
365*38fd1498Szrj 	  else
366*38fd1498Szrj 	    __first = __next;
367*38fd1498Szrj 	  __next = __first;
368*38fd1498Szrj 	}
369*38fd1498Szrj     }
370*38fd1498Szrj 
371*38fd1498Szrj   template<typename _Tp, typename _Alloc>
372*38fd1498Szrj     void
373*38fd1498Szrj     list<_Tp, _Alloc>::
374*38fd1498Szrj #if __cplusplus >= 201103L
merge(list && __x)375*38fd1498Szrj     merge(list&& __x)
376*38fd1498Szrj #else
377*38fd1498Szrj     merge(list& __x)
378*38fd1498Szrj #endif
379*38fd1498Szrj     {
380*38fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
381*38fd1498Szrj       // 300. list::merge() specification incomplete
382*38fd1498Szrj       if (this != std::__addressof(__x))
383*38fd1498Szrj 	{
384*38fd1498Szrj 	  _M_check_equal_allocators(__x);
385*38fd1498Szrj 
386*38fd1498Szrj 	  iterator __first1 = begin();
387*38fd1498Szrj 	  iterator __last1 = end();
388*38fd1498Szrj 	  iterator __first2 = __x.begin();
389*38fd1498Szrj 	  iterator __last2 = __x.end();
390*38fd1498Szrj 	  const size_t __orig_size = __x.size();
391*38fd1498Szrj 	  __try {
392*38fd1498Szrj 	    while (__first1 != __last1 && __first2 != __last2)
393*38fd1498Szrj 	      if (*__first2 < *__first1)
394*38fd1498Szrj 		{
395*38fd1498Szrj 		  iterator __next = __first2;
396*38fd1498Szrj 		  _M_transfer(__first1, __first2, ++__next);
397*38fd1498Szrj 		  __first2 = __next;
398*38fd1498Szrj 		}
399*38fd1498Szrj 	      else
400*38fd1498Szrj 		++__first1;
401*38fd1498Szrj 	    if (__first2 != __last2)
402*38fd1498Szrj 	      _M_transfer(__last1, __first2, __last2);
403*38fd1498Szrj 
404*38fd1498Szrj 	    this->_M_inc_size(__x._M_get_size());
405*38fd1498Szrj 	    __x._M_set_size(0);
406*38fd1498Szrj 	  }
407*38fd1498Szrj 	  __catch(...)
408*38fd1498Szrj 	    {
409*38fd1498Szrj 	      const size_t __dist = std::distance(__first2, __last2);
410*38fd1498Szrj 	      this->_M_inc_size(__orig_size - __dist);
411*38fd1498Szrj 	      __x._M_set_size(__dist);
412*38fd1498Szrj 	      __throw_exception_again;
413*38fd1498Szrj 	    }
414*38fd1498Szrj 	}
415*38fd1498Szrj     }
416*38fd1498Szrj 
417*38fd1498Szrj   template<typename _Tp, typename _Alloc>
418*38fd1498Szrj     template <typename _StrictWeakOrdering>
419*38fd1498Szrj       void
420*38fd1498Szrj       list<_Tp, _Alloc>::
421*38fd1498Szrj #if __cplusplus >= 201103L
merge(list && __x,_StrictWeakOrdering __comp)422*38fd1498Szrj       merge(list&& __x, _StrictWeakOrdering __comp)
423*38fd1498Szrj #else
424*38fd1498Szrj       merge(list& __x, _StrictWeakOrdering __comp)
425*38fd1498Szrj #endif
426*38fd1498Szrj       {
427*38fd1498Szrj 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
428*38fd1498Szrj 	// 300. list::merge() specification incomplete
429*38fd1498Szrj 	if (this != std::__addressof(__x))
430*38fd1498Szrj 	  {
431*38fd1498Szrj 	    _M_check_equal_allocators(__x);
432*38fd1498Szrj 
433*38fd1498Szrj 	    iterator __first1 = begin();
434*38fd1498Szrj 	    iterator __last1 = end();
435*38fd1498Szrj 	    iterator __first2 = __x.begin();
436*38fd1498Szrj 	    iterator __last2 = __x.end();
437*38fd1498Szrj 	    const size_t __orig_size = __x.size();
438*38fd1498Szrj 	    __try
439*38fd1498Szrj 	      {
440*38fd1498Szrj 		while (__first1 != __last1 && __first2 != __last2)
441*38fd1498Szrj 		  if (__comp(*__first2, *__first1))
442*38fd1498Szrj 		    {
443*38fd1498Szrj 		      iterator __next = __first2;
444*38fd1498Szrj 		      _M_transfer(__first1, __first2, ++__next);
445*38fd1498Szrj 		      __first2 = __next;
446*38fd1498Szrj 		    }
447*38fd1498Szrj 		  else
448*38fd1498Szrj 		    ++__first1;
449*38fd1498Szrj 		if (__first2 != __last2)
450*38fd1498Szrj 		  _M_transfer(__last1, __first2, __last2);
451*38fd1498Szrj 
452*38fd1498Szrj 		this->_M_inc_size(__x._M_get_size());
453*38fd1498Szrj 		__x._M_set_size(0);
454*38fd1498Szrj 	      }
455*38fd1498Szrj 	    __catch(...)
456*38fd1498Szrj 	      {
457*38fd1498Szrj 		const size_t __dist = std::distance(__first2, __last2);
458*38fd1498Szrj 		this->_M_inc_size(__orig_size - __dist);
459*38fd1498Szrj 		__x._M_set_size(__dist);
460*38fd1498Szrj 		__throw_exception_again;
461*38fd1498Szrj 	      }
462*38fd1498Szrj 	  }
463*38fd1498Szrj       }
464*38fd1498Szrj 
465*38fd1498Szrj   template<typename _Tp, typename _Alloc>
466*38fd1498Szrj     void
467*38fd1498Szrj     list<_Tp, _Alloc>::
sort()468*38fd1498Szrj     sort()
469*38fd1498Szrj     {
470*38fd1498Szrj       // Do nothing if the list has length 0 or 1.
471*38fd1498Szrj       if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
472*38fd1498Szrj 	  && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
473*38fd1498Szrj       {
474*38fd1498Szrj         list __carry;
475*38fd1498Szrj         list __tmp[64];
476*38fd1498Szrj         list * __fill = __tmp;
477*38fd1498Szrj         list * __counter;
478*38fd1498Szrj 	__try
479*38fd1498Szrj 	  {
480*38fd1498Szrj 	    do
481*38fd1498Szrj 	      {
482*38fd1498Szrj 		__carry.splice(__carry.begin(), *this, begin());
483*38fd1498Szrj 
484*38fd1498Szrj 		for(__counter = __tmp;
485*38fd1498Szrj 		    __counter != __fill && !__counter->empty();
486*38fd1498Szrj 		    ++__counter)
487*38fd1498Szrj 		  {
488*38fd1498Szrj 		    __counter->merge(__carry);
489*38fd1498Szrj 		    __carry.swap(*__counter);
490*38fd1498Szrj 		  }
491*38fd1498Szrj 		__carry.swap(*__counter);
492*38fd1498Szrj 		if (__counter == __fill)
493*38fd1498Szrj 		  ++__fill;
494*38fd1498Szrj 	      }
495*38fd1498Szrj 	    while ( !empty() );
496*38fd1498Szrj 
497*38fd1498Szrj 	    for (__counter = __tmp + 1; __counter != __fill; ++__counter)
498*38fd1498Szrj 	      __counter->merge(*(__counter - 1));
499*38fd1498Szrj 	    swap( *(__fill - 1) );
500*38fd1498Szrj 	  }
501*38fd1498Szrj 	__catch(...)
502*38fd1498Szrj 	  {
503*38fd1498Szrj 	    this->splice(this->end(), __carry);
504*38fd1498Szrj 	    for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i)
505*38fd1498Szrj 	      this->splice(this->end(), __tmp[__i]);
506*38fd1498Szrj 	    __throw_exception_again;
507*38fd1498Szrj 	  }
508*38fd1498Szrj       }
509*38fd1498Szrj     }
510*38fd1498Szrj 
511*38fd1498Szrj   template<typename _Tp, typename _Alloc>
512*38fd1498Szrj     template <typename _Predicate>
513*38fd1498Szrj       void
514*38fd1498Szrj       list<_Tp, _Alloc>::
remove_if(_Predicate __pred)515*38fd1498Szrj       remove_if(_Predicate __pred)
516*38fd1498Szrj       {
517*38fd1498Szrj         iterator __first = begin();
518*38fd1498Szrj         iterator __last = end();
519*38fd1498Szrj         while (__first != __last)
520*38fd1498Szrj 	  {
521*38fd1498Szrj 	    iterator __next = __first;
522*38fd1498Szrj 	    ++__next;
523*38fd1498Szrj 	    if (__pred(*__first))
524*38fd1498Szrj 	      _M_erase(__first);
525*38fd1498Szrj 	    __first = __next;
526*38fd1498Szrj 	  }
527*38fd1498Szrj       }
528*38fd1498Szrj 
529*38fd1498Szrj   template<typename _Tp, typename _Alloc>
530*38fd1498Szrj     template <typename _BinaryPredicate>
531*38fd1498Szrj       void
532*38fd1498Szrj       list<_Tp, _Alloc>::
unique(_BinaryPredicate __binary_pred)533*38fd1498Szrj       unique(_BinaryPredicate __binary_pred)
534*38fd1498Szrj       {
535*38fd1498Szrj         iterator __first = begin();
536*38fd1498Szrj         iterator __last = end();
537*38fd1498Szrj         if (__first == __last)
538*38fd1498Szrj 	  return;
539*38fd1498Szrj         iterator __next = __first;
540*38fd1498Szrj         while (++__next != __last)
541*38fd1498Szrj 	  {
542*38fd1498Szrj 	    if (__binary_pred(*__first, *__next))
543*38fd1498Szrj 	      _M_erase(__next);
544*38fd1498Szrj 	    else
545*38fd1498Szrj 	      __first = __next;
546*38fd1498Szrj 	    __next = __first;
547*38fd1498Szrj 	  }
548*38fd1498Szrj       }
549*38fd1498Szrj 
550*38fd1498Szrj   template<typename _Tp, typename _Alloc>
551*38fd1498Szrj     template <typename _StrictWeakOrdering>
552*38fd1498Szrj       void
553*38fd1498Szrj       list<_Tp, _Alloc>::
sort(_StrictWeakOrdering __comp)554*38fd1498Szrj       sort(_StrictWeakOrdering __comp)
555*38fd1498Szrj       {
556*38fd1498Szrj 	// Do nothing if the list has length 0 or 1.
557*38fd1498Szrj 	if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
558*38fd1498Szrj 	    && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
559*38fd1498Szrj 	  {
560*38fd1498Szrj 	    list __carry;
561*38fd1498Szrj 	    list __tmp[64];
562*38fd1498Szrj 	    list * __fill = __tmp;
563*38fd1498Szrj 	    list * __counter;
564*38fd1498Szrj 	    __try
565*38fd1498Szrj 	      {
566*38fd1498Szrj 		do
567*38fd1498Szrj 		  {
568*38fd1498Szrj 		    __carry.splice(__carry.begin(), *this, begin());
569*38fd1498Szrj 
570*38fd1498Szrj 		    for(__counter = __tmp;
571*38fd1498Szrj 			__counter != __fill && !__counter->empty();
572*38fd1498Szrj 			++__counter)
573*38fd1498Szrj 		      {
574*38fd1498Szrj 			__counter->merge(__carry, __comp);
575*38fd1498Szrj 			__carry.swap(*__counter);
576*38fd1498Szrj 		      }
577*38fd1498Szrj 		    __carry.swap(*__counter);
578*38fd1498Szrj 		    if (__counter == __fill)
579*38fd1498Szrj 		      ++__fill;
580*38fd1498Szrj 		  }
581*38fd1498Szrj 		while ( !empty() );
582*38fd1498Szrj 
583*38fd1498Szrj 		for (__counter = __tmp + 1; __counter != __fill; ++__counter)
584*38fd1498Szrj 		  __counter->merge(*(__counter - 1), __comp);
585*38fd1498Szrj 		swap(*(__fill - 1));
586*38fd1498Szrj 	      }
587*38fd1498Szrj 	    __catch(...)
588*38fd1498Szrj 	      {
589*38fd1498Szrj 		this->splice(this->end(), __carry);
590*38fd1498Szrj 		for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i)
591*38fd1498Szrj 		  this->splice(this->end(), __tmp[__i]);
592*38fd1498Szrj 		__throw_exception_again;
593*38fd1498Szrj 	      }
594*38fd1498Szrj 	  }
595*38fd1498Szrj       }
596*38fd1498Szrj 
597*38fd1498Szrj _GLIBCXX_END_NAMESPACE_CONTAINER
598*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
599*38fd1498Szrj } // namespace std
600*38fd1498Szrj 
601*38fd1498Szrj #endif /* _LIST_TCC */
602*38fd1498Szrj 
603