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

// Copyright (C) 2007, 2008, 2009, 2010, 2011 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 <bits/c++0x_warning.h>
#else

#include <utility>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  // 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
    {
      constexpr _Head_base()
      : _Head() { }

      constexpr _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& __h)
      {
	using std::swap;
	swap(__h, _M_head());
      }
    };

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

      constexpr _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());
      }

      _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; }

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

      explicit 
      constexpr _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)) { }

      constexpr _Tuple_impl(const _Tuple_impl&) = default;

      _Tuple_impl(_Tuple_impl&& __in)
      : _Inherited(std::move(__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 _UHead, typename... _UTails>
        _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
	: _Inherited(std::move(__in._M_tail())),
	  _Base(std::forward<_UHead>(__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::forward<_Head>(__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 _UHead, typename... _UTails>
        _Tuple_impl&
        operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
        {
	  _M_head() = std::forward<_UHead>(__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:
      constexpr tuple()
      : _Inherited() { }

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

      template<typename... _UElements, typename = typename
	       std::enable_if<sizeof...(_UElements)
			      == sizeof...(_Elements)>::type>
        explicit
        tuple(_UElements&&... __elements)
	: _Inherited(std::forward<_UElements>(__elements)...) {	}

      constexpr tuple(const tuple&) = default;

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

      template<typename... _UElements, typename = typename
	       std::enable_if<sizeof...(_UElements)
			      == sizeof...(_Elements)>::type>
        tuple(const tuple<_UElements...>& __in)
        : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
        { }

      template<typename... _UElements, typename = typename
	       std::enable_if<sizeof...(_UElements)
			      == sizeof...(_Elements)>::type>
        tuple(tuple<_UElements...>&& __in)
        : _Inherited(static_cast<_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, typename = typename
	       std::enable_if<sizeof...(_UElements)
			      == sizeof...(_Elements)>::type>
        tuple&
        operator=(const tuple<_UElements...>& __in)
        {
	  static_cast<_Inherited&>(*this) = __in;
	  return *this;
	}

      template<typename... _UElements, typename = typename
	       std::enable_if<sizeof...(_UElements)
			      == sizeof...(_Elements)>::type>
        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:
      constexpr tuple()
      : _Inherited() { }

      explicit
      constexpr 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)) { }

      constexpr tuple(const tuple&) = default;

      tuple(tuple&& __in)
      : _Inherited(static_cast<_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(static_cast<_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::forward<_U1>(__in.first),
		     std::forward<_U2>(__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::forward<_U1>(__in.first);
	  this->_M_tail()._M_head() = std::forward<_U2>(__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());	
      }
    };

  /// tuple (1-element).
  template<typename _T1>
    class tuple<_T1> : public _Tuple_impl<0, _T1>
    {
      typedef _Tuple_impl<0, _T1> _Inherited;

    public:
      constexpr tuple()
      : _Inherited() { }

      explicit
      constexpr tuple(const _T1& __a1)
      : _Inherited(__a1) { }

      template<typename _U1, typename = typename
	       std::enable_if<std::is_convertible<_U1, _T1>::value>::type>
        explicit
        tuple(_U1&& __a1)
	: _Inherited(std::forward<_U1>(__a1)) { }

      constexpr tuple(const tuple&) = default;

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

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

      template<typename _U1>
        tuple(tuple<_U1>&& __in)
	: _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__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 _U1>
        tuple&
        operator=(const tuple<_U1>& __in)
        {
	  static_cast<_Inherited&>(*this) = __in;
	  return *this;
	}

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

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


  /// 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<typename... _Elements>
    inline tuple<_Elements&&...>
    forward_as_tuple(_Elements&&... __args)
    { return tuple<_Elements&&...>(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::forward<_TElements>(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::forward<_UElements>(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::forward<_TElements>(get<_TIdx>(__t))...,
	 std::forward<_UElements>(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); }

  // 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>
      const _Swallow_assign&
      operator=(const _Tp&) const
      { return *this; }
  };

  const _Swallow_assign ignore{};

  /**
   * Stores a tuple of indices. Used by bind() to extract the elements
   * in a tuple. 
   */
  template<int... _Indexes>
    struct _Index_tuple
    {
      typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
    };

  /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
  template<std::size_t _Num>
    struct _Build_index_tuple
    {
      typedef typename _Build_index_tuple<_Num-1>::__type::__next __type;
    };

  template<>
    struct _Build_index_tuple<0>
    {
      typedef _Index_tuple<> __type;
    };

  // See stl_pair.h...
  template<class _T1, class _T2>
    template<typename _Tp, typename... _Args>
      inline _Tp
      pair<_T1, _T2>::
      __cons(tuple<_Args...>&& __tuple)
      {
	typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
	  _Indexes;
	return __do_cons<_Tp>(std::move(__tuple), _Indexes());
      }

  template<class _T1, class _T2>
    template<typename _Tp, typename... _Args, int... _Indexes>
      inline _Tp
      pair<_T1, _T2>::
      __do_cons(tuple<_Args...>&& __tuple,
		const _Index_tuple<_Indexes...>&)
      { return _Tp(std::forward<_Args>(get<_Indexes>(__tuple))...); }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif // __GXX_EXPERIMENTAL_CXX0X__

#endif // _GLIBCXX_TUPLE
