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

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

/** @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 <bits/c++config.h>
namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug {
  template<typename _Tp, typename _Allocator> class forward_list;
} } // namespace std::__debug

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

// Special validity check for forward_list ranges.
#define __glibcxx_check_valid_fl_range(_First,_Last,_Dist)		\
_GLIBCXX_DEBUG_VERIFY(_First._M_valid_range(_Last, _Dist, false),	\
		      _M_message(__gnu_debug::__msg_valid_range)	\
		      ._M_iterator(_First, #_First)			\
		      ._M_iterator(_Last, #_Last))

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 = std::__addressof(__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;

      template<typename _ItT, typename _SeqT, typename _CatT>
	friend class ::__gnu_debug::_Safe_iterator;

      // Reference wrapper for base class. See PR libstdc++/90102.
      struct _Base_ref
      {
	_Base_ref(const _Base& __r) : _M_ref(__r) { }

	const _Base& _M_ref;
      };

    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:

      forward_list() = default;

      explicit
      forward_list(const allocator_type& __al) noexcept
      : _Base(__al) { }

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

      forward_list(forward_list&& __list, const allocator_type& __al)
	noexcept(
	  std::is_nothrow_constructible<_Base,
	    _Base, const allocator_type&>::value )
      : _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 __type_identity_t<_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(
		  __glibcxx_check_valid_constructor_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(_Base_ref __x) : _Base(__x._M_ref) { }

      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)
	{
	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
	  __glibcxx_check_valid_range2(__first, __last, __dist);

	  if (__dist.second >= __gnu_debug::__dp_sign)
	    _Base::assign(__gnu_debug::__unsafe(__first),
			  __gnu_debug::__unsafe(__last));
	  else
	    _Base::assign(__first, __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:

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

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

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

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

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

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

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

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

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

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

      // element access:

      [[__nodiscard__]]
      reference
      front()
      {
	__glibcxx_check_nonempty();
	return _Base::front();
      }

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

      // modifiers:

      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 { _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 { _Base::insert_after(__pos.base(), __val), this };
      }

      iterator
      insert_after(const_iterator __pos, _Tp&& __val)
      {
	__glibcxx_check_insert_after(__pos);
	return { _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 { _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)
	{
	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
	  __glibcxx_check_insert_range_after(__pos, __first, __last, __dist);

	  if (__dist.second >= __gnu_debug::__dp_sign)
	    return
	      {
		_Base::insert_after(__pos.base(),
				    __gnu_debug::__unsafe(__first),
				    __gnu_debug::__unsafe(__last)),
		this
	      };
	  else
	    return { _Base::insert_after(__pos.base(), __first, __last), this };
	}

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

      iterator
      erase_after(const_iterator __pos)
      {
	__glibcxx_check_erase_after(__pos);

	_Base_const_iterator __next = std::next(__pos.base());
	this->_M_invalidate_if([__next](_Base_const_iterator __it)
			       { return __it == __next; });
	return { _Base::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::cend(),
				  _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 { _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(std::__addressof(__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(std::__addressof(__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)
      {
	typename __gnu_debug::_Distance_traits<const_iterator>::__type __dist;
	auto __listptr = std::__addressof(__list);
	__glibcxx_check_insert_after(__pos);
	__glibcxx_check_valid_fl_range(__before, __last, __dist);
	_GLIBCXX_DEBUG_VERIFY(__before._M_attached_to(__listptr),
			      _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(__listptr != 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); }

    private:
#if __cplusplus > 201703L
      using __remove_return_type = size_type;
# define _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG \
      __attribute__((__abi_tag__("__cxx20")))
# define _GLIBCXX20_ONLY(__expr) __expr
#else
      using __remove_return_type = void;
# define _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
# define _GLIBCXX20_ONLY(__expr)
#endif

    public:
      _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
      __remove_return_type
      remove(const _Tp& __val)
      {
	if (!this->_M_iterators && !this->_M_const_iterators)
	  return _Base::remove(__val);

	size_type __removed __attribute__((__unused__)) = 0;
	_Base __to_destroy(get_allocator());
	_Base_const_iterator __x = _Base::cbefore_begin();
	_Base_const_iterator __old = __x++;
	while (__x != _Base::cend())
	  {
	    if (*__x == __val)
	      {
		_Base_const_iterator __next = std::next(__old);
		this->_M_invalidate_if([__next](_Base_const_iterator __it)
				       { return __it == __next; });
		__to_destroy.splice_after(__to_destroy.cbefore_begin(),
					  _M_base(), __old);
		__x = __old;
		_GLIBCXX20_ONLY( __removed++ );
	      }

	    __old = __x++;
	  }

	return _GLIBCXX20_ONLY( __removed );
      }

      template<typename _Pred>
	__remove_return_type
	remove_if(_Pred __pred)
	{
	  if (!this->_M_iterators && !this->_M_const_iterators)
	    return _Base::remove_if(__pred);

	  size_type __removed __attribute__((__unused__)) = 0;
	  _Base __to_destroy(get_allocator());
	  _Base_iterator __x = _Base::before_begin();
	  _Base_iterator __old = __x++;
	  while (__x != _Base::end())
	    {
	      if (__pred(*__x))
		{
		  this->_M_invalidate_if([__x](_Base_const_iterator __it)
					 { return __it == __x; });
		  __to_destroy.splice_after(__to_destroy.cbefore_begin(),
					    _M_base(), __old);
		  __x = __old;
		  _GLIBCXX20_ONLY( __removed++ );
		}

	      __old = __x++;
	    }

	  return _GLIBCXX20_ONLY( __removed );
	}

      _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
      __remove_return_type
      unique()
      { return unique(std::equal_to<_Tp>()); }

      template<typename _BinPred>
	__remove_return_type
	unique(_BinPred __binary_pred)
	{
	  if (!this->_M_iterators && !this->_M_const_iterators)
	    return _Base::unique(__binary_pred);

	  _Base_const_iterator __first = _Base::cbegin();
	  _Base_const_iterator __last = _Base::cend();
	  if (__first == __last)
	    return _GLIBCXX20_ONLY(0);

	  size_type __removed __attribute__((__unused__)) = 0;
	  _Base __to_destroy(get_allocator());
	  _Base_const_iterator __next = std::next(__first);
	  while (__next != __last)
	    {
	      if (__binary_pred(*__first, *__next))
		{
		  this->_M_invalidate_if([__next](_Base_const_iterator __it)
					 { return __it == __next; });
		  __to_destroy.splice_after(__to_destroy.cbefore_begin(),
					    _M_base(), __first);
		  __next = __first;
		  _GLIBCXX20_ONLY( __removed++ );
		}

	      __first = __next++;
	    }

	  return _GLIBCXX20_ONLY( __removed );
	}

#undef _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
#undef _GLIBCXX20_ONLY

      void
      merge(forward_list&& __list)
      {
	if (this != std::__addressof(__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 != std::__addressof(__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; }
    };

#if __cpp_deduction_guides >= 201606
  template<typename _InputIterator, typename _ValT
	     = typename iterator_traits<_InputIterator>::value_type,
	   typename _Allocator = allocator<_ValT>,
	   typename = _RequireInputIter<_InputIterator>,
	   typename = _RequireAllocator<_Allocator>>
    forward_list(_InputIterator, _InputIterator, _Allocator = _Allocator())
      -> forward_list<_ValT, _Allocator>;

  template<typename _Tp, typename _Allocator = allocator<_Tp>,
	   typename = _RequireAllocator<_Allocator>>
    forward_list(size_t, _Tp, _Allocator = _Allocator())
      -> forward_list<_Tp, _Allocator>;
#endif

  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(); }

#if __cpp_lib_three_way_comparison
  template<typename _Tp, typename _Alloc>
    constexpr __detail::__synth3way_t<_Tp>
    operator<=>(const forward_list<_Tp, _Alloc>& __x,
		const forward_list<_Tp, _Alloc>& __y)
    { return __x._M_base() <=> __y._M_base(); }
#else
  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); }
#endif // three-way comparison

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

} // namespace __debug
} // namespace std

namespace __gnu_debug
{
  template<typename _Tp, typename _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); }
    };

  template<typename _Tp, typename _Alloc>
    struct _Sequence_traits<std::__debug::forward_list<_Tp, _Alloc> >
    {
      typedef typename std::__debug::forward_list<_Tp, _Alloc>::iterator _It;

      static typename _Distance_traits<_It>::__type
      _S_size(const std::__debug::forward_list<_Tp, _Alloc>& __seq)
      {
	return __seq.empty()
	  ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_sign);
      }
    };

#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
