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

// Copyright (C) 2008-2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file 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 *static_cast<_Node_alloc_type*>(&this->_M_impl); }

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

      _Fwd_list_base()
      : _M_impl() { }

      _Fwd_list_base(const _Node_alloc_type& __a)
      : _M_impl(__a) { }

      _Fwd_list_base(_Fwd_list_base&& __lst, const _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.
       *  @param  __al  An allocator object.
       */
      explicit
      forward_list(const _Alloc& __al = _Alloc())
      : _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))
      { }

      /**
       *  @brief  Creates a %forward_list with default constructed elements.
       *  @param  __n  The number of elements to initially create.
       *
       *  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),
                       integral_constant<bool, __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(_Node_alloc_traits::_S_nothrow_swap())
      {
        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)
      {
	if (!__list.empty())
	  _M_splice_after(__pos, __list.before_begin(), __list.end());
      }

      void
      splice_after(const_iterator __pos, forward_list& __list)
      { 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);

      void
      splice_after(const_iterator __pos, forward_list& __list,
                   const_iterator __i)
      { 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)
      { _M_splice_after(__pos, __before, __last); }

      void
      splice_after(const_iterator __pos, forward_list&,
                   const_iterator __before, const_iterator __last)
      { _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();
        std::swap(this->_M_impl._M_head._M_next,
                  __list._M_impl._M_head._M_next);
        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)
    { __lx.swap(__ly); }

_GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std

#endif // _FORWARD_LIST_H
