// <forward_list> -*- C++ -*-

// Copyright (C) 2010-2015 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/>.

/** @file debug/forward_list
 *  This file is a GNU debug extension to the Standard C++ Library.
 */

#ifndef _GLIBCXX_DEBUG_FORWARD_LIST
#define _GLIBCXX_DEBUG_FORWARD_LIST 1

#pragma GCC system_header

#include <forward_list>
#include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h>

namespace __gnu_debug
{
  /// Special iterators swap and invalidation for forward_list because of the
  /// before_begin iterator.
  template<typename _SafeSequence>
    class _Safe_forward_list
    : public _Safe_sequence<_SafeSequence>
    {
      _SafeSequence&
      _M_this() noexcept
      { return *static_cast<_SafeSequence*>(this); }

      static void
      _M_swap_aux(_Safe_sequence_base& __lhs,
		  _Safe_iterator_base*& __lhs_iterators,
		  _Safe_sequence_base& __rhs,
		  _Safe_iterator_base*& __rhs_iterators);

      void _M_swap_single(_Safe_sequence_base&) noexcept;

    protected:
      void
      _M_invalidate_all()
      {
	using _Base_const_iterator = __decltype(_M_this()._M_base().cend());
	this->_M_invalidate_if([this](_Base_const_iterator __it)
	{
	  return __it != _M_this()._M_base().cbefore_begin()
	    && __it != _M_this()._M_base().cend(); });
      }

      void _M_swap(_Safe_sequence_base&) noexcept;
    };

   template<typename _SafeSequence>
    void
    _Safe_forward_list<_SafeSequence>::
    _M_swap_aux(_Safe_sequence_base& __lhs,
		_Safe_iterator_base*& __lhs_iterators,
		_Safe_sequence_base& __rhs,
		_Safe_iterator_base*& __rhs_iterators)
    {
      using const_iterator = typename _SafeSequence::const_iterator;
      _Safe_iterator_base* __bbegin_its = 0;
      _Safe_iterator_base* __last_bbegin = 0;
      _SafeSequence& __rseq = static_cast<_SafeSequence&>(__rhs);

      for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;)
	{
	  // Even iterator is cast to const_iterator, not a problem.
	  _Safe_iterator_base* __victim_base = __iter;
	  const_iterator* __victim =
	    static_cast<const_iterator*>(__victim_base);
	  __iter = __iter->_M_next;
	  if (__victim->base() == __rseq._M_base().cbefore_begin())
	    {
	      __victim->_M_unlink();
	      if (__lhs_iterators == __victim_base)
		__lhs_iterators = __victim_base->_M_next;
	      if (__bbegin_its)
		{
		  __victim_base->_M_next = __bbegin_its;
		  __bbegin_its->_M_prior = __victim_base;
		}
	      else
		__last_bbegin = __victim_base;
	      __bbegin_its = __victim_base;
	    }
	  else
	    __victim_base->_M_sequence = &__lhs;
	}

      if (__bbegin_its)
	{
	  if (__rhs_iterators)
	    {
	      __rhs_iterators->_M_prior = __last_bbegin;
	      __last_bbegin->_M_next = __rhs_iterators;
	    }
	  __rhs_iterators = __bbegin_its;
	}
    }

   template<typename _SafeSequence>
    void
    _Safe_forward_list<_SafeSequence>::
    _M_swap_single(_Safe_sequence_base& __other) noexcept
    {
      std::swap(_M_this()._M_iterators, __other._M_iterators);
      std::swap(_M_this()._M_const_iterators, __other._M_const_iterators);
      // Useless, always 1 on forward_list
      //std::swap(_M_this()_M_version, __other._M_version);
      _Safe_iterator_base* __this_its = _M_this()._M_iterators;
      _M_swap_aux(__other, __other._M_iterators,
		  _M_this(), _M_this()._M_iterators);
      _Safe_iterator_base* __this_const_its = _M_this()._M_const_iterators;
      _M_swap_aux(__other, __other._M_const_iterators,
		  _M_this(), _M_this()._M_const_iterators);
      _M_swap_aux(_M_this(), __this_its,
		  __other, __other._M_iterators);
      _M_swap_aux(_M_this(), __this_const_its,
		  __other, __other._M_const_iterators);
    }

  /* Special forward_list _M_swap version that does not swap the
   * before-begin ownership.*/
   template<typename _SafeSequence>
    void
    _Safe_forward_list<_SafeSequence>::
    _M_swap(_Safe_sequence_base& __other) noexcept
    {
      // We need to lock both sequences to swap
      using namespace __gnu_cxx;
      __mutex *__this_mutex = &_M_this()._M_get_mutex();
      __mutex *__other_mutex =
	&static_cast<_SafeSequence&>(__other)._M_get_mutex();
      if (__this_mutex == __other_mutex)
	{
	  __scoped_lock __lock(*__this_mutex);
	  _M_swap_single(__other);
	}
      else
	{
	  __scoped_lock __l1(__this_mutex < __other_mutex
			     ? *__this_mutex : *__other_mutex);
	  __scoped_lock __l2(__this_mutex < __other_mutex
			     ? *__other_mutex : *__this_mutex);
	  _M_swap_single(__other);
	}
    }
}

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __debug
{
  /// Class std::forward_list with safety/checking/debug instrumentation.
  template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
    class forward_list
    : public __gnu_debug::_Safe_container<
	forward_list<_Tp, _Alloc>, _Alloc, __gnu_debug::_Safe_forward_list>,
      public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>
    {
      typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>		_Base;
      typedef __gnu_debug::_Safe_container<
	forward_list, _Alloc, __gnu_debug::_Safe_forward_list>	_Safe;

      typedef typename _Base::iterator		_Base_iterator;
      typedef typename _Base::const_iterator	_Base_const_iterator;

    public:
      typedef typename _Base::reference		reference;
      typedef typename _Base::const_reference	const_reference;

      typedef __gnu_debug::_Safe_iterator<
	_Base_iterator, forward_list>		iterator;
      typedef __gnu_debug::_Safe_iterator<
	_Base_const_iterator, forward_list>	const_iterator;

      typedef typename _Base::size_type		size_type;
      typedef typename _Base::difference_type	difference_type;

      typedef _Tp				value_type;
      typedef typename _Base::allocator_type	allocator_type;
      typedef typename _Base::pointer		pointer;
      typedef typename _Base::const_pointer	const_pointer;

      // 23.2.3.1 construct/copy/destroy:
      explicit
      forward_list(const allocator_type& __al = allocator_type())
      : _Base(__al) { }

      forward_list(const forward_list& __list, const allocator_type& __al)
      : _Base(__list, __al)
      { }

      forward_list(forward_list&& __list, const allocator_type& __al)
	: _Safe(std::move(__list._M_safe()), __al),
	  _Base(std::move(__list._M_base()), __al)
      { }

      explicit
      forward_list(size_type __n, const allocator_type& __al = allocator_type())
      : _Base(__n, __al)
      { }

      forward_list(size_type __n, const _Tp& __value,
		   const allocator_type& __al = allocator_type())
      : _Base(__n, __value, __al)
      { }

      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
	forward_list(_InputIterator __first, _InputIterator __last,
		     const allocator_type& __al = allocator_type())
	: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
								     __last)),
		__gnu_debug::__base(__last), __al)
	{ }

      forward_list(const forward_list&) = default;

      forward_list(forward_list&&) = default;

      forward_list(std::initializer_list<_Tp> __il,
		   const allocator_type& __al = allocator_type())
      : _Base(__il, __al)
      { }

      ~forward_list() = default;

      forward_list&
      operator=(const forward_list&) = default;

      forward_list&
      operator=(forward_list&&) = default;

      forward_list&
      operator=(std::initializer_list<_Tp> __il)
      {
	_M_base() = __il;
	this->_M_invalidate_all();
	return *this;
      }

      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
	void
	assign(_InputIterator __first, _InputIterator __last)
	{
	  __glibcxx_check_valid_range(__first, __last);
	  _Base::assign(__gnu_debug::__base(__first),
			__gnu_debug::__base(__last));
	  this->_M_invalidate_all();
	}

      void
      assign(size_type __n, const _Tp& __val)
      {
	_Base::assign(__n, __val);
	this->_M_invalidate_all();
      }

      void
      assign(std::initializer_list<_Tp> __il)
      {
	_Base::assign(__il);
	this->_M_invalidate_all();
      }

      using _Base::get_allocator;

      // iterators:

      iterator
      before_begin() noexcept
      { return iterator(_Base::before_begin(), this); }

      const_iterator
      before_begin() const noexcept
      { return const_iterator(_Base::before_begin(), this); }

      iterator
      begin() noexcept
      { return iterator(_Base::begin(), this); }

      const_iterator
      begin() const noexcept
      { return const_iterator(_Base::begin(), this); }

      iterator
      end() noexcept
      { return iterator(_Base::end(), this); }

      const_iterator
      end() const noexcept
      { return const_iterator(_Base::end(), this); }

      const_iterator
      cbegin() const noexcept
      { return const_iterator(_Base::cbegin(), this); }

      const_iterator
      cbefore_begin() const noexcept
      { return const_iterator(_Base::cbefore_begin(), this); }

      const_iterator
      cend() const noexcept
      { return const_iterator(_Base::cend(), this); }

      using _Base::empty;
      using _Base::max_size;

      // element access:

      reference
      front()
      {
	__glibcxx_check_nonempty();
	return _Base::front();
      }

      const_reference
      front() const
      {
	__glibcxx_check_nonempty();
	return _Base::front();
      }

      // modiﬁers:

      using _Base::emplace_front;
      using _Base::push_front;

      void
      pop_front()
      {
	__glibcxx_check_nonempty();
	this->_M_invalidate_if([this](_Base_const_iterator __it)
	  { return __it == this->_M_base().cbegin(); });
	_Base::pop_front();
      }

      template<typename... _Args>
	iterator
	emplace_after(const_iterator __pos, _Args&&... __args)
	{
	  __glibcxx_check_insert_after(__pos);
	  return iterator(_Base::emplace_after(__pos.base(),
					std::forward<_Args>(__args)...),
			  this);
       	}

      iterator
      insert_after(const_iterator __pos, const _Tp& __val)
      {
	__glibcxx_check_insert_after(__pos);
	return iterator(_Base::insert_after(__pos.base(), __val), this);
      }

      iterator
      insert_after(const_iterator __pos, _Tp&& __val)
      {
	__glibcxx_check_insert_after(__pos);
	return iterator(_Base::insert_after(__pos.base(), std::move(__val)),
		       	this);
      }

      iterator
      insert_after(const_iterator __pos, size_type __n, const _Tp& __val)
      {
	__glibcxx_check_insert_after(__pos);
	return iterator(_Base::insert_after(__pos.base(), __n, __val),
		       	this);
      }

      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
	iterator
	insert_after(const_iterator __pos,
		     _InputIterator __first, _InputIterator __last)
	{
	  __glibcxx_check_insert_range_after(__pos, __first, __last);
	  return iterator(_Base::insert_after(__pos.base(),
					      __gnu_debug::__base(__first),
					      __gnu_debug::__base(__last)),
			  this);
	}

      iterator
      insert_after(const_iterator __pos, std::initializer_list<_Tp> __il)
      {
	__glibcxx_check_insert_after(__pos);
	return iterator(_Base::insert_after(__pos.base(), __il), this);
      }

    private:
      _Base_iterator
      _M_erase_after(_Base_const_iterator __pos)
      {
	_Base_const_iterator __next = std::next(__pos);
	this->_M_invalidate_if([__next](_Base_const_iterator __it)
	  { return __it == __next; });
	return _Base::erase_after(__pos);
      }
    public:
      iterator
      erase_after(const_iterator __pos)
      {
	__glibcxx_check_erase_after(__pos);
	return iterator(_M_erase_after(__pos.base()), this);
      }

      iterator
      erase_after(const_iterator __pos, const_iterator __last)
      {
	__glibcxx_check_erase_range_after(__pos, __last);
	for (_Base_const_iterator __victim = std::next(__pos.base());
	    __victim != __last.base(); ++__victim)
	  {
	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
				  _M_message(__gnu_debug::__msg_valid_range2)
				  ._M_sequence(*this, "this")
				  ._M_iterator(__pos, "pos")
				  ._M_iterator(__last, "last"));
	    this->_M_invalidate_if([__victim](_Base_const_iterator __it)
	      { return __it == __victim; });
	  }
	return iterator(_Base::erase_after(__pos.base(), __last.base()), this);
      }

      void
      swap(forward_list& __list)
	noexcept( noexcept(declval<_Base>().swap(__list)) )
      {
	_Safe::_M_swap(__list);
	_Base::swap(__list);
      }

      void
      resize(size_type __sz)
      {
	this->_M_detach_singular();

	// if __sz < size(), invalidate all iterators in [begin+__sz, end()
	_Base_iterator __victim = _Base::begin();
	_Base_iterator __end = _Base::end();
	for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
	  ++__victim;

	for (; __victim != __end; ++__victim)
	  {
	    this->_M_invalidate_if([__victim](_Base_const_iterator __it)
	      { return __it == __victim; });
	  }

	__try
	  {
	    _Base::resize(__sz);
	  }
	__catch(...)
	  {
	    this->_M_revalidate_singular();
	    __throw_exception_again;
	  }
      }

      void
      resize(size_type __sz, const value_type& __val)
      {
	this->_M_detach_singular();

	// if __sz < size(), invalidate all iterators in [begin+__sz, end())
	_Base_iterator __victim = _Base::begin();
	_Base_iterator __end = _Base::end();
	for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
	  ++__victim;

	for (; __victim != __end; ++__victim)
	  {
	    this->_M_invalidate_if([__victim](_Base_const_iterator __it)
	      { return __it == __victim; });
	  }

	__try
	  {
	    _Base::resize(__sz, __val);
	  }
	__catch(...)
	  {
	    this->_M_revalidate_singular();
	    __throw_exception_again;
	  }
      }

      void
      clear() noexcept
      {
	_Base::clear();
	this->_M_invalidate_all();
      }

      // 23.2.3.5 forward_list operations:
      void
      splice_after(const_iterator __pos, forward_list&& __list)
      {
	__glibcxx_check_insert_after(__pos);
	_GLIBCXX_DEBUG_VERIFY(&__list != this,
			      _M_message(__gnu_debug::__msg_self_splice)
			      ._M_sequence(*this, "this"));
	_GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
			      _M_message(__gnu_debug::__msg_splice_alloc)
			      ._M_sequence(*this)
			      ._M_sequence(__list, "__list"));
	this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it)
	  {
	    return __it != __list._M_base().cbefore_begin()
		   && __it != __list._M_base().end();
	  });
	_Base::splice_after(__pos.base(), std::move(__list._M_base()));
      }

      void
      splice_after(const_iterator __pos, forward_list& __list)
      { splice_after(__pos, std::move(__list)); }

      void
      splice_after(const_iterator __pos, forward_list&& __list,
		   const_iterator __i)
      {
	__glibcxx_check_insert_after(__pos);
	_GLIBCXX_DEBUG_VERIFY(__i._M_before_dereferenceable(),
			      _M_message(__gnu_debug::__msg_splice_bad)
			      ._M_iterator(__i, "__i"));
	_GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__list),
			      _M_message(__gnu_debug::__msg_splice_other)
			      ._M_iterator(__i, "__i")
			      ._M_sequence(__list, "__list"));
	_GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
			      _M_message(__gnu_debug::__msg_splice_alloc)
			      ._M_sequence(*this)
			      ._M_sequence(__list, "__list"));

	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 250. splicing invalidates iterators
	_Base_const_iterator __next = std::next(__i.base());
	this->_M_transfer_from_if(__list, [__next](_Base_const_iterator __it)
	  { return __it == __next; });
	_Base::splice_after(__pos.base(), std::move(__list._M_base()),
			    __i.base());
      }

      void
      splice_after(const_iterator __pos, forward_list& __list,
		   const_iterator __i)
      { splice_after(__pos, std::move(__list), __i); }

      void
      splice_after(const_iterator __pos, forward_list&& __list,
		   const_iterator __before, const_iterator __last)
      {
	__glibcxx_check_insert_after(__pos);
	__glibcxx_check_valid_range(__before, __last);
	_GLIBCXX_DEBUG_VERIFY(__before._M_attached_to(&__list),
			      _M_message(__gnu_debug::__msg_splice_other)
			      ._M_sequence(__list, "list")
			      ._M_iterator(__before, "before"));
	_GLIBCXX_DEBUG_VERIFY(__before._M_dereferenceable()
			      || __before._M_is_before_begin(),
			      _M_message(__gnu_debug::__msg_valid_range2)
			      ._M_sequence(__list, "list")
			      ._M_iterator(__before, "before")
			      ._M_iterator(__last, "last"));
	_GLIBCXX_DEBUG_VERIFY(__before != __last,
			      _M_message(__gnu_debug::__msg_valid_range2)
			      ._M_sequence(__list, "list")
			      ._M_iterator(__before, "before")
			      ._M_iterator(__last, "last"));
	_GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
			      _M_message(__gnu_debug::__msg_splice_alloc)
			      ._M_sequence(*this)
			      ._M_sequence(__list, "__list"));

	for (_Base_const_iterator __tmp = std::next(__before.base());
	     __tmp != __last.base(); ++__tmp)
	  {
	    _GLIBCXX_DEBUG_VERIFY(__tmp != __list._M_base().end(),
				  _M_message(__gnu_debug::__msg_valid_range2)
				  ._M_sequence(__list, "list")
				  ._M_iterator(__before, "before")
				  ._M_iterator(__last, "last"));
	    _GLIBCXX_DEBUG_VERIFY(&__list != this || __tmp != __pos.base(),
				  _M_message(__gnu_debug::__msg_splice_overlap)
				  ._M_iterator(__tmp, "position")
				  ._M_iterator(__before, "before")
				  ._M_iterator(__last, "last"));
	    // _GLIBCXX_RESOLVE_LIB_DEFECTS
	    // 250. splicing invalidates iterators
	    this->_M_transfer_from_if(__list, [__tmp](_Base_const_iterator __it)
	      { return __it == __tmp; });
	  }

	_Base::splice_after(__pos.base(), std::move(__list._M_base()),
			    __before.base(), __last.base());
      }

      void
      splice_after(const_iterator __pos, forward_list& __list,
		   const_iterator __before, const_iterator __last)
      { splice_after(__pos, std::move(__list), __before, __last); }

      void
      remove(const _Tp& __val)
      {
	_Base_iterator __x = _Base::before_begin();
	_Base_iterator __old = __x++;
	while (__x != _Base::end())
	  {
	    if (*__x == __val)
	      __x = _M_erase_after(__old);
	    else
	      __old = __x++;
	  }
      }

      template<typename _Pred>
	void
	remove_if(_Pred __pred)
	{
	  _Base_iterator __x = _Base::before_begin();
	  _Base_iterator __old = __x++;
	  while (__x != _Base::end())
	    {
	      if (__pred(*__x))
		__x = _M_erase_after(__old);
	      else
		__old = __x++;
	    }
	}

      void
      unique()
      {
	_Base_iterator __first = _Base::begin();
	_Base_iterator __last = _Base::end();
	if (__first == __last)
	  return;
	_Base_iterator __next = std::next(__first);
	while (__next != __last)
	  {
	    if (*__first == *__next)
	      __next = _M_erase_after(__first);
	    else
	      __first = __next++;
	  }
      }

      template<typename _BinPred>
	void
	unique(_BinPred __binary_pred)
	{
	  _Base_iterator __first = _Base::begin();
	  _Base_iterator __last = _Base::end();
	  if (__first == __last)
	    return;
	  _Base_iterator __next = std::next(__first);
	  while (__next != __last)
	    {
	      if (__binary_pred(*__first, *__next))
		__next = _M_erase_after(__first);
	      else
		__first = __next++;
	    }
	}

      void
      merge(forward_list&& __list)
      {
	if (this != &__list)
	{
	  __glibcxx_check_sorted(_Base::begin(), _Base::end());
	  __glibcxx_check_sorted(__list._M_base().begin(),
				 __list._M_base().end());
	  this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it)
	    {
	      return __it != __list._M_base().cbefore_begin()
		     && __it != __list._M_base().cend();
	    });
	  _Base::merge(std::move(__list._M_base()));
	}
      }

      void
      merge(forward_list& __list)
      { merge(std::move(__list)); }

      template<typename _Comp>
	void
	merge(forward_list&& __list, _Comp __comp)
	{
	  if (this != &__list)
	  {
	    __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp);
	    __glibcxx_check_sorted_pred(__list._M_base().begin(),
					__list._M_base().end(), __comp);
	    this->_M_transfer_from_if(__list,
				      [&__list](_Base_const_iterator __it)
	      {
		return __it != __list._M_base().cbefore_begin()
		       && __it != __list._M_base().cend();
	      });
	    _Base::merge(std::move(__list._M_base()), __comp);
	  }
	}

      template<typename _Comp>
	void
	merge(forward_list& __list, _Comp __comp)
	{ merge(std::move(__list), __comp); }

      using _Base::sort;
      using _Base::reverse;

      _Base&
      _M_base() noexcept { return *this; }

      const _Base&
      _M_base() const noexcept { return *this; }
    };

  template<typename _Tp, typename _Alloc>
    bool
    operator==(const forward_list<_Tp, _Alloc>& __lx,
	       const forward_list<_Tp, _Alloc>& __ly)
    { return __lx._M_base() == __ly._M_base(); }

  template<typename _Tp, typename _Alloc>
    inline bool
    operator<(const forward_list<_Tp, _Alloc>& __lx,
	      const forward_list<_Tp, _Alloc>& __ly)
    { return __lx._M_base() < __ly._M_base(); }

  template<typename _Tp, typename _Alloc>
    inline bool
    operator!=(const forward_list<_Tp, _Alloc>& __lx,
	       const forward_list<_Tp, _Alloc>& __ly)
    { return !(__lx == __ly); }

  /// Based on operator<
  template<typename _Tp, typename _Alloc>
    inline bool
    operator>(const forward_list<_Tp, _Alloc>& __lx,
	      const forward_list<_Tp, _Alloc>& __ly)
    { return (__ly < __lx); }

  /// Based on operator<
  template<typename _Tp, typename _Alloc>
    inline bool
    operator>=(const forward_list<_Tp, _Alloc>& __lx,
	       const forward_list<_Tp, _Alloc>& __ly)
    { return !(__lx < __ly); }

  /// Based on operator<
  template<typename _Tp, typename _Alloc>
    inline bool
    operator<=(const forward_list<_Tp, _Alloc>& __lx,
	       const forward_list<_Tp, _Alloc>& __ly)
    { return !(__ly < __lx); }

  /// See std::forward_list::swap().
  template<typename _Tp, typename _Alloc>
    inline void
    swap(forward_list<_Tp, _Alloc>& __lx,
	 forward_list<_Tp, _Alloc>& __ly)
    { __lx.swap(__ly); }

} // namespace __debug
} // namespace std

namespace __gnu_debug
{
  template<class _Tp, class _Alloc>
    struct _BeforeBeginHelper<std::__debug::forward_list<_Tp, _Alloc> >
    {
      typedef std::__debug::forward_list<_Tp, _Alloc> _Sequence;

      template<typename _Iterator>
	static bool
	_S_Is(const _Safe_iterator<_Iterator, _Sequence>& __it)
	{
	  return
	    __it.base() == __it._M_get_sequence()->_M_base().before_begin();
	}

      template<typename _Iterator>
	static bool
	_S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence>& __it)
	{ return _S_Is(__it); }
    };

#ifndef _GLIBCXX_DEBUG_PEDANTIC
  template<class _Tp, class _Alloc>
    struct _Insert_range_from_self_is_safe<
      std::__debug::forward_list<_Tp, _Alloc> >
    { enum { __value = 1 }; };
#endif
}

#endif
