// <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() { }explicitconstexpr _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());}};/// tupletemplate<typename... _Elements>class tuple : public _Tuple_impl<0, _Elements...>{typedef _Tuple_impl<0, _Elements...> _Inherited;public:constexpr tuple(): _Inherited() { }explicitconstexpr tuple(const _Elements&... __elements): _Inherited(__elements...) { }template<typename... _UElements, typename = typenamestd::enable_if<sizeof...(_UElements)== sizeof...(_Elements)>::type>explicittuple(_UElements&&... __elements): _Inherited(std::forward<_UElements>(__elements)...) { }constexpr tuple(const tuple&) = default;tuple(tuple&& __in): _Inherited(static_cast<_Inherited&&>(__in)) { }template<typename... _UElements, typename = typenamestd::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 = typenamestd::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 = typenamestd::enable_if<sizeof...(_UElements)== sizeof...(_Elements)>::type>tuple&operator=(const tuple<_UElements...>& __in){static_cast<_Inherited&>(*this) = __in;return *this;}template<typename... _UElements, typename = typenamestd::enable_if<sizeof...(_UElements)== sizeof...(_Elements)>::type>tuple&operator=(tuple<_UElements...>&& __in){static_cast<_Inherited&>(*this) = std::move(__in);return *this;}voidswap(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() { }explicitconstexpr tuple(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)) { }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;}voidswap(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() { }explicitconstexpr tuple(const _T1& __a1): _Inherited(__a1) { }template<typename _U1, typename = typenamestd::enable_if<std::is_convertible<_U1, _T1>::value>::type>explicittuple(_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;}voidswap(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_sizetemplate<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>::typeget(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>::typeget(const tuple<_Elements...>& __t){ return __get_helper<__i>(__t); }// This class helps construct the various comparison operations on tuplestemplate<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>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<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 voidswap(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 requiredstruct _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 _Tppair<_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 _Tppair<_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