// Singly-linked list implementation -*- C++ -*-

// Copyright (C) 2001-2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/*
 * Copyright (c) 1997
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 */

/** @file ext/slist
 *  This file is a GNU extension to the Standard C++ Library (possibly
 *  containing extensions from the HP/SGI STL subset). 
 */

#ifndef _SLIST
#define _SLIST 1

#include <algorithm>
#include <bits/allocator.h>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <bits/concept_check.h>

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  using std::size_t;
  using std::ptrdiff_t;
  using std::_Construct;
  using std::_Destroy;
  using std::allocator;
  using std::__true_type;
  using std::__false_type;

  struct _Slist_node_base
  {
    _Slist_node_base* _M_next;
  };
  
  inline _Slist_node_base*
  __slist_make_link(_Slist_node_base* __prev_node,
		    _Slist_node_base* __new_node)
  {
    __new_node->_M_next = __prev_node->_M_next;
    __prev_node->_M_next = __new_node;
    return __new_node;
  }

  inline _Slist_node_base*
  __slist_previous(_Slist_node_base* __head,
		   const _Slist_node_base* __node)
  {
    while (__head && __head->_M_next != __node)
      __head = __head->_M_next;
    return __head;
  }

  inline const _Slist_node_base*
  __slist_previous(const _Slist_node_base* __head,
		   const _Slist_node_base* __node)
  {
    while (__head && __head->_M_next != __node)
      __head = __head->_M_next;
    return __head;
  }

  inline void
  __slist_splice_after(_Slist_node_base* __pos,
		       _Slist_node_base* __before_first,
		       _Slist_node_base* __before_last)
  {
    if (__pos != __before_first && __pos != __before_last)
      {
	_Slist_node_base* __first = __before_first->_M_next;
	_Slist_node_base* __after = __pos->_M_next;
	__before_first->_M_next = __before_last->_M_next;
	__pos->_M_next = __first;
	__before_last->_M_next = __after;
      }
  }

  inline void
  __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head)
  {
    _Slist_node_base* __before_last = __slist_previous(__head, 0);
    if (__before_last != __head)
      {
	_Slist_node_base* __after = __pos->_M_next;
	__pos->_M_next = __head->_M_next;
	__head->_M_next = 0;
	__before_last->_M_next = __after;
      }
  }

  inline _Slist_node_base*
  __slist_reverse(_Slist_node_base* __node)
  {
    _Slist_node_base* __result = __node;
    __node = __node->_M_next;
    __result->_M_next = 0;
    while(__node)
      {
	_Slist_node_base* __next = __node->_M_next;
	__node->_M_next = __result;
	__result = __node;
	__node = __next;
      }
    return __result;
  }

  inline size_t
  __slist_size(_Slist_node_base* __node)
  {
    size_t __result = 0;
    for (; __node != 0; __node = __node->_M_next)
      ++__result;
    return __result;
  }

  template <class _Tp>
    struct _Slist_node : public _Slist_node_base
    {
      _Tp _M_data;
    };

  struct _Slist_iterator_base
  {
    typedef size_t                    size_type;
    typedef ptrdiff_t                 difference_type;
    typedef std::forward_iterator_tag iterator_category;

    _Slist_node_base* _M_node;
    
    _Slist_iterator_base(_Slist_node_base* __x)
    : _M_node(__x) {}

    void
    _M_incr()
    { _M_node = _M_node->_M_next; }

    bool
    operator==(const _Slist_iterator_base& __x) const
    { return _M_node == __x._M_node; }

    bool
    operator!=(const _Slist_iterator_base& __x) const
    { return _M_node != __x._M_node; }
  };

  template <class _Tp, class _Ref, class _Ptr>
    struct _Slist_iterator : public _Slist_iterator_base
    {
      typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
      typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
      typedef _Slist_iterator<_Tp, _Ref, _Ptr>             _Self;

      typedef _Tp              value_type;
      typedef _Ptr             pointer;
      typedef _Ref             reference;
      typedef _Slist_node<_Tp> _Node;

      explicit
      _Slist_iterator(_Node* __x)
      : _Slist_iterator_base(__x) {}

      _Slist_iterator()
      : _Slist_iterator_base(0) {}

      _Slist_iterator(const iterator& __x)
      : _Slist_iterator_base(__x._M_node) {}

      reference
      operator*() const
      { return ((_Node*) _M_node)->_M_data; }

      pointer
      operator->() const
      { return &(operator*()); }

      _Self&
      operator++()
      {
	_M_incr();
	return *this;
      }

      _Self
      operator++(int)
      {
	_Self __tmp = *this;
	_M_incr();
	return __tmp;
      }
    };

  template <class _Tp, class _Alloc>
    struct _Slist_base
    : public _Alloc::template rebind<_Slist_node<_Tp> >::other
    {
      typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other
        _Node_alloc;
      typedef _Alloc allocator_type;

      allocator_type
      get_allocator() const
      { return *static_cast<const _Node_alloc*>(this); }

      _Slist_base(const allocator_type& __a)
      : _Node_alloc(__a)
      { this->_M_head._M_next = 0; }

      ~_Slist_base()
      { _M_erase_after(&this->_M_head, 0); }

    protected:
      _Slist_node_base _M_head;

      _Slist_node<_Tp>*
      _M_get_node()
      { return _Node_alloc::allocate(1); }
  
      void
      _M_put_node(_Slist_node<_Tp>* __p)
      { _Node_alloc::deallocate(__p, 1); }

    protected:
      _Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
      {
	_Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);
	_Slist_node_base* __next_next = __next->_M_next;
	__pos->_M_next = __next_next;
	get_allocator().destroy(&__next->_M_data);
	_M_put_node(__next);
	return __next_next;
      }
      _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
    };

  template <class _Tp, class _Alloc>
    _Slist_node_base*
    _Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first,
					    _Slist_node_base* __last_node)
    {
      _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next);
      while (__cur != __last_node)
	{
	  _Slist_node<_Tp>* __tmp = __cur;
	  __cur = (_Slist_node<_Tp>*) __cur->_M_next;
	  get_allocator().destroy(&__tmp->_M_data);
	  _M_put_node(__tmp);
	}
      __before_first->_M_next = __last_node;
      return __last_node;
    }

  /**
   *  This is an SGI extension.
   *  @ingroup SGIextensions
   *  @doctodo
   */
  template <class _Tp, class _Alloc = allocator<_Tp> >
    class slist : private _Slist_base<_Tp,_Alloc>
    {
      // concept requirements
      __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
	
    private:
      typedef _Slist_base<_Tp,_Alloc> _Base;

    public:
      typedef _Tp               value_type;
      typedef value_type*       pointer;
      typedef const value_type* const_pointer;
      typedef value_type&       reference;
      typedef const value_type& const_reference;
      typedef size_t            size_type;
      typedef ptrdiff_t         difference_type;
      
      typedef _Slist_iterator<_Tp, _Tp&, _Tp*>             iterator;
      typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
      
      typedef typename _Base::allocator_type allocator_type;

      allocator_type
      get_allocator() const
      { return _Base::get_allocator(); }

    private:
      typedef _Slist_node<_Tp>      _Node;
      typedef _Slist_node_base      _Node_base;
      typedef _Slist_iterator_base  _Iterator_base;
      
      _Node*
      _M_create_node(const value_type& __x)
      {
	_Node* __node = this->_M_get_node();
	__try
	  {
	    get_allocator().construct(&__node->_M_data, __x);
	    __node->_M_next = 0;
	  }
	__catch(...)
	  {
	    this->_M_put_node(__node);
	    __throw_exception_again;
	  }
	return __node;
      }

      _Node*
      _M_create_node()
      {
	_Node* __node = this->_M_get_node();
	__try
	  {
	    get_allocator().construct(&__node->_M_data, value_type());
	    __node->_M_next = 0;
	  }
	__catch(...)
	  {
	    this->_M_put_node(__node);
	    __throw_exception_again;
	  }
	return __node;
      }

    public:
      explicit
      slist(const allocator_type& __a = allocator_type())
      : _Base(__a) {}

      slist(size_type __n, const value_type& __x,
	    const allocator_type& __a =  allocator_type())
      : _Base(__a)
      { _M_insert_after_fill(&this->_M_head, __n, __x); }

      explicit
      slist(size_type __n)
      : _Base(allocator_type())
      { _M_insert_after_fill(&this->_M_head, __n, value_type()); }

      // We don't need any dispatching tricks here, because
      // _M_insert_after_range already does them.
      template <class _InputIterator>
        slist(_InputIterator __first, _InputIterator __last,
	      const allocator_type& __a =  allocator_type())
	: _Base(__a)
        { _M_insert_after_range(&this->_M_head, __first, __last); }

      slist(const slist& __x)
      : _Base(__x.get_allocator())
      { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); }

      slist&
      operator= (const slist& __x);

      ~slist() {}

    public:
      // assign(), a generalized assignment member function.  Two
      // versions: one that takes a count, and one that takes a range.
      // The range version is a member template, so we dispatch on whether
      // or not the type is an integer.
      
      void
      assign(size_type __n, const _Tp& __val)
      { _M_fill_assign(__n, __val); }

      void
      _M_fill_assign(size_type __n, const _Tp& __val);

      template <class _InputIterator>
        void
        assign(_InputIterator __first, _InputIterator __last)
        {
	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
	  _M_assign_dispatch(__first, __last, _Integral());
	}

      template <class _Integer>
      void
      _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
      { _M_fill_assign((size_type) __n, (_Tp) __val); }

      template <class _InputIterator>
      void
      _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
			 __false_type);

    public:

      iterator
      begin()
      { return iterator((_Node*)this->_M_head._M_next); }

      const_iterator
      begin() const
      { return const_iterator((_Node*)this->_M_head._M_next);}

      iterator
      end()
      { return iterator(0); }

      const_iterator
      end() const
      { return const_iterator(0); }

      // Experimental new feature: before_begin() returns a
      // non-dereferenceable iterator that, when incremented, yields
      // begin().  This iterator may be used as the argument to
      // insert_after, erase_after, etc.  Note that even for an empty
      // slist, before_begin() is not the same iterator as end().  It
      // is always necessary to increment before_begin() at least once to
      // obtain end().
      iterator
      before_begin()
      { return iterator((_Node*) &this->_M_head); }

      const_iterator
      before_begin() const
      { return const_iterator((_Node*) &this->_M_head); }

      size_type
      size() const
      { return __slist_size(this->_M_head._M_next); }

      size_type
      max_size() const
      { return size_type(-1); }

      bool
      empty() const
      { return this->_M_head._M_next == 0; }

      void
      swap(slist& __x)
      { std::swap(this->_M_head._M_next, __x._M_head._M_next); }

    public:

      reference
      front()
      { return ((_Node*) this->_M_head._M_next)->_M_data; }

      const_reference
      front() const
      { return ((_Node*) this->_M_head._M_next)->_M_data; }

      void
      push_front(const value_type& __x)
      { __slist_make_link(&this->_M_head, _M_create_node(__x)); }

      void
      push_front()
      { __slist_make_link(&this->_M_head, _M_create_node()); }

      void
      pop_front()
      {
	_Node* __node = (_Node*) this->_M_head._M_next;
	this->_M_head._M_next = __node->_M_next;
	get_allocator().destroy(&__node->_M_data);
	this->_M_put_node(__node);
      }

      iterator
      previous(const_iterator __pos)
      { return iterator((_Node*) __slist_previous(&this->_M_head,
						  __pos._M_node)); }

      const_iterator
      previous(const_iterator __pos) const
      { return const_iterator((_Node*) __slist_previous(&this->_M_head,
							__pos._M_node)); }

    private:
      _Node*
      _M_insert_after(_Node_base* __pos, const value_type& __x)
      { return (_Node*) (__slist_make_link(__pos, _M_create_node(__x))); }

      _Node*
      _M_insert_after(_Node_base* __pos)
      { return (_Node*) (__slist_make_link(__pos, _M_create_node())); }

      void
      _M_insert_after_fill(_Node_base* __pos,
			   size_type __n, const value_type& __x)
      {
	for (size_type __i = 0; __i < __n; ++__i)
	  __pos = __slist_make_link(__pos, _M_create_node(__x));
      }

      // Check whether it's an integral type.  If so, it's not an iterator.
      template <class _InIterator>
        void
        _M_insert_after_range(_Node_base* __pos,
			      _InIterator __first, _InIterator __last)
        {
	  typedef typename std::__is_integer<_InIterator>::__type _Integral;
	  _M_insert_after_range(__pos, __first, __last, _Integral());
	}

      template <class _Integer>
        void
        _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
			      __true_type)
        { _M_insert_after_fill(__pos, __n, __x); }

      template <class _InIterator>
        void
        _M_insert_after_range(_Node_base* __pos,
			      _InIterator __first, _InIterator __last,
			      __false_type)
        {
	  while (__first != __last)
	    {
	      __pos = __slist_make_link(__pos, _M_create_node(*__first));
	      ++__first;
	    }
	}

    public:
      iterator
      insert_after(iterator __pos, const value_type& __x)
      { return iterator(_M_insert_after(__pos._M_node, __x)); }

      iterator
      insert_after(iterator __pos)
      { return insert_after(__pos, value_type()); }

      void
      insert_after(iterator __pos, size_type __n, const value_type& __x)
      { _M_insert_after_fill(__pos._M_node, __n, __x); }

      // We don't need any dispatching tricks here, because
      // _M_insert_after_range already does them.
      template <class _InIterator>
        void
        insert_after(iterator __pos, _InIterator __first, _InIterator __last)
        { _M_insert_after_range(__pos._M_node, __first, __last); }

      iterator
      insert(iterator __pos, const value_type& __x)
      { return iterator(_M_insert_after(__slist_previous(&this->_M_head,
							 __pos._M_node),
					__x)); }

      iterator
      insert(iterator __pos)
      { return iterator(_M_insert_after(__slist_previous(&this->_M_head,
							 __pos._M_node),
					value_type())); }

      void
      insert(iterator __pos, size_type __n, const value_type& __x)
      { _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node),
			     __n, __x); }

      // We don't need any dispatching tricks here, because
      // _M_insert_after_range already does them.
      template <class _InIterator>
        void
        insert(iterator __pos, _InIterator __first, _InIterator __last)
        { _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node),
				__first, __last); }

    public:
      iterator
      erase_after(iterator __pos)
      { return iterator((_Node*) this->_M_erase_after(__pos._M_node)); }

      iterator
      erase_after(iterator __before_first, iterator __last)
      { 
	return iterator((_Node*) this->_M_erase_after(__before_first._M_node,
						      __last._M_node));
      }

      iterator
      erase(iterator __pos)
      { 
	return iterator((_Node*) this->_M_erase_after
			(__slist_previous(&this->_M_head, __pos._M_node)));
      }

      iterator
      erase(iterator __first, iterator __last)
      { 
	return iterator((_Node*) this->_M_erase_after
			(__slist_previous(&this->_M_head, __first._M_node),
			 __last._M_node));
      }
      
      void
      resize(size_type new_size, const _Tp& __x);

      void
      resize(size_type new_size)
      { resize(new_size, _Tp()); }

      void
      clear()
      { this->_M_erase_after(&this->_M_head, 0); }

    public:
      // Moves the range [__before_first + 1, __before_last + 1) to *this,
      //  inserting it immediately after __pos.  This is constant time.
      void
      splice_after(iterator __pos,
		   iterator __before_first, iterator __before_last)
      {
	if (__before_first != __before_last)
	  __slist_splice_after(__pos._M_node, __before_first._M_node,
			       __before_last._M_node);
      }

      // Moves the element that follows __prev to *this, inserting it
      // immediately after __pos.  This is constant time.
      void
      splice_after(iterator __pos, iterator __prev)
      { __slist_splice_after(__pos._M_node,
			     __prev._M_node, __prev._M_node->_M_next); }

      // Removes all of the elements from the list __x to *this, inserting
      // them immediately after __pos.  __x must not be *this.  Complexity:
      // linear in __x.size().
      void
      splice_after(iterator __pos, slist& __x)
      { __slist_splice_after(__pos._M_node, &__x._M_head); }

      // Linear in distance(begin(), __pos), and linear in __x.size().
      void
      splice(iterator __pos, slist& __x)
      {
	if (__x._M_head._M_next)
	  __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
			       &__x._M_head,
			       __slist_previous(&__x._M_head, 0)); }

      // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
      void
      splice(iterator __pos, slist& __x, iterator __i)
      { __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
			     __slist_previous(&__x._M_head, __i._M_node),
			     __i._M_node); }

      // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
      // and in distance(__first, __last).
      void
      splice(iterator __pos, slist& __x, iterator __first, iterator __last)
      {
	if (__first != __last)
	  __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node),
			       __slist_previous(&__x._M_head, __first._M_node),
			       __slist_previous(__first._M_node,
						__last._M_node));
      }

    public:
      void
      reverse()
      {
	if (this->_M_head._M_next)
	  this->_M_head._M_next = __slist_reverse(this->_M_head._M_next);
      }

      void
      remove(const _Tp& __val);

      void
      unique();
      
      void
      merge(slist& __x);
      
      void
      sort();

      template <class _Predicate>
        void
        remove_if(_Predicate __pred);

      template <class _BinaryPredicate>
        void
        unique(_BinaryPredicate __pred);

      template <class _StrictWeakOrdering>
        void
        merge(slist&, _StrictWeakOrdering);

      template <class _StrictWeakOrdering>
        void
        sort(_StrictWeakOrdering __comp);
    };

  template <class _Tp, class _Alloc>
    slist<_Tp, _Alloc>&
    slist<_Tp, _Alloc>::operator=(const slist<_Tp, _Alloc>& __x)
    {
      if (&__x != this)
	{
	  _Node_base* __p1 = &this->_M_head;
	  _Node* __n1 = (_Node*) this->_M_head._M_next;
	  const _Node* __n2 = (const _Node*) __x._M_head._M_next;
	  while (__n1 && __n2)
	    {
	      __n1->_M_data = __n2->_M_data;
	      __p1 = __n1;
	      __n1 = (_Node*) __n1->_M_next;
	      __n2 = (const _Node*) __n2->_M_next;
	    }
	  if (__n2 == 0)
	    this->_M_erase_after(__p1, 0);
	  else
	    _M_insert_after_range(__p1, const_iterator((_Node*)__n2),
                                  const_iterator(0));
	}
      return *this;
    }

  template <class _Tp, class _Alloc>
    void
    slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val)
    {
      _Node_base* __prev = &this->_M_head;
      _Node* __node = (_Node*) this->_M_head._M_next;
      for (; __node != 0 && __n > 0; --__n)
	{
	  __node->_M_data = __val;
	  __prev = __node;
	  __node = (_Node*) __node->_M_next;
	}
      if (__n > 0)
	_M_insert_after_fill(__prev, __n, __val);
      else
	this->_M_erase_after(__prev, 0);
    }
  
  template <class _Tp, class _Alloc>
    template <class _InputIterator>
      void
      slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first,
					     _InputIterator __last,
					     __false_type)
      {
	_Node_base* __prev = &this->_M_head;
	_Node* __node = (_Node*) this->_M_head._M_next;
	while (__node != 0 && __first != __last)
	  {
	    __node->_M_data = *__first;
	    __prev = __node;
	    __node = (_Node*) __node->_M_next;
	    ++__first;
	  }
	if (__first != __last)
	  _M_insert_after_range(__prev, __first, __last);
	else
	  this->_M_erase_after(__prev, 0);
      }
  
  template <class _Tp, class _Alloc>
    inline bool
    operator==(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
    {
      typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator;
      const_iterator __end1 = _SL1.end();
      const_iterator __end2 = _SL2.end();
      
      const_iterator __i1 = _SL1.begin();
      const_iterator __i2 = _SL2.begin();
      while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2)
	{
	  ++__i1;
	  ++__i2;
	}
      return __i1 == __end1 && __i2 == __end2;
    }


  template <class _Tp, class _Alloc>
    inline bool
    operator<(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
    { return std::lexicographical_compare(_SL1.begin(), _SL1.end(),
					  _SL2.begin(), _SL2.end()); }

  template <class _Tp, class _Alloc>
    inline bool
    operator!=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
    { return !(_SL1 == _SL2); }

  template <class _Tp, class _Alloc>
    inline bool
    operator>(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
    { return _SL2 < _SL1; }

  template <class _Tp, class _Alloc>
    inline bool
    operator<=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
    { return !(_SL2 < _SL1); }

  template <class _Tp, class _Alloc>
    inline bool
    operator>=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2)
    { return !(_SL1 < _SL2); }

  template <class _Tp, class _Alloc>
    inline void
    swap(slist<_Tp, _Alloc>& __x, slist<_Tp, _Alloc>& __y)
    { __x.swap(__y); }

  template <class _Tp, class _Alloc>
    void
    slist<_Tp, _Alloc>::resize(size_type __len, const _Tp& __x)
    {
      _Node_base* __cur = &this->_M_head;
      while (__cur->_M_next != 0 && __len > 0)
	{
	  --__len;
	  __cur = __cur->_M_next;
	}
      if (__cur->_M_next)
	this->_M_erase_after(__cur, 0);
      else
	_M_insert_after_fill(__cur, __len, __x);
    }

  template <class _Tp, class _Alloc>
    void
    slist<_Tp, _Alloc>::remove(const _Tp& __val)
    { 
      _Node_base* __cur = &this->_M_head;
      while (__cur && __cur->_M_next)
	{
	  if (((_Node*) __cur->_M_next)->_M_data == __val)
	    this->_M_erase_after(__cur);
	  else
	    __cur = __cur->_M_next;
	}
    }

  template <class _Tp, class _Alloc>
    void
    slist<_Tp, _Alloc>::unique()
    {
      _Node_base* __cur = this->_M_head._M_next;
      if (__cur)
	{
	  while (__cur->_M_next)
	    {
	      if (((_Node*)__cur)->_M_data
		  == ((_Node*)(__cur->_M_next))->_M_data)
		this->_M_erase_after(__cur);
	      else
		__cur = __cur->_M_next;
	    }
	}
    }

  template <class _Tp, class _Alloc>
    void
    slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x)
    {
      _Node_base* __n1 = &this->_M_head;
      while (__n1->_M_next && __x._M_head._M_next)
	{
	  if (((_Node*) __x._M_head._M_next)->_M_data
	      < ((_Node*) __n1->_M_next)->_M_data)
	    __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
	  __n1 = __n1->_M_next;
	}
      if (__x._M_head._M_next)
	{
	  __n1->_M_next = __x._M_head._M_next;
	  __x._M_head._M_next = 0;
	}
    }

  template <class _Tp, class _Alloc>
    void
    slist<_Tp, _Alloc>::sort()
    {
      if (this->_M_head._M_next && this->_M_head._M_next->_M_next)
	{
	  slist __carry;
	  slist __counter[64];
	  int __fill = 0;
	  while (!empty())
	    {
	      __slist_splice_after(&__carry._M_head,
				   &this->_M_head, this->_M_head._M_next);
	      int __i = 0;
	      while (__i < __fill && !__counter[__i].empty())
		{
		  __counter[__i].merge(__carry);
		  __carry.swap(__counter[__i]);
		  ++__i;
		}
	      __carry.swap(__counter[__i]);
	      if (__i == __fill)
		++__fill;
	    }
	  
	  for (int __i = 1; __i < __fill; ++__i)
	    __counter[__i].merge(__counter[__i-1]);
	  this->swap(__counter[__fill-1]);
	}
    }

  template <class _Tp, class _Alloc>
    template <class _Predicate>
      void slist<_Tp, _Alloc>::remove_if(_Predicate __pred)
      {
	_Node_base* __cur = &this->_M_head;
	while (__cur->_M_next)
	  {
	    if (__pred(((_Node*) __cur->_M_next)->_M_data))
	      this->_M_erase_after(__cur);
	    else
	      __cur = __cur->_M_next;
	  }
      }

  template <class _Tp, class _Alloc>
    template <class _BinaryPredicate>
      void
      slist<_Tp, _Alloc>::unique(_BinaryPredicate __pred)
      {
	_Node* __cur = (_Node*) this->_M_head._M_next;
	if (__cur)
	  {
	    while (__cur->_M_next)
	      {
		if (__pred(((_Node*)__cur)->_M_data,
			   ((_Node*)(__cur->_M_next))->_M_data))
		  this->_M_erase_after(__cur);
		else
		  __cur = (_Node*) __cur->_M_next;
	      }
	  }
      }

  template <class _Tp, class _Alloc>
    template <class _StrictWeakOrdering>
      void
      slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x,
			       _StrictWeakOrdering __comp)
      {
	_Node_base* __n1 = &this->_M_head;
	while (__n1->_M_next && __x._M_head._M_next)
	  {
	    if (__comp(((_Node*) __x._M_head._M_next)->_M_data,
		       ((_Node*) __n1->_M_next)->_M_data))
	      __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next);
	    __n1 = __n1->_M_next;
	  }
	if (__x._M_head._M_next)
	  {
	    __n1->_M_next = __x._M_head._M_next;
	    __x._M_head._M_next = 0;
	  }
      }

  template <class _Tp, class _Alloc>
    template <class _StrictWeakOrdering>
      void
      slist<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp)
      {
	if (this->_M_head._M_next && this->_M_head._M_next->_M_next)
	  {
	    slist __carry;
	    slist __counter[64];
	    int __fill = 0;
	    while (!empty())
	      {
		__slist_splice_after(&__carry._M_head,
				     &this->_M_head, this->_M_head._M_next);
		int __i = 0;
		while (__i < __fill && !__counter[__i].empty())
		  {
		    __counter[__i].merge(__carry, __comp);
		    __carry.swap(__counter[__i]);
		    ++__i;
		  }
		__carry.swap(__counter[__i]);
		if (__i == __fill)
		  ++__fill;
	      }

	    for (int __i = 1; __i < __fill; ++__i)
	      __counter[__i].merge(__counter[__i-1], __comp);
	    this->swap(__counter[__fill-1]);
	  }
      }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  // Specialization of insert_iterator so that insertions will be constant
  // time rather than linear time.
  template <class _Tp, class _Alloc>
    class insert_iterator<__gnu_cxx::slist<_Tp, _Alloc> >
    {
    protected:
      typedef __gnu_cxx::slist<_Tp, _Alloc> _Container;
      _Container* container;
      typename _Container::iterator iter;

    public:
      typedef _Container          container_type;
      typedef output_iterator_tag iterator_category;
      typedef void                value_type;
      typedef void                difference_type;
      typedef void                pointer;
      typedef void                reference;

      insert_iterator(_Container& __x, typename _Container::iterator __i)
      : container(&__x)
      {
	if (__i == __x.begin())
	  iter = __x.before_begin();
	else
	  iter = __x.previous(__i);
      }

      insert_iterator<_Container>&
      operator=(const typename _Container::value_type& __value)
      {
	iter = container->insert_after(iter, __value);
	return *this;
      }

      insert_iterator<_Container>&
      operator*()
      { return *this; }

      insert_iterator<_Container>&
      operator++()
      { return *this; }

      insert_iterator<_Container>&
      operator++(int)
      { return *this; }
    };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif
