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