// <tuple> -*- C++ -*-// Copyright (C) 2007, 2008 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 2, 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.// You should have received a copy of the GNU General Public License// along with this library; see the file COPYING. If not, write to// the Free Software Foundation, 51 Franklin Street, Fifth Floor,// Boston, MA 02110-1301, USA.// As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License./** @file include/tuple* This is a Standard C++ Library header.*/#ifndef _GLIBCXX_CXX0X_TUPLE#define _GLIBCXX_CXX0X_TUPLE 1#pragma GCC system_header#ifndef __GXX_EXPERIMENTAL_CXX0X__# include <c++0x_warning.h>#endif#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<int _Idx, typename _Head, bool _IsEmpty>struct _Head_base;template<int _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; }};template<int _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; }_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<int _Idx, typename... _Elements>struct _Tuple_impl;/*** Zero-element tuple implementation. This is the basis case for the* inheritance recursion.*/template<int _Idx>struct _Tuple_impl<_Idx> { };/*** 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<int _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;}};/// tupletemplate<typename... _Elements>class tuple : public _Tuple_impl<0, _Elements...>{typedef _Tuple_impl<0, _Elements...> _Inherited;public:tuple(): _Inherited() { }explicittuple(const _Elements&... __elements): _Inherited(__elements...) { }template<typename... _UElements>explicittuple(_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.htmltemplate<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;}};template<>class tuple<> { };/// 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() { }explicittuple(const _T1& __a1, const _T2& __a2): _Inherited(__a1, __a2) { }template<typename _U1, typename _U2>explicittuple(_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;}};/// Gives the type of the ith element of a given tuple type.template<int __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<int __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_sizetemplate<typename... _Elements>struct tuple_size<tuple<_Elements...> >{static const int value = sizeof...(_Elements);};template<typename... _Elements>const int tuple_size<tuple<_Elements...> >::value;template<int __i, typename _Head, typename... _Tail>inline typename __add_ref<_Head>::type__get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t){ return __t._M_head(); }template<int __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<int __i, typename... _Elements>inline typename __add_ref<typename tuple_element<__i, tuple<_Elements...> >::type>::typeget(tuple<_Elements...>& __t){ return __get_helper<__i>(__t); }template<int __i, typename... _Elements>inline typename __add_c_ref<typename tuple_element<__i, tuple<_Elements...> >::type>::typeget(const tuple<_Elements...>& __t){ return __get_helper<__i>(__t); }// This class helps construct the various comparison operations on tuplestemplate<int __check_equal_size, int __i, int __j,typename _Tp, typename _Up>struct __tuple_compare;template<int __i, int __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<int __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>booloperator==(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>booloperator<(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 booloperator!=(const tuple<_TElements...>& __t,const tuple<_UElements...>& __u){ return !(__t == __u); }template<typename... _TElements, typename... _UElements>inline booloperator>(const tuple<_TElements...>& __t,const tuple<_UElements...>& __u){ return __u < __t; }template<typename... _TElements, typename... _UElements>inline booloperator<=(const tuple<_TElements...>& __t,const tuple<_UElements...>& __u){ return !(__u < __t); }template<typename... _TElements, typename... _UElements>inline booloperator>=(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<int...> struct __index_holder { };template<int __i, typename _IdxHolder, typename... _Elements>struct __index_holder_impl;template<int __i, int... _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<int __i, int... _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, int... _TIdx,typename... _UElements, int... _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, int... _TIdx,typename... _UElements, int... _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, int... _TIdx,typename... _UElements, int... _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, int... _TIdx,typename... _UElements, int... _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...); }// A class (and instance) which can be used in 'tie' when an element// of a tuple is not requiredstruct _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 // _GLIBCXX_CXX0X_TUPLE