100db7afdSDavid E. O'Brien// Singly-linked list implementation -*- C++ -*-
200db7afdSDavid E. O'Brien
3*f8a1b7d9SAlexander Kabaev// Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
400db7afdSDavid E. O'Brien//
500db7afdSDavid E. O'Brien// This file is part of the GNU ISO C++ Library.  This library is free
600db7afdSDavid E. O'Brien// software; you can redistribute it and/or modify it under the
700db7afdSDavid E. O'Brien// terms of the GNU General Public License as published by the
800db7afdSDavid E. O'Brien// Free Software Foundation; either version 2, or (at your option)
900db7afdSDavid E. O'Brien// any later version.
1000db7afdSDavid E. O'Brien
1100db7afdSDavid E. O'Brien// This library is distributed in the hope that it will be useful,
1200db7afdSDavid E. O'Brien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1300db7afdSDavid E. O'Brien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1400db7afdSDavid E. O'Brien// GNU General Public License for more details.
1500db7afdSDavid E. O'Brien
1600db7afdSDavid E. O'Brien// You should have received a copy of the GNU General Public License along
1700db7afdSDavid E. O'Brien// with this library; see the file COPYING.  If not, write to the Free
18*f8a1b7d9SAlexander Kabaev// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
1900db7afdSDavid E. O'Brien// USA.
2000db7afdSDavid E. O'Brien
2100db7afdSDavid E. O'Brien// As a special exception, you may use this file as part of a free software
2200db7afdSDavid E. O'Brien// library without restriction.  Specifically, if other files instantiate
2300db7afdSDavid E. O'Brien// templates or use macros or inline functions from this file, or you compile
2400db7afdSDavid E. O'Brien// this file and link it with other files to produce an executable, this
2500db7afdSDavid E. O'Brien// file does not by itself cause the resulting executable to be covered by
2600db7afdSDavid E. O'Brien// the GNU General Public License.  This exception does not however
2700db7afdSDavid E. O'Brien// invalidate any other reasons why the executable file might be covered by
2800db7afdSDavid E. O'Brien// the GNU General Public License.
2900db7afdSDavid E. O'Brien
3000db7afdSDavid E. O'Brien/*
3100db7afdSDavid E. O'Brien * Copyright (c) 1997
3200db7afdSDavid E. O'Brien * Silicon Graphics Computer Systems, Inc.
3300db7afdSDavid E. O'Brien *
3400db7afdSDavid E. O'Brien * Permission to use, copy, modify, distribute and sell this software
3500db7afdSDavid E. O'Brien * and its documentation for any purpose is hereby granted without fee,
3600db7afdSDavid E. O'Brien * provided that the above copyright notice appear in all copies and
3700db7afdSDavid E. O'Brien * that both that copyright notice and this permission notice appear
3800db7afdSDavid E. O'Brien * in supporting documentation.  Silicon Graphics makes no
3900db7afdSDavid E. O'Brien * representations about the suitability of this software for any
4000db7afdSDavid E. O'Brien * purpose.  It is provided "as is" without express or implied warranty.
4100db7afdSDavid E. O'Brien *
4200db7afdSDavid E. O'Brien */
4300db7afdSDavid E. O'Brien
4400db7afdSDavid E. O'Brien/** @file ext/slist
4500db7afdSDavid E. O'Brien *  This file is a GNU extension to the Standard C++ Library (possibly
46*f8a1b7d9SAlexander Kabaev *  containing extensions from the HP/SGI STL subset).
4700db7afdSDavid E. O'Brien */
4800db7afdSDavid E. O'Brien
49ffeaf689SAlexander Kabaev#ifndef _SLIST
50ffeaf689SAlexander Kabaev#define _SLIST 1
5100db7afdSDavid E. O'Brien
5200db7afdSDavid E. O'Brien#include <bits/stl_algobase.h>
53ffeaf689SAlexander Kabaev#include <bits/allocator.h>
5400db7afdSDavid E. O'Brien#include <bits/stl_construct.h>
5500db7afdSDavid E. O'Brien#include <bits/stl_uninitialized.h>
5600db7afdSDavid E. O'Brien#include <bits/concept_check.h>
5700db7afdSDavid E. O'Brien
58*f8a1b7d9SAlexander Kabaev_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
59*f8a1b7d9SAlexander Kabaev
6000db7afdSDavid E. O'Brien  using std::size_t;
6100db7afdSDavid E. O'Brien  using std::ptrdiff_t;
6200db7afdSDavid E. O'Brien  using std::_Construct;
6300db7afdSDavid E. O'Brien  using std::_Destroy;
6400db7afdSDavid E. O'Brien  using std::allocator;
65*f8a1b7d9SAlexander Kabaev  using std::__true_type;
66*f8a1b7d9SAlexander Kabaev  using std::__false_type;
6700db7afdSDavid E. O'Brien
6800db7afdSDavid E. O'Brien  struct _Slist_node_base
6900db7afdSDavid E. O'Brien  {
7000db7afdSDavid E. O'Brien    _Slist_node_base* _M_next;
7100db7afdSDavid E. O'Brien  };
7200db7afdSDavid E. O'Brien
7300db7afdSDavid E. O'Brien  inline _Slist_node_base*
7400db7afdSDavid E. O'Brien  __slist_make_link(_Slist_node_base* __prev_node,
7500db7afdSDavid E. O'Brien		    _Slist_node_base* __new_node)
7600db7afdSDavid E. O'Brien  {
7700db7afdSDavid E. O'Brien    __new_node->_M_next = __prev_node->_M_next;
7800db7afdSDavid E. O'Brien    __prev_node->_M_next = __new_node;
7900db7afdSDavid E. O'Brien    return __new_node;
8000db7afdSDavid E. O'Brien  }
8100db7afdSDavid E. O'Brien
8200db7afdSDavid E. O'Brien  inline _Slist_node_base*
8300db7afdSDavid E. O'Brien  __slist_previous(_Slist_node_base* __head,
8400db7afdSDavid E. O'Brien		   const _Slist_node_base* __node)
8500db7afdSDavid E. O'Brien  {
8600db7afdSDavid E. O'Brien    while (__head && __head->_M_next != __node)
8700db7afdSDavid E. O'Brien      __head = __head->_M_next;
8800db7afdSDavid E. O'Brien    return __head;
8900db7afdSDavid E. O'Brien  }
9000db7afdSDavid E. O'Brien
9100db7afdSDavid E. O'Brien  inline const _Slist_node_base*
9200db7afdSDavid E. O'Brien  __slist_previous(const _Slist_node_base* __head,
9300db7afdSDavid E. O'Brien		   const _Slist_node_base* __node)
9400db7afdSDavid E. O'Brien  {
9500db7afdSDavid E. O'Brien    while (__head && __head->_M_next != __node)
9600db7afdSDavid E. O'Brien      __head = __head->_M_next;
9700db7afdSDavid E. O'Brien    return __head;
9800db7afdSDavid E. O'Brien  }
9900db7afdSDavid E. O'Brien
100*f8a1b7d9SAlexander Kabaev  inline void
101*f8a1b7d9SAlexander Kabaev  __slist_splice_after(_Slist_node_base* __pos,
10200db7afdSDavid E. O'Brien		       _Slist_node_base* __before_first,
10300db7afdSDavid E. O'Brien		       _Slist_node_base* __before_last)
10400db7afdSDavid E. O'Brien  {
105*f8a1b7d9SAlexander Kabaev    if (__pos != __before_first && __pos != __before_last)
106*f8a1b7d9SAlexander Kabaev      {
10700db7afdSDavid E. O'Brien	_Slist_node_base* __first = __before_first->_M_next;
10800db7afdSDavid E. O'Brien	_Slist_node_base* __after = __pos->_M_next;
10900db7afdSDavid E. O'Brien	__before_first->_M_next = __before_last->_M_next;
11000db7afdSDavid E. O'Brien	__pos->_M_next = __first;
11100db7afdSDavid E. O'Brien	__before_last->_M_next = __after;
11200db7afdSDavid E. O'Brien      }
11300db7afdSDavid E. O'Brien  }
11400db7afdSDavid E. O'Brien
11500db7afdSDavid E. O'Brien  inline void
11600db7afdSDavid E. O'Brien  __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head)
11700db7afdSDavid E. O'Brien  {
11800db7afdSDavid E. O'Brien    _Slist_node_base* __before_last = __slist_previous(__head, 0);
119*f8a1b7d9SAlexander Kabaev    if (__before_last != __head)
120*f8a1b7d9SAlexander Kabaev      {
12100db7afdSDavid E. O'Brien	_Slist_node_base* __after = __pos->_M_next;
12200db7afdSDavid E. O'Brien	__pos->_M_next = __head->_M_next;
12300db7afdSDavid E. O'Brien	__head->_M_next = 0;
12400db7afdSDavid E. O'Brien	__before_last->_M_next = __after;
12500db7afdSDavid E. O'Brien      }
12600db7afdSDavid E. O'Brien  }
12700db7afdSDavid E. O'Brien
128*f8a1b7d9SAlexander Kabaev  inline _Slist_node_base*
129*f8a1b7d9SAlexander Kabaev  __slist_reverse(_Slist_node_base* __node)
13000db7afdSDavid E. O'Brien  {
13100db7afdSDavid E. O'Brien    _Slist_node_base* __result = __node;
13200db7afdSDavid E. O'Brien    __node = __node->_M_next;
13300db7afdSDavid E. O'Brien    __result->_M_next = 0;
134*f8a1b7d9SAlexander Kabaev    while(__node)
135*f8a1b7d9SAlexander Kabaev      {
13600db7afdSDavid E. O'Brien	_Slist_node_base* __next = __node->_M_next;
13700db7afdSDavid E. O'Brien	__node->_M_next = __result;
13800db7afdSDavid E. O'Brien	__result = __node;
13900db7afdSDavid E. O'Brien	__node = __next;
14000db7afdSDavid E. O'Brien      }
14100db7afdSDavid E. O'Brien    return __result;
14200db7afdSDavid E. O'Brien  }
14300db7afdSDavid E. O'Brien
144*f8a1b7d9SAlexander Kabaev  inline size_t
145*f8a1b7d9SAlexander Kabaev  __slist_size(_Slist_node_base* __node)
14600db7afdSDavid E. O'Brien  {
14700db7afdSDavid E. O'Brien    size_t __result = 0;
14800db7afdSDavid E. O'Brien    for (; __node != 0; __node = __node->_M_next)
14900db7afdSDavid E. O'Brien      ++__result;
15000db7afdSDavid E. O'Brien    return __result;
15100db7afdSDavid E. O'Brien  }
15200db7afdSDavid E. O'Brien
15300db7afdSDavid E. O'Brien  template <class _Tp>
15400db7afdSDavid E. O'Brien    struct _Slist_node : public _Slist_node_base
15500db7afdSDavid E. O'Brien    {
15600db7afdSDavid E. O'Brien      _Tp _M_data;
15700db7afdSDavid E. O'Brien    };
15800db7afdSDavid E. O'Brien
15900db7afdSDavid E. O'Brien  struct _Slist_iterator_base
16000db7afdSDavid E. O'Brien  {
16100db7afdSDavid E. O'Brien    typedef size_t                    size_type;
16200db7afdSDavid E. O'Brien    typedef ptrdiff_t                 difference_type;
16300db7afdSDavid E. O'Brien    typedef std::forward_iterator_tag iterator_category;
16400db7afdSDavid E. O'Brien
16500db7afdSDavid E. O'Brien    _Slist_node_base* _M_node;
16600db7afdSDavid E. O'Brien
167*f8a1b7d9SAlexander Kabaev    _Slist_iterator_base(_Slist_node_base* __x)
168*f8a1b7d9SAlexander Kabaev    : _M_node(__x) {}
16900db7afdSDavid E. O'Brien
170*f8a1b7d9SAlexander Kabaev    void
171*f8a1b7d9SAlexander Kabaev    _M_incr()
172*f8a1b7d9SAlexander Kabaev    { _M_node = _M_node->_M_next; }
173*f8a1b7d9SAlexander Kabaev
174*f8a1b7d9SAlexander Kabaev    bool
175*f8a1b7d9SAlexander Kabaev    operator==(const _Slist_iterator_base& __x) const
176*f8a1b7d9SAlexander Kabaev    { return _M_node == __x._M_node; }
177*f8a1b7d9SAlexander Kabaev
178*f8a1b7d9SAlexander Kabaev    bool
179*f8a1b7d9SAlexander Kabaev    operator!=(const _Slist_iterator_base& __x) const
180*f8a1b7d9SAlexander Kabaev    { return _M_node != __x._M_node; }
18100db7afdSDavid E. O'Brien  };
18200db7afdSDavid E. O'Brien
18300db7afdSDavid E. O'Brien  template <class _Tp, class _Ref, class _Ptr>
18400db7afdSDavid E. O'Brien    struct _Slist_iterator : public _Slist_iterator_base
18500db7afdSDavid E. O'Brien    {
18600db7afdSDavid E. O'Brien      typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
18700db7afdSDavid E. O'Brien      typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
18800db7afdSDavid E. O'Brien      typedef _Slist_iterator<_Tp, _Ref, _Ptr>             _Self;
18900db7afdSDavid E. O'Brien
19000db7afdSDavid E. O'Brien      typedef _Tp              value_type;
19100db7afdSDavid E. O'Brien      typedef _Ptr             pointer;
19200db7afdSDavid E. O'Brien      typedef _Ref             reference;
19300db7afdSDavid E. O'Brien      typedef _Slist_node<_Tp> _Node;
19400db7afdSDavid E. O'Brien
195*f8a1b7d9SAlexander Kabaev      explicit
196*f8a1b7d9SAlexander Kabaev      _Slist_iterator(_Node* __x)
197*f8a1b7d9SAlexander Kabaev      : _Slist_iterator_base(__x) {}
19800db7afdSDavid E. O'Brien
199*f8a1b7d9SAlexander Kabaev      _Slist_iterator()
200*f8a1b7d9SAlexander Kabaev      : _Slist_iterator_base(0) {}
20100db7afdSDavid E. O'Brien
202*f8a1b7d9SAlexander Kabaev      _Slist_iterator(const iterator& __x)
203*f8a1b7d9SAlexander Kabaev      : _Slist_iterator_base(__x._M_node) {}
204*f8a1b7d9SAlexander Kabaev
205*f8a1b7d9SAlexander Kabaev      reference
206*f8a1b7d9SAlexander Kabaev      operator*() const
207*f8a1b7d9SAlexander Kabaev      { return ((_Node*) _M_node)->_M_data; }
208*f8a1b7d9SAlexander Kabaev
209*f8a1b7d9SAlexander Kabaev      pointer
210*f8a1b7d9SAlexander Kabaev      operator->() const
211*f8a1b7d9SAlexander Kabaev      { return &(operator*()); }
212*f8a1b7d9SAlexander Kabaev
213*f8a1b7d9SAlexander Kabaev      _Self&
214*f8a1b7d9SAlexander Kabaev      operator++()
21500db7afdSDavid E. O'Brien      {
21600db7afdSDavid E. O'Brien	_M_incr();
21700db7afdSDavid E. O'Brien	return *this;
21800db7afdSDavid E. O'Brien      }
219*f8a1b7d9SAlexander Kabaev
220*f8a1b7d9SAlexander Kabaev      _Self
221*f8a1b7d9SAlexander Kabaev      operator++(int)
22200db7afdSDavid E. O'Brien      {
22300db7afdSDavid E. O'Brien	_Self __tmp = *this;
22400db7afdSDavid E. O'Brien	_M_incr();
22500db7afdSDavid E. O'Brien	return __tmp;
22600db7afdSDavid E. O'Brien      }
22700db7afdSDavid E. O'Brien    };
22800db7afdSDavid E. O'Brien
22900db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
23000db7afdSDavid E. O'Brien    struct _Slist_base
231ffeaf689SAlexander Kabaev    : public _Alloc::template rebind<_Slist_node<_Tp> >::other
23200db7afdSDavid E. O'Brien    {
233*f8a1b7d9SAlexander Kabaev      typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other
234*f8a1b7d9SAlexander Kabaev        _Node_alloc;
235ffeaf689SAlexander Kabaev      typedef _Alloc allocator_type;
236*f8a1b7d9SAlexander Kabaev
237*f8a1b7d9SAlexander Kabaev      allocator_type
238*f8a1b7d9SAlexander Kabaev      get_allocator() const
239*f8a1b7d9SAlexander Kabaev      { return *static_cast<const _Node_alloc*>(this); }
24000db7afdSDavid E. O'Brien
24100db7afdSDavid E. O'Brien      _Slist_base(const allocator_type& __a)
242*f8a1b7d9SAlexander Kabaev      : _Node_alloc(__a)
243*f8a1b7d9SAlexander Kabaev      { this->_M_head._M_next = 0; }
244*f8a1b7d9SAlexander Kabaev
245*f8a1b7d9SAlexander Kabaev      ~_Slist_base()
246*f8a1b7d9SAlexander Kabaev      { _M_erase_after(&this->_M_head, 0); }
24700db7afdSDavid E. O'Brien
24800db7afdSDavid E. O'Brien    protected:
249ffeaf689SAlexander Kabaev      _Slist_node_base _M_head;
25000db7afdSDavid E. O'Brien
251*f8a1b7d9SAlexander Kabaev      _Slist_node<_Tp>*
252*f8a1b7d9SAlexander Kabaev      _M_get_node()
253*f8a1b7d9SAlexander Kabaev      { return _Node_alloc::allocate(1); }
254*f8a1b7d9SAlexander Kabaev
255*f8a1b7d9SAlexander Kabaev      void
256*f8a1b7d9SAlexander Kabaev      _M_put_node(_Slist_node<_Tp>* __p)
257*f8a1b7d9SAlexander Kabaev      { _Node_alloc::deallocate(__p, 1); }
258ffeaf689SAlexander Kabaev
259ffeaf689SAlexander Kabaev    protected:
26000db7afdSDavid E. O'Brien      _Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
26100db7afdSDavid E. O'Brien      {
26200db7afdSDavid E. O'Brien	_Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);
26300db7afdSDavid E. O'Brien	_Slist_node_base* __next_next = __next->_M_next;
26400db7afdSDavid E. O'Brien	__pos->_M_next = __next_next;
265*f8a1b7d9SAlexander Kabaev	get_allocator().destroy(&__next->_M_data);
26600db7afdSDavid E. O'Brien	_M_put_node(__next);
26700db7afdSDavid E. O'Brien	return __next_next;
26800db7afdSDavid E. O'Brien      }
26900db7afdSDavid E. O'Brien      _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
27000db7afdSDavid E. O'Brien    };
27100db7afdSDavid E. O'Brien
27200db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
27300db7afdSDavid E. O'Brien    _Slist_node_base*
27400db7afdSDavid E. O'Brien    _Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first,
275*f8a1b7d9SAlexander Kabaev					    _Slist_node_base* __last_node)
276*f8a1b7d9SAlexander Kabaev    {
27700db7afdSDavid E. O'Brien      _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next);
278*f8a1b7d9SAlexander Kabaev      while (__cur != __last_node)
279*f8a1b7d9SAlexander Kabaev	{
28000db7afdSDavid E. O'Brien	  _Slist_node<_Tp>* __tmp = __cur;
28100db7afdSDavid E. O'Brien	  __cur = (_Slist_node<_Tp>*) __cur->_M_next;
282*f8a1b7d9SAlexander Kabaev	  get_allocator().destroy(&__tmp->_M_data);
28300db7afdSDavid E. O'Brien	  _M_put_node(__tmp);
28400db7afdSDavid E. O'Brien	}
28500db7afdSDavid E. O'Brien      __before_first->_M_next = __last_node;
28600db7afdSDavid E. O'Brien      return __last_node;
28700db7afdSDavid E. O'Brien    }
28800db7afdSDavid E. O'Brien
289ca6500fcSAlexander Kabaev  /**
290ca6500fcSAlexander Kabaev   *  This is an SGI extension.
291ca6500fcSAlexander Kabaev   *  @ingroup SGIextensions
292ca6500fcSAlexander Kabaev   *  @doctodo
293ca6500fcSAlexander Kabaev   */
29400db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc = allocator<_Tp> >
29500db7afdSDavid E. O'Brien    class slist : private _Slist_base<_Tp,_Alloc>
29600db7afdSDavid E. O'Brien    {
29700db7afdSDavid E. O'Brien      // concept requirements
298ffeaf689SAlexander Kabaev      __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
29900db7afdSDavid E. O'Brien
30000db7afdSDavid E. O'Brien    private:
30100db7afdSDavid E. O'Brien      typedef _Slist_base<_Tp,_Alloc> _Base;
302*f8a1b7d9SAlexander Kabaev
30300db7afdSDavid E. O'Brien    public:
30400db7afdSDavid E. O'Brien      typedef _Tp               value_type;
30500db7afdSDavid E. O'Brien      typedef value_type*       pointer;
30600db7afdSDavid E. O'Brien      typedef const value_type* const_pointer;
30700db7afdSDavid E. O'Brien      typedef value_type&       reference;
30800db7afdSDavid E. O'Brien      typedef const value_type& const_reference;
30900db7afdSDavid E. O'Brien      typedef size_t            size_type;
31000db7afdSDavid E. O'Brien      typedef ptrdiff_t         difference_type;
31100db7afdSDavid E. O'Brien
31200db7afdSDavid E. O'Brien      typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
31300db7afdSDavid E. O'Brien      typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
31400db7afdSDavid E. O'Brien
31500db7afdSDavid E. O'Brien      typedef typename _Base::allocator_type allocator_type;
316*f8a1b7d9SAlexander Kabaev
317*f8a1b7d9SAlexander Kabaev      allocator_type
318*f8a1b7d9SAlexander Kabaev      get_allocator() const
319*f8a1b7d9SAlexander Kabaev      { return _Base::get_allocator(); }
32000db7afdSDavid E. O'Brien
32100db7afdSDavid E. O'Brien    private:
32200db7afdSDavid E. O'Brien      typedef _Slist_node<_Tp>      _Node;
32300db7afdSDavid E. O'Brien      typedef _Slist_node_base      _Node_base;
32400db7afdSDavid E. O'Brien      typedef _Slist_iterator_base  _Iterator_base;
32500db7afdSDavid E. O'Brien
326*f8a1b7d9SAlexander Kabaev      _Node*
327*f8a1b7d9SAlexander Kabaev      _M_create_node(const value_type& __x)
328*f8a1b7d9SAlexander Kabaev      {
32900db7afdSDavid E. O'Brien	_Node* __node = this->_M_get_node();
330*f8a1b7d9SAlexander Kabaev	try
331*f8a1b7d9SAlexander Kabaev	  {
332*f8a1b7d9SAlexander Kabaev	    get_allocator().construct(&__node->_M_data, __x);
33300db7afdSDavid E. O'Brien	    __node->_M_next = 0;
33400db7afdSDavid E. O'Brien	  }
33500db7afdSDavid E. O'Brien	catch(...)
33600db7afdSDavid E. O'Brien	  {
33700db7afdSDavid E. O'Brien	    this->_M_put_node(__node);
33800db7afdSDavid E. O'Brien	    __throw_exception_again;
33900db7afdSDavid E. O'Brien	  }
34000db7afdSDavid E. O'Brien	return __node;
34100db7afdSDavid E. O'Brien      }
34200db7afdSDavid E. O'Brien
343*f8a1b7d9SAlexander Kabaev      _Node*
344*f8a1b7d9SAlexander Kabaev      _M_create_node()
345*f8a1b7d9SAlexander Kabaev      {
34600db7afdSDavid E. O'Brien	_Node* __node = this->_M_get_node();
347*f8a1b7d9SAlexander Kabaev	try
348*f8a1b7d9SAlexander Kabaev	  {
349*f8a1b7d9SAlexander Kabaev	    get_allocator().construct(&__node->_M_data, value_type());
35000db7afdSDavid E. O'Brien	    __node->_M_next = 0;
35100db7afdSDavid E. O'Brien	  }
35200db7afdSDavid E. O'Brien	catch(...)
35300db7afdSDavid E. O'Brien	  {
35400db7afdSDavid E. O'Brien	    this->_M_put_node(__node);
35500db7afdSDavid E. O'Brien	    __throw_exception_again;
35600db7afdSDavid E. O'Brien	  }
35700db7afdSDavid E. O'Brien	return __node;
35800db7afdSDavid E. O'Brien      }
35900db7afdSDavid E. O'Brien
36000db7afdSDavid E. O'Brien    public:
361*f8a1b7d9SAlexander Kabaev      explicit
362*f8a1b7d9SAlexander Kabaev      slist(const allocator_type& __a = allocator_type())
363*f8a1b7d9SAlexander Kabaev      : _Base(__a) {}
36400db7afdSDavid E. O'Brien
36500db7afdSDavid E. O'Brien      slist(size_type __n, const value_type& __x,
366*f8a1b7d9SAlexander Kabaev	    const allocator_type& __a =  allocator_type())
367*f8a1b7d9SAlexander Kabaev      : _Base(__a)
36800db7afdSDavid E. O'Brien      { _M_insert_after_fill(&this->_M_head, __n, __x); }
36900db7afdSDavid E. O'Brien
370*f8a1b7d9SAlexander Kabaev      explicit
371*f8a1b7d9SAlexander Kabaev      slist(size_type __n)
372*f8a1b7d9SAlexander Kabaev      : _Base(allocator_type())
37300db7afdSDavid E. O'Brien      { _M_insert_after_fill(&this->_M_head, __n, value_type()); }
37400db7afdSDavid E. O'Brien
375*f8a1b7d9SAlexander Kabaev      // We don't need any dispatching tricks here, because
376*f8a1b7d9SAlexander Kabaev      // _M_insert_after_range already does them.
37700db7afdSDavid E. O'Brien      template <class _InputIterator>
37800db7afdSDavid E. O'Brien        slist(_InputIterator __first, _InputIterator __last,
379*f8a1b7d9SAlexander Kabaev	      const allocator_type& __a =  allocator_type())
380*f8a1b7d9SAlexander Kabaev	: _Base(__a)
38100db7afdSDavid E. O'Brien        { _M_insert_after_range(&this->_M_head, __first, __last); }
38200db7afdSDavid E. O'Brien
383*f8a1b7d9SAlexander Kabaev      slist(const slist& __x)
384*f8a1b7d9SAlexander Kabaev      : _Base(__x.get_allocator())
38500db7afdSDavid E. O'Brien      { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); }
38600db7afdSDavid E. O'Brien
387*f8a1b7d9SAlexander Kabaev      slist&
388*f8a1b7d9SAlexander Kabaev      operator= (const slist& __x);
38900db7afdSDavid E. O'Brien
39000db7afdSDavid E. O'Brien      ~slist() {}
39100db7afdSDavid E. O'Brien
39200db7afdSDavid E. O'Brien    public:
39300db7afdSDavid E. O'Brien      // assign(), a generalized assignment member function.  Two
39400db7afdSDavid E. O'Brien      // versions: one that takes a count, and one that takes a range.
39500db7afdSDavid E. O'Brien      // The range version is a member template, so we dispatch on whether
39600db7afdSDavid E. O'Brien      // or not the type is an integer.
39700db7afdSDavid E. O'Brien
398*f8a1b7d9SAlexander Kabaev      void
399*f8a1b7d9SAlexander Kabaev      assign(size_type __n, const _Tp& __val)
40000db7afdSDavid E. O'Brien      { _M_fill_assign(__n, __val); }
40100db7afdSDavid E. O'Brien
402*f8a1b7d9SAlexander Kabaev      void
403*f8a1b7d9SAlexander Kabaev      _M_fill_assign(size_type __n, const _Tp& __val);
40400db7afdSDavid E. O'Brien
40500db7afdSDavid E. O'Brien      template <class _InputIterator>
406*f8a1b7d9SAlexander Kabaev        void
407*f8a1b7d9SAlexander Kabaev        assign(_InputIterator __first, _InputIterator __last)
408*f8a1b7d9SAlexander Kabaev        {
409*f8a1b7d9SAlexander Kabaev	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
41000db7afdSDavid E. O'Brien	  _M_assign_dispatch(__first, __last, _Integral());
41100db7afdSDavid E. O'Brien	}
41200db7afdSDavid E. O'Brien
41300db7afdSDavid E. O'Brien      template <class _Integer>
414*f8a1b7d9SAlexander Kabaev      void
415*f8a1b7d9SAlexander Kabaev      _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
41600db7afdSDavid E. O'Brien      { _M_fill_assign((size_type) __n, (_Tp) __val); }
41700db7afdSDavid E. O'Brien
41800db7afdSDavid E. O'Brien      template <class _InputIterator>
419*f8a1b7d9SAlexander Kabaev      void
420*f8a1b7d9SAlexander Kabaev      _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
42100db7afdSDavid E. O'Brien			 __false_type);
42200db7afdSDavid E. O'Brien
42300db7afdSDavid E. O'Brien    public:
42400db7afdSDavid E. O'Brien
425*f8a1b7d9SAlexander Kabaev      iterator
426*f8a1b7d9SAlexander Kabaev      begin()
427*f8a1b7d9SAlexander Kabaev      { return iterator((_Node*)this->_M_head._M_next); }
428*f8a1b7d9SAlexander Kabaev
429*f8a1b7d9SAlexander Kabaev      const_iterator
430*f8a1b7d9SAlexander Kabaev      begin() const
43100db7afdSDavid E. O'Brien      { return const_iterator((_Node*)this->_M_head._M_next);}
43200db7afdSDavid E. O'Brien
433*f8a1b7d9SAlexander Kabaev      iterator
434*f8a1b7d9SAlexander Kabaev      end()
435*f8a1b7d9SAlexander Kabaev      { return iterator(0); }
436*f8a1b7d9SAlexander Kabaev
437*f8a1b7d9SAlexander Kabaev      const_iterator
438*f8a1b7d9SAlexander Kabaev      end() const
439*f8a1b7d9SAlexander Kabaev      { return const_iterator(0); }
44000db7afdSDavid E. O'Brien
44100db7afdSDavid E. O'Brien      // Experimental new feature: before_begin() returns a
44200db7afdSDavid E. O'Brien      // non-dereferenceable iterator that, when incremented, yields
44300db7afdSDavid E. O'Brien      // begin().  This iterator may be used as the argument to
44400db7afdSDavid E. O'Brien      // insert_after, erase_after, etc.  Note that even for an empty
44500db7afdSDavid E. O'Brien      // slist, before_begin() is not the same iterator as end().  It
44600db7afdSDavid E. O'Brien      // is always necessary to increment before_begin() at least once to
44700db7afdSDavid E. O'Brien      // obtain end().
448*f8a1b7d9SAlexander Kabaev      iterator
449*f8a1b7d9SAlexander Kabaev      before_begin()
450*f8a1b7d9SAlexander Kabaev      { return iterator((_Node*) &this->_M_head); }
451*f8a1b7d9SAlexander Kabaev
452*f8a1b7d9SAlexander Kabaev      const_iterator
453*f8a1b7d9SAlexander Kabaev      before_begin() const
45400db7afdSDavid E. O'Brien      { return const_iterator((_Node*) &this->_M_head); }
45500db7afdSDavid E. O'Brien
456*f8a1b7d9SAlexander Kabaev      size_type
457*f8a1b7d9SAlexander Kabaev      size() const
458*f8a1b7d9SAlexander Kabaev      { return __slist_size(this->_M_head._M_next); }
45900db7afdSDavid E. O'Brien
460*f8a1b7d9SAlexander Kabaev      size_type
461*f8a1b7d9SAlexander Kabaev      max_size() const
462*f8a1b7d9SAlexander Kabaev      { return size_type(-1); }
46300db7afdSDavid E. O'Brien
464*f8a1b7d9SAlexander Kabaev      bool
465*f8a1b7d9SAlexander Kabaev      empty() const
466*f8a1b7d9SAlexander Kabaev      { return this->_M_head._M_next == 0; }
46700db7afdSDavid E. O'Brien
468*f8a1b7d9SAlexander Kabaev      void
469*f8a1b7d9SAlexander Kabaev      swap(slist& __x)
47000db7afdSDavid E. O'Brien      { std::swap(this->_M_head._M_next, __x._M_head._M_next); }
47100db7afdSDavid E. O'Brien
47200db7afdSDavid E. O'Brien    public:
47300db7afdSDavid E. O'Brien
474*f8a1b7d9SAlexander Kabaev      reference
475*f8a1b7d9SAlexander Kabaev      front()
47600db7afdSDavid E. O'Brien      { return ((_Node*) this->_M_head._M_next)->_M_data; }
477*f8a1b7d9SAlexander Kabaev
478*f8a1b7d9SAlexander Kabaev      const_reference
479*f8a1b7d9SAlexander Kabaev      front() const
480*f8a1b7d9SAlexander Kabaev      { return ((_Node*) this->_M_head._M_next)->_M_data; }
481*f8a1b7d9SAlexander Kabaev
482*f8a1b7d9SAlexander Kabaev      void
483*f8a1b7d9SAlexander Kabaev      push_front(const value_type& __x)
484*f8a1b7d9SAlexander Kabaev      { __slist_make_link(&this->_M_head, _M_create_node(__x)); }
485*f8a1b7d9SAlexander Kabaev
486*f8a1b7d9SAlexander Kabaev      void
487*f8a1b7d9SAlexander Kabaev      push_front()
488*f8a1b7d9SAlexander Kabaev      { __slist_make_link(&this->_M_head, _M_create_node()); }
489*f8a1b7d9SAlexander Kabaev
490*f8a1b7d9SAlexander Kabaev      void
491*f8a1b7d9SAlexander Kabaev      pop_front()
492*f8a1b7d9SAlexander Kabaev      {
49300db7afdSDavid E. O'Brien	_Node* __node = (_Node*) this->_M_head._M_next;
49400db7afdSDavid E. O'Brien	this->_M_head._M_next = __node->_M_next;
495*f8a1b7d9SAlexander Kabaev	get_allocator().destroy(&__node->_M_data);
49600db7afdSDavid E. O'Brien	this->_M_put_node(__node);
49700db7afdSDavid E. O'Brien      }
49800db7afdSDavid E. O'Brien
499*f8a1b7d9SAlexander Kabaev      iterator
500*f8a1b7d9SAlexander Kabaev      previous(const_iterator __pos)
501*f8a1b7d9SAlexander Kabaev      { return iterator((_Node*) __slist_previous(&this->_M_head,
502*f8a1b7d9SAlexander Kabaev						  __pos._M_node)); }
503*f8a1b7d9SAlexander Kabaev
504*f8a1b7d9SAlexander Kabaev      const_iterator
505*f8a1b7d9SAlexander Kabaev      previous(const_iterator __pos) const
506*f8a1b7d9SAlexander Kabaev      { return const_iterator((_Node*) __slist_previous(&this->_M_head,
507*f8a1b7d9SAlexander Kabaev							__pos._M_node)); }
50800db7afdSDavid E. O'Brien
50900db7afdSDavid E. O'Brien    private:
510*f8a1b7d9SAlexander Kabaev      _Node*
511*f8a1b7d9SAlexander Kabaev      _M_insert_after(_Node_base* __pos, const value_type& __x)
512*f8a1b7d9SAlexander Kabaev      { return (_Node*) (__slist_make_link(__pos, _M_create_node(__x))); }
51300db7afdSDavid E. O'Brien
514*f8a1b7d9SAlexander Kabaev      _Node*
515*f8a1b7d9SAlexander Kabaev      _M_insert_after(_Node_base* __pos)
516*f8a1b7d9SAlexander Kabaev      { return (_Node*) (__slist_make_link(__pos, _M_create_node())); }
51700db7afdSDavid E. O'Brien
518*f8a1b7d9SAlexander Kabaev      void
519*f8a1b7d9SAlexander Kabaev      _M_insert_after_fill(_Node_base* __pos,
520*f8a1b7d9SAlexander Kabaev			   size_type __n, const value_type& __x)
521*f8a1b7d9SAlexander Kabaev      {
52200db7afdSDavid E. O'Brien	for (size_type __i = 0; __i < __n; ++__i)
52300db7afdSDavid E. O'Brien	  __pos = __slist_make_link(__pos, _M_create_node(__x));
52400db7afdSDavid E. O'Brien      }
52500db7afdSDavid E. O'Brien
52600db7afdSDavid E. O'Brien      // Check whether it's an integral type.  If so, it's not an iterator.
527ffeaf689SAlexander Kabaev      template <class _InIterator>
528*f8a1b7d9SAlexander Kabaev        void
529*f8a1b7d9SAlexander Kabaev        _M_insert_after_range(_Node_base* __pos,
530*f8a1b7d9SAlexander Kabaev			      _InIterator __first, _InIterator __last)
531*f8a1b7d9SAlexander Kabaev        {
532*f8a1b7d9SAlexander Kabaev	  typedef typename std::__is_integer<_InIterator>::__type _Integral;
53300db7afdSDavid E. O'Brien	  _M_insert_after_range(__pos, __first, __last, _Integral());
53400db7afdSDavid E. O'Brien	}
53500db7afdSDavid E. O'Brien
53600db7afdSDavid E. O'Brien      template <class _Integer>
537*f8a1b7d9SAlexander Kabaev        void
538*f8a1b7d9SAlexander Kabaev        _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
539*f8a1b7d9SAlexander Kabaev			      __true_type)
540*f8a1b7d9SAlexander Kabaev        { _M_insert_after_fill(__pos, __n, __x); }
54100db7afdSDavid E. O'Brien
542ffeaf689SAlexander Kabaev      template <class _InIterator>
543*f8a1b7d9SAlexander Kabaev        void
544*f8a1b7d9SAlexander Kabaev        _M_insert_after_range(_Node_base* __pos,
545ffeaf689SAlexander Kabaev			      _InIterator __first, _InIterator __last,
546*f8a1b7d9SAlexander Kabaev			      __false_type)
547*f8a1b7d9SAlexander Kabaev        {
548*f8a1b7d9SAlexander Kabaev	  while (__first != __last)
549*f8a1b7d9SAlexander Kabaev	    {
55000db7afdSDavid E. O'Brien	      __pos = __slist_make_link(__pos, _M_create_node(*__first));
55100db7afdSDavid E. O'Brien	      ++__first;
55200db7afdSDavid E. O'Brien	    }
55300db7afdSDavid E. O'Brien	}
55400db7afdSDavid E. O'Brien
55500db7afdSDavid E. O'Brien    public:
556*f8a1b7d9SAlexander Kabaev      iterator
557*f8a1b7d9SAlexander Kabaev      insert_after(iterator __pos, const value_type& __x)
558*f8a1b7d9SAlexander Kabaev      { return iterator(_M_insert_after(__pos._M_node, __x)); }
55900db7afdSDavid E. O'Brien
560*f8a1b7d9SAlexander Kabaev      iterator
561*f8a1b7d9SAlexander Kabaev      insert_after(iterator __pos)
562*f8a1b7d9SAlexander Kabaev      { return insert_after(__pos, value_type()); }
56300db7afdSDavid E. O'Brien
564*f8a1b7d9SAlexander Kabaev      void
565*f8a1b7d9SAlexander Kabaev      insert_after(iterator __pos, size_type __n, const value_type& __x)
566*f8a1b7d9SAlexander Kabaev      { _M_insert_after_fill(__pos._M_node, __n, __x); }
56700db7afdSDavid E. O'Brien
568*f8a1b7d9SAlexander Kabaev      // We don't need any dispatching tricks here, because
569*f8a1b7d9SAlexander Kabaev      // _M_insert_after_range already does them.
570ffeaf689SAlexander Kabaev      template <class _InIterator>
571*f8a1b7d9SAlexander Kabaev        void
572*f8a1b7d9SAlexander Kabaev        insert_after(iterator __pos, _InIterator __first, _InIterator __last)
573*f8a1b7d9SAlexander Kabaev        { _M_insert_after_range(__pos._M_node, __first, __last); }
57400db7afdSDavid E. O'Brien
575*f8a1b7d9SAlexander Kabaev      iterator
576*f8a1b7d9SAlexander Kabaev      insert(iterator __pos, const value_type& __x)
577*f8a1b7d9SAlexander Kabaev      { return iterator(_M_insert_after(__slist_previous(&this->_M_head,
57800db7afdSDavid E. O'Brien							 __pos._M_node),
579*f8a1b7d9SAlexander Kabaev					__x)); }
58000db7afdSDavid E. O'Brien
581*f8a1b7d9SAlexander Kabaev      iterator
582*f8a1b7d9SAlexander Kabaev      insert(iterator __pos)
583*f8a1b7d9SAlexander Kabaev      { return iterator(_M_insert_after(__slist_previous(&this->_M_head,
58400db7afdSDavid E. O'Brien							 __pos._M_node),
585*f8a1b7d9SAlexander Kabaev					value_type())); }
58600db7afdSDavid E. O'Brien
587*f8a1b7d9SAlexander Kabaev      void
588*f8a1b7d9SAlexander Kabaev      insert(iterator __pos, size_type __n, const value_type& __x)
589*f8a1b7d9SAlexander Kabaev      { _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node),
590*f8a1b7d9SAlexander Kabaev			     __n, __x); }
59100db7afdSDavid E. O'Brien
592*f8a1b7d9SAlexander Kabaev      // We don't need any dispatching tricks here, because
593*f8a1b7d9SAlexander Kabaev      // _M_insert_after_range already does them.
594ffeaf689SAlexander Kabaev      template <class _InIterator>
595*f8a1b7d9SAlexander Kabaev        void
596*f8a1b7d9SAlexander Kabaev        insert(iterator __pos, _InIterator __first, _InIterator __last)
597*f8a1b7d9SAlexander Kabaev        { _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node),
598*f8a1b7d9SAlexander Kabaev				__first, __last); }
59900db7afdSDavid E. O'Brien
60000db7afdSDavid E. O'Brien    public:
601*f8a1b7d9SAlexander Kabaev      iterator
602*f8a1b7d9SAlexander Kabaev      erase_after(iterator __pos)
603*f8a1b7d9SAlexander Kabaev      { return iterator((_Node*) this->_M_erase_after(__pos._M_node)); }
604*f8a1b7d9SAlexander Kabaev
605*f8a1b7d9SAlexander Kabaev      iterator
606*f8a1b7d9SAlexander Kabaev      erase_after(iterator __before_first, iterator __last)
607*f8a1b7d9SAlexander Kabaev      {
60800db7afdSDavid E. O'Brien	return iterator((_Node*) this->_M_erase_after(__before_first._M_node,
60900db7afdSDavid E. O'Brien						      __last._M_node));
61000db7afdSDavid E. O'Brien      }
61100db7afdSDavid E. O'Brien
612*f8a1b7d9SAlexander Kabaev      iterator
613*f8a1b7d9SAlexander Kabaev      erase(iterator __pos)
614*f8a1b7d9SAlexander Kabaev      {
615*f8a1b7d9SAlexander Kabaev	return iterator((_Node*) this->_M_erase_after
616*f8a1b7d9SAlexander Kabaev			(__slist_previous(&this->_M_head, __pos._M_node)));
61700db7afdSDavid E. O'Brien      }
61800db7afdSDavid E. O'Brien
619*f8a1b7d9SAlexander Kabaev      iterator
620*f8a1b7d9SAlexander Kabaev      erase(iterator __first, iterator __last)
621*f8a1b7d9SAlexander Kabaev      {
622*f8a1b7d9SAlexander Kabaev	return iterator((_Node*) this->_M_erase_after
623*f8a1b7d9SAlexander Kabaev			(__slist_previous(&this->_M_head, __first._M_node),
624*f8a1b7d9SAlexander Kabaev			 __last._M_node));
625*f8a1b7d9SAlexander Kabaev      }
626*f8a1b7d9SAlexander Kabaev
627*f8a1b7d9SAlexander Kabaev      void
628*f8a1b7d9SAlexander Kabaev      resize(size_type new_size, const _Tp& __x);
629*f8a1b7d9SAlexander Kabaev
630*f8a1b7d9SAlexander Kabaev      void
631*f8a1b7d9SAlexander Kabaev      resize(size_type new_size)
632*f8a1b7d9SAlexander Kabaev      { resize(new_size, _Tp()); }
633*f8a1b7d9SAlexander Kabaev
634*f8a1b7d9SAlexander Kabaev      void
635*f8a1b7d9SAlexander Kabaev      clear()
636*f8a1b7d9SAlexander Kabaev      { this->_M_erase_after(&this->_M_head, 0); }
63700db7afdSDavid E. O'Brien
63800db7afdSDavid E. O'Brien    public:
63900db7afdSDavid E. O'Brien      // Moves the range [__before_first + 1, __before_last + 1) to *this,
64000db7afdSDavid E. O'Brien      //  inserting it immediately after __pos.  This is constant time.
641*f8a1b7d9SAlexander Kabaev      void
642*f8a1b7d9SAlexander Kabaev      splice_after(iterator __pos,
64300db7afdSDavid E. O'Brien		   iterator __before_first, iterator __before_last)
64400db7afdSDavid E. O'Brien      {
64500db7afdSDavid E. O'Brien	if (__before_first != __before_last)
64600db7afdSDavid E. O'Brien	  __slist_splice_after(__pos._M_node, __before_first._M_node,
64700db7afdSDavid E. O'Brien			       __before_last._M_node);
64800db7afdSDavid E. O'Brien      }
64900db7afdSDavid E. O'Brien
650*f8a1b7d9SAlexander Kabaev      // Moves the element that follows __prev to *this, inserting it
651*f8a1b7d9SAlexander Kabaev      // immediately after __pos.  This is constant time.
652*f8a1b7d9SAlexander Kabaev      void
653*f8a1b7d9SAlexander Kabaev      splice_after(iterator __pos, iterator __prev)
654*f8a1b7d9SAlexander Kabaev      { __slist_splice_after(__pos._M_node,
655*f8a1b7d9SAlexander Kabaev			     __prev._M_node, __prev._M_node->_M_next); }
65600db7afdSDavid E. O'Brien
65700db7afdSDavid E. O'Brien      // Removes all of the elements from the list __x to *this, inserting
65800db7afdSDavid E. O'Brien      // them immediately after __pos.  __x must not be *this.  Complexity:
65900db7afdSDavid E. O'Brien      // linear in __x.size().
660*f8a1b7d9SAlexander Kabaev      void
661*f8a1b7d9SAlexander Kabaev      splice_after(iterator __pos, slist& __x)
662*f8a1b7d9SAlexander Kabaev      { __slist_splice_after(__pos._M_node, &__x._M_head); }
66300db7afdSDavid E. O'Brien
66400db7afdSDavid E. O'Brien      // Linear in distance(begin(), __pos), and linear in __x.size().
665*f8a1b7d9SAlexander Kabaev      void
666*f8a1b7d9SAlexander Kabaev      splice(iterator __pos, slist& __x)
667*f8a1b7d9SAlexander Kabaev      {
66800db7afdSDavid E. O'Brien	if (__x._M_head._M_next)
66900db7afdSDavid E. O'Brien	  __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
670*f8a1b7d9SAlexander Kabaev			       &__x._M_head,
671*f8a1b7d9SAlexander Kabaev			       __slist_previous(&__x._M_head, 0)); }
67200db7afdSDavid E. O'Brien
67300db7afdSDavid E. O'Brien      // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
674*f8a1b7d9SAlexander Kabaev      void
675*f8a1b7d9SAlexander Kabaev      splice(iterator __pos, slist& __x, iterator __i)
676*f8a1b7d9SAlexander Kabaev      { __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
67700db7afdSDavid E. O'Brien			     __slist_previous(&__x._M_head, __i._M_node),
678*f8a1b7d9SAlexander Kabaev			     __i._M_node); }
67900db7afdSDavid E. O'Brien
68000db7afdSDavid E. O'Brien      // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
68100db7afdSDavid E. O'Brien      // and in distance(__first, __last).
682*f8a1b7d9SAlexander Kabaev      void
683*f8a1b7d9SAlexander Kabaev      splice(iterator __pos, slist& __x, iterator __first, iterator __last)
68400db7afdSDavid E. O'Brien      {
68500db7afdSDavid E. O'Brien	if (__first != __last)
68600db7afdSDavid E. O'Brien	  __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
68700db7afdSDavid E. O'Brien			       __slist_previous(&__x._M_head, __first._M_node),
688*f8a1b7d9SAlexander Kabaev			       __slist_previous(__first._M_node,
689*f8a1b7d9SAlexander Kabaev						__last._M_node));
69000db7afdSDavid E. O'Brien      }
69100db7afdSDavid E. O'Brien
69200db7afdSDavid E. O'Brien    public:
693*f8a1b7d9SAlexander Kabaev      void
694*f8a1b7d9SAlexander Kabaev      reverse()
695*f8a1b7d9SAlexander Kabaev      {
69600db7afdSDavid E. O'Brien	if (this->_M_head._M_next)
69700db7afdSDavid E. O'Brien	  this->_M_head._M_next = __slist_reverse(this->_M_head._M_next);
69800db7afdSDavid E. O'Brien      }
69900db7afdSDavid E. O'Brien
700*f8a1b7d9SAlexander Kabaev      void
701*f8a1b7d9SAlexander Kabaev      remove(const _Tp& __val);
702*f8a1b7d9SAlexander Kabaev
703*f8a1b7d9SAlexander Kabaev      void
704*f8a1b7d9SAlexander Kabaev      unique();
705*f8a1b7d9SAlexander Kabaev
706*f8a1b7d9SAlexander Kabaev      void
707*f8a1b7d9SAlexander Kabaev      merge(slist& __x);
708*f8a1b7d9SAlexander Kabaev
709*f8a1b7d9SAlexander Kabaev      void
710*f8a1b7d9SAlexander Kabaev      sort();
71100db7afdSDavid E. O'Brien
71200db7afdSDavid E. O'Brien      template <class _Predicate>
713*f8a1b7d9SAlexander Kabaev        void
714*f8a1b7d9SAlexander Kabaev        remove_if(_Predicate __pred);
71500db7afdSDavid E. O'Brien
71600db7afdSDavid E. O'Brien      template <class _BinaryPredicate>
717*f8a1b7d9SAlexander Kabaev        void
718*f8a1b7d9SAlexander Kabaev        unique(_BinaryPredicate __pred);
71900db7afdSDavid E. O'Brien
72000db7afdSDavid E. O'Brien      template <class _StrictWeakOrdering>
721*f8a1b7d9SAlexander Kabaev        void
722*f8a1b7d9SAlexander Kabaev        merge(slist&, _StrictWeakOrdering);
72300db7afdSDavid E. O'Brien
72400db7afdSDavid E. O'Brien      template <class _StrictWeakOrdering>
725*f8a1b7d9SAlexander Kabaev        void
726*f8a1b7d9SAlexander Kabaev        sort(_StrictWeakOrdering __comp);
72700db7afdSDavid E. O'Brien    };
72800db7afdSDavid E. O'Brien
72900db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
730*f8a1b7d9SAlexander Kabaev    slist<_Tp, _Alloc>&
731*f8a1b7d9SAlexander Kabaev    slist<_Tp, _Alloc>::operator=(const slist<_Tp, _Alloc>& __x)
73200db7afdSDavid E. O'Brien    {
733*f8a1b7d9SAlexander Kabaev      if (&__x != this)
734*f8a1b7d9SAlexander Kabaev	{
73500db7afdSDavid E. O'Brien	  _Node_base* __p1 = &this->_M_head;
73600db7afdSDavid E. O'Brien	  _Node* __n1 = (_Node*) this->_M_head._M_next;
73700db7afdSDavid E. O'Brien	  const _Node* __n2 = (const _Node*) __x._M_head._M_next;
738*f8a1b7d9SAlexander Kabaev	  while (__n1 && __n2)
739*f8a1b7d9SAlexander Kabaev	    {
74000db7afdSDavid E. O'Brien	      __n1->_M_data = __n2->_M_data;
74100db7afdSDavid E. O'Brien	      __p1 = __n1;
74200db7afdSDavid E. O'Brien	      __n1 = (_Node*) __n1->_M_next;
74300db7afdSDavid E. O'Brien	      __n2 = (const _Node*) __n2->_M_next;
74400db7afdSDavid E. O'Brien	    }
74500db7afdSDavid E. O'Brien	  if (__n2 == 0)
74600db7afdSDavid E. O'Brien	    this->_M_erase_after(__p1, 0);
74700db7afdSDavid E. O'Brien	  else
74800db7afdSDavid E. O'Brien	    _M_insert_after_range(__p1, const_iterator((_Node*)__n2),
74900db7afdSDavid E. O'Brien                                  const_iterator(0));
75000db7afdSDavid E. O'Brien	}
75100db7afdSDavid E. O'Brien      return *this;
75200db7afdSDavid E. O'Brien    }
75300db7afdSDavid E. O'Brien
75400db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
755*f8a1b7d9SAlexander Kabaev    void
756*f8a1b7d9SAlexander Kabaev    slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val)
757*f8a1b7d9SAlexander Kabaev    {
75800db7afdSDavid E. O'Brien      _Node_base* __prev = &this->_M_head;
75900db7afdSDavid E. O'Brien      _Node* __node = (_Node*) this->_M_head._M_next;
760*f8a1b7d9SAlexander Kabaev      for (; __node != 0 && __n > 0; --__n)
761*f8a1b7d9SAlexander Kabaev	{
76200db7afdSDavid E. O'Brien	  __node->_M_data = __val;
76300db7afdSDavid E. O'Brien	  __prev = __node;
76400db7afdSDavid E. O'Brien	  __node = (_Node*) __node->_M_next;
76500db7afdSDavid E. O'Brien	}
76600db7afdSDavid E. O'Brien      if (__n > 0)
76700db7afdSDavid E. O'Brien	_M_insert_after_fill(__prev, __n, __val);
76800db7afdSDavid E. O'Brien      else
76900db7afdSDavid E. O'Brien	this->_M_erase_after(__prev, 0);
77000db7afdSDavid E. O'Brien    }
77100db7afdSDavid E. O'Brien
772*f8a1b7d9SAlexander Kabaev  template <class _Tp, class _Alloc>
773*f8a1b7d9SAlexander Kabaev    template <class _InputIterator>
77400db7afdSDavid E. O'Brien      void
775*f8a1b7d9SAlexander Kabaev      slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first,
776*f8a1b7d9SAlexander Kabaev					     _InputIterator __last,
77700db7afdSDavid E. O'Brien					     __false_type)
77800db7afdSDavid E. O'Brien      {
77900db7afdSDavid E. O'Brien	_Node_base* __prev = &this->_M_head;
78000db7afdSDavid E. O'Brien	_Node* __node = (_Node*) this->_M_head._M_next;
781*f8a1b7d9SAlexander Kabaev	while (__node != 0 && __first != __last)
782*f8a1b7d9SAlexander Kabaev	  {
78300db7afdSDavid E. O'Brien	    __node->_M_data = *__first;
78400db7afdSDavid E. O'Brien	    __prev = __node;
78500db7afdSDavid E. O'Brien	    __node = (_Node*) __node->_M_next;
78600db7afdSDavid E. O'Brien	    ++__first;
78700db7afdSDavid E. O'Brien	  }
78800db7afdSDavid E. O'Brien	if (__first != __last)
78900db7afdSDavid E. O'Brien	  _M_insert_after_range(__prev, __first, __last);
79000db7afdSDavid E. O'Brien	else
79100db7afdSDavid E. O'Brien	  this->_M_erase_after(__prev, 0);
79200db7afdSDavid E. O'Brien      }
79300db7afdSDavid E. O'Brien
79400db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
79500db7afdSDavid E. O'Brien    inline bool
79600db7afdSDavid E. O'Brien    operator==(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
79700db7afdSDavid E. O'Brien    {
79800db7afdSDavid E. O'Brien      typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator;
79900db7afdSDavid E. O'Brien      const_iterator __end1 = _SL1.end();
80000db7afdSDavid E. O'Brien      const_iterator __end2 = _SL2.end();
80100db7afdSDavid E. O'Brien
80200db7afdSDavid E. O'Brien      const_iterator __i1 = _SL1.begin();
80300db7afdSDavid E. O'Brien      const_iterator __i2 = _SL2.begin();
804*f8a1b7d9SAlexander Kabaev      while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2)
805*f8a1b7d9SAlexander Kabaev	{
80600db7afdSDavid E. O'Brien	  ++__i1;
80700db7afdSDavid E. O'Brien	  ++__i2;
80800db7afdSDavid E. O'Brien	}
80900db7afdSDavid E. O'Brien      return __i1 == __end1 && __i2 == __end2;
81000db7afdSDavid E. O'Brien    }
81100db7afdSDavid E. O'Brien
81200db7afdSDavid E. O'Brien
81300db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
81400db7afdSDavid E. O'Brien    inline bool
81500db7afdSDavid E. O'Brien    operator<(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
816*f8a1b7d9SAlexander Kabaev    { return std::lexicographical_compare(_SL1.begin(), _SL1.end(),
817*f8a1b7d9SAlexander Kabaev					  _SL2.begin(), _SL2.end()); }
81800db7afdSDavid E. O'Brien
81900db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
82000db7afdSDavid E. O'Brien    inline bool
821*f8a1b7d9SAlexander Kabaev    operator!=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
822*f8a1b7d9SAlexander Kabaev    { return !(_SL1 == _SL2); }
82300db7afdSDavid E. O'Brien
82400db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
82500db7afdSDavid E. O'Brien    inline bool
826*f8a1b7d9SAlexander Kabaev    operator>(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
827*f8a1b7d9SAlexander Kabaev    { return _SL2 < _SL1; }
82800db7afdSDavid E. O'Brien
82900db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
83000db7afdSDavid E. O'Brien    inline bool
831*f8a1b7d9SAlexander Kabaev    operator<=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
832*f8a1b7d9SAlexander Kabaev    { return !(_SL2 < _SL1); }
83300db7afdSDavid E. O'Brien
83400db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
83500db7afdSDavid E. O'Brien    inline bool
836*f8a1b7d9SAlexander Kabaev    operator>=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
837*f8a1b7d9SAlexander Kabaev    { return !(_SL1 < _SL2); }
83800db7afdSDavid E. O'Brien
83900db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
840*f8a1b7d9SAlexander Kabaev    inline void
841*f8a1b7d9SAlexander Kabaev    swap(slist<_Tp, _Alloc>& __x, slist<_Tp, _Alloc>& __y)
842*f8a1b7d9SAlexander Kabaev    { __x.swap(__y); }
84300db7afdSDavid E. O'Brien
84400db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
845*f8a1b7d9SAlexander Kabaev    void
846*f8a1b7d9SAlexander Kabaev    slist<_Tp, _Alloc>::resize(size_type __len, const _Tp& __x)
84700db7afdSDavid E. O'Brien    {
84800db7afdSDavid E. O'Brien      _Node_base* __cur = &this->_M_head;
849*f8a1b7d9SAlexander Kabaev      while (__cur->_M_next != 0 && __len > 0)
850*f8a1b7d9SAlexander Kabaev	{
85100db7afdSDavid E. O'Brien	  --__len;
85200db7afdSDavid E. O'Brien	  __cur = __cur->_M_next;
85300db7afdSDavid E. O'Brien	}
85400db7afdSDavid E. O'Brien      if (__cur->_M_next)
85500db7afdSDavid E. O'Brien	this->_M_erase_after(__cur, 0);
85600db7afdSDavid E. O'Brien      else
85700db7afdSDavid E. O'Brien	_M_insert_after_fill(__cur, __len, __x);
85800db7afdSDavid E. O'Brien    }
85900db7afdSDavid E. O'Brien
86000db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
861*f8a1b7d9SAlexander Kabaev    void
862*f8a1b7d9SAlexander Kabaev    slist<_Tp, _Alloc>::remove(const _Tp& __val)
86300db7afdSDavid E. O'Brien    {
86400db7afdSDavid E. O'Brien      _Node_base* __cur = &this->_M_head;
865*f8a1b7d9SAlexander Kabaev      while (__cur && __cur->_M_next)
866*f8a1b7d9SAlexander Kabaev	{
86700db7afdSDavid E. O'Brien	  if (((_Node*) __cur->_M_next)->_M_data == __val)
86800db7afdSDavid E. O'Brien	    this->_M_erase_after(__cur);
86900db7afdSDavid E. O'Brien	  else
87000db7afdSDavid E. O'Brien	    __cur = __cur->_M_next;
87100db7afdSDavid E. O'Brien	}
87200db7afdSDavid E. O'Brien    }
87300db7afdSDavid E. O'Brien
87400db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
875*f8a1b7d9SAlexander Kabaev    void
876*f8a1b7d9SAlexander Kabaev    slist<_Tp, _Alloc>::unique()
87700db7afdSDavid E. O'Brien    {
87800db7afdSDavid E. O'Brien      _Node_base* __cur = this->_M_head._M_next;
879*f8a1b7d9SAlexander Kabaev      if (__cur)
880*f8a1b7d9SAlexander Kabaev	{
881*f8a1b7d9SAlexander Kabaev	  while (__cur->_M_next)
882*f8a1b7d9SAlexander Kabaev	    {
883*f8a1b7d9SAlexander Kabaev	      if (((_Node*)__cur)->_M_data
884*f8a1b7d9SAlexander Kabaev		  == ((_Node*)(__cur->_M_next))->_M_data)
88500db7afdSDavid E. O'Brien		this->_M_erase_after(__cur);
88600db7afdSDavid E. O'Brien	      else
88700db7afdSDavid E. O'Brien		__cur = __cur->_M_next;
88800db7afdSDavid E. O'Brien	    }
88900db7afdSDavid E. O'Brien	}
89000db7afdSDavid E. O'Brien    }
89100db7afdSDavid E. O'Brien
89200db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
893*f8a1b7d9SAlexander Kabaev    void
894*f8a1b7d9SAlexander Kabaev    slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x)
89500db7afdSDavid E. O'Brien    {
89600db7afdSDavid E. O'Brien      _Node_base* __n1 = &this->_M_head;
897*f8a1b7d9SAlexander Kabaev      while (__n1->_M_next && __x._M_head._M_next)
898*f8a1b7d9SAlexander Kabaev	{
899*f8a1b7d9SAlexander Kabaev	  if (((_Node*) __x._M_head._M_next)->_M_data
900*f8a1b7d9SAlexander Kabaev	      < ((_Node*) __n1->_M_next)->_M_data)
90100db7afdSDavid E. O'Brien	    __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
90200db7afdSDavid E. O'Brien	  __n1 = __n1->_M_next;
90300db7afdSDavid E. O'Brien	}
904*f8a1b7d9SAlexander Kabaev      if (__x._M_head._M_next)
905*f8a1b7d9SAlexander Kabaev	{
90600db7afdSDavid E. O'Brien	  __n1->_M_next = __x._M_head._M_next;
90700db7afdSDavid E. O'Brien	  __x._M_head._M_next = 0;
90800db7afdSDavid E. O'Brien	}
90900db7afdSDavid E. O'Brien    }
91000db7afdSDavid E. O'Brien
91100db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
912*f8a1b7d9SAlexander Kabaev    void
913*f8a1b7d9SAlexander Kabaev    slist<_Tp, _Alloc>::sort()
91400db7afdSDavid E. O'Brien    {
915*f8a1b7d9SAlexander Kabaev      if (this->_M_head._M_next && this->_M_head._M_next->_M_next)
916*f8a1b7d9SAlexander Kabaev	{
91700db7afdSDavid E. O'Brien	  slist __carry;
91800db7afdSDavid E. O'Brien	  slist __counter[64];
91900db7afdSDavid E. O'Brien	  int __fill = 0;
920*f8a1b7d9SAlexander Kabaev	  while (!empty())
921*f8a1b7d9SAlexander Kabaev	    {
92200db7afdSDavid E. O'Brien	      __slist_splice_after(&__carry._M_head,
92300db7afdSDavid E. O'Brien				   &this->_M_head, this->_M_head._M_next);
92400db7afdSDavid E. O'Brien	      int __i = 0;
925*f8a1b7d9SAlexander Kabaev	      while (__i < __fill && !__counter[__i].empty())
926*f8a1b7d9SAlexander Kabaev		{
92700db7afdSDavid E. O'Brien		  __counter[__i].merge(__carry);
92800db7afdSDavid E. O'Brien		  __carry.swap(__counter[__i]);
92900db7afdSDavid E. O'Brien		  ++__i;
93000db7afdSDavid E. O'Brien		}
93100db7afdSDavid E. O'Brien	      __carry.swap(__counter[__i]);
93200db7afdSDavid E. O'Brien	      if (__i == __fill)
93300db7afdSDavid E. O'Brien		++__fill;
93400db7afdSDavid E. O'Brien	    }
93500db7afdSDavid E. O'Brien
93600db7afdSDavid E. O'Brien	  for (int __i = 1; __i < __fill; ++__i)
93700db7afdSDavid E. O'Brien	    __counter[__i].merge(__counter[__i-1]);
93800db7afdSDavid E. O'Brien	  this->swap(__counter[__fill-1]);
93900db7afdSDavid E. O'Brien	}
94000db7afdSDavid E. O'Brien    }
94100db7afdSDavid E. O'Brien
94200db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
94300db7afdSDavid E. O'Brien    template <class _Predicate>
94400db7afdSDavid E. O'Brien      void slist<_Tp, _Alloc>::remove_if(_Predicate __pred)
94500db7afdSDavid E. O'Brien      {
94600db7afdSDavid E. O'Brien	_Node_base* __cur = &this->_M_head;
947*f8a1b7d9SAlexander Kabaev	while (__cur->_M_next)
948*f8a1b7d9SAlexander Kabaev	  {
94900db7afdSDavid E. O'Brien	    if (__pred(((_Node*) __cur->_M_next)->_M_data))
95000db7afdSDavid E. O'Brien	      this->_M_erase_after(__cur);
95100db7afdSDavid E. O'Brien	    else
95200db7afdSDavid E. O'Brien	      __cur = __cur->_M_next;
95300db7afdSDavid E. O'Brien	  }
95400db7afdSDavid E. O'Brien      }
95500db7afdSDavid E. O'Brien
956*f8a1b7d9SAlexander Kabaev  template <class _Tp, class _Alloc>
957*f8a1b7d9SAlexander Kabaev    template <class _BinaryPredicate>
958*f8a1b7d9SAlexander Kabaev      void
959*f8a1b7d9SAlexander Kabaev      slist<_Tp, _Alloc>::unique(_BinaryPredicate __pred)
96000db7afdSDavid E. O'Brien      {
96100db7afdSDavid E. O'Brien	_Node* __cur = (_Node*) this->_M_head._M_next;
962*f8a1b7d9SAlexander Kabaev	if (__cur)
963*f8a1b7d9SAlexander Kabaev	  {
964*f8a1b7d9SAlexander Kabaev	    while (__cur->_M_next)
965*f8a1b7d9SAlexander Kabaev	      {
96600db7afdSDavid E. O'Brien		if (__pred(((_Node*)__cur)->_M_data,
96700db7afdSDavid E. O'Brien			   ((_Node*)(__cur->_M_next))->_M_data))
96800db7afdSDavid E. O'Brien		  this->_M_erase_after(__cur);
96900db7afdSDavid E. O'Brien		else
97000db7afdSDavid E. O'Brien		  __cur = (_Node*) __cur->_M_next;
97100db7afdSDavid E. O'Brien	      }
97200db7afdSDavid E. O'Brien	  }
97300db7afdSDavid E. O'Brien      }
97400db7afdSDavid E. O'Brien
975*f8a1b7d9SAlexander Kabaev  template <class _Tp, class _Alloc>
976*f8a1b7d9SAlexander Kabaev    template <class _StrictWeakOrdering>
977*f8a1b7d9SAlexander Kabaev      void
978*f8a1b7d9SAlexander Kabaev      slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x,
97900db7afdSDavid E. O'Brien			       _StrictWeakOrdering __comp)
98000db7afdSDavid E. O'Brien      {
98100db7afdSDavid E. O'Brien	_Node_base* __n1 = &this->_M_head;
982*f8a1b7d9SAlexander Kabaev	while (__n1->_M_next && __x._M_head._M_next)
983*f8a1b7d9SAlexander Kabaev	  {
98400db7afdSDavid E. O'Brien	    if (__comp(((_Node*) __x._M_head._M_next)->_M_data,
98500db7afdSDavid E. O'Brien		       ((_Node*) __n1->_M_next)->_M_data))
98600db7afdSDavid E. O'Brien	      __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
98700db7afdSDavid E. O'Brien	    __n1 = __n1->_M_next;
98800db7afdSDavid E. O'Brien	  }
989*f8a1b7d9SAlexander Kabaev	if (__x._M_head._M_next)
990*f8a1b7d9SAlexander Kabaev	  {
99100db7afdSDavid E. O'Brien	    __n1->_M_next = __x._M_head._M_next;
99200db7afdSDavid E. O'Brien	    __x._M_head._M_next = 0;
99300db7afdSDavid E. O'Brien	  }
99400db7afdSDavid E. O'Brien      }
99500db7afdSDavid E. O'Brien
996*f8a1b7d9SAlexander Kabaev  template <class _Tp, class _Alloc>
997*f8a1b7d9SAlexander Kabaev    template <class _StrictWeakOrdering>
998*f8a1b7d9SAlexander Kabaev      void
999*f8a1b7d9SAlexander Kabaev      slist<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp)
100000db7afdSDavid E. O'Brien      {
1001*f8a1b7d9SAlexander Kabaev	if (this->_M_head._M_next && this->_M_head._M_next->_M_next)
1002*f8a1b7d9SAlexander Kabaev	  {
100300db7afdSDavid E. O'Brien	    slist __carry;
100400db7afdSDavid E. O'Brien	    slist __counter[64];
100500db7afdSDavid E. O'Brien	    int __fill = 0;
1006*f8a1b7d9SAlexander Kabaev	    while (!empty())
1007*f8a1b7d9SAlexander Kabaev	      {
100800db7afdSDavid E. O'Brien		__slist_splice_after(&__carry._M_head,
100900db7afdSDavid E. O'Brien				     &this->_M_head, this->_M_head._M_next);
101000db7afdSDavid E. O'Brien		int __i = 0;
1011*f8a1b7d9SAlexander Kabaev		while (__i < __fill && !__counter[__i].empty())
1012*f8a1b7d9SAlexander Kabaev		  {
101300db7afdSDavid E. O'Brien		    __counter[__i].merge(__carry, __comp);
101400db7afdSDavid E. O'Brien		    __carry.swap(__counter[__i]);
101500db7afdSDavid E. O'Brien		    ++__i;
101600db7afdSDavid E. O'Brien		  }
101700db7afdSDavid E. O'Brien		__carry.swap(__counter[__i]);
101800db7afdSDavid E. O'Brien		if (__i == __fill)
101900db7afdSDavid E. O'Brien		  ++__fill;
102000db7afdSDavid E. O'Brien	      }
102100db7afdSDavid E. O'Brien
102200db7afdSDavid E. O'Brien	    for (int __i = 1; __i < __fill; ++__i)
102300db7afdSDavid E. O'Brien	      __counter[__i].merge(__counter[__i-1], __comp);
102400db7afdSDavid E. O'Brien	    this->swap(__counter[__fill-1]);
102500db7afdSDavid E. O'Brien	  }
102600db7afdSDavid E. O'Brien      }
102700db7afdSDavid E. O'Brien
1028*f8a1b7d9SAlexander Kabaev_GLIBCXX_END_NAMESPACE
102900db7afdSDavid E. O'Brien
1030*f8a1b7d9SAlexander Kabaev_GLIBCXX_BEGIN_NAMESPACE(std)
1031*f8a1b7d9SAlexander Kabaev
103200db7afdSDavid E. O'Brien  // Specialization of insert_iterator so that insertions will be constant
103300db7afdSDavid E. O'Brien  // time rather than linear time.
103400db7afdSDavid E. O'Brien  template <class _Tp, class _Alloc>
1035*f8a1b7d9SAlexander Kabaev    class insert_iterator<__gnu_cxx::slist<_Tp, _Alloc> >
1036*f8a1b7d9SAlexander Kabaev    {
103700db7afdSDavid E. O'Brien    protected:
103800db7afdSDavid E. O'Brien      typedef __gnu_cxx::slist<_Tp, _Alloc> _Container;
103900db7afdSDavid E. O'Brien      _Container* container;
104000db7afdSDavid E. O'Brien      typename _Container::iterator iter;
1041*f8a1b7d9SAlexander Kabaev
104200db7afdSDavid E. O'Brien    public:
104300db7afdSDavid E. O'Brien      typedef _Container          container_type;
104400db7afdSDavid E. O'Brien      typedef output_iterator_tag iterator_category;
104500db7afdSDavid E. O'Brien      typedef void                value_type;
104600db7afdSDavid E. O'Brien      typedef void                difference_type;
104700db7afdSDavid E. O'Brien      typedef void                pointer;
104800db7afdSDavid E. O'Brien      typedef void                reference;
104900db7afdSDavid E. O'Brien
105000db7afdSDavid E. O'Brien      insert_iterator(_Container& __x, typename _Container::iterator __i)
1051*f8a1b7d9SAlexander Kabaev      : container(&__x)
1052*f8a1b7d9SAlexander Kabaev      {
105300db7afdSDavid E. O'Brien	if (__i == __x.begin())
105400db7afdSDavid E. O'Brien	  iter = __x.before_begin();
105500db7afdSDavid E. O'Brien	else
105600db7afdSDavid E. O'Brien	  iter = __x.previous(__i);
105700db7afdSDavid E. O'Brien      }
105800db7afdSDavid E. O'Brien
105900db7afdSDavid E. O'Brien      insert_iterator<_Container>&
1060*f8a1b7d9SAlexander Kabaev      operator=(const typename _Container::value_type& __value)
1061*f8a1b7d9SAlexander Kabaev      {
106200db7afdSDavid E. O'Brien	iter = container->insert_after(iter, __value);
106300db7afdSDavid E. O'Brien	return *this;
106400db7afdSDavid E. O'Brien      }
1065*f8a1b7d9SAlexander Kabaev
1066*f8a1b7d9SAlexander Kabaev      insert_iterator<_Container>&
1067*f8a1b7d9SAlexander Kabaev      operator*()
1068*f8a1b7d9SAlexander Kabaev      { return *this; }
1069*f8a1b7d9SAlexander Kabaev
1070*f8a1b7d9SAlexander Kabaev      insert_iterator<_Container>&
1071*f8a1b7d9SAlexander Kabaev      operator++()
1072*f8a1b7d9SAlexander Kabaev      { return *this; }
1073*f8a1b7d9SAlexander Kabaev
1074*f8a1b7d9SAlexander Kabaev      insert_iterator<_Container>&
1075*f8a1b7d9SAlexander Kabaev      operator++(int)
1076*f8a1b7d9SAlexander Kabaev      { return *this; }
107700db7afdSDavid E. O'Brien    };
107800db7afdSDavid E. O'Brien
1079*f8a1b7d9SAlexander Kabaev_GLIBCXX_END_NAMESPACE
108000db7afdSDavid E. O'Brien
1081ffeaf689SAlexander Kabaev#endif
1082