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

// Copyright (C) 2001-2026 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 <bits/requires_hosted.h> // std::allocator

#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
