// <tuple> -*- C++ -*-

// Copyright (C) 2007, 2008, 2009 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 include/tuple
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_TUPLE
#define _GLIBCXX_TUPLE 1

#pragma GCC system_header

#ifndef __GXX_EXPERIMENTAL_CXX0X__
# include <c++0x_warning.h>
#else

#include <utility>

namespace std
{
  // Adds a const reference to a non-reference type.
  template<typename _Tp>
    struct __add_c_ref
    { typedef const _Tp& type; };

  template<typename _Tp>
    struct __add_c_ref<_Tp&>
    { typedef _Tp& type; };

  // Adds a reference to a non-reference type.
  template<typename _Tp>
    struct __add_ref
    { typedef _Tp& type; };

  template<typename _Tp>
    struct __add_ref<_Tp&>
    { typedef _Tp& type; };

  template<std::size_t _Idx, typename _Head, bool _IsEmpty>
    struct _Head_base;

  template<std::size_t _Idx, typename _Head>
    struct _Head_base<_Idx, _Head, true>
    : public _Head
    {
      _Head_base()
      : _Head() { }

      _Head_base(const _Head& __h)
      : _Head(__h) { }

      template<typename _UHead>
        _Head_base(_UHead&& __h)
	: _Head(std::forward<_UHead>(__h)) { }

      _Head&       _M_head()       { return *this; }
      const _Head& _M_head() const { return *this; }
    
      void _M_swap_impl(_Head&&) { /* no-op */ }
    };

  template<std::size_t _Idx, typename _Head>
    struct _Head_base<_Idx, _Head, false>
    {
      _Head_base()
      : _M_head_impl() { }

      _Head_base(const _Head& __h)
      : _M_head_impl(__h) { }

      template<typename _UHead>
        _Head_base(_UHead&& __h)
	: _M_head_impl(std::forward<_UHead>(__h)) { }

      _Head&       _M_head()       { return _M_head_impl; }
      const _Head& _M_head() const { return _M_head_impl; }        

      void
      _M_swap_impl(_Head&& __h)
      { 
	using std::swap;
	swap(__h, _M_head_impl);
      }

      _Head _M_head_impl; 
    };

  /**
   * Contains the actual implementation of the @c tuple template, stored
   * as a recursive inheritance hierarchy from the first element (most
   * derived class) to the last (least derived class). The @c Idx
   * parameter gives the 0-based index of the element stored at this
   * point in the hierarchy; we use it to implement a constant-time
   * get() operation.
   */
  template<std::size_t _Idx, typename... _Elements>
    struct _Tuple_impl; 

  /**
   * Zero-element tuple implementation. This is the basis case for the 
   * inheritance recursion.
   */
  template<std::size_t _Idx>
    struct _Tuple_impl<_Idx>
    { 
    protected:
      void _M_swap_impl(_Tuple_impl&&) { /* no-op */ }
    };

  /**
   * Recursive tuple implementation. Here we store the @c Head element
   * and derive from a @c Tuple_impl containing the remaining elements
   * (which contains the @c Tail).
   */
  template<std::size_t _Idx, typename _Head, typename... _Tail>
    struct _Tuple_impl<_Idx, _Head, _Tail...>
    : public _Tuple_impl<_Idx + 1, _Tail...>,
      private _Head_base<_Idx, _Head, std::is_empty<_Head>::value>
    {
      typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
      typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base;

      _Head&            _M_head()       { return _Base::_M_head(); }
      const _Head&      _M_head() const { return _Base::_M_head(); }

      _Inherited&       _M_tail()       { return *this; }
      const _Inherited& _M_tail() const { return *this; }

      _Tuple_impl()
      : _Inherited(), _Base() { }

      explicit 
      _Tuple_impl(const _Head& __head, const _Tail&... __tail)
      : _Inherited(__tail...), _Base(__head) { }

      template<typename _UHead, typename... _UTail> 
        explicit
        _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
	: _Inherited(std::forward<_UTail>(__tail)...),
	  _Base(std::forward<_UHead>(__head)) { }

      _Tuple_impl(const _Tuple_impl& __in)
      : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }

