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

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

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

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

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

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

#ifndef _GLIBCXX_PROFILE_FORWARD_LIST
#define _GLIBCXX_PROFILE_FORWARD_LIST 1

#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else

#include <forward_list>

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __profile
{
  /// Class std::forward_list wrapper with performance instrumentation.
  template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
    class forward_list
    : public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>
    {
      typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base;

    public:
      typedef typename _Base::size_type		size_type;
      typedef typename _Base::const_iterator	const_iterator;

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

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

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

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

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

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

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

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

      ~forward_list() = default;

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

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

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

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

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

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

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

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

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

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

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

      void
      merge(forward_list& __list)
      { _Base::merge(__list); }

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

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

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

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

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

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

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

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

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

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

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

} // namespace __profile
} // namespace std

#endif // C++11

#endif
