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

// Copyright (C) 2001-2021 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>
#include <ext/alloc_traits.h>

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  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 std::size_t
  __slist_size(_Slist_node_base* __node)
  {
    std::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 std::size_t                    size_type;
    typedef std::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_traits<_Alloc>::template rebind<_Slist_node<_Tp> >::other
    {
      typedef typename __alloc_traits<_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;
	allocator_type __a = get_allocator();
	__alloc_traits<allocator_type>::destroy(__a, &__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;
	  allocator_type __a = get_allocator();
	  __alloc_traits<allocator_type>::destroy(__a, &__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 = std::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 std::size_t            size_type;
      typedef std::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
	  {
	    allocator_type __a = get_allocator();
	    __alloc_traits<allocator_type>::construct(__a, &__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
	  {
	    allocator_type __a = get_allocator();
	    __alloc_traits<allocator_type>::construct(__a, &__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, std::__true_type)
      { _M_fill_assign((size_type) __n, (_Tp) __val); }

      template <class _InputIterator>
      void
      _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
			 std::__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); }

      _GLIBCXX_NODISCARD 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;
	allocator_type __a = get_allocator();
	__alloc_traits<allocator_type>::destroy(__a, &__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,
			      std::__true_type)
        { _M_insert_after_fill(__pos, __n, __x); }

      template <class _InIterator>
        void
        _M_insert_after_range(_Node_base* __pos,
			      _InIterator __first, _InIterator __last,
			      std::__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,
					     std::__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