      _Tuple_impl(_Tuple_impl&& __in)
      : _Inherited(std::move<_Inherited&&>(__in._M_tail())),
	_Base(std::forward<_Head>(__in._M_head())) { }

      template<typename... _UElements>
        _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
	: _Inherited(__in._M_tail()), _Base(__in._M_head()) { }

      template<typename... _UElements>
        _Tuple_impl(_Tuple_impl<_Idx, _UElements...>&& __in)
	: _Inherited(std::move<typename _Tuple_impl<_Idx, _UElements...>::
		     _Inherited&&>(__in._M_tail())),
	  _Base(std::forward<typename _Tuple_impl<_Idx, _UElements...>::
		_Base>(__in._M_head())) { }

      _Tuple_impl&
      operator=(const _Tuple_impl& __in)
      {
	_M_head() = __in._M_head();
	_M_tail() = __in._M_tail();
	return *this;
      }

      _Tuple_impl&
      operator=(_Tuple_impl&& __in)
      {
	_M_head() = std::move(__in._M_head());
	_M_tail() = std::move(__in._M_tail());
	return *this;
      }

      template<typename... _UElements>
        _Tuple_impl&
        operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
        {
	  _M_head() = __in._M_head();
	  _M_tail() = __in._M_tail();
	  return *this;
	}

      template<typename... _UElements>
        _Tuple_impl&
        operator=(_Tuple_impl<_Idx, _UElements...>&& __in)
        {
	  _M_head() = std::move(__in._M_head());
	  _M_tail() = std::move(__in._M_tail());
	  return *this;
	}

