xref: /openbsd-src/gnu/gcc/libstdc++-v3/include/ext/slist (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert// Singly-linked list implementation -*- C++ -*-
2*404b540aSrobert
3*404b540aSrobert// Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
4*404b540aSrobert//
5*404b540aSrobert// This file is part of the GNU ISO C++ Library.  This library is free
6*404b540aSrobert// software; you can redistribute it and/or modify it under the
7*404b540aSrobert// terms of the GNU General Public License as published by the
8*404b540aSrobert// Free Software Foundation; either version 2, or (at your option)
9*404b540aSrobert// any later version.
10*404b540aSrobert
11*404b540aSrobert// This library is distributed in the hope that it will be useful,
12*404b540aSrobert// but WITHOUT ANY WARRANTY; without even the implied warranty of
13*404b540aSrobert// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*404b540aSrobert// GNU General Public License for more details.
15*404b540aSrobert
16*404b540aSrobert// You should have received a copy of the GNU General Public License along
17*404b540aSrobert// with this library; see the file COPYING.  If not, write to the Free
18*404b540aSrobert// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19*404b540aSrobert// USA.
20*404b540aSrobert
21*404b540aSrobert// As a special exception, you may use this file as part of a free software
22*404b540aSrobert// library without restriction.  Specifically, if other files instantiate
23*404b540aSrobert// templates or use macros or inline functions from this file, or you compile
24*404b540aSrobert// this file and link it with other files to produce an executable, this
25*404b540aSrobert// file does not by itself cause the resulting executable to be covered by
26*404b540aSrobert// the GNU General Public License.  This exception does not however
27*404b540aSrobert// invalidate any other reasons why the executable file might be covered by
28*404b540aSrobert// the GNU General Public License.
29*404b540aSrobert
30*404b540aSrobert/*
31*404b540aSrobert * Copyright (c) 1997
32*404b540aSrobert * Silicon Graphics Computer Systems, Inc.
33*404b540aSrobert *
34*404b540aSrobert * Permission to use, copy, modify, distribute and sell this software
35*404b540aSrobert * and its documentation for any purpose is hereby granted without fee,
36*404b540aSrobert * provided that the above copyright notice appear in all copies and
37*404b540aSrobert * that both that copyright notice and this permission notice appear
38*404b540aSrobert * in supporting documentation.  Silicon Graphics makes no
39*404b540aSrobert * representations about the suitability of this software for any
40*404b540aSrobert * purpose.  It is provided "as is" without express or implied warranty.
41*404b540aSrobert *
42*404b540aSrobert */
43*404b540aSrobert
44*404b540aSrobert/** @file ext/slist
45*404b540aSrobert *  This file is a GNU extension to the Standard C++ Library (possibly
46*404b540aSrobert *  containing extensions from the HP/SGI STL subset).
47*404b540aSrobert */
48*404b540aSrobert
49*404b540aSrobert#ifndef _SLIST
50*404b540aSrobert#define _SLIST 1
51*404b540aSrobert
52*404b540aSrobert#include <bits/stl_algobase.h>
53*404b540aSrobert#include <bits/allocator.h>
54*404b540aSrobert#include <bits/stl_construct.h>
55*404b540aSrobert#include <bits/stl_uninitialized.h>
56*404b540aSrobert#include <bits/concept_check.h>
57*404b540aSrobert
58*404b540aSrobert_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
59*404b540aSrobert
60*404b540aSrobert  using std::size_t;
61*404b540aSrobert  using std::ptrdiff_t;
62*404b540aSrobert  using std::_Construct;
63*404b540aSrobert  using std::_Destroy;
64*404b540aSrobert  using std::allocator;
65*404b540aSrobert  using std::__true_type;
66*404b540aSrobert  using std::__false_type;
67*404b540aSrobert
68*404b540aSrobert  struct _Slist_node_base
69*404b540aSrobert  {
70*404b540aSrobert    _Slist_node_base* _M_next;
71*404b540aSrobert  };
72*404b540aSrobert
73*404b540aSrobert  inline _Slist_node_base*
74*404b540aSrobert  __slist_make_link(_Slist_node_base* __prev_node,
75*404b540aSrobert		    _Slist_node_base* __new_node)
76*404b540aSrobert  {
77*404b540aSrobert    __new_node->_M_next = __prev_node->_M_next;
78*404b540aSrobert    __prev_node->_M_next = __new_node;
79*404b540aSrobert    return __new_node;
80*404b540aSrobert  }
81*404b540aSrobert
82*404b540aSrobert  inline _Slist_node_base*
83*404b540aSrobert  __slist_previous(_Slist_node_base* __head,
84*404b540aSrobert		   const _Slist_node_base* __node)
85*404b540aSrobert  {
86*404b540aSrobert    while (__head && __head->_M_next != __node)
87*404b540aSrobert      __head = __head->_M_next;
88*404b540aSrobert    return __head;
89*404b540aSrobert  }
90*404b540aSrobert
91*404b540aSrobert  inline const _Slist_node_base*
92*404b540aSrobert  __slist_previous(const _Slist_node_base* __head,
93*404b540aSrobert		   const _Slist_node_base* __node)
94*404b540aSrobert  {
95*404b540aSrobert    while (__head && __head->_M_next != __node)
96*404b540aSrobert      __head = __head->_M_next;
97*404b540aSrobert    return __head;
98*404b540aSrobert  }
99*404b540aSrobert
100*404b540aSrobert  inline void
101*404b540aSrobert  __slist_splice_after(_Slist_node_base* __pos,
102*404b540aSrobert		       _Slist_node_base* __before_first,
103*404b540aSrobert		       _Slist_node_base* __before_last)
104*404b540aSrobert  {
105*404b540aSrobert    if (__pos != __before_first && __pos != __before_last)
106*404b540aSrobert      {
107*404b540aSrobert	_Slist_node_base* __first = __before_first->_M_next;
108*404b540aSrobert	_Slist_node_base* __after = __pos->_M_next;
109*404b540aSrobert	__before_first->_M_next = __before_last->_M_next;
110*404b540aSrobert	__pos->_M_next = __first;
111*404b540aSrobert	__before_last->_M_next = __after;
112*404b540aSrobert      }
113*404b540aSrobert  }
114*404b540aSrobert
115*404b540aSrobert  inline void
116*404b540aSrobert  __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head)
117*404b540aSrobert  {
118*404b540aSrobert    _Slist_node_base* __before_last = __slist_previous(__head, 0);
119*404b540aSrobert    if (__before_last != __head)
120*404b540aSrobert      {
121*404b540aSrobert	_Slist_node_base* __after = __pos->_M_next;
122*404b540aSrobert	__pos->_M_next = __head->_M_next;
123*404b540aSrobert	__head->_M_next = 0;
124*404b540aSrobert	__before_last->_M_next = __after;
125*404b540aSrobert      }
126*404b540aSrobert  }
127*404b540aSrobert
128*404b540aSrobert  inline _Slist_node_base*
129*404b540aSrobert  __slist_reverse(_Slist_node_base* __node)
130*404b540aSrobert  {
131*404b540aSrobert    _Slist_node_base* __result = __node;
132*404b540aSrobert    __node = __node->_M_next;
133*404b540aSrobert    __result->_M_next = 0;
134*404b540aSrobert    while(__node)
135*404b540aSrobert      {
136*404b540aSrobert	_Slist_node_base* __next = __node->_M_next;
137*404b540aSrobert	__node->_M_next = __result;
138*404b540aSrobert	__result = __node;
139*404b540aSrobert	__node = __next;
140*404b540aSrobert      }
141*404b540aSrobert    return __result;
142*404b540aSrobert  }
143*404b540aSrobert
144*404b540aSrobert  inline size_t
145*404b540aSrobert  __slist_size(_Slist_node_base* __node)
146*404b540aSrobert  {
147*404b540aSrobert    size_t __result = 0;
148*404b540aSrobert    for (; __node != 0; __node = __node->_M_next)
149*404b540aSrobert      ++__result;
150*404b540aSrobert    return __result;
151*404b540aSrobert  }
152*404b540aSrobert
153*404b540aSrobert  template <class _Tp>
154*404b540aSrobert    struct _Slist_node : public _Slist_node_base
155*404b540aSrobert    {
156*404b540aSrobert      _Tp _M_data;
157*404b540aSrobert    };
158*404b540aSrobert
159*404b540aSrobert  struct _Slist_iterator_base
160*404b540aSrobert  {
161*404b540aSrobert    typedef size_t                    size_type;
162*404b540aSrobert    typedef ptrdiff_t                 difference_type;
163*404b540aSrobert    typedef std::forward_iterator_tag iterator_category;
164*404b540aSrobert
165*404b540aSrobert    _Slist_node_base* _M_node;
166*404b540aSrobert
167*404b540aSrobert    _Slist_iterator_base(_Slist_node_base* __x)
168*404b540aSrobert    : _M_node(__x) {}
169*404b540aSrobert
170*404b540aSrobert    void
171*404b540aSrobert    _M_incr()
172*404b540aSrobert    { _M_node = _M_node->_M_next; }
173*404b540aSrobert
174*404b540aSrobert    bool
175*404b540aSrobert    operator==(const _Slist_iterator_base& __x) const
176*404b540aSrobert    { return _M_node == __x._M_node; }
177*404b540aSrobert
178*404b540aSrobert    bool
179*404b540aSrobert    operator!=(const _Slist_iterator_base& __x) const
180*404b540aSrobert    { return _M_node != __x._M_node; }
181*404b540aSrobert  };
182*404b540aSrobert
183*404b540aSrobert  template <class _Tp, class _Ref, class _Ptr>
184*404b540aSrobert    struct _Slist_iterator : public _Slist_iterator_base
185*404b540aSrobert    {
186*404b540aSrobert      typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
187*404b540aSrobert      typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
188*404b540aSrobert      typedef _Slist_iterator<_Tp, _Ref, _Ptr>             _Self;
189*404b540aSrobert
190*404b540aSrobert      typedef _Tp              value_type;
191*404b540aSrobert      typedef _Ptr             pointer;
192*404b540aSrobert      typedef _Ref             reference;
193*404b540aSrobert      typedef _Slist_node<_Tp> _Node;
194*404b540aSrobert
195*404b540aSrobert      explicit
196*404b540aSrobert      _Slist_iterator(_Node* __x)
197*404b540aSrobert      : _Slist_iterator_base(__x) {}
198*404b540aSrobert
199*404b540aSrobert      _Slist_iterator()
200*404b540aSrobert      : _Slist_iterator_base(0) {}
201*404b540aSrobert
202*404b540aSrobert      _Slist_iterator(const iterator& __x)
203*404b540aSrobert      : _Slist_iterator_base(__x._M_node) {}
204*404b540aSrobert
205*404b540aSrobert      reference
206*404b540aSrobert      operator*() const
207*404b540aSrobert      { return ((_Node*) _M_node)->_M_data; }
208*404b540aSrobert
209*404b540aSrobert      pointer
210*404b540aSrobert      operator->() const
211*404b540aSrobert      { return &(operator*()); }
212*404b540aSrobert
213*404b540aSrobert      _Self&
214*404b540aSrobert      operator++()
215*404b540aSrobert      {
216*404b540aSrobert	_M_incr();
217*404b540aSrobert	return *this;
218*404b540aSrobert      }
219*404b540aSrobert
220*404b540aSrobert      _Self
221*404b540aSrobert      operator++(int)
222*404b540aSrobert      {
223*404b540aSrobert	_Self __tmp = *this;
224*404b540aSrobert	_M_incr();
225*404b540aSrobert	return __tmp;
226*404b540aSrobert      }
227*404b540aSrobert    };
228*404b540aSrobert
229*404b540aSrobert  template <class _Tp, class _Alloc>
230*404b540aSrobert    struct _Slist_base
231*404b540aSrobert    : public _Alloc::template rebind<_Slist_node<_Tp> >::other
232*404b540aSrobert    {
233*404b540aSrobert      typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other
234*404b540aSrobert        _Node_alloc;
235*404b540aSrobert      typedef _Alloc allocator_type;
236*404b540aSrobert
237*404b540aSrobert      allocator_type
238*404b540aSrobert      get_allocator() const
239*404b540aSrobert      { return *static_cast<const _Node_alloc*>(this); }
240*404b540aSrobert
241*404b540aSrobert      _Slist_base(const allocator_type& __a)
242*404b540aSrobert      : _Node_alloc(__a)
243*404b540aSrobert      { this->_M_head._M_next = 0; }
244*404b540aSrobert
245*404b540aSrobert      ~_Slist_base()
246*404b540aSrobert      { _M_erase_after(&this->_M_head, 0); }
247*404b540aSrobert
248*404b540aSrobert    protected:
249*404b540aSrobert      _Slist_node_base _M_head;
250*404b540aSrobert
251*404b540aSrobert      _Slist_node<_Tp>*
252*404b540aSrobert      _M_get_node()
253*404b540aSrobert      { return _Node_alloc::allocate(1); }
254*404b540aSrobert
255*404b540aSrobert      void
256*404b540aSrobert      _M_put_node(_Slist_node<_Tp>* __p)
257*404b540aSrobert      { _Node_alloc::deallocate(__p, 1); }
258*404b540aSrobert
259*404b540aSrobert    protected:
260*404b540aSrobert      _Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
261*404b540aSrobert      {
262*404b540aSrobert	_Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);
263*404b540aSrobert	_Slist_node_base* __next_next = __next->_M_next;
264*404b540aSrobert	__pos->_M_next = __next_next;
265*404b540aSrobert	get_allocator().destroy(&__next->_M_data);
266*404b540aSrobert	_M_put_node(__next);
267*404b540aSrobert	return __next_next;
268*404b540aSrobert      }
269*404b540aSrobert      _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
270*404b540aSrobert    };
271*404b540aSrobert
272*404b540aSrobert  template <class _Tp, class _Alloc>
273*404b540aSrobert    _Slist_node_base*
274*404b540aSrobert    _Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first,
275*404b540aSrobert					    _Slist_node_base* __last_node)
276*404b540aSrobert    {
277*404b540aSrobert      _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next);
278*404b540aSrobert      while (__cur != __last_node)
279*404b540aSrobert	{
280*404b540aSrobert	  _Slist_node<_Tp>* __tmp = __cur;
281*404b540aSrobert	  __cur = (_Slist_node<_Tp>*) __cur->_M_next;
282*404b540aSrobert	  get_allocator().destroy(&__tmp->_M_data);
283*404b540aSrobert	  _M_put_node(__tmp);
284*404b540aSrobert	}
285*404b540aSrobert      __before_first->_M_next = __last_node;
286*404b540aSrobert      return __last_node;
287*404b540aSrobert    }
288*404b540aSrobert
289*404b540aSrobert  /**
290*404b540aSrobert   *  This is an SGI extension.
291*404b540aSrobert   *  @ingroup SGIextensions
292*404b540aSrobert   *  @doctodo
293*404b540aSrobert   */
294*404b540aSrobert  template <class _Tp, class _Alloc = allocator<_Tp> >
295*404b540aSrobert    class slist : private _Slist_base<_Tp,_Alloc>
296*404b540aSrobert    {
297*404b540aSrobert      // concept requirements
298*404b540aSrobert      __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
299*404b540aSrobert
300*404b540aSrobert    private:
301*404b540aSrobert      typedef _Slist_base<_Tp,_Alloc> _Base;
302*404b540aSrobert
303*404b540aSrobert    public:
304*404b540aSrobert      typedef _Tp               value_type;
305*404b540aSrobert      typedef value_type*       pointer;
306*404b540aSrobert      typedef const value_type* const_pointer;
307*404b540aSrobert      typedef value_type&       reference;
308*404b540aSrobert      typedef const value_type& const_reference;
309*404b540aSrobert      typedef size_t            size_type;
310*404b540aSrobert      typedef ptrdiff_t         difference_type;
311*404b540aSrobert
312*404b540aSrobert      typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
313*404b540aSrobert      typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
314*404b540aSrobert
315*404b540aSrobert      typedef typename _Base::allocator_type allocator_type;
316*404b540aSrobert
317*404b540aSrobert      allocator_type
318*404b540aSrobert      get_allocator() const
319*404b540aSrobert      { return _Base::get_allocator(); }
320*404b540aSrobert
321*404b540aSrobert    private:
322*404b540aSrobert      typedef _Slist_node<_Tp>      _Node;
323*404b540aSrobert      typedef _Slist_node_base      _Node_base;
324*404b540aSrobert      typedef _Slist_iterator_base  _Iterator_base;
325*404b540aSrobert
326*404b540aSrobert      _Node*
327*404b540aSrobert      _M_create_node(const value_type& __x)
328*404b540aSrobert      {
329*404b540aSrobert	_Node* __node = this->_M_get_node();
330*404b540aSrobert	try
331*404b540aSrobert	  {
332*404b540aSrobert	    get_allocator().construct(&__node->_M_data, __x);
333*404b540aSrobert	    __node->_M_next = 0;
334*404b540aSrobert	  }
335*404b540aSrobert	catch(...)
336*404b540aSrobert	  {
337*404b540aSrobert	    this->_M_put_node(__node);
338*404b540aSrobert	    __throw_exception_again;
339*404b540aSrobert	  }
340*404b540aSrobert	return __node;
341*404b540aSrobert      }
342*404b540aSrobert
343*404b540aSrobert      _Node*
344*404b540aSrobert      _M_create_node()
345*404b540aSrobert      {
346*404b540aSrobert	_Node* __node = this->_M_get_node();
347*404b540aSrobert	try
348*404b540aSrobert	  {
349*404b540aSrobert	    get_allocator().construct(&__node->_M_data, value_type());
350*404b540aSrobert	    __node->_M_next = 0;
351*404b540aSrobert	  }
352*404b540aSrobert	catch(...)
353*404b540aSrobert	  {
354*404b540aSrobert	    this->_M_put_node(__node);
355*404b540aSrobert	    __throw_exception_again;
356*404b540aSrobert	  }
357*404b540aSrobert	return __node;
358*404b540aSrobert      }
359*404b540aSrobert
360*404b540aSrobert    public:
361*404b540aSrobert      explicit
362*404b540aSrobert      slist(const allocator_type& __a = allocator_type())
363*404b540aSrobert      : _Base(__a) {}
364*404b540aSrobert
365*404b540aSrobert      slist(size_type __n, const value_type& __x,
366*404b540aSrobert	    const allocator_type& __a =  allocator_type())
367*404b540aSrobert      : _Base(__a)
368*404b540aSrobert      { _M_insert_after_fill(&this->_M_head, __n, __x); }
369*404b540aSrobert
370*404b540aSrobert      explicit
371*404b540aSrobert      slist(size_type __n)
372*404b540aSrobert      : _Base(allocator_type())
373*404b540aSrobert      { _M_insert_after_fill(&this->_M_head, __n, value_type()); }
374*404b540aSrobert
375*404b540aSrobert      // We don't need any dispatching tricks here, because
376*404b540aSrobert      // _M_insert_after_range already does them.
377*404b540aSrobert      template <class _InputIterator>
378*404b540aSrobert        slist(_InputIterator __first, _InputIterator __last,
379*404b540aSrobert	      const allocator_type& __a =  allocator_type())
380*404b540aSrobert	: _Base(__a)
381*404b540aSrobert        { _M_insert_after_range(&this->_M_head, __first, __last); }
382*404b540aSrobert
383*404b540aSrobert      slist(const slist& __x)
384*404b540aSrobert      : _Base(__x.get_allocator())
385*404b540aSrobert      { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); }
386*404b540aSrobert
387*404b540aSrobert      slist&
388*404b540aSrobert      operator= (const slist& __x);
389*404b540aSrobert
390*404b540aSrobert      ~slist() {}
391*404b540aSrobert
392*404b540aSrobert    public:
393*404b540aSrobert      // assign(), a generalized assignment member function.  Two
394*404b540aSrobert      // versions: one that takes a count, and one that takes a range.
395*404b540aSrobert      // The range version is a member template, so we dispatch on whether
396*404b540aSrobert      // or not the type is an integer.
397*404b540aSrobert
398*404b540aSrobert      void
399*404b540aSrobert      assign(size_type __n, const _Tp& __val)
400*404b540aSrobert      { _M_fill_assign(__n, __val); }
401*404b540aSrobert
402*404b540aSrobert      void
403*404b540aSrobert      _M_fill_assign(size_type __n, const _Tp& __val);
404*404b540aSrobert
405*404b540aSrobert      template <class _InputIterator>
406*404b540aSrobert        void
407*404b540aSrobert        assign(_InputIterator __first, _InputIterator __last)
408*404b540aSrobert        {
409*404b540aSrobert	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
410*404b540aSrobert	  _M_assign_dispatch(__first, __last, _Integral());
411*404b540aSrobert	}
412*404b540aSrobert
413*404b540aSrobert      template <class _Integer>
414*404b540aSrobert      void
415*404b540aSrobert      _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
416*404b540aSrobert      { _M_fill_assign((size_type) __n, (_Tp) __val); }
417*404b540aSrobert
418*404b540aSrobert      template <class _InputIterator>
419*404b540aSrobert      void
420*404b540aSrobert      _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
421*404b540aSrobert			 __false_type);
422*404b540aSrobert
423*404b540aSrobert    public:
424*404b540aSrobert
425*404b540aSrobert      iterator
426*404b540aSrobert      begin()
427*404b540aSrobert      { return iterator((_Node*)this->_M_head._M_next); }
428*404b540aSrobert
429*404b540aSrobert      const_iterator
430*404b540aSrobert      begin() const
431*404b540aSrobert      { return const_iterator((_Node*)this->_M_head._M_next);}
432*404b540aSrobert
433*404b540aSrobert      iterator
434*404b540aSrobert      end()
435*404b540aSrobert      { return iterator(0); }
436*404b540aSrobert
437*404b540aSrobert      const_iterator
438*404b540aSrobert      end() const
439*404b540aSrobert      { return const_iterator(0); }
440*404b540aSrobert
441*404b540aSrobert      // Experimental new feature: before_begin() returns a
442*404b540aSrobert      // non-dereferenceable iterator that, when incremented, yields
443*404b540aSrobert      // begin().  This iterator may be used as the argument to
444*404b540aSrobert      // insert_after, erase_after, etc.  Note that even for an empty
445*404b540aSrobert      // slist, before_begin() is not the same iterator as end().  It
446*404b540aSrobert      // is always necessary to increment before_begin() at least once to
447*404b540aSrobert      // obtain end().
448*404b540aSrobert      iterator
449*404b540aSrobert      before_begin()
450*404b540aSrobert      { return iterator((_Node*) &this->_M_head); }
451*404b540aSrobert
452*404b540aSrobert      const_iterator
453*404b540aSrobert      before_begin() const
454*404b540aSrobert      { return const_iterator((_Node*) &this->_M_head); }
455*404b540aSrobert
456*404b540aSrobert      size_type
457*404b540aSrobert      size() const
458*404b540aSrobert      { return __slist_size(this->_M_head._M_next); }
459*404b540aSrobert
460*404b540aSrobert      size_type
461*404b540aSrobert      max_size() const
462*404b540aSrobert      { return size_type(-1); }
463*404b540aSrobert
464*404b540aSrobert      bool
465*404b540aSrobert      empty() const
466*404b540aSrobert      { return this->_M_head._M_next == 0; }
467*404b540aSrobert
468*404b540aSrobert      void
469*404b540aSrobert      swap(slist& __x)
470*404b540aSrobert      { std::swap(this->_M_head._M_next, __x._M_head._M_next); }
471*404b540aSrobert
472*404b540aSrobert    public:
473*404b540aSrobert
474*404b540aSrobert      reference
475*404b540aSrobert      front()
476*404b540aSrobert      { return ((_Node*) this->_M_head._M_next)->_M_data; }
477*404b540aSrobert
478*404b540aSrobert      const_reference
479*404b540aSrobert      front() const
480*404b540aSrobert      { return ((_Node*) this->_M_head._M_next)->_M_data; }
481*404b540aSrobert
482*404b540aSrobert      void
483*404b540aSrobert      push_front(const value_type& __x)
484*404b540aSrobert      { __slist_make_link(&this->_M_head, _M_create_node(__x)); }
485*404b540aSrobert
486*404b540aSrobert      void
487*404b540aSrobert      push_front()
488*404b540aSrobert      { __slist_make_link(&this->_M_head, _M_create_node()); }
489*404b540aSrobert
490*404b540aSrobert      void
491*404b540aSrobert      pop_front()
492*404b540aSrobert      {
493*404b540aSrobert	_Node* __node = (_Node*) this->_M_head._M_next;
494*404b540aSrobert	this->_M_head._M_next = __node->_M_next;
495*404b540aSrobert	get_allocator().destroy(&__node->_M_data);
496*404b540aSrobert	this->_M_put_node(__node);
497*404b540aSrobert      }
498*404b540aSrobert
499*404b540aSrobert      iterator
500*404b540aSrobert      previous(const_iterator __pos)
501*404b540aSrobert      { return iterator((_Node*) __slist_previous(&this->_M_head,
502*404b540aSrobert						  __pos._M_node)); }
503*404b540aSrobert
504*404b540aSrobert      const_iterator
505*404b540aSrobert      previous(const_iterator __pos) const
506*404b540aSrobert      { return const_iterator((_Node*) __slist_previous(&this->_M_head,
507*404b540aSrobert							__pos._M_node)); }
508*404b540aSrobert
509*404b540aSrobert    private:
510*404b540aSrobert      _Node*
511*404b540aSrobert      _M_insert_after(_Node_base* __pos, const value_type& __x)
512*404b540aSrobert      { return (_Node*) (__slist_make_link(__pos, _M_create_node(__x))); }
513*404b540aSrobert
514*404b540aSrobert      _Node*
515*404b540aSrobert      _M_insert_after(_Node_base* __pos)
516*404b540aSrobert      { return (_Node*) (__slist_make_link(__pos, _M_create_node())); }
517*404b540aSrobert
518*404b540aSrobert      void
519*404b540aSrobert      _M_insert_after_fill(_Node_base* __pos,
520*404b540aSrobert			   size_type __n, const value_type& __x)
521*404b540aSrobert      {
522*404b540aSrobert	for (size_type __i = 0; __i < __n; ++__i)
523*404b540aSrobert	  __pos = __slist_make_link(__pos, _M_create_node(__x));
524*404b540aSrobert      }
525*404b540aSrobert
526*404b540aSrobert      // Check whether it's an integral type.  If so, it's not an iterator.
527*404b540aSrobert      template <class _InIterator>
528*404b540aSrobert        void
529*404b540aSrobert        _M_insert_after_range(_Node_base* __pos,
530*404b540aSrobert			      _InIterator __first, _InIterator __last)
531*404b540aSrobert        {
532*404b540aSrobert	  typedef typename std::__is_integer<_InIterator>::__type _Integral;
533*404b540aSrobert	  _M_insert_after_range(__pos, __first, __last, _Integral());
534*404b540aSrobert	}
535*404b540aSrobert
536*404b540aSrobert      template <class _Integer>
537*404b540aSrobert        void
538*404b540aSrobert        _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
539*404b540aSrobert			      __true_type)
540*404b540aSrobert        { _M_insert_after_fill(__pos, __n, __x); }
541*404b540aSrobert
542*404b540aSrobert      template <class _InIterator>
543*404b540aSrobert        void
544*404b540aSrobert        _M_insert_after_range(_Node_base* __pos,
545*404b540aSrobert			      _InIterator __first, _InIterator __last,
546*404b540aSrobert			      __false_type)
547*404b540aSrobert        {
548*404b540aSrobert	  while (__first != __last)
549*404b540aSrobert	    {
550*404b540aSrobert	      __pos = __slist_make_link(__pos, _M_create_node(*__first));
551*404b540aSrobert	      ++__first;
552*404b540aSrobert	    }
553*404b540aSrobert	}
554*404b540aSrobert
555*404b540aSrobert    public:
556*404b540aSrobert      iterator
557*404b540aSrobert      insert_after(iterator __pos, const value_type& __x)
558*404b540aSrobert      { return iterator(_M_insert_after(__pos._M_node, __x)); }
559*404b540aSrobert
560*404b540aSrobert      iterator
561*404b540aSrobert      insert_after(iterator __pos)
562*404b540aSrobert      { return insert_after(__pos, value_type()); }
563*404b540aSrobert
564*404b540aSrobert      void
565*404b540aSrobert      insert_after(iterator __pos, size_type __n, const value_type& __x)
566*404b540aSrobert      { _M_insert_after_fill(__pos._M_node, __n, __x); }
567*404b540aSrobert
568*404b540aSrobert      // We don't need any dispatching tricks here, because
569*404b540aSrobert      // _M_insert_after_range already does them.
570*404b540aSrobert      template <class _InIterator>
571*404b540aSrobert        void
572*404b540aSrobert        insert_after(iterator __pos, _InIterator __first, _InIterator __last)
573*404b540aSrobert        { _M_insert_after_range(__pos._M_node, __first, __last); }
574*404b540aSrobert
575*404b540aSrobert      iterator
576*404b540aSrobert      insert(iterator __pos, const value_type& __x)
577*404b540aSrobert      { return iterator(_M_insert_after(__slist_previous(&this->_M_head,
578*404b540aSrobert							 __pos._M_node),
579*404b540aSrobert					__x)); }
580*404b540aSrobert
581*404b540aSrobert      iterator
582*404b540aSrobert      insert(iterator __pos)
583*404b540aSrobert      { return iterator(_M_insert_after(__slist_previous(&this->_M_head,
584*404b540aSrobert							 __pos._M_node),
585*404b540aSrobert					value_type())); }
586*404b540aSrobert
587*404b540aSrobert      void
588*404b540aSrobert      insert(iterator __pos, size_type __n, const value_type& __x)
589*404b540aSrobert      { _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node),
590*404b540aSrobert			     __n, __x); }
591*404b540aSrobert
592*404b540aSrobert      // We don't need any dispatching tricks here, because
593*404b540aSrobert      // _M_insert_after_range already does them.
594*404b540aSrobert      template <class _InIterator>
595*404b540aSrobert        void
596*404b540aSrobert        insert(iterator __pos, _InIterator __first, _InIterator __last)
597*404b540aSrobert        { _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node),
598*404b540aSrobert				__first, __last); }
599*404b540aSrobert
600*404b540aSrobert    public:
601*404b540aSrobert      iterator
602*404b540aSrobert      erase_after(iterator __pos)
603*404b540aSrobert      { return iterator((_Node*) this->_M_erase_after(__pos._M_node)); }
604*404b540aSrobert
605*404b540aSrobert      iterator
606*404b540aSrobert      erase_after(iterator __before_first, iterator __last)
607*404b540aSrobert      {
608*404b540aSrobert	return iterator((_Node*) this->_M_erase_after(__before_first._M_node,
609*404b540aSrobert						      __last._M_node));
610*404b540aSrobert      }
611*404b540aSrobert
612*404b540aSrobert      iterator
613*404b540aSrobert      erase(iterator __pos)
614*404b540aSrobert      {
615*404b540aSrobert	return iterator((_Node*) this->_M_erase_after
616*404b540aSrobert			(__slist_previous(&this->_M_head, __pos._M_node)));
617*404b540aSrobert      }
618*404b540aSrobert
619*404b540aSrobert      iterator
620*404b540aSrobert      erase(iterator __first, iterator __last)
621*404b540aSrobert      {
622*404b540aSrobert	return iterator((_Node*) this->_M_erase_after
623*404b540aSrobert			(__slist_previous(&this->_M_head, __first._M_node),
624*404b540aSrobert			 __last._M_node));
625*404b540aSrobert      }
626*404b540aSrobert
627*404b540aSrobert      void
628*404b540aSrobert      resize(size_type new_size, const _Tp& __x);
629*404b540aSrobert
630*404b540aSrobert      void
631*404b540aSrobert      resize(size_type new_size)
632*404b540aSrobert      { resize(new_size, _Tp()); }
633*404b540aSrobert
634*404b540aSrobert      void
635*404b540aSrobert      clear()
636*404b540aSrobert      { this->_M_erase_after(&this->_M_head, 0); }
637*404b540aSrobert
638*404b540aSrobert    public:
639*404b540aSrobert      // Moves the range [__before_first + 1, __before_last + 1) to *this,
640*404b540aSrobert      //  inserting it immediately after __pos.  This is constant time.
641*404b540aSrobert      void
642*404b540aSrobert      splice_after(iterator __pos,
643*404b540aSrobert		   iterator __before_first, iterator __before_last)
644*404b540aSrobert      {
645*404b540aSrobert	if (__before_first != __before_last)
646*404b540aSrobert	  __slist_splice_after(__pos._M_node, __before_first._M_node,
647*404b540aSrobert			       __before_last._M_node);
648*404b540aSrobert      }
649*404b540aSrobert
650*404b540aSrobert      // Moves the element that follows __prev to *this, inserting it
651*404b540aSrobert      // immediately after __pos.  This is constant time.
652*404b540aSrobert      void
653*404b540aSrobert      splice_after(iterator __pos, iterator __prev)
654*404b540aSrobert      { __slist_splice_after(__pos._M_node,
655*404b540aSrobert			     __prev._M_node, __prev._M_node->_M_next); }
656*404b540aSrobert
657*404b540aSrobert      // Removes all of the elements from the list __x to *this, inserting
658*404b540aSrobert      // them immediately after __pos.  __x must not be *this.  Complexity:
659*404b540aSrobert      // linear in __x.size().
660*404b540aSrobert      void
661*404b540aSrobert      splice_after(iterator __pos, slist& __x)
662*404b540aSrobert      { __slist_splice_after(__pos._M_node, &__x._M_head); }
663*404b540aSrobert
664*404b540aSrobert      // Linear in distance(begin(), __pos), and linear in __x.size().
665*404b540aSrobert      void
666*404b540aSrobert      splice(iterator __pos, slist& __x)
667*404b540aSrobert      {
668*404b540aSrobert	if (__x._M_head._M_next)
669*404b540aSrobert	  __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
670*404b540aSrobert			       &__x._M_head,
671*404b540aSrobert			       __slist_previous(&__x._M_head, 0)); }
672*404b540aSrobert
673*404b540aSrobert      // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
674*404b540aSrobert      void
675*404b540aSrobert      splice(iterator __pos, slist& __x, iterator __i)
676*404b540aSrobert      { __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
677*404b540aSrobert			     __slist_previous(&__x._M_head, __i._M_node),
678*404b540aSrobert			     __i._M_node); }
679*404b540aSrobert
680*404b540aSrobert      // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
681*404b540aSrobert      // and in distance(__first, __last).
682*404b540aSrobert      void
683*404b540aSrobert      splice(iterator __pos, slist& __x, iterator __first, iterator __last)
684*404b540aSrobert      {
685*404b540aSrobert	if (__first != __last)
686*404b540aSrobert	  __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
687*404b540aSrobert			       __slist_previous(&__x._M_head, __first._M_node),
688*404b540aSrobert			       __slist_previous(__first._M_node,
689*404b540aSrobert						__last._M_node));
690*404b540aSrobert      }
691*404b540aSrobert
692*404b540aSrobert    public:
693*404b540aSrobert      void
694*404b540aSrobert      reverse()
695*404b540aSrobert      {
696*404b540aSrobert	if (this->_M_head._M_next)
697*404b540aSrobert	  this->_M_head._M_next = __slist_reverse(this->_M_head._M_next);
698*404b540aSrobert      }
699*404b540aSrobert
700*404b540aSrobert      void
701*404b540aSrobert      remove(const _Tp& __val);
702*404b540aSrobert
703*404b540aSrobert      void
704*404b540aSrobert      unique();
705*404b540aSrobert
706*404b540aSrobert      void
707*404b540aSrobert      merge(slist& __x);
708*404b540aSrobert
709*404b540aSrobert      void
710*404b540aSrobert      sort();
711*404b540aSrobert
712*404b540aSrobert      template <class _Predicate>
713*404b540aSrobert        void
714*404b540aSrobert        remove_if(_Predicate __pred);
715*404b540aSrobert
716*404b540aSrobert      template <class _BinaryPredicate>
717*404b540aSrobert        void
718*404b540aSrobert        unique(_BinaryPredicate __pred);
719*404b540aSrobert
720*404b540aSrobert      template <class _StrictWeakOrdering>
721*404b540aSrobert        void
722*404b540aSrobert        merge(slist&, _StrictWeakOrdering);
723*404b540aSrobert
724*404b540aSrobert      template <class _StrictWeakOrdering>
725*404b540aSrobert        void
726*404b540aSrobert        sort(_StrictWeakOrdering __comp);
727*404b540aSrobert    };
728*404b540aSrobert
729*404b540aSrobert  template <class _Tp, class _Alloc>
730*404b540aSrobert    slist<_Tp, _Alloc>&
731*404b540aSrobert    slist<_Tp, _Alloc>::operator=(const slist<_Tp, _Alloc>& __x)
732*404b540aSrobert    {
733*404b540aSrobert      if (&__x != this)
734*404b540aSrobert	{
735*404b540aSrobert	  _Node_base* __p1 = &this->_M_head;
736*404b540aSrobert	  _Node* __n1 = (_Node*) this->_M_head._M_next;
737*404b540aSrobert	  const _Node* __n2 = (const _Node*) __x._M_head._M_next;
738*404b540aSrobert	  while (__n1 && __n2)
739*404b540aSrobert	    {
740*404b540aSrobert	      __n1->_M_data = __n2->_M_data;
741*404b540aSrobert	      __p1 = __n1;
742*404b540aSrobert	      __n1 = (_Node*) __n1->_M_next;
743*404b540aSrobert	      __n2 = (const _Node*) __n2->_M_next;
744*404b540aSrobert	    }
745*404b540aSrobert	  if (__n2 == 0)
746*404b540aSrobert	    this->_M_erase_after(__p1, 0);
747*404b540aSrobert	  else
748*404b540aSrobert	    _M_insert_after_range(__p1, const_iterator((_Node*)__n2),
749*404b540aSrobert                                  const_iterator(0));
750*404b540aSrobert	}
751*404b540aSrobert      return *this;
752*404b540aSrobert    }
753*404b540aSrobert
754*404b540aSrobert  template <class _Tp, class _Alloc>
755*404b540aSrobert    void
756*404b540aSrobert    slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val)
757*404b540aSrobert    {
758*404b540aSrobert      _Node_base* __prev = &this->_M_head;
759*404b540aSrobert      _Node* __node = (_Node*) this->_M_head._M_next;
760*404b540aSrobert      for (; __node != 0 && __n > 0; --__n)
761*404b540aSrobert	{
762*404b540aSrobert	  __node->_M_data = __val;
763*404b540aSrobert	  __prev = __node;
764*404b540aSrobert	  __node = (_Node*) __node->_M_next;
765*404b540aSrobert	}
766*404b540aSrobert      if (__n > 0)
767*404b540aSrobert	_M_insert_after_fill(__prev, __n, __val);
768*404b540aSrobert      else
769*404b540aSrobert	this->_M_erase_after(__prev, 0);
770*404b540aSrobert    }
771*404b540aSrobert
772*404b540aSrobert  template <class _Tp, class _Alloc>
773*404b540aSrobert    template <class _InputIterator>
774*404b540aSrobert      void
775*404b540aSrobert      slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first,
776*404b540aSrobert					     _InputIterator __last,
777*404b540aSrobert					     __false_type)
778*404b540aSrobert      {
779*404b540aSrobert	_Node_base* __prev = &this->_M_head;
780*404b540aSrobert	_Node* __node = (_Node*) this->_M_head._M_next;
781*404b540aSrobert	while (__node != 0 && __first != __last)
782*404b540aSrobert	  {
783*404b540aSrobert	    __node->_M_data = *__first;
784*404b540aSrobert	    __prev = __node;
785*404b540aSrobert	    __node = (_Node*) __node->_M_next;
786*404b540aSrobert	    ++__first;
787*404b540aSrobert	  }
788*404b540aSrobert	if (__first != __last)
789*404b540aSrobert	  _M_insert_after_range(__prev, __first, __last);
790*404b540aSrobert	else
791*404b540aSrobert	  this->_M_erase_after(__prev, 0);
792*404b540aSrobert      }
793*404b540aSrobert
794*404b540aSrobert  template <class _Tp, class _Alloc>
795*404b540aSrobert    inline bool
796*404b540aSrobert    operator==(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
797*404b540aSrobert    {
798*404b540aSrobert      typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator;
799*404b540aSrobert      const_iterator __end1 = _SL1.end();
800*404b540aSrobert      const_iterator __end2 = _SL2.end();
801*404b540aSrobert
802*404b540aSrobert      const_iterator __i1 = _SL1.begin();
803*404b540aSrobert      const_iterator __i2 = _SL2.begin();
804*404b540aSrobert      while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2)
805*404b540aSrobert	{
806*404b540aSrobert	  ++__i1;
807*404b540aSrobert	  ++__i2;
808*404b540aSrobert	}
809*404b540aSrobert      return __i1 == __end1 && __i2 == __end2;
810*404b540aSrobert    }
811*404b540aSrobert
812*404b540aSrobert
813*404b540aSrobert  template <class _Tp, class _Alloc>
814*404b540aSrobert    inline bool
815*404b540aSrobert    operator<(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
816*404b540aSrobert    { return std::lexicographical_compare(_SL1.begin(), _SL1.end(),
817*404b540aSrobert					  _SL2.begin(), _SL2.end()); }
818*404b540aSrobert
819*404b540aSrobert  template <class _Tp, class _Alloc>
820*404b540aSrobert    inline bool
821*404b540aSrobert    operator!=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
822*404b540aSrobert    { return !(_SL1 == _SL2); }
823*404b540aSrobert
824*404b540aSrobert  template <class _Tp, class _Alloc>
825*404b540aSrobert    inline bool
826*404b540aSrobert    operator>(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
827*404b540aSrobert    { return _SL2 < _SL1; }
828*404b540aSrobert
829*404b540aSrobert  template <class _Tp, class _Alloc>
830*404b540aSrobert    inline bool
831*404b540aSrobert    operator<=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
832*404b540aSrobert    { return !(_SL2 < _SL1); }
833*404b540aSrobert
834*404b540aSrobert  template <class _Tp, class _Alloc>
835*404b540aSrobert    inline bool
836*404b540aSrobert    operator>=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
837*404b540aSrobert    { return !(_SL1 < _SL2); }
838*404b540aSrobert
839*404b540aSrobert  template <class _Tp, class _Alloc>
840*404b540aSrobert    inline void
841*404b540aSrobert    swap(slist<_Tp, _Alloc>& __x, slist<_Tp, _Alloc>& __y)
842*404b540aSrobert    { __x.swap(__y); }
843*404b540aSrobert
844*404b540aSrobert  template <class _Tp, class _Alloc>
845*404b540aSrobert    void
846*404b540aSrobert    slist<_Tp, _Alloc>::resize(size_type __len, const _Tp& __x)
847*404b540aSrobert    {
848*404b540aSrobert      _Node_base* __cur = &this->_M_head;
849*404b540aSrobert      while (__cur->_M_next != 0 && __len > 0)
850*404b540aSrobert	{
851*404b540aSrobert	  --__len;
852*404b540aSrobert	  __cur = __cur->_M_next;
853*404b540aSrobert	}
854*404b540aSrobert      if (__cur->_M_next)
855*404b540aSrobert	this->_M_erase_after(__cur, 0);
856*404b540aSrobert      else
857*404b540aSrobert	_M_insert_after_fill(__cur, __len, __x);
858*404b540aSrobert    }
859*404b540aSrobert
860*404b540aSrobert  template <class _Tp, class _Alloc>
861*404b540aSrobert    void
862*404b540aSrobert    slist<_Tp, _Alloc>::remove(const _Tp& __val)
863*404b540aSrobert    {
864*404b540aSrobert      _Node_base* __cur = &this->_M_head;
865*404b540aSrobert      while (__cur && __cur->_M_next)
866*404b540aSrobert	{
867*404b540aSrobert	  if (((_Node*) __cur->_M_next)->_M_data == __val)
868*404b540aSrobert	    this->_M_erase_after(__cur);
869*404b540aSrobert	  else
870*404b540aSrobert	    __cur = __cur->_M_next;
871*404b540aSrobert	}
872*404b540aSrobert    }
873*404b540aSrobert
874*404b540aSrobert  template <class _Tp, class _Alloc>
875*404b540aSrobert    void
876*404b540aSrobert    slist<_Tp, _Alloc>::unique()
877*404b540aSrobert    {
878*404b540aSrobert      _Node_base* __cur = this->_M_head._M_next;
879*404b540aSrobert      if (__cur)
880*404b540aSrobert	{
881*404b540aSrobert	  while (__cur->_M_next)
882*404b540aSrobert	    {
883*404b540aSrobert	      if (((_Node*)__cur)->_M_data
884*404b540aSrobert		  == ((_Node*)(__cur->_M_next))->_M_data)
885*404b540aSrobert		this->_M_erase_after(__cur);
886*404b540aSrobert	      else
887*404b540aSrobert		__cur = __cur->_M_next;
888*404b540aSrobert	    }
889*404b540aSrobert	}
890*404b540aSrobert    }
891*404b540aSrobert
892*404b540aSrobert  template <class _Tp, class _Alloc>
893*404b540aSrobert    void
894*404b540aSrobert    slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x)
895*404b540aSrobert    {
896*404b540aSrobert      _Node_base* __n1 = &this->_M_head;
897*404b540aSrobert      while (__n1->_M_next && __x._M_head._M_next)
898*404b540aSrobert	{
899*404b540aSrobert	  if (((_Node*) __x._M_head._M_next)->_M_data
900*404b540aSrobert	      < ((_Node*) __n1->_M_next)->_M_data)
901*404b540aSrobert	    __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
902*404b540aSrobert	  __n1 = __n1->_M_next;
903*404b540aSrobert	}
904*404b540aSrobert      if (__x._M_head._M_next)
905*404b540aSrobert	{
906*404b540aSrobert	  __n1->_M_next = __x._M_head._M_next;
907*404b540aSrobert	  __x._M_head._M_next = 0;
908*404b540aSrobert	}
909*404b540aSrobert    }
910*404b540aSrobert
911*404b540aSrobert  template <class _Tp, class _Alloc>
912*404b540aSrobert    void
913*404b540aSrobert    slist<_Tp, _Alloc>::sort()
914*404b540aSrobert    {
915*404b540aSrobert      if (this->_M_head._M_next && this->_M_head._M_next->_M_next)
916*404b540aSrobert	{
917*404b540aSrobert	  slist __carry;
918*404b540aSrobert	  slist __counter[64];
919*404b540aSrobert	  int __fill = 0;
920*404b540aSrobert	  while (!empty())
921*404b540aSrobert	    {
922*404b540aSrobert	      __slist_splice_after(&__carry._M_head,
923*404b540aSrobert				   &this->_M_head, this->_M_head._M_next);
924*404b540aSrobert	      int __i = 0;
925*404b540aSrobert	      while (__i < __fill && !__counter[__i].empty())
926*404b540aSrobert		{
927*404b540aSrobert		  __counter[__i].merge(__carry);
928*404b540aSrobert		  __carry.swap(__counter[__i]);
929*404b540aSrobert		  ++__i;
930*404b540aSrobert		}
931*404b540aSrobert	      __carry.swap(__counter[__i]);
932*404b540aSrobert	      if (__i == __fill)
933*404b540aSrobert		++__fill;
934*404b540aSrobert	    }
935*404b540aSrobert
936*404b540aSrobert	  for (int __i = 1; __i < __fill; ++__i)
937*404b540aSrobert	    __counter[__i].merge(__counter[__i-1]);
938*404b540aSrobert	  this->swap(__counter[__fill-1]);
939*404b540aSrobert	}
940*404b540aSrobert    }
941*404b540aSrobert
942*404b540aSrobert  template <class _Tp, class _Alloc>
943*404b540aSrobert    template <class _Predicate>
944*404b540aSrobert      void slist<_Tp, _Alloc>::remove_if(_Predicate __pred)
945*404b540aSrobert      {
946*404b540aSrobert	_Node_base* __cur = &this->_M_head;
947*404b540aSrobert	while (__cur->_M_next)
948*404b540aSrobert	  {
949*404b540aSrobert	    if (__pred(((_Node*) __cur->_M_next)->_M_data))
950*404b540aSrobert	      this->_M_erase_after(__cur);
951*404b540aSrobert	    else
952*404b540aSrobert	      __cur = __cur->_M_next;
953*404b540aSrobert	  }
954*404b540aSrobert      }
955*404b540aSrobert
956*404b540aSrobert  template <class _Tp, class _Alloc>
957*404b540aSrobert    template <class _BinaryPredicate>
958*404b540aSrobert      void
959*404b540aSrobert      slist<_Tp, _Alloc>::unique(_BinaryPredicate __pred)
960*404b540aSrobert      {
961*404b540aSrobert	_Node* __cur = (_Node*) this->_M_head._M_next;
962*404b540aSrobert	if (__cur)
963*404b540aSrobert	  {
964*404b540aSrobert	    while (__cur->_M_next)
965*404b540aSrobert	      {
966*404b540aSrobert		if (__pred(((_Node*)__cur)->_M_data,
967*404b540aSrobert			   ((_Node*)(__cur->_M_next))->_M_data))
968*404b540aSrobert		  this->_M_erase_after(__cur);
969*404b540aSrobert		else
970*404b540aSrobert		  __cur = (_Node*) __cur->_M_next;
971*404b540aSrobert	      }
972*404b540aSrobert	  }
973*404b540aSrobert      }
974*404b540aSrobert
975*404b540aSrobert  template <class _Tp, class _Alloc>
976*404b540aSrobert    template <class _StrictWeakOrdering>
977*404b540aSrobert      void
978*404b540aSrobert      slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x,
979*404b540aSrobert			       _StrictWeakOrdering __comp)
980*404b540aSrobert      {
981*404b540aSrobert	_Node_base* __n1 = &this->_M_head;
982*404b540aSrobert	while (__n1->_M_next && __x._M_head._M_next)
983*404b540aSrobert	  {
984*404b540aSrobert	    if (__comp(((_Node*) __x._M_head._M_next)->_M_data,
985*404b540aSrobert		       ((_Node*) __n1->_M_next)->_M_data))
986*404b540aSrobert	      __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
987*404b540aSrobert	    __n1 = __n1->_M_next;
988*404b540aSrobert	  }
989*404b540aSrobert	if (__x._M_head._M_next)
990*404b540aSrobert	  {
991*404b540aSrobert	    __n1->_M_next = __x._M_head._M_next;
992*404b540aSrobert	    __x._M_head._M_next = 0;
993*404b540aSrobert	  }
994*404b540aSrobert      }
995*404b540aSrobert
996*404b540aSrobert  template <class _Tp, class _Alloc>
997*404b540aSrobert    template <class _StrictWeakOrdering>
998*404b540aSrobert      void
999*404b540aSrobert      slist<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp)
1000*404b540aSrobert      {
1001*404b540aSrobert	if (this->_M_head._M_next && this->_M_head._M_next->_M_next)
1002*404b540aSrobert	  {
1003*404b540aSrobert	    slist __carry;
1004*404b540aSrobert	    slist __counter[64];
1005*404b540aSrobert	    int __fill = 0;
1006*404b540aSrobert	    while (!empty())
1007*404b540aSrobert	      {
1008*404b540aSrobert		__slist_splice_after(&__carry._M_head,
1009*404b540aSrobert				     &this->_M_head, this->_M_head._M_next);
1010*404b540aSrobert		int __i = 0;
1011*404b540aSrobert		while (__i < __fill && !__counter[__i].empty())
1012*404b540aSrobert		  {
1013*404b540aSrobert		    __counter[__i].merge(__carry, __comp);
1014*404b540aSrobert		    __carry.swap(__counter[__i]);
1015*404b540aSrobert		    ++__i;
1016*404b540aSrobert		  }
1017*404b540aSrobert		__carry.swap(__counter[__i]);
1018*404b540aSrobert		if (__i == __fill)
1019*404b540aSrobert		  ++__fill;
1020*404b540aSrobert	      }
1021*404b540aSrobert
1022*404b540aSrobert	    for (int __i = 1; __i < __fill; ++__i)
1023*404b540aSrobert	      __counter[__i].merge(__counter[__i-1], __comp);
1024*404b540aSrobert	    this->swap(__counter[__fill-1]);
1025*404b540aSrobert	  }
1026*404b540aSrobert      }
1027*404b540aSrobert
1028*404b540aSrobert_GLIBCXX_END_NAMESPACE
1029*404b540aSrobert
1030*404b540aSrobert_GLIBCXX_BEGIN_NAMESPACE(std)
1031*404b540aSrobert
1032*404b540aSrobert  // Specialization of insert_iterator so that insertions will be constant
1033*404b540aSrobert  // time rather than linear time.
1034*404b540aSrobert  template <class _Tp, class _Alloc>
1035*404b540aSrobert    class insert_iterator<__gnu_cxx::slist<_Tp, _Alloc> >
1036*404b540aSrobert    {
1037*404b540aSrobert    protected:
1038*404b540aSrobert      typedef __gnu_cxx::slist<_Tp, _Alloc> _Container;
1039*404b540aSrobert      _Container* container;
1040*404b540aSrobert      typename _Container::iterator iter;
1041*404b540aSrobert
1042*404b540aSrobert    public:
1043*404b540aSrobert      typedef _Container          container_type;
1044*404b540aSrobert      typedef output_iterator_tag iterator_category;
1045*404b540aSrobert      typedef void                value_type;
1046*404b540aSrobert      typedef void                difference_type;
1047*404b540aSrobert      typedef void                pointer;
1048*404b540aSrobert      typedef void                reference;
1049*404b540aSrobert
1050*404b540aSrobert      insert_iterator(_Container& __x, typename _Container::iterator __i)
1051*404b540aSrobert      : container(&__x)
1052*404b540aSrobert      {
1053*404b540aSrobert	if (__i == __x.begin())
1054*404b540aSrobert	  iter = __x.before_begin();
1055*404b540aSrobert	else
1056*404b540aSrobert	  iter = __x.previous(__i);
1057*404b540aSrobert      }
1058*404b540aSrobert
1059*404b540aSrobert      insert_iterator<_Container>&
1060*404b540aSrobert      operator=(const typename _Container::value_type& __value)
1061*404b540aSrobert      {
1062*404b540aSrobert	iter = container->insert_after(iter, __value);
1063*404b540aSrobert	return *this;
1064*404b540aSrobert      }
1065*404b540aSrobert
1066*404b540aSrobert      insert_iterator<_Container>&
1067*404b540aSrobert      operator*()
1068*404b540aSrobert      { return *this; }
1069*404b540aSrobert
1070*404b540aSrobert      insert_iterator<_Container>&
1071*404b540aSrobert      operator++()
1072*404b540aSrobert      { return *this; }
1073*404b540aSrobert
1074*404b540aSrobert      insert_iterator<_Container>&
1075*404b540aSrobert      operator++(int)
1076*404b540aSrobert      { return *this; }
1077*404b540aSrobert    };
1078*404b540aSrobert
1079*404b540aSrobert_GLIBCXX_END_NAMESPACE
1080*404b540aSrobert
1081*404b540aSrobert#endif
1082