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

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

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 _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>,
      public __gnu_debug::_Safe_sequence<forward_list<_Tp, _Alloc> >
    {
      typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base;

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

      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
        rebind<_GLIBCXX_STD_C::_Fwd_list_node<_Tp>>::other _Node_alloc_type;

      typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;

    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 _Alloc                                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 _Alloc& __al = _Alloc())
      : _Base(__al) { }

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

      forward_list(forward_list&& __list, const _Alloc& __al)
      : _Base(std::move(__list._M_base()), __al)
      {
	if (__list.get_allocator() == __al)
	  this->_M_swap(__list);
	else
	  __list._M_invalidate_all();
      }

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

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

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

      forward_list(const forward_list& __list)
      : _Base(__list)
      { }

      forward_list(forward_list&& __list) noexcept
      : _Base(std::move(__list._M_base()))
      {
	this->_M_swap(__list);
      }

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

      ~forward_list() noexcept
      { }

      forward_list&
      operator=(const forward_list& __list)
      {
	static_cast<_Base&>(*this) = __list;
	this->_M_invalidate_all();
	return *this;
      }

      forward_list&
      operator=(forward_list&& __list)
      noexcept(_Node_alloc_traits::_S_nothrow_move())
      {
	__glibcxx_check_self_move_assign(__list);
	bool xfer_memory = _Node_alloc_traits::_S_propagate_on_move_assign()
	    || __list.get_allocator() == this->get_allocator();
	static_cast<_Base&>(*this) = std::move(__list);
	if (xfer_memory)
	  this->_M_swap(__list);
	else
	  this->_M_invalidate_all();
	__list._M_invalidate_all();
	return *this;
      }

      forward_list&
      operator=(std::initializer_list<_Tp> __il)
      {
	static_cast<_Base&>(*this) = __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(_Node_alloc_traits::_S_nothrow_swap())
      {
	if (!_Node_alloc_traits::_S_propagate_on_swap())
	  __glibcxx_check_equal_allocs(__list);
	_Base::swap(__list);
	this->_M_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; }

    private:
      void
      _M_invalidate_all()
      {
	this->_M_invalidate_if([this](_Base_const_iterator __it)
	  {
	    return __it != this->_M_base().cbefore_begin()
		   && __it != this->_M_base().cend();
	  });
      }
      typedef __gnu_debug::_Safe_iterator_base _Safe_iterator_base;
      static void
      _M_swap_aux(forward_list& __lhs,
		  _Safe_iterator_base*& __lhs_iterators,
		  forward_list& __rhs,
		  _Safe_iterator_base*& __rhs_iterators);
      void _M_swap(forward_list& __list);
    };

   template<typename _Tp, typename _Alloc>
    void
    forward_list<_Tp, _Alloc>::
    _M_swap_aux(forward_list<_Tp, _Alloc>& __lhs,
		__gnu_debug::_Safe_iterator_base*& __lhs_iterators,
		forward_list<_Tp, _Alloc>& __rhs,
		__gnu_debug::_Safe_iterator_base*& __rhs_iterators)
    {
      using __gnu_debug::_Safe_iterator_base;
      _Safe_iterator_base* __bbegin_its = 0;
      _Safe_iterator_base* __last_bbegin = 0;
      for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;)
	{
	  // Even iterator are casted to const_iterator, not a problem.
	  const_iterator* __victim = static_cast<const_iterator*>(__iter);
	  __iter = __iter->_M_next;
	  if (__victim->base() == __rhs._M_base().cbefore_begin())
	    {
	      __victim->_M_unlink();
	      if (__lhs_iterators == __victim)
		__lhs_iterators = __victim->_M_next;
	      if (__bbegin_its)
		{
		  __victim->_M_next = __bbegin_its;
		  __bbegin_its->_M_prior = __victim;
		}
	      else
		__last_bbegin = __victim;
	      __bbegin_its = __victim;
	    }
	  else
	    __victim->_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;
	}
    }

  /* Special forward_list _M_swap version that do not swap the
   * before-begin ownership.*/
  template<typename _Tp, typename _Alloc>
    void
    forward_list<_Tp, _Alloc>::
    _M_swap(forward_list<_Tp, _Alloc>& __list)
    {
      __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
      std::swap(this->_M_iterators, __list._M_iterators);
      std::swap(this->_M_const_iterators, __list._M_const_iterators);
      // Useless, always 1 on forward_list
      //std::swap(this->_M_version, __list._M_version);
      _Safe_iterator_base* __this_its = this->_M_iterators;
      _M_swap_aux(__list, __list._M_iterators, *this, this->_M_iterators);
      _Safe_iterator_base* __this_const_its = this->_M_const_iterators;
      _M_swap_aux(__list, __list._M_const_iterators, *this,
		  this->_M_const_iterators);
      _M_swap_aux(*this, __this_its, __list, __list._M_iterators);
      _M_swap_aux(*this, __this_const_its, __list, __list._M_const_iterators);
    }

  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;
      typedef typename _Sequence::const_iterator _It;
      typedef typename _It::iterator_type _BaseIt;

      static bool
      _S_Is(_BaseIt __it, const _Sequence* __seq)
      { return __it == __seq->_M_base().cbefore_begin(); }

      static bool
      _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq)
      { return _S_Is(__it, __seq); }
    };
}

#endif
