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

// Copyright (C) 2008-2016 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 bits/forward_list.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{forward_list}
 */

#ifndef _FORWARD_LIST_H
#define _FORWARD_LIST_H 1

#pragma GCC system_header

#include <initializer_list>
#include <bits/stl_iterator_base_types.h>
#include <bits/stl_iterator.h>
#include <bits/stl_algobase.h>
#include <bits/stl_function.h>
#include <bits/allocator.h>
#include <ext/alloc_traits.h>
#include <ext/aligned_buffer.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER

  /**
   *  @brief  A helper basic node class for %forward_list.
   *          This is just a linked list with nothing inside it.
   *          There are purely list shuffling utility methods here.
   */
  struct _Fwd_list_node_base
  {
    _Fwd_list_node_base() = default;

    _Fwd_list_node_base* _M_next = nullptr;

    _Fwd_list_node_base*
    _M_transfer_after(_Fwd_list_node_base* __begin,
		      _Fwd_list_node_base* __end) noexcept
    {
      _Fwd_list_node_base* __keep = __begin->_M_next;
      if (__end)
	{
	  __begin->_M_next = __end->_M_next;
	  __end->_M_next = _M_next;
	}
      else
	__begin->_M_next = 0;
      _M_next = __keep;
      return __end;
    }

    void
    _M_reverse_after() noexcept
    {
      _Fwd_list_node_base* __tail = _M_next;
      if (!__tail)
	return;
      while (_Fwd_list_node_base* __temp = __tail->_M_next)
	{
	  _Fwd_list_node_base* __keep = _M_next;
	  _M_next = __temp;
	  __tail->_M_next = __temp->_M_next;
	  _M_next->_M_next = __keep;
	}
    }
  };

  /**
   *  @brief  A helper node class for %forward_list.
   *          This is just a linked list with uninitialized storage for a
   *          data value in each node.
   *          There is a sorting utility method.
   */
  template<typename _Tp>
    struct _Fwd_list_node
    : public _Fwd_list_node_base
    {
      _Fwd_list_node() = default;

      __gnu_cxx::__aligned_buffer<_Tp> _M_storage;

      _Tp*
      _M_valptr() noexcept
      { return _M_storage._M_ptr(); }

      const _Tp*
      _M_valptr() const noexcept
      { return _M_storage._M_ptr(); }
    };

  /**
   *   @brief A forward_list::iterator.
   * 
   *   All the functions are op overloads.
   */
  template<typename _Tp>
    struct _Fwd_list_iterator
    {
      typedef _Fwd_list_iterator<_Tp>            _Self;
      typedef _Fwd_list_node<_Tp>                _Node;

      typedef _Tp                                value_type;
      typedef _Tp*                               pointer;
      typedef _Tp&                               reference;
      typedef ptrdiff_t                          difference_type;
      typedef std::forward_iterator_tag          iterator_category;

      _Fwd_list_iterator() noexcept
      : _M_node() { }

      explicit
      _Fwd_list_iterator(_Fwd_list_node_base* __n) noexcept
      : _M_node(__n) { }

      reference
      operator*() const noexcept
      { return *static_cast<_Node*>(this->_M_node)->_M_valptr(); }

      pointer
      operator->() const noexcept
      { return static_cast<_Node*>(this->_M_node)->_M_valptr(); }

      _Self&
      operator++() noexcept
      {
        _M_node = _M_node->_M_next;
        return *this;
      }

      _Self
      operator++(int) noexcept
      {
        _Self __tmp(*this);
        _M_node = _M_node->_M_next;
        return __tmp;
      }

      bool
      operator==(const _Self& __x) const noexcept
      { return _M_node == __x._M_node; }

      bool
      operator!=(const _Self& __x) const noexcept
      { return _M_node != __x._M_node; }

      _Self
      _M_next() const noexcept
      {
        if (_M_node)
          return _Fwd_list_iterator(_M_node->_M_next);
        else
          return _Fwd_list_iterator(0);
      }

      _Fwd_list_node_base* _M_node;
    };

  /**
   *   @brief A forward_list::const_iterator.
   * 
   *   All the functions are op overloads.
   */
  template<typename _Tp>
    struct _Fwd_list_const_iterator
    {
      typedef _Fwd_list_const_iterator<_Tp>      _Self;
      typedef const _Fwd_list_node<_Tp>          _Node;
      typedef _Fwd_list_iterator<_Tp>            iterator;

      typedef _Tp                                value_type;
      typedef const _Tp*                         pointer;
      typedef const _Tp&                         reference;
      typedef ptrdiff_t                          difference_type;
      typedef std::forward_iterator_tag          iterator_category;

      _Fwd_list_const_iterator() noexcept
      : _M_node() { }

      explicit
      _Fwd_list_const_iterator(const _Fwd_list_node_base* __n)  noexcept
      : _M_node(__n) { }

      _Fwd_list_const_iterator(const iterator& __iter) noexcept
      : _M_node(__iter._M_node) { }

      reference
      operator*() const noexcept
      { return *static_cast<_Node*>(this->_M_node)->_M_valptr(); }

      pointer
      operator->() const noexcept
      { return static_cast<_Node*>(this->_M_node)->_M_valptr(); }

      _Self&
      operator++() noexcept
      {
        _M_node = _M_node->_M_next;
        return *this;
      }

      _Self
      operator++(int) noexcept
      {
        _Self __tmp(*this);
        _M_node = _M_node->_M_next;
        return __tmp;
      }

      bool
      operator==(const _Self& __x) const noexcept
      { return _M_node == __x._M_node; }

      bool
      operator!=(const _Self& __x) const noexcept
      { return _M_node != __x._M_node; }

      _Self
      _M_next() const noexcept
      {
        if (this->_M_node)
          return _Fwd_list_const_iterator(_M_node->_M_next);
        else
          return _Fwd_list_const_iterator(0);
      }

      const _Fwd_list_node_base* _M_node;
    };

  /**
   *  @brief  Forward list iterator equality comparison.
   */
  template<typename _Tp>
    inline bool
    operator==(const _Fwd_list_iterator<_Tp>& __x,
               const _Fwd_list_const_iterator<_Tp>& __y) noexcept
    { return __x._M_node == __y._M_node; }

  /**
   *  @brief  Forward list iterator inequality comparison.
   */
  template<typename _Tp>
    inline bool
    operator!=(const _Fwd_list_iterator<_Tp>& __x,
               const _Fwd_list_const_iterator<_Tp>& __y) noexcept
    { return __x._M_node != __y._M_node; }

  /**
   *  @brief  Base class for %forward_list.
   */
  template<typename _Tp, typename _Alloc>
    struct _Fwd_list_base
    {
    protected:
      typedef __alloc_rebind<_Alloc, _Tp> 		  _Tp_alloc_type;
      typedef __alloc_rebind<_Alloc, _Fwd_list_node<_Tp>> _Node_alloc_type;
      typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;

      struct _Fwd_list_impl 
      : public _Node_alloc_type
      {
        _Fwd_list_node_base _M_head;

        _Fwd_list_impl()
        : _Node_alloc_type(), _M_head()
        { }

        _Fwd_list_impl(const _Node_alloc_type& __a)
        : _Node_alloc_type(__a), _M_head()
        { }

        _Fwd_list_impl(_Node_alloc_type&& __a)
	: _Node_alloc_type(std::move(__a)), _M_head()
        { }
      };

      _Fwd_list_impl _M_impl;

    public:
      typedef _Fwd_list_iterator<_Tp>                 iterator;
      typedef _Fwd_list_const_iterator<_Tp>           const_iterator;
      typedef _Fwd_list_node<_Tp>                     _Node;

      _Node_alloc_type&
      _M_get_Node_allocator() noexcept
      { return this->_M_impl; }

      const _Node_alloc_type&
      _M_get_Node_allocator() const noexcept
      { return this->_M_impl; }

      _Fwd_list_base()
      : _M_impl() { }

      _Fwd_list_base(_Node_alloc_type&& __a)
      : _M_impl(std::move(__a)) { }

      _Fwd_list_base(_Fwd_list_base&& __lst, _Node_alloc_type&& __a);

      _Fwd_list_base(_Fwd_list_base&& __lst)
      : _M_impl(std::move(__lst._M_get_Node_allocator()))
      {
	this->_M_impl._M_head._M_next = __lst._M_impl._M_head._M_next;
	__lst._M_impl._M_head._M_next = 0;
      }

      ~_Fwd_list_base()
      { _M_erase_after(&_M_impl._M_head, 0); }

    protected:

      _Node*
      _M_get_node()
      {
	auto __ptr = _Node_alloc_traits::allocate(_M_get_Node_allocator(), 1);
	return std::__addressof(*__ptr);
      }

      template<typename... _Args>
        _Node*
        _M_create_node(_Args&&... __args)
        {
          _Node* __node = this->_M_get_node();
          __try
            {
	      _Tp_alloc_type __a(_M_get_Node_allocator());
	      typedef allocator_traits<_Tp_alloc_type> _Alloc_traits;
	      ::new ((void*)__node) _Node;
	      _Alloc_traits::construct(__a, __node->_M_valptr(),
				       std::forward<_Args>(__args)...);
            }
          __catch(...)
            {
              this->_M_put_node(__node);
              __throw_exception_again;
            }
          return __node;
        }

      template<typename... _Args>
        _Fwd_list_node_base*
        _M_insert_after(const_iterator __pos, _Args&&... __args);

      void
      _M_put_node(_Node* __p)
      {
	typedef typename _Node_alloc_traits::pointer _Ptr;
	auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__p);
	_Node_alloc_traits::deallocate(_M_get_Node_allocator(), __ptr, 1);
      }

      _Fwd_list_node_base*
      _M_erase_after(_Fwd_list_node_base* __pos);

      _Fwd_list_node_base*
      _M_erase_after(_Fwd_list_node_base* __pos, 
                     _Fwd_list_node_base* __last);
    };

  /**
   *  @brief A standard container with linear time access to elements,
   *  and fixed time insertion/deletion at any point in the sequence.
   *
   *  @ingroup sequences
   *
   *  @tparam _Tp  Type of element.
   *  @tparam _Alloc  Allocator type, defaults to allocator<_Tp>.
   *
   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
   *  <a href="tables.html#67">sequence</a>, including the
   *  <a href="tables.html#68">optional sequence requirements</a> with the
   *  %exception of @c at and @c operator[].
   *
   *  This is a @e singly @e linked %list.  Traversal up the
   *  %list requires linear time, but adding and removing elements (or
   *  @e nodes) is done in constant time, regardless of where the
   *  change takes place.  Unlike std::vector and std::deque,
   *  random-access iterators are not provided, so subscripting ( @c
   *  [] ) access is not allowed.  For algorithms which only need
   *  sequential access, this lack makes no difference.
   *
   *  Also unlike the other standard containers, std::forward_list provides
   *  specialized algorithms %unique to linked lists, such as
   *  splicing, sorting, and in-place reversal.
   */
  template<typename _Tp, typename _Alloc = allocator<_Tp> >
    class forward_list : private _Fwd_list_base<_Tp, _Alloc>
    {
    private:
      typedef _Fwd_list_base<_Tp, _Alloc>                  _Base;
      typedef _Fwd_list_node<_Tp>                          _Node;
      typedef _Fwd_list_node_base                          _Node_base;
      typedef typename _Base::_Tp_alloc_type               _Tp_alloc_type;
      typedef typename _Base::_Node_alloc_type             _Node_alloc_type;
      typedef typename _Base::_Node_alloc_traits           _Node_alloc_traits;
      typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type>    _Alloc_traits;

    public:
      // types:
      typedef _Tp                                          value_type;
      typedef typename _Alloc_traits::pointer              pointer;
      typedef typename _Alloc_traits::const_pointer        const_pointer;
      typedef value_type&				   reference;
      typedef const value_type&				   const_reference;
 
      typedef _Fwd_list_iterator<_Tp>                      iterator;
      typedef _Fwd_list_const_iterator<_Tp>                const_iterator;
      typedef std::size_t                                  size_type;
      typedef std::ptrdiff_t                               difference_type;
      typedef _Alloc                                       allocator_type;

      // 23.3.4.2 construct/copy/destroy:

      /**
       *  @brief  Creates a %forward_list with no elements.
       */
      forward_list()
      noexcept(is_nothrow_default_constructible<_Node_alloc_type>::value)
      : _Base()
      { }

      /**
       *  @brief  Creates a %forward_list with no elements.
       *  @param  __al  An allocator object.
       */
      explicit
      forward_list(const _Alloc& __al) noexcept
      : _Base(_Node_alloc_type(__al))
      { }


      /**
       *  @brief  Copy constructor with allocator argument.
       *  @param  __list  Input list to copy.
       *  @param  __al    An allocator object.
       */
      forward_list(const forward_list& __list, const _Alloc& __al)
      : _Base(_Node_alloc_type(__al))
      { _M_range_initialize(__list.begin(), __list.end()); }

      /**
       *  @brief  Move constructor with allocator argument.
       *  @param  __list  Input list to move.
       *  @param  __al    An allocator object.
       */
      forward_list(forward_list&& __list, const _Alloc& __al)
      noexcept(_Node_alloc_traits::_S_always_equal())
      : _Base(std::move(__list), _Node_alloc_type(__al))
      {
	// If __list is not empty it means its allocator is not equal to __a,
	// so we need to move from each element individually.
	insert_after(cbefore_begin(),
		     std::__make_move_if_noexcept_iterator(__list.begin()),
		     std::__make_move_if_noexcept_iterator(__list.end()));
      }

      /**
       *  @brief  Creates a %forward_list with default constructed elements.
       *  @param  __n   The number of elements to initially create.
       *  @param  __al  An allocator object.
       *
       *  This constructor creates the %forward_list with @a __n default
       *  constructed elements.
       */
      explicit
      forward_list(size_type __n, const _Alloc& __al = _Alloc())
      : _Base(_Node_alloc_type(__al))
      { _M_default_initialize(__n); }

      /**
       *  @brief  Creates a %forward_list with copies of an exemplar element.
       *  @param  __n      The number of elements to initially create.
       *  @param  __value  An element to copy.
       *  @param  __al     An allocator object.
       *
       *  This constructor fills the %forward_list with @a __n copies of
       *  @a __value.
       */
      forward_list(size_type __n, const _Tp& __value,
                   const _Alloc& __al = _Alloc())
      : _Base(_Node_alloc_type(__al))
      { _M_fill_initialize(__n, __value); }

      /**
       *  @brief  Builds a %forward_list from a range.
       *  @param  __first  An input iterator.
       *  @param  __last   An input iterator.
       *  @param  __al     An allocator object.
       *
       *  Create a %forward_list consisting of copies of the elements from
       *  [@a __first,@a __last).  This is linear in N (where N is
       *  distance(@a __first,@a __last)).
       */
      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
        forward_list(_InputIterator __first, _InputIterator __last,
                     const _Alloc& __al = _Alloc())
	: _Base(_Node_alloc_type(__al))
        { _M_range_initialize(__first, __last); }

      /**
       *  @brief  The %forward_list copy constructor.
       *  @param  __list  A %forward_list of identical element and allocator
       *                  types.
       */
      forward_list(const forward_list& __list)
      : _Base(_Node_alloc_traits::_S_select_on_copy(
                __list._M_get_Node_allocator()))
      { _M_range_initialize(__list.begin(), __list.end()); }

      /**
       *  @brief  The %forward_list move constructor.
       *  @param  __list  A %forward_list of identical element and allocator
       *                  types.
       *
       *  The newly-created %forward_list contains the exact contents of @a
       *  __list. The contents of @a __list are a valid, but unspecified
       *  %forward_list.
       */
      forward_list(forward_list&& __list) noexcept
      : _Base(std::move(__list)) { }

      /**
       *  @brief  Builds a %forward_list from an initializer_list
       *  @param  __il  An initializer_list of value_type.
       *  @param  __al  An allocator object.
       *
       *  Create a %forward_list consisting of copies of the elements
       *  in the initializer_list @a __il.  This is linear in __il.size().
       */
      forward_list(std::initializer_list<_Tp> __il,
                   const _Alloc& __al = _Alloc())
      : _Base(_Node_alloc_type(__al))
      { _M_range_initialize(__il.begin(), __il.end()); }

      /**
       *  @brief  The forward_list dtor.
       */
      ~forward_list() noexcept
      { }

      /**
       *  @brief  The %forward_list assignment operator.
       *  @param  __list  A %forward_list of identical element and allocator
       *                types.
       *
       *  All the elements of @a __list are copied, but unlike the copy
       *  constructor, the allocator object is not copied.
       */
      forward_list&
      operator=(const forward_list& __list);

      /**
       *  @brief  The %forward_list move assignment operator.
       *  @param  __list  A %forward_list of identical element and allocator
       *                types.
       *
       *  The contents of @a __list are moved into this %forward_list
       *  (without copying, if the allocators permit it).
       *  @a __list is a valid, but unspecified %forward_list
       */
      forward_list&
      operator=(forward_list&& __list)
      noexcept(_Node_alloc_traits::_S_nothrow_move())
      {
        constexpr bool __move_storage =
          _Node_alloc_traits::_S_propagate_on_move_assign()
          || _Node_alloc_traits::_S_always_equal();
        _M_move_assign(std::move(__list), __bool_constant<__move_storage>());
	return *this;
      }

      /**
       *  @brief  The %forward_list initializer list assignment operator.
       *  @param  __il  An initializer_list of value_type.
       *
       *  Replace the contents of the %forward_list with copies of the
       *  elements in the initializer_list @a __il.  This is linear in
       *  __il.size().
       */
      forward_list&
      operator=(std::initializer_list<_Tp> __il)
      {
        assign(__il);
        return *this;
      }

      /**
       *  @brief  Assigns a range to a %forward_list.
       *  @param  __first  An input iterator.
       *  @param  __last   An input iterator.
       *
       *  This function fills a %forward_list with copies of the elements
       *  in the range [@a __first,@a __last).
       *
       *  Note that the assignment completely changes the %forward_list and
       *  that the number of elements of the resulting %forward_list is the
       *  same as the number of elements assigned.  Old data is lost.
       */
      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
	void
        assign(_InputIterator __first, _InputIterator __last)
        {
	  typedef is_assignable<_Tp, decltype(*__first)> __assignable;
	  _M_assign(__first, __last, __assignable());
	}

      /**
       *  @brief  Assigns a given value to a %forward_list.
       *  @param  __n  Number of elements to be assigned.
       *  @param  __val  Value to be assigned.
       *
       *  This function fills a %forward_list with @a __n copies of the
       *  given value.  Note that the assignment completely changes the
       *  %forward_list, and that the resulting %forward_list has __n
       *  elements.  Old data is lost.
       */
      void
      assign(size_type __n, const _Tp& __val)
      { _M_assign_n(__n, __val, is_copy_assignable<_Tp>()); }

      /**
       *  @brief  Assigns an initializer_list to a %forward_list.
       *  @param  __il  An initializer_list of value_type.
       *
       *  Replace the contents of the %forward_list with copies of the
       *  elements in the initializer_list @a __il.  This is linear in
       *  il.size().
       */
      void
      assign(std::initializer_list<_Tp> __il)
      { assign(__il.begin(), __il.end()); }

      /// Get a copy of the memory allocation object.
      allocator_type
      get_allocator() const noexcept
      { return allocator_type(this->_M_get_Node_allocator()); }

      // 23.3.4.3 iterators:

      /**
       *  Returns a read/write iterator that points before the first element
       *  in the %forward_list.  Iteration is done in ordinary element order.
       */
      iterator
      before_begin() noexcept
      { return iterator(&this->_M_impl._M_head); }

      /**
       *  Returns a read-only (constant) iterator that points before the
       *  first element in the %forward_list.  Iteration is done in ordinary
       *  element order.
       */
      const_iterator
      before_begin() const noexcept
      { return const_iterator(&this->_M_impl._M_head); }

      /**
       *  Returns a read/write iterator that points to the first element
       *  in the %forward_list.  Iteration is done in ordinary element order.
       */
      iterator
      begin() noexcept
      { return iterator(this->_M_impl._M_head._M_next); }

      /**
       *  Returns a read-only (constant) iterator that points to the first
       *  element in the %forward_list.  Iteration is done in ordinary
       *  element order.
       */
      const_iterator
      begin() const noexcept
      { return const_iterator(this->_M_impl._M_head._M_next); }

      /**
       *  Returns a read/write iterator that points one past the last
       *  element in the %forward_list.  Iteration is done in ordinary
       *  element order.
       */
      iterator
      end() noexcept
      { return iterator(0); }

      /**
       *  Returns a read-only iterator that points one past the last
       *  element in the %forward_list.  Iteration is done in ordinary
       *  element order.
       */
      const_iterator
      end() const noexcept
      { return const_iterator(0); }

      /**
       *  Returns a read-only (constant) iterator that points to the
       *  first element in the %forward_list.  Iteration is done in ordinary
       *  element order.
       */
      const_iterator
      cbegin() const noexcept
      { return const_iterator(this->_M_impl._M_head._M_next); }

      /**
       *  Returns a read-only (constant) iterator that points before the
       *  first element in the %forward_list.  Iteration is done in ordinary
       *  element order.
       */
      const_iterator
      cbefore_begin() const noexcept
      { return const_iterator(&this->_M_impl._M_head); }

      /**
       *  Returns a read-only (constant) iterator that points one past
       *  the last element in the %forward_list.  Iteration is done in
       *  ordinary element order.
       */
      const_iterator
      cend() const noexcept
      { return const_iterator(0); }

      /**
       *  Returns true if the %forward_list is empty.  (Thus begin() would
       *  equal end().)
       */
      bool
      empty() const noexcept
      { return this->_M_impl._M_head._M_next == 0; }

      /**
       *  Returns the largest possible number of elements of %forward_list.
       */
      size_type
      max_size() const noexcept
      { return _Node_alloc_traits::max_size(this->_M_get_Node_allocator()); }

      // 23.3.4.4 element access:

      /**
       *  Returns a read/write reference to the data at the first
       *  element of the %forward_list.
       */
      reference
      front()
      {
        _Node* __front = static_cast<_Node*>(this->_M_impl._M_head._M_next);
        return *__front->_M_valptr();
      }

      /**
       *  Returns a read-only (constant) reference to the data at the first
       *  element of the %forward_list.
       */
      const_reference
      front() const
      {
        _Node* __front = static_cast<_Node*>(this->_M_impl._M_head._M_next);
        return *__front->_M_valptr();
      }

      // 23.3.4.5 modiﬁers:

      /**
       *  @brief  Constructs object in %forward_list at the front of the
       *          list.
       *  @param  __args  Arguments.
       *
       *  This function will insert an object of type Tp constructed
       *  with Tp(std::forward<Args>(args)...) at the front of the list
       *  Due to the nature of a %forward_list this operation can
       *  be done in constant time, and does not invalidate iterators
       *  and references.
       */
      template<typename... _Args>
        void
        emplace_front(_Args&&... __args)
        { this->_M_insert_after(cbefore_begin(),
                                std::forward<_Args>(__args)...); }

      /**
       *  @brief  Add data to the front of the %forward_list.
       *  @param  __val  Data to be added.
       *
       *  This is a typical stack operation.  The function creates an
       *  element at the front of the %forward_list and assigns the given
       *  data to it.  Due to the nature of a %forward_list this operation
       *  can be done in constant time, and does not invalidate iterators
       *  and references.
       */
      void
      push_front(const _Tp& __val)
      { this->_M_insert_after(cbefore_begin(), __val); }

      /**
       *
       */
      void
      push_front(_Tp&& __val)
      { this->_M_insert_after(cbefore_begin(), std::move(__val)); }

      /**
       *  @brief  Removes first element.
       *
       *  This is a typical stack operation.  It shrinks the %forward_list
       *  by one.  Due to the nature of a %forward_list this operation can
       *  be done in constant time, and only invalidates iterators/references
       *  to the element being removed.
       *
       *  Note that no data is returned, and if the first element's data
       *  is needed, it should be retrieved before pop_front() is
       *  called.
       */
      void
      pop_front()
      { this->_M_erase_after(&this->_M_impl._M_head); }

      /**
       *  @brief  Constructs object in %forward_list after the specified
       *          iterator.
       *  @param  __pos  A const_iterator into the %forward_list.
       *  @param  __args  Arguments.
       *  @return  An iterator that points to the inserted data.
       *
       *  This function will insert an object of type T constructed
       *  with T(std::forward<Args>(args)...) after the specified
       *  location.  Due to the nature of a %forward_list this operation can
       *  be done in constant time, and does not invalidate iterators
       *  and references.
       */
      template<typename... _Args>
        iterator
        emplace_after(const_iterator __pos, _Args&&... __args)
        { return iterator(this->_M_insert_after(__pos,
                                          std::forward<_Args>(__args)...)); }

      /**
       *  @brief  Inserts given value into %forward_list after specified
       *          iterator.
       *  @param  __pos  An iterator into the %forward_list.
       *  @param  __val  Data to be inserted.
       *  @return  An iterator that points to the inserted data.
       *
       *  This function will insert a copy of the given value after
       *  the specified location.  Due to the nature of a %forward_list this
       *  operation can be done in constant time, and does not
       *  invalidate iterators and references.
       */
      iterator
      insert_after(const_iterator __pos, const _Tp& __val)
      { return iterator(this->_M_insert_after(__pos, __val)); }

      /**
       *
       */
      iterator
      insert_after(const_iterator __pos, _Tp&& __val)
      { return iterator(this->_M_insert_after(__pos, std::move(__val))); }

      /**
       *  @brief  Inserts a number of copies of given data into the
       *          %forward_list.
       *  @param  __pos  An iterator into the %forward_list.
       *  @param  __n  Number of elements to be inserted.
       *  @param  __val  Data to be inserted.
       *  @return  An iterator pointing to the last inserted copy of
       *           @a val or @a pos if @a n == 0.
       *
       *  This function will insert a specified number of copies of the
       *  given data after the location specified by @a pos.
       *
       *  This operation is linear in the number of elements inserted and
       *  does not invalidate iterators and references.
       */
      iterator
      insert_after(const_iterator __pos, size_type __n, const _Tp& __val);

      /**
       *  @brief  Inserts a range into the %forward_list.
       *  @param  __pos  An iterator into the %forward_list.
       *  @param  __first  An input iterator.
       *  @param  __last   An input iterator.
       *  @return  An iterator pointing to the last inserted element or
       *           @a __pos if @a __first == @a __last.
       *
       *  This function will insert copies of the data in the range
       *  [@a __first,@a __last) into the %forward_list after the
       *  location specified by @a __pos.
       *
       *  This operation is linear in the number of elements inserted and
       *  does not invalidate iterators and references.
       */
      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
        iterator
        insert_after(const_iterator __pos,
                     _InputIterator __first, _InputIterator __last);

      /**
       *  @brief  Inserts the contents of an initializer_list into
       *          %forward_list after the specified iterator.
       *  @param  __pos  An iterator into the %forward_list.
       *  @param  __il  An initializer_list of value_type.
       *  @return  An iterator pointing to the last inserted element
       *           or @a __pos if @a __il is empty.
       *
       *  This function will insert copies of the data in the
       *  initializer_list @a __il into the %forward_list before the location
       *  specified by @a __pos.
       *
       *  This operation is linear in the number of elements inserted and
       *  does not invalidate iterators and references.
       */
      iterator
      insert_after(const_iterator __pos, std::initializer_list<_Tp> __il)
      { return insert_after(__pos, __il.begin(), __il.end()); }

      /**
       *  @brief  Removes the element pointed to by the iterator following
       *          @c pos.
       *  @param  __pos  Iterator pointing before element to be erased.
       *  @return  An iterator pointing to the element following the one
       *           that was erased, or end() if no such element exists.
       *
       *  This function will erase the element at the given position and
       *  thus shorten the %forward_list by one.
       *
       *  Due to the nature of a %forward_list this operation can be done
       *  in constant time, and only invalidates iterators/references to
       *  the element being removed.  The user is also cautioned that
       *  this function only erases the element, and that if the element
       *  is itself a pointer, the pointed-to memory is not touched in
       *  any way.  Managing the pointer is the user's responsibility.
       */
      iterator
      erase_after(const_iterator __pos)
      { return iterator(this->_M_erase_after(const_cast<_Node_base*>
					     (__pos._M_node))); }

      /**
       *  @brief  Remove a range of elements.
       *  @param  __pos  Iterator pointing before the first element to be
       *                 erased.
       *  @param  __last  Iterator pointing to one past the last element to be
       *                  erased.
       *  @return  @ __last.
       *
       *  This function will erase the elements in the range
       *  @a (__pos,__last) and shorten the %forward_list accordingly.
       *
       *  This operation is linear time in the size of the range and only
       *  invalidates iterators/references to the element being removed.
       *  The user is also cautioned that this function only erases the
       *  elements, and that if the elements themselves are pointers, the
       *  pointed-to memory is not touched in any way.  Managing the pointer
       *  is the user's responsibility.
       */
      iterator
      erase_after(const_iterator __pos, const_iterator __last)
      { return iterator(this->_M_erase_after(const_cast<_Node_base*>
					     (__pos._M_node),
					     const_cast<_Node_base*>
					     (__last._M_node))); }

      /**
       *  @brief  Swaps data with another %forward_list.
       *  @param  __list  A %forward_list of the same element and allocator
       *                  types.
       *
       *  This exchanges the elements between two lists in constant
       *  time.  Note that the global std::swap() function is
       *  specialized such that std::swap(l1,l2) will feed to this
       *  function.
       */
      void
      swap(forward_list& __list) noexcept
      {
        std::swap(this->_M_impl._M_head._M_next,
		  __list._M_impl._M_head._M_next);
	_Node_alloc_traits::_S_on_swap(this->_M_get_Node_allocator(),
                                       __list._M_get_Node_allocator());
      }

      /**
       *  @brief Resizes the %forward_list to the specified number of
       *         elements.
       *  @param __sz Number of elements the %forward_list should contain.
       *
       *  This function will %resize the %forward_list to the specified
       *  number of elements.  If the number is smaller than the
       *  %forward_list's current number of elements the %forward_list
       *  is truncated, otherwise the %forward_list is extended and the
       *  new elements are default constructed.
       */
      void
      resize(size_type __sz);

      /**
       *  @brief Resizes the %forward_list to the specified number of
       *         elements.
       *  @param __sz Number of elements the %forward_list should contain.
       *  @param __val Data with which new elements should be populated.
       *
       *  This function will %resize the %forward_list to the specified
       *  number of elements.  If the number is smaller than the
       *  %forward_list's current number of elements the %forward_list
       *  is truncated, otherwise the %forward_list is extended and new
       *  elements are populated with given data.
       */
      void
      resize(size_type __sz, const value_type& __val);

      /**
       *  @brief  Erases all the elements.
       *
       *  Note that this function only erases
       *  the elements, and that if the elements themselves are
       *  pointers, the pointed-to memory is not touched in any way.
       *  Managing the pointer is the user's responsibility.
       */
      void
      clear() noexcept
      { this->_M_erase_after(&this->_M_impl._M_head, 0); }

      // 23.3.4.6 forward_list operations:

      /**
       *  @brief  Insert contents of another %forward_list.
       *  @param  __pos  Iterator referencing the element to insert after.
       *  @param  __list  Source list.
       *
       *  The elements of @a list are inserted in constant time after
       *  the element referenced by @a pos.  @a list becomes an empty
       *  list.
       *
       *  Requires this != @a x.
       */
      void
      splice_after(const_iterator __pos, forward_list&& __list) noexcept
      {
	if (!__list.empty())
	  _M_splice_after(__pos, __list.before_begin(), __list.end());
      }

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

      /**
       *  @brief  Insert element from another %forward_list.
       *  @param  __pos  Iterator referencing the element to insert after.
       *  @param  __list  Source list.
       *  @param  __i   Iterator referencing the element before the element
       *                to move.
       *
       *  Removes the element in list @a list referenced by @a i and
       *  inserts it into the current list after @a pos.
       */
      void
      splice_after(const_iterator __pos, forward_list&& __list,
                   const_iterator __i) noexcept;

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

      /**
       *  @brief  Insert range from another %forward_list.
       *  @param  __pos  Iterator referencing the element to insert after.
       *  @param  __list  Source list.
       *  @param  __before  Iterator referencing before the start of range
       *                    in list.
       *  @param  __last  Iterator referencing the end of range in list.
       *
       *  Removes elements in the range (__before,__last) and inserts them
       *  after @a __pos in constant time.
       *
       *  Undefined if @a __pos is in (__before,__last).
       *  @{
       */
      void
      splice_after(const_iterator __pos, forward_list&&,
                   const_iterator __before, const_iterator __last) noexcept
      { _M_splice_after(__pos, __before, __last); }

      void
      splice_after(const_iterator __pos, forward_list&,
                   const_iterator __before, const_iterator __last) noexcept
      { _M_splice_after(__pos, __before, __last); }
      // @}

      /**
       *  @brief  Remove all elements equal to value.
       *  @param  __val  The value to remove.
       *
       *  Removes every element in the list equal to @a __val.
       *  Remaining elements stay in list order.  Note that this
       *  function only erases the elements, and that if the elements
       *  themselves are pointers, the pointed-to memory is not
       *  touched in any way.  Managing the pointer is the user's
       *  responsibility.
       */
      void
      remove(const _Tp& __val);

      /**
       *  @brief  Remove all elements satisfying a predicate.
       *  @param  __pred  Unary predicate function or object.
       *
       *  Removes every element in the list for which the predicate
       *  returns true.  Remaining elements stay in list order.  Note
       *  that this function only erases the elements, and that if the
       *  elements themselves are pointers, the pointed-to memory is
       *  not touched in any way.  Managing the pointer is the user's
       *  responsibility.
       */
      template<typename _Pred>
        void
        remove_if(_Pred __pred);

      /**
       *  @brief  Remove consecutive duplicate elements.
       *
       *  For each consecutive set of elements with the same value,
       *  remove all but the first one.  Remaining elements stay in
       *  list order.  Note that this function only erases the
       *  elements, and that if the elements themselves are pointers,
       *  the pointed-to memory is not touched in any way.  Managing
       *  the pointer is the user's responsibility.
       */
      void
      unique()
      { unique(std::equal_to<_Tp>()); }

      /**
       *  @brief  Remove consecutive elements satisfying a predicate.
       *  @param  __binary_pred  Binary predicate function or object.
       *
       *  For each consecutive set of elements [first,last) that
       *  satisfy predicate(first,i) where i is an iterator in
       *  [first,last), remove all but the first one.  Remaining
       *  elements stay in list order.  Note that this function only
       *  erases the elements, and that if the elements themselves are
       *  pointers, the pointed-to memory is not touched in any way.
       *  Managing the pointer is the user's responsibility.
       */
      template<typename _BinPred>
        void
        unique(_BinPred __binary_pred);

      /**
       *  @brief  Merge sorted lists.
       *  @param  __list  Sorted list to merge.
       *
       *  Assumes that both @a list and this list are sorted according to
       *  operator<().  Merges elements of @a __list into this list in
       *  sorted order, leaving @a __list empty when complete.  Elements in
       *  this list precede elements in @a __list that are equal.
       */
      void
      merge(forward_list&& __list)
      { merge(std::move(__list), std::less<_Tp>()); }

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

      /**
       *  @brief  Merge sorted lists according to comparison function.
       *  @param  __list  Sorted list to merge.
       *  @param  __comp Comparison function defining sort order.
       *
       *  Assumes that both @a __list and this list are sorted according to
       *  comp.  Merges elements of @a __list into this list
       *  in sorted order, leaving @a __list empty when complete.  Elements
       *  in this list precede elements in @a __list that are equivalent
       *  according to comp().
       */
      template<typename _Comp>
        void
        merge(forward_list&& __list, _Comp __comp);

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

      /**
       *  @brief  Sort the elements of the list.
       *
       *  Sorts the elements of this list in NlogN time.  Equivalent
       *  elements remain in list order.
       */
      void
      sort()
      { sort(std::less<_Tp>()); }

      /**
       *  @brief  Sort the forward_list using a comparison function.
       *
       *  Sorts the elements of this list in NlogN time.  Equivalent
       *  elements remain in list order.
       */
      template<typename _Comp>
        void
        sort(_Comp __comp);

      /**
       *  @brief  Reverse the elements in list.
       *
       *  Reverse the order of elements in the list in linear time.
       */
      void
      reverse() noexcept
      { this->_M_impl._M_head._M_reverse_after(); }

    private:
      // Called by the range constructor to implement [23.3.4.2]/9
      template<typename _InputIterator>
        void
        _M_range_initialize(_InputIterator __first, _InputIterator __last);

      // Called by forward_list(n,v,a), and the range constructor when it
      // turns out to be the same thing.
      void
      _M_fill_initialize(size_type __n, const value_type& __value);

      // Called by splice_after and insert_after.
      iterator
      _M_splice_after(const_iterator __pos, const_iterator __before,
		      const_iterator __last);

      // Called by forward_list(n).
      void
      _M_default_initialize(size_type __n);

      // Called by resize(sz).
      void
      _M_default_insert_after(const_iterator __pos, size_type __n);

      // Called by operator=(forward_list&&)
      void
      _M_move_assign(forward_list&& __list, std::true_type) noexcept
      {
        clear();
        this->_M_impl._M_head._M_next = __list._M_impl._M_head._M_next;
        __list._M_impl._M_head._M_next = nullptr;
        std::__alloc_on_move(this->_M_get_Node_allocator(),
                             __list._M_get_Node_allocator());
      }

      // Called by operator=(forward_list&&)
      void
      _M_move_assign(forward_list&& __list, std::false_type)
      {
        if (__list._M_get_Node_allocator() == this->_M_get_Node_allocator())
          _M_move_assign(std::move(__list), std::true_type());
        else
	  // The rvalue's allocator cannot be moved, or is not equal,
	  // so we need to individually move each element.
	  this->assign(std::__make_move_if_noexcept_iterator(__list.begin()),
		       std::__make_move_if_noexcept_iterator(__list.end()));
      }

      // Called by assign(_InputIterator, _InputIterator) if _Tp is
      // CopyAssignable.
      template<typename _InputIterator>
	void
        _M_assign(_InputIterator __first, _InputIterator __last, true_type)
	{
	  auto __prev = before_begin();
	  auto __curr = begin();
	  auto __end = end();
	  while (__curr != __end && __first != __last)
	    {
	      *__curr = *__first;
	      ++__prev;
	      ++__curr;
	      ++__first;
	    }
	  if (__first != __last)
	    insert_after(__prev, __first, __last);
	  else if (__curr != __end)
	    erase_after(__prev, __end);
        }

      // Called by assign(_InputIterator, _InputIterator) if _Tp is not
      // CopyAssignable.
      template<typename _InputIterator>
	void
        _M_assign(_InputIterator __first, _InputIterator __last, false_type)
	{
	  clear();
	  insert_after(cbefore_begin(), __first, __last);
	}

      // Called by assign(size_type, const _Tp&) if Tp is CopyAssignable
      void
      _M_assign_n(size_type __n, const _Tp& __val, true_type)
      {
	auto __prev = before_begin();
	auto __curr = begin();
	auto __end = end();
	while (__curr != __end && __n > 0)
	  {
	    *__curr = __val;
	    ++__prev;
	    ++__curr;
	    --__n;
	  }
	if (__n > 0)
	  insert_after(__prev, __n, __val);
	else if (__curr != __end)
	  erase_after(__prev, __end);
      }

      // Called by assign(size_type, const _Tp&) if Tp is non-CopyAssignable
      void
      _M_assign_n(size_type __n, const _Tp& __val, false_type)
      {
	clear();
	insert_after(cbefore_begin(), __n, __val);
      }
    };

  /**
   *  @brief  Forward list equality comparison.
   *  @param  __lx  A %forward_list
   *  @param  __ly  A %forward_list of the same type as @a __lx.
   *  @return  True iff the elements of the forward lists are equal.
   *
   *  This is an equivalence relation.  It is linear in the number of 
   *  elements of the forward lists.  Deques are considered equivalent
   *  if corresponding elements compare equal.
   */
  template<typename _Tp, typename _Alloc>
    bool
    operator==(const forward_list<_Tp, _Alloc>& __lx,
               const forward_list<_Tp, _Alloc>& __ly);

  /**
   *  @brief  Forward list ordering relation.
   *  @param  __lx  A %forward_list.
   *  @param  __ly  A %forward_list of the same type as @a __lx.
   *  @return  True iff @a __lx is lexicographically less than @a __ly.
   *
   *  This is a total ordering relation.  It is linear in the number of 
   *  elements of the forward lists.  The elements must be comparable
   *  with @c <.
   *
   *  See std::lexicographical_compare() for how the determination is made.
   */
  template<typename _Tp, typename _Alloc>
    inline bool
    operator<(const forward_list<_Tp, _Alloc>& __lx,
              const forward_list<_Tp, _Alloc>& __ly)
    { return std::lexicographical_compare(__lx.cbegin(), __lx.cend(),
					  __ly.cbegin(), __ly.cend()); }

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

  /// 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)
    noexcept(noexcept(__lx.swap(__ly)))
    { __lx.swap(__ly); }

_GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std

#endif // _FORWARD_LIST_H