    protected:
      void
      _M_swap_impl(_Tuple_impl&& __in)
      {
	_Base::_M_swap_impl(__in._M_head());
	_Inherited::_M_swap_impl(__in._M_tail());
      }
    };

  /// tuple
  template<typename... _Elements> 
    class tuple : public _Tuple_impl<0, _Elements...>
    {
      typedef _Tuple_impl<0, _Elements...> _Inherited;

    public:
      tuple()
      : _Inherited() { }

      explicit
      tuple(const _Elements&... __elements)
      : _Inherited(__elements...) { }

      template<typename... _UElements>
        explicit
        tuple(_UElements&&... __elements)
	: _Inherited(std::forward<_UElements>(__elements)...) {	}

      tuple(const tuple& __in)
      : _Inherited(static_cast<const _Inherited&>(__in)) { }

      tuple(tuple&& __in)
      : _Inherited(std::move<_Inherited>(__in)) { }

      template<typename... _UElements>
        tuple(const tuple<_UElements...>& __in)
	: _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
	{ }

      template<typename... _UElements>
        tuple(tuple<_UElements...>&& __in)
	: _Inherited(std::move<_Tuple_impl<0, _UElements...> >(__in)) { }

      // XXX http://gcc.gnu.org/ml/libstdc++/2008-02/msg00047.html
      template<typename... _UElements>
        tuple(tuple<_UElements...>& __in)
	: _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
	{ }

      tuple&
      operator=(const tuple& __in)
      {
	static_cast<_Inherited&>(*this) = __in;
	return *this;
      }

      tuple&
      operator=(tuple&& __in)
      {
	static_cast<_Inherited&>(*this) = std::move(__in);
	return *this;
      }

      template<typename... _UElements>
        tuple&
        operator=(const tuple<_UElements...>& __in)
        {
	  static_cast<_Inherited&>(*this) = __in;
	  return *this;
	}

      template<typename... _UElements>
        tuple&
        operator=(tuple<_UElements...>&& __in)
        {
	  static_cast<_Inherited&>(*this) = std::move(__in);
	  return *this;
	}

      void
      swap(tuple&& __in)
      { _Inherited::_M_swap_impl(__in); }
    };


  template<>  
    class tuple<>
    {
    public:
      void swap(tuple&&) { /* no-op */ }
    };

  /// tuple (2-element), with construction and assignment from a pair.
  template<typename _T1, typename _T2>
    class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
    {
      typedef _Tuple_impl<0, _T1, _T2> _Inherited;

    public:
      tuple()
      : _Inherited() { }

      explicit
      tuple(const _T1& __a1, const _T2& __a2)
      : _Inherited(__a1, __a2) { }

      template<typename _U1, typename _U2>
        explicit
        tuple(_U1&& __a1, _U2&& __a2)
	: _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }

      tuple(const tuple& __in)
      : _Inherited(static_cast<const _Inherited&>(__in)) { }

      tuple(tuple&& __in)
      : _Inherited(std::move<_Inherited>(__in)) { }

      template<typename _U1, typename _U2>
        tuple(const tuple<_U1, _U2>& __in)
	: _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }

      template<typename _U1, typename _U2>
        tuple(tuple<_U1, _U2>&& __in)
	: _Inherited(std::move<_Tuple_impl<0, _U1, _U2> >(__in)) { }

      template<typename _U1, typename _U2>
        tuple(const pair<_U1, _U2>& __in)
	: _Inherited(__in.first, __in.second) { }

      template<typename _U1, typename _U2>
        tuple(pair<_U1, _U2>&& __in)
	: _Inherited(std::move(__in.first), std::move(__in.second)) { }

      tuple&
      operator=(const tuple& __in)
      {
	static_cast<_Inherited&>(*this) = __in;
	return *this;
      }

      tuple&
      operator=(tuple&& __in)
      {
	static_cast<_Inherited&>(*this) = std::move(__in);
	return *this;
      }

      template<typename _U1, typename _U2>
        tuple&
        operator=(const tuple<_U1, _U2>& __in)
        {
	  static_cast<_Inherited&>(*this) = __in;
	  return *this;
	}

      template<typename _U1, typename _U2>
        tuple&
        operator=(tuple<_U1, _U2>&& __in)
        {
	  static_cast<_Inherited&>(*this) = std::move(__in);
	  return *this;
	}

      template<typename _U1, typename _U2>
        tuple&
        operator=(const pair<_U1, _U2>& __in)
        {
	  this->_M_head() = __in.first;
	  this->_M_tail()._M_head() = __in.second;
	  return *this;
	}

      template<typename _U1, typename _U2>
        tuple&
        operator=(pair<_U1, _U2>&& __in)
        {
	  this->_M_head() = std::move(__in.first);
	  this->_M_tail()._M_head() = std::move(__in.second);
	  return *this;
	}

      void
      swap(tuple&& __in)
      { 
	using std::swap;
	swap(this->_M_head(), __in._M_head());
	swap(this->_M_tail()._M_head(), __in._M_tail()._M_head());	
      }
    };


  /// Gives the type of the ith element of a given tuple type.
  template<std::size_t __i, typename _Tp>
    struct tuple_element;

  /**
   * Recursive case for tuple_element: strip off the first element in
   * the tuple and retrieve the (i-1)th element of the remaining tuple.
   */
  template<std::size_t __i, typename _Head, typename... _Tail>
    struct tuple_element<__i, tuple<_Head, _Tail...> >
    : tuple_element<__i - 1, tuple<_Tail...> > { };

  /**
   * Basis case for tuple_element: The first element is the one we're seeking.
   */
  template<typename _Head, typename... _Tail>
    struct tuple_element<0, tuple<_Head, _Tail...> >
    {
      typedef _Head type;
    };

  /// Finds the size of a given tuple type.
  template<typename _Tp>
    struct tuple_size;

  /// class tuple_size
  template<typename... _Elements>
    struct tuple_size<tuple<_Elements...> >
    {
      static const std::size_t value = sizeof...(_Elements);
    };

  template<typename... _Elements>
    const std::size_t tuple_size<tuple<_Elements...> >::value;

  template<std::size_t __i, typename _Head, typename... _Tail>
    inline typename __add_ref<_Head>::type
    __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
    { return __t._M_head(); }

  template<std::size_t __i, typename _Head, typename... _Tail>
    inline typename __add_c_ref<_Head>::type
    __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
    { return __t._M_head(); }

  // Return a reference (const reference) to the ith element of a tuple.
  // Any const or non-const ref elements are returned with their original type.
  template<std::size_t __i, typename... _Elements>
    inline typename __add_ref<
                      typename tuple_element<__i, tuple<_Elements...> >::type
                    >::type
    get(tuple<_Elements...>& __t)
    { return __get_helper<__i>(__t); }

  template<std::size_t __i, typename... _Elements>
    inline typename __add_c_ref<
                      typename tuple_element<__i, tuple<_Elements...> >::type
                    >::type
    get(const tuple<_Elements...>& __t)
    { return __get_helper<__i>(__t); }

  // This class helps construct the various comparison operations on tuples
  template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
	   typename _Tp, typename _Up>
    struct __tuple_compare;

  template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
    struct __tuple_compare<0, __i, __j, _Tp, _Up>
    {
      static bool __eq(const _Tp& __t, const _Up& __u)
      {
	return (get<__i>(__t) == get<__i>(__u) &&
		__tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
      }
     
      static bool __less(const _Tp& __t, const _Up& __u)
      {
	return ((get<__i>(__t) < get<__i>(__u))
		|| !(get<__i>(__u) < get<__i>(__t)) &&
		__tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
      }
    };

  template<std::size_t __i, typename _Tp, typename _Up>
    struct __tuple_compare<0, __i, __i, _Tp, _Up>
    {
      static bool __eq(const _Tp&, const _Up&)
      { return true; }
     
      static bool __less(const _Tp&, const _Up&)
      { return false; }
    };

  template<typename... _TElements, typename... _UElements>
    bool
    operator==(const tuple<_TElements...>& __t,
	       const tuple<_UElements...>& __u)
    {
      typedef tuple<_TElements...> _Tp;
      typedef tuple<_UElements...> _Up;
      return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
	      0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
    }

  template<typename... _TElements, typename... _UElements>
    bool
    operator<(const tuple<_TElements...>& __t,
	      const tuple<_UElements...>& __u)
    {
      typedef tuple<_TElements...> _Tp;
      typedef tuple<_UElements...> _Up;
      return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
	      0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
    }

  template<typename... _TElements, typename... _UElements>
    inline bool
    operator!=(const tuple<_TElements...>& __t,
	       const tuple<_UElements...>& __u)
    { return !(__t == __u); }

  template<typename... _TElements, typename... _UElements>
    inline bool
    operator>(const tuple<_TElements...>& __t,
	      const tuple<_UElements...>& __u)
    { return __u < __t; }

  template<typename... _TElements, typename... _UElements>
    inline bool
    operator<=(const tuple<_TElements...>& __t,
	       const tuple<_UElements...>& __u)
    { return !(__u < __t); }

  template<typename... _TElements, typename... _UElements>
    inline bool
    operator>=(const tuple<_TElements...>& __t,
	       const tuple<_UElements...>& __u)
    { return !(__t < __u); }

  // NB: DR 705.
  template<typename... _Elements>
    inline tuple<typename __decay_and_strip<_Elements>::__type...>
    make_tuple(_Elements&&... __args)
    {
      typedef tuple<typename __decay_and_strip<_Elements>::__type...>
	__result_type;
      return __result_type(std::forward<_Elements>(__args)...);
    }

  template<std::size_t...> struct __index_holder { };    

  template<std::size_t __i, typename _IdxHolder, typename... _Elements>
    struct __index_holder_impl;

  template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder,
	   typename... _Elements>
    struct __index_holder_impl<__i, __index_holder<_Indexes...>,
			       _IdxHolder, _Elements...> 
    {
      typedef typename __index_holder_impl<__i + 1,
					   __index_holder<_Indexes..., __i>,
					   _Elements...>::type type;
    };
 
  template<std::size_t __i, std::size_t... _Indexes>
    struct __index_holder_impl<__i, __index_holder<_Indexes...> >
    { typedef __index_holder<_Indexes...> type; };

  template<typename... _Elements>
    struct __make_index_holder 
    : __index_holder_impl<0, __index_holder<>, _Elements...> { };
    
  template<typename... _TElements, std::size_t... _TIdx,
	   typename... _UElements, std::size_t... _UIdx> 
    inline tuple<_TElements..., _UElements...> 
    __tuple_cat_helper(const tuple<_TElements...>& __t,
		       const __index_holder<_TIdx...>&,
                       const tuple<_UElements...>& __u,
		       const __index_holder<_UIdx...>&)
    { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)...,
						 get<_UIdx>(__u)...); }

  template<typename... _TElements, std::size_t... _TIdx,
	   typename... _UElements, std::size_t... _UIdx> 
    inline tuple<_TElements..., _UElements...> 
    __tuple_cat_helper(tuple<_TElements...>&& __t,
		       const __index_holder<_TIdx...>&, 
		       const tuple<_UElements...>& __u,
		       const __index_holder<_UIdx...>&)
    { return tuple<_TElements..., _UElements...>
	(std::move(get<_TIdx>(__t))..., get<_UIdx>(__u)...); }

  template<typename... _TElements, std::size_t... _TIdx,
	   typename... _UElements, std::size_t... _UIdx>
    inline tuple<_TElements..., _UElements...> 
    __tuple_cat_helper(const tuple<_TElements...>& __t,
		       const __index_holder<_TIdx...>&, 
		       tuple<_UElements...>&& __u,
		       const __index_holder<_UIdx...>&)
    { return tuple<_TElements..., _UElements...>
	(get<_TIdx>(__t)..., std::move(get<_UIdx>(__u))...); }

  template<typename... _TElements, std::size_t... _TIdx,
	   typename... _UElements, std::size_t... _UIdx> 
    inline tuple<_TElements..., _UElements...> 
    __tuple_cat_helper(tuple<_TElements...>&& __t,
		       const __index_holder<_TIdx...>&, 
		       tuple<_UElements...>&& __u,
		       const __index_holder<_UIdx...>&)
    { return tuple<_TElements..., _UElements...>
	(std::move(get<_TIdx>(__t))..., std::move(get<_UIdx>(__u))...); }

  template<typename... _TElements, typename... _UElements>
    inline tuple<_TElements..., _UElements...> 
    tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u)
    {
      return __tuple_cat_helper(__t, typename
				__make_index_holder<_TElements...>::type(),
				__u, typename
				__make_index_holder<_UElements...>::type());
    }

  template<typename... _TElements, typename... _UElements>
    inline tuple<_TElements..., _UElements...> 
    tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
    {
      return __tuple_cat_helper(std::move(__t), typename
				 __make_index_holder<_TElements...>::type(),
				 __u, typename
				 __make_index_holder<_UElements...>::type());
    }

  template<typename... _TElements, typename... _UElements>
    inline tuple<_TElements..., _UElements...> 
    tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u)
    {
      return __tuple_cat_helper(__t, typename
				__make_index_holder<_TElements...>::type(),
				std::move(__u), typename
				__make_index_holder<_UElements...>::type());
    }

  template<typename... _TElements, typename... _UElements>
    inline tuple<_TElements..., _UElements...>
    tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
    {
      return __tuple_cat_helper(std::move(__t), typename
				__make_index_holder<_TElements...>::type(),
				std::move(__u), typename
				__make_index_holder<_UElements...>::type());
    }

  template<typename... _Elements>
    inline tuple<_Elements&...>
    tie(_Elements&... __args)
    { return tuple<_Elements&...>(__args...); }

  template<typename... _Elements>
    inline void 
    swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
    { __x.swap(__y); }

  template<typename... _Elements>
    inline void
    swap(tuple<_Elements...>&& __x, tuple<_Elements...>& __y)
    { __x.swap(__y); }

  template<typename... _Elements>
    inline void
    swap(tuple<_Elements...>& __x, tuple<_Elements...>&& __y)
    { __x.swap(__y); }

  // A class (and instance) which can be used in 'tie' when an element
  // of a tuple is not required
  struct _Swallow_assign
  {
    template<class _Tp>
      _Swallow_assign&
      operator=(const _Tp&)
      { return *this; }
  };

  // TODO: Put this in some kind of shared file.
  namespace
  {
    _Swallow_assign ignore;
  }; // anonymous namespace
}

#endif // __GXX_EXPERIMENTAL_CXX0X__

#endif // _GLIBCXX_TUPLE
