1*e4b17023SJohn Marino// <tuple> -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4*e4b17023SJohn Marino// 5*e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library. This library is free 6*e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the 7*e4b17023SJohn Marino// terms of the GNU General Public License as published by the 8*e4b17023SJohn Marino// Free Software Foundation; either version 3, or (at your option) 9*e4b17023SJohn Marino// any later version. 10*e4b17023SJohn Marino 11*e4b17023SJohn Marino// This library is distributed in the hope that it will be useful, 12*e4b17023SJohn Marino// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*e4b17023SJohn Marino// GNU General Public License for more details. 15*e4b17023SJohn Marino 16*e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional 17*e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version 18*e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation. 19*e4b17023SJohn Marino 20*e4b17023SJohn Marino// You should have received a copy of the GNU General Public License and 21*e4b17023SJohn Marino// a copy of the GCC Runtime Library Exception along with this program; 22*e4b17023SJohn Marino// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*e4b17023SJohn Marino// <http://www.gnu.org/licenses/>. 24*e4b17023SJohn Marino 25*e4b17023SJohn Marino/** @file include/tuple 26*e4b17023SJohn Marino * This is a Standard C++ Library header. 27*e4b17023SJohn Marino */ 28*e4b17023SJohn Marino 29*e4b17023SJohn Marino#ifndef _GLIBCXX_TUPLE 30*e4b17023SJohn Marino#define _GLIBCXX_TUPLE 1 31*e4b17023SJohn Marino 32*e4b17023SJohn Marino#pragma GCC system_header 33*e4b17023SJohn Marino 34*e4b17023SJohn Marino#ifndef __GXX_EXPERIMENTAL_CXX0X__ 35*e4b17023SJohn Marino# include <bits/c++0x_warning.h> 36*e4b17023SJohn Marino#else 37*e4b17023SJohn Marino 38*e4b17023SJohn Marino#include <utility> 39*e4b17023SJohn Marino#include <bits/uses_allocator.h> 40*e4b17023SJohn Marino 41*e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default) 42*e4b17023SJohn Marino{ 43*e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION 44*e4b17023SJohn Marino 45*e4b17023SJohn Marino // Adds a const reference to a non-reference type. 46*e4b17023SJohn Marino template<typename _Tp> 47*e4b17023SJohn Marino struct __add_c_ref 48*e4b17023SJohn Marino { typedef const _Tp& type; }; 49*e4b17023SJohn Marino 50*e4b17023SJohn Marino template<typename _Tp> 51*e4b17023SJohn Marino struct __add_c_ref<_Tp&> 52*e4b17023SJohn Marino { typedef _Tp& type; }; 53*e4b17023SJohn Marino 54*e4b17023SJohn Marino // Adds a reference to a non-reference type. 55*e4b17023SJohn Marino template<typename _Tp> 56*e4b17023SJohn Marino struct __add_ref 57*e4b17023SJohn Marino { typedef _Tp& type; }; 58*e4b17023SJohn Marino 59*e4b17023SJohn Marino template<typename _Tp> 60*e4b17023SJohn Marino struct __add_ref<_Tp&> 61*e4b17023SJohn Marino { typedef _Tp& type; }; 62*e4b17023SJohn Marino 63*e4b17023SJohn Marino // Adds an rvalue reference to a non-reference type. 64*e4b17023SJohn Marino template<typename _Tp> 65*e4b17023SJohn Marino struct __add_r_ref 66*e4b17023SJohn Marino { typedef _Tp&& type; }; 67*e4b17023SJohn Marino 68*e4b17023SJohn Marino template<typename _Tp> 69*e4b17023SJohn Marino struct __add_r_ref<_Tp&> 70*e4b17023SJohn Marino { typedef _Tp& type; }; 71*e4b17023SJohn Marino 72*e4b17023SJohn Marino template<std::size_t _Idx, typename _Head, bool _IsEmptyNotFinal> 73*e4b17023SJohn Marino struct _Head_base; 74*e4b17023SJohn Marino 75*e4b17023SJohn Marino template<std::size_t _Idx, typename _Head> 76*e4b17023SJohn Marino struct _Head_base<_Idx, _Head, true> 77*e4b17023SJohn Marino : public _Head 78*e4b17023SJohn Marino { 79*e4b17023SJohn Marino constexpr _Head_base() 80*e4b17023SJohn Marino : _Head() { } 81*e4b17023SJohn Marino 82*e4b17023SJohn Marino constexpr _Head_base(const _Head& __h) 83*e4b17023SJohn Marino : _Head(__h) { } 84*e4b17023SJohn Marino 85*e4b17023SJohn Marino template<typename _UHead, typename = typename 86*e4b17023SJohn Marino enable_if<!is_convertible<_UHead, 87*e4b17023SJohn Marino __uses_alloc_base>::value>::type> 88*e4b17023SJohn Marino constexpr _Head_base(_UHead&& __h) 89*e4b17023SJohn Marino : _Head(std::forward<_UHead>(__h)) { } 90*e4b17023SJohn Marino 91*e4b17023SJohn Marino _Head_base(__uses_alloc0) 92*e4b17023SJohn Marino : _Head() { } 93*e4b17023SJohn Marino 94*e4b17023SJohn Marino template<typename _Alloc> 95*e4b17023SJohn Marino _Head_base(__uses_alloc1<_Alloc> __a) 96*e4b17023SJohn Marino : _Head(allocator_arg, *__a._M_a) { } 97*e4b17023SJohn Marino 98*e4b17023SJohn Marino template<typename _Alloc> 99*e4b17023SJohn Marino _Head_base(__uses_alloc2<_Alloc> __a) 100*e4b17023SJohn Marino : _Head(*__a._M_a) { } 101*e4b17023SJohn Marino 102*e4b17023SJohn Marino template<typename _UHead> 103*e4b17023SJohn Marino _Head_base(__uses_alloc0, _UHead&& __uhead) 104*e4b17023SJohn Marino : _Head(std::forward<_UHead>(__uhead)) { } 105*e4b17023SJohn Marino 106*e4b17023SJohn Marino template<typename _Alloc, typename _UHead> 107*e4b17023SJohn Marino _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 108*e4b17023SJohn Marino : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } 109*e4b17023SJohn Marino 110*e4b17023SJohn Marino template<typename _Alloc, typename _UHead> 111*e4b17023SJohn Marino _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 112*e4b17023SJohn Marino : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } 113*e4b17023SJohn Marino 114*e4b17023SJohn Marino static constexpr _Head& 115*e4b17023SJohn Marino _M_head(_Head_base& __b) noexcept { return __b; } 116*e4b17023SJohn Marino 117*e4b17023SJohn Marino static constexpr const _Head& 118*e4b17023SJohn Marino _M_head(const _Head_base& __b) noexcept { return __b; } 119*e4b17023SJohn Marino }; 120*e4b17023SJohn Marino 121*e4b17023SJohn Marino template<std::size_t _Idx, typename _Head> 122*e4b17023SJohn Marino struct _Head_base<_Idx, _Head, false> 123*e4b17023SJohn Marino { 124*e4b17023SJohn Marino constexpr _Head_base() 125*e4b17023SJohn Marino : _M_head_impl() { } 126*e4b17023SJohn Marino 127*e4b17023SJohn Marino constexpr _Head_base(const _Head& __h) 128*e4b17023SJohn Marino : _M_head_impl(__h) { } 129*e4b17023SJohn Marino 130*e4b17023SJohn Marino template<typename _UHead, typename = typename 131*e4b17023SJohn Marino enable_if<!is_convertible<_UHead, 132*e4b17023SJohn Marino __uses_alloc_base>::value>::type> 133*e4b17023SJohn Marino constexpr _Head_base(_UHead&& __h) 134*e4b17023SJohn Marino : _M_head_impl(std::forward<_UHead>(__h)) { } 135*e4b17023SJohn Marino 136*e4b17023SJohn Marino _Head_base(__uses_alloc0) 137*e4b17023SJohn Marino : _M_head_impl() { } 138*e4b17023SJohn Marino 139*e4b17023SJohn Marino template<typename _Alloc> 140*e4b17023SJohn Marino _Head_base(__uses_alloc1<_Alloc> __a) 141*e4b17023SJohn Marino : _M_head_impl(allocator_arg, *__a._M_a) { } 142*e4b17023SJohn Marino 143*e4b17023SJohn Marino template<typename _Alloc> 144*e4b17023SJohn Marino _Head_base(__uses_alloc2<_Alloc> __a) 145*e4b17023SJohn Marino : _M_head_impl(*__a._M_a) { } 146*e4b17023SJohn Marino 147*e4b17023SJohn Marino template<typename _UHead> 148*e4b17023SJohn Marino _Head_base(__uses_alloc0, _UHead&& __uhead) 149*e4b17023SJohn Marino : _M_head_impl(std::forward<_UHead>(__uhead)) { } 150*e4b17023SJohn Marino 151*e4b17023SJohn Marino template<typename _Alloc, typename _UHead> 152*e4b17023SJohn Marino _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 153*e4b17023SJohn Marino : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) 154*e4b17023SJohn Marino { } 155*e4b17023SJohn Marino 156*e4b17023SJohn Marino template<typename _Alloc, typename _UHead> 157*e4b17023SJohn Marino _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 158*e4b17023SJohn Marino : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } 159*e4b17023SJohn Marino 160*e4b17023SJohn Marino static constexpr _Head& 161*e4b17023SJohn Marino _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } 162*e4b17023SJohn Marino 163*e4b17023SJohn Marino static constexpr const _Head& 164*e4b17023SJohn Marino _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } 165*e4b17023SJohn Marino 166*e4b17023SJohn Marino _Head _M_head_impl; 167*e4b17023SJohn Marino }; 168*e4b17023SJohn Marino 169*e4b17023SJohn Marino /** 170*e4b17023SJohn Marino * Contains the actual implementation of the @c tuple template, stored 171*e4b17023SJohn Marino * as a recursive inheritance hierarchy from the first element (most 172*e4b17023SJohn Marino * derived class) to the last (least derived class). The @c Idx 173*e4b17023SJohn Marino * parameter gives the 0-based index of the element stored at this 174*e4b17023SJohn Marino * point in the hierarchy; we use it to implement a constant-time 175*e4b17023SJohn Marino * get() operation. 176*e4b17023SJohn Marino */ 177*e4b17023SJohn Marino template<std::size_t _Idx, typename... _Elements> 178*e4b17023SJohn Marino struct _Tuple_impl; 179*e4b17023SJohn Marino 180*e4b17023SJohn Marino /** 181*e4b17023SJohn Marino * Zero-element tuple implementation. This is the basis case for the 182*e4b17023SJohn Marino * inheritance recursion. 183*e4b17023SJohn Marino */ 184*e4b17023SJohn Marino template<std::size_t _Idx> 185*e4b17023SJohn Marino struct _Tuple_impl<_Idx> 186*e4b17023SJohn Marino { 187*e4b17023SJohn Marino template<std::size_t, typename...> friend class _Tuple_impl; 188*e4b17023SJohn Marino 189*e4b17023SJohn Marino _Tuple_impl() = default; 190*e4b17023SJohn Marino 191*e4b17023SJohn Marino template<typename _Alloc> 192*e4b17023SJohn Marino _Tuple_impl(allocator_arg_t, const _Alloc&) { } 193*e4b17023SJohn Marino 194*e4b17023SJohn Marino template<typename _Alloc> 195*e4b17023SJohn Marino _Tuple_impl(allocator_arg_t, const _Alloc&, const _Tuple_impl&) { } 196*e4b17023SJohn Marino 197*e4b17023SJohn Marino template<typename _Alloc> 198*e4b17023SJohn Marino _Tuple_impl(allocator_arg_t, const _Alloc&, _Tuple_impl&&) { } 199*e4b17023SJohn Marino 200*e4b17023SJohn Marino protected: 201*e4b17023SJohn Marino void _M_swap(_Tuple_impl&) noexcept { /* no-op */ } 202*e4b17023SJohn Marino }; 203*e4b17023SJohn Marino 204*e4b17023SJohn Marino // Use the Empty Base-class Optimization for empty, non-final types. 205*e4b17023SJohn Marino template<typename _Tp> 206*e4b17023SJohn Marino using __empty_not_final 207*e4b17023SJohn Marino = typename conditional<__is_final(_Tp), false_type, is_empty<_Tp>>::type; 208*e4b17023SJohn Marino 209*e4b17023SJohn Marino /** 210*e4b17023SJohn Marino * Recursive tuple implementation. Here we store the @c Head element 211*e4b17023SJohn Marino * and derive from a @c Tuple_impl containing the remaining elements 212*e4b17023SJohn Marino * (which contains the @c Tail). 213*e4b17023SJohn Marino */ 214*e4b17023SJohn Marino template<std::size_t _Idx, typename _Head, typename... _Tail> 215*e4b17023SJohn Marino struct _Tuple_impl<_Idx, _Head, _Tail...> 216*e4b17023SJohn Marino : public _Tuple_impl<_Idx + 1, _Tail...>, 217*e4b17023SJohn Marino private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> 218*e4b17023SJohn Marino { 219*e4b17023SJohn Marino template<std::size_t, typename...> friend class _Tuple_impl; 220*e4b17023SJohn Marino 221*e4b17023SJohn Marino typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; 222*e4b17023SJohn Marino typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base; 223*e4b17023SJohn Marino 224*e4b17023SJohn Marino static constexpr _Head& 225*e4b17023SJohn Marino _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 226*e4b17023SJohn Marino 227*e4b17023SJohn Marino static constexpr const _Head& 228*e4b17023SJohn Marino _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 229*e4b17023SJohn Marino 230*e4b17023SJohn Marino static constexpr _Inherited& 231*e4b17023SJohn Marino _M_tail(_Tuple_impl& __t) noexcept { return __t; } 232*e4b17023SJohn Marino 233*e4b17023SJohn Marino static constexpr const _Inherited& 234*e4b17023SJohn Marino _M_tail(const _Tuple_impl& __t) noexcept { return __t; } 235*e4b17023SJohn Marino 236*e4b17023SJohn Marino constexpr _Tuple_impl() 237*e4b17023SJohn Marino : _Inherited(), _Base() { } 238*e4b17023SJohn Marino 239*e4b17023SJohn Marino explicit 240*e4b17023SJohn Marino constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) 241*e4b17023SJohn Marino : _Inherited(__tail...), _Base(__head) { } 242*e4b17023SJohn Marino 243*e4b17023SJohn Marino template<typename _UHead, typename... _UTail, typename = typename 244*e4b17023SJohn Marino enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> 245*e4b17023SJohn Marino explicit 246*e4b17023SJohn Marino constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail) 247*e4b17023SJohn Marino : _Inherited(std::forward<_UTail>(__tail)...), 248*e4b17023SJohn Marino _Base(std::forward<_UHead>(__head)) { } 249*e4b17023SJohn Marino 250*e4b17023SJohn Marino constexpr _Tuple_impl(const _Tuple_impl&) = default; 251*e4b17023SJohn Marino 252*e4b17023SJohn Marino constexpr 253*e4b17023SJohn Marino _Tuple_impl(_Tuple_impl&& __in) 254*e4b17023SJohn Marino noexcept(__and_<is_nothrow_move_constructible<_Head>, 255*e4b17023SJohn Marino is_nothrow_move_constructible<_Inherited>>::value) 256*e4b17023SJohn Marino : _Inherited(std::move(_M_tail(__in))), 257*e4b17023SJohn Marino _Base(std::forward<_Head>(_M_head(__in))) { } 258*e4b17023SJohn Marino 259*e4b17023SJohn Marino template<typename... _UElements> 260*e4b17023SJohn Marino constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) 261*e4b17023SJohn Marino : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 262*e4b17023SJohn Marino _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } 263*e4b17023SJohn Marino 264*e4b17023SJohn Marino template<typename _UHead, typename... _UTails> 265*e4b17023SJohn Marino constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 266*e4b17023SJohn Marino : _Inherited(std::move 267*e4b17023SJohn Marino (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 268*e4b17023SJohn Marino _Base(std::forward<_UHead> 269*e4b17023SJohn Marino (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } 270*e4b17023SJohn Marino 271*e4b17023SJohn Marino template<typename _Alloc> 272*e4b17023SJohn Marino _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 273*e4b17023SJohn Marino : _Inherited(__tag, __a), 274*e4b17023SJohn Marino _Base(__use_alloc<_Head>(__a)) { } 275*e4b17023SJohn Marino 276*e4b17023SJohn Marino template<typename _Alloc> 277*e4b17023SJohn Marino _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 278*e4b17023SJohn Marino const _Head& __head, const _Tail&... __tail) 279*e4b17023SJohn Marino : _Inherited(__tag, __a, __tail...), 280*e4b17023SJohn Marino _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } 281*e4b17023SJohn Marino 282*e4b17023SJohn Marino template<typename _Alloc, typename _UHead, typename... _UTail, 283*e4b17023SJohn Marino typename = typename enable_if<sizeof...(_Tail) 284*e4b17023SJohn Marino == sizeof...(_UTail)>::type> 285*e4b17023SJohn Marino _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 286*e4b17023SJohn Marino _UHead&& __head, _UTail&&... __tail) 287*e4b17023SJohn Marino : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), 288*e4b17023SJohn Marino _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 289*e4b17023SJohn Marino std::forward<_UHead>(__head)) { } 290*e4b17023SJohn Marino 291*e4b17023SJohn Marino template<typename _Alloc> 292*e4b17023SJohn Marino _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 293*e4b17023SJohn Marino const _Tuple_impl& __in) 294*e4b17023SJohn Marino : _Inherited(__tag, __a, _M_tail(__in)), 295*e4b17023SJohn Marino _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } 296*e4b17023SJohn Marino 297*e4b17023SJohn Marino template<typename _Alloc> 298*e4b17023SJohn Marino _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 299*e4b17023SJohn Marino _Tuple_impl&& __in) 300*e4b17023SJohn Marino : _Inherited(__tag, __a, std::move(_M_tail(__in))), 301*e4b17023SJohn Marino _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 302*e4b17023SJohn Marino std::forward<_Head>(_M_head(__in))) { } 303*e4b17023SJohn Marino 304*e4b17023SJohn Marino template<typename _Alloc, typename... _UElements> 305*e4b17023SJohn Marino _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 306*e4b17023SJohn Marino const _Tuple_impl<_Idx, _UElements...>& __in) 307*e4b17023SJohn Marino : _Inherited(__tag, __a, 308*e4b17023SJohn Marino _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 309*e4b17023SJohn Marino _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 310*e4b17023SJohn Marino _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } 311*e4b17023SJohn Marino 312*e4b17023SJohn Marino template<typename _Alloc, typename _UHead, typename... _UTails> 313*e4b17023SJohn Marino _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 314*e4b17023SJohn Marino _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 315*e4b17023SJohn Marino : _Inherited(__tag, __a, std::move 316*e4b17023SJohn Marino (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 317*e4b17023SJohn Marino _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 318*e4b17023SJohn Marino std::forward<_UHead> 319*e4b17023SJohn Marino (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } 320*e4b17023SJohn Marino 321*e4b17023SJohn Marino _Tuple_impl& 322*e4b17023SJohn Marino operator=(const _Tuple_impl& __in) 323*e4b17023SJohn Marino { 324*e4b17023SJohn Marino _M_head(*this) = _M_head(__in); 325*e4b17023SJohn Marino _M_tail(*this) = _M_tail(__in); 326*e4b17023SJohn Marino return *this; 327*e4b17023SJohn Marino } 328*e4b17023SJohn Marino 329*e4b17023SJohn Marino _Tuple_impl& 330*e4b17023SJohn Marino operator=(_Tuple_impl&& __in) 331*e4b17023SJohn Marino noexcept(__and_<is_nothrow_move_assignable<_Head>, 332*e4b17023SJohn Marino is_nothrow_move_assignable<_Inherited>>::value) 333*e4b17023SJohn Marino { 334*e4b17023SJohn Marino _M_head(*this) = std::forward<_Head>(_M_head(__in)); 335*e4b17023SJohn Marino _M_tail(*this) = std::move(_M_tail(__in)); 336*e4b17023SJohn Marino return *this; 337*e4b17023SJohn Marino } 338*e4b17023SJohn Marino 339*e4b17023SJohn Marino template<typename... _UElements> 340*e4b17023SJohn Marino _Tuple_impl& 341*e4b17023SJohn Marino operator=(const _Tuple_impl<_Idx, _UElements...>& __in) 342*e4b17023SJohn Marino { 343*e4b17023SJohn Marino _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); 344*e4b17023SJohn Marino _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in); 345*e4b17023SJohn Marino return *this; 346*e4b17023SJohn Marino } 347*e4b17023SJohn Marino 348*e4b17023SJohn Marino template<typename _UHead, typename... _UTails> 349*e4b17023SJohn Marino _Tuple_impl& 350*e4b17023SJohn Marino operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 351*e4b17023SJohn Marino { 352*e4b17023SJohn Marino _M_head(*this) = std::forward<_UHead> 353*e4b17023SJohn Marino (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); 354*e4b17023SJohn Marino _M_tail(*this) = std::move 355*e4b17023SJohn Marino (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)); 356*e4b17023SJohn Marino return *this; 357*e4b17023SJohn Marino } 358*e4b17023SJohn Marino 359*e4b17023SJohn Marino protected: 360*e4b17023SJohn Marino void 361*e4b17023SJohn Marino _M_swap(_Tuple_impl& __in) 362*e4b17023SJohn Marino noexcept(noexcept(swap(std::declval<_Head&>(), 363*e4b17023SJohn Marino std::declval<_Head&>())) 364*e4b17023SJohn Marino && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) 365*e4b17023SJohn Marino { 366*e4b17023SJohn Marino using std::swap; 367*e4b17023SJohn Marino swap(_M_head(*this), _M_head(__in)); 368*e4b17023SJohn Marino _Inherited::_M_swap(_M_tail(__in)); 369*e4b17023SJohn Marino } 370*e4b17023SJohn Marino }; 371*e4b17023SJohn Marino 372*e4b17023SJohn Marino /// Primary class template, tuple 373*e4b17023SJohn Marino template<typename... _Elements> 374*e4b17023SJohn Marino class tuple : public _Tuple_impl<0, _Elements...> 375*e4b17023SJohn Marino { 376*e4b17023SJohn Marino typedef _Tuple_impl<0, _Elements...> _Inherited; 377*e4b17023SJohn Marino 378*e4b17023SJohn Marino public: 379*e4b17023SJohn Marino constexpr tuple() 380*e4b17023SJohn Marino : _Inherited() { } 381*e4b17023SJohn Marino 382*e4b17023SJohn Marino explicit 383*e4b17023SJohn Marino constexpr tuple(const _Elements&... __elements) 384*e4b17023SJohn Marino : _Inherited(__elements...) { } 385*e4b17023SJohn Marino 386*e4b17023SJohn Marino template<typename... _UElements, typename = typename 387*e4b17023SJohn Marino enable_if<__and_<is_convertible<_UElements, 388*e4b17023SJohn Marino _Elements>...>::value>::type> 389*e4b17023SJohn Marino explicit 390*e4b17023SJohn Marino constexpr tuple(_UElements&&... __elements) 391*e4b17023SJohn Marino : _Inherited(std::forward<_UElements>(__elements)...) { } 392*e4b17023SJohn Marino 393*e4b17023SJohn Marino constexpr tuple(const tuple&) = default; 394*e4b17023SJohn Marino 395*e4b17023SJohn Marino constexpr tuple(tuple&&) = default; 396*e4b17023SJohn Marino 397*e4b17023SJohn Marino template<typename... _UElements, typename = typename 398*e4b17023SJohn Marino enable_if<__and_<is_convertible<const _UElements&, 399*e4b17023SJohn Marino _Elements>...>::value>::type> 400*e4b17023SJohn Marino constexpr tuple(const tuple<_UElements...>& __in) 401*e4b17023SJohn Marino : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 402*e4b17023SJohn Marino { } 403*e4b17023SJohn Marino 404*e4b17023SJohn Marino template<typename... _UElements, typename = typename 405*e4b17023SJohn Marino enable_if<__and_<is_convertible<_UElements, 406*e4b17023SJohn Marino _Elements>...>::value>::type> 407*e4b17023SJohn Marino constexpr tuple(tuple<_UElements...>&& __in) 408*e4b17023SJohn Marino : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 409*e4b17023SJohn Marino 410*e4b17023SJohn Marino // Allocator-extended constructors. 411*e4b17023SJohn Marino 412*e4b17023SJohn Marino template<typename _Alloc> 413*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a) 414*e4b17023SJohn Marino : _Inherited(__tag, __a) { } 415*e4b17023SJohn Marino 416*e4b17023SJohn Marino template<typename _Alloc> 417*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, 418*e4b17023SJohn Marino const _Elements&... __elements) 419*e4b17023SJohn Marino : _Inherited(__tag, __a, __elements...) { } 420*e4b17023SJohn Marino 421*e4b17023SJohn Marino template<typename _Alloc, typename... _UElements, typename = typename 422*e4b17023SJohn Marino enable_if<sizeof...(_UElements) 423*e4b17023SJohn Marino == sizeof...(_Elements)>::type> 424*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, 425*e4b17023SJohn Marino _UElements&&... __elements) 426*e4b17023SJohn Marino : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 427*e4b17023SJohn Marino { } 428*e4b17023SJohn Marino 429*e4b17023SJohn Marino template<typename _Alloc> 430*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 431*e4b17023SJohn Marino : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 432*e4b17023SJohn Marino 433*e4b17023SJohn Marino template<typename _Alloc> 434*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 435*e4b17023SJohn Marino : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 436*e4b17023SJohn Marino 437*e4b17023SJohn Marino template<typename _Alloc, typename... _UElements, typename = typename 438*e4b17023SJohn Marino enable_if<sizeof...(_UElements) 439*e4b17023SJohn Marino == sizeof...(_Elements)>::type> 440*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, 441*e4b17023SJohn Marino const tuple<_UElements...>& __in) 442*e4b17023SJohn Marino : _Inherited(__tag, __a, 443*e4b17023SJohn Marino static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 444*e4b17023SJohn Marino { } 445*e4b17023SJohn Marino 446*e4b17023SJohn Marino template<typename _Alloc, typename... _UElements, typename = typename 447*e4b17023SJohn Marino enable_if<sizeof...(_UElements) 448*e4b17023SJohn Marino == sizeof...(_Elements)>::type> 449*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, 450*e4b17023SJohn Marino tuple<_UElements...>&& __in) 451*e4b17023SJohn Marino : _Inherited(__tag, __a, 452*e4b17023SJohn Marino static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 453*e4b17023SJohn Marino { } 454*e4b17023SJohn Marino 455*e4b17023SJohn Marino tuple& 456*e4b17023SJohn Marino operator=(const tuple& __in) 457*e4b17023SJohn Marino { 458*e4b17023SJohn Marino static_cast<_Inherited&>(*this) = __in; 459*e4b17023SJohn Marino return *this; 460*e4b17023SJohn Marino } 461*e4b17023SJohn Marino 462*e4b17023SJohn Marino tuple& 463*e4b17023SJohn Marino operator=(tuple&& __in) 464*e4b17023SJohn Marino noexcept(is_nothrow_move_assignable<_Inherited>::value) 465*e4b17023SJohn Marino { 466*e4b17023SJohn Marino static_cast<_Inherited&>(*this) = std::move(__in); 467*e4b17023SJohn Marino return *this; 468*e4b17023SJohn Marino } 469*e4b17023SJohn Marino 470*e4b17023SJohn Marino template<typename... _UElements, typename = typename 471*e4b17023SJohn Marino enable_if<sizeof...(_UElements) 472*e4b17023SJohn Marino == sizeof...(_Elements)>::type> 473*e4b17023SJohn Marino tuple& 474*e4b17023SJohn Marino operator=(const tuple<_UElements...>& __in) 475*e4b17023SJohn Marino { 476*e4b17023SJohn Marino static_cast<_Inherited&>(*this) = __in; 477*e4b17023SJohn Marino return *this; 478*e4b17023SJohn Marino } 479*e4b17023SJohn Marino 480*e4b17023SJohn Marino template<typename... _UElements, typename = typename 481*e4b17023SJohn Marino enable_if<sizeof...(_UElements) 482*e4b17023SJohn Marino == sizeof...(_Elements)>::type> 483*e4b17023SJohn Marino tuple& 484*e4b17023SJohn Marino operator=(tuple<_UElements...>&& __in) 485*e4b17023SJohn Marino { 486*e4b17023SJohn Marino static_cast<_Inherited&>(*this) = std::move(__in); 487*e4b17023SJohn Marino return *this; 488*e4b17023SJohn Marino } 489*e4b17023SJohn Marino 490*e4b17023SJohn Marino void 491*e4b17023SJohn Marino swap(tuple& __in) 492*e4b17023SJohn Marino noexcept(noexcept(__in._M_swap(__in))) 493*e4b17023SJohn Marino { _Inherited::_M_swap(__in); } 494*e4b17023SJohn Marino }; 495*e4b17023SJohn Marino 496*e4b17023SJohn Marino // Explicit specialization, zero-element tuple. 497*e4b17023SJohn Marino template<> 498*e4b17023SJohn Marino class tuple<> 499*e4b17023SJohn Marino { 500*e4b17023SJohn Marino public: 501*e4b17023SJohn Marino void swap(tuple&) noexcept { /* no-op */ } 502*e4b17023SJohn Marino }; 503*e4b17023SJohn Marino 504*e4b17023SJohn Marino /// Partial specialization, 2-element tuple. 505*e4b17023SJohn Marino /// Includes construction and assignment from a pair. 506*e4b17023SJohn Marino template<typename _T1, typename _T2> 507*e4b17023SJohn Marino class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 508*e4b17023SJohn Marino { 509*e4b17023SJohn Marino typedef _Tuple_impl<0, _T1, _T2> _Inherited; 510*e4b17023SJohn Marino 511*e4b17023SJohn Marino public: 512*e4b17023SJohn Marino constexpr tuple() 513*e4b17023SJohn Marino : _Inherited() { } 514*e4b17023SJohn Marino 515*e4b17023SJohn Marino explicit 516*e4b17023SJohn Marino constexpr tuple(const _T1& __a1, const _T2& __a2) 517*e4b17023SJohn Marino : _Inherited(__a1, __a2) { } 518*e4b17023SJohn Marino 519*e4b17023SJohn Marino template<typename _U1, typename _U2, typename = typename 520*e4b17023SJohn Marino enable_if<__and_<is_convertible<_U1, _T1>, 521*e4b17023SJohn Marino is_convertible<_U2, _T2>>::value>::type> 522*e4b17023SJohn Marino explicit 523*e4b17023SJohn Marino constexpr tuple(_U1&& __a1, _U2&& __a2) 524*e4b17023SJohn Marino : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 525*e4b17023SJohn Marino 526*e4b17023SJohn Marino constexpr tuple(const tuple&) = default; 527*e4b17023SJohn Marino 528*e4b17023SJohn Marino constexpr tuple(tuple&&) = default; 529*e4b17023SJohn Marino 530*e4b17023SJohn Marino template<typename _U1, typename _U2, typename = typename 531*e4b17023SJohn Marino enable_if<__and_<is_convertible<const _U1&, _T1>, 532*e4b17023SJohn Marino is_convertible<const _U2&, _T2>>::value>::type> 533*e4b17023SJohn Marino constexpr tuple(const tuple<_U1, _U2>& __in) 534*e4b17023SJohn Marino : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 535*e4b17023SJohn Marino 536*e4b17023SJohn Marino template<typename _U1, typename _U2, typename = typename 537*e4b17023SJohn Marino enable_if<__and_<is_convertible<_U1, _T1>, 538*e4b17023SJohn Marino is_convertible<_U2, _T2>>::value>::type> 539*e4b17023SJohn Marino constexpr tuple(tuple<_U1, _U2>&& __in) 540*e4b17023SJohn Marino : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 541*e4b17023SJohn Marino 542*e4b17023SJohn Marino template<typename _U1, typename _U2, typename = typename 543*e4b17023SJohn Marino enable_if<__and_<is_convertible<const _U1&, _T1>, 544*e4b17023SJohn Marino is_convertible<const _U2&, _T2>>::value>::type> 545*e4b17023SJohn Marino constexpr tuple(const pair<_U1, _U2>& __in) 546*e4b17023SJohn Marino : _Inherited(__in.first, __in.second) { } 547*e4b17023SJohn Marino 548*e4b17023SJohn Marino template<typename _U1, typename _U2, typename = typename 549*e4b17023SJohn Marino enable_if<__and_<is_convertible<_U1, _T1>, 550*e4b17023SJohn Marino is_convertible<_U2, _T2>>::value>::type> 551*e4b17023SJohn Marino constexpr tuple(pair<_U1, _U2>&& __in) 552*e4b17023SJohn Marino : _Inherited(std::forward<_U1>(__in.first), 553*e4b17023SJohn Marino std::forward<_U2>(__in.second)) { } 554*e4b17023SJohn Marino 555*e4b17023SJohn Marino // Allocator-extended constructors. 556*e4b17023SJohn Marino 557*e4b17023SJohn Marino template<typename _Alloc> 558*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a) 559*e4b17023SJohn Marino : _Inherited(__tag, __a) { } 560*e4b17023SJohn Marino 561*e4b17023SJohn Marino template<typename _Alloc> 562*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, 563*e4b17023SJohn Marino const _T1& __a1, const _T2& __a2) 564*e4b17023SJohn Marino : _Inherited(__tag, __a, __a1, __a2) { } 565*e4b17023SJohn Marino 566*e4b17023SJohn Marino template<typename _Alloc, typename _U1, typename _U2> 567*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 568*e4b17023SJohn Marino : _Inherited(__tag, __a, std::forward<_U1>(__a1), 569*e4b17023SJohn Marino std::forward<_U2>(__a2)) { } 570*e4b17023SJohn Marino 571*e4b17023SJohn Marino template<typename _Alloc> 572*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 573*e4b17023SJohn Marino : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 574*e4b17023SJohn Marino 575*e4b17023SJohn Marino template<typename _Alloc> 576*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 577*e4b17023SJohn Marino : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 578*e4b17023SJohn Marino 579*e4b17023SJohn Marino template<typename _Alloc, typename _U1, typename _U2> 580*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, 581*e4b17023SJohn Marino const tuple<_U1, _U2>& __in) 582*e4b17023SJohn Marino : _Inherited(__tag, __a, 583*e4b17023SJohn Marino static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 584*e4b17023SJohn Marino { } 585*e4b17023SJohn Marino 586*e4b17023SJohn Marino template<typename _Alloc, typename _U1, typename _U2> 587*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 588*e4b17023SJohn Marino : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 589*e4b17023SJohn Marino { } 590*e4b17023SJohn Marino 591*e4b17023SJohn Marino template<typename _Alloc, typename _U1, typename _U2> 592*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, 593*e4b17023SJohn Marino const pair<_U1, _U2>& __in) 594*e4b17023SJohn Marino : _Inherited(__tag, __a, __in.first, __in.second) { } 595*e4b17023SJohn Marino 596*e4b17023SJohn Marino template<typename _Alloc, typename _U1, typename _U2> 597*e4b17023SJohn Marino tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 598*e4b17023SJohn Marino : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 599*e4b17023SJohn Marino std::forward<_U2>(__in.second)) { } 600*e4b17023SJohn Marino 601*e4b17023SJohn Marino tuple& 602*e4b17023SJohn Marino operator=(const tuple& __in) 603*e4b17023SJohn Marino { 604*e4b17023SJohn Marino static_cast<_Inherited&>(*this) = __in; 605*e4b17023SJohn Marino return *this; 606*e4b17023SJohn Marino } 607*e4b17023SJohn Marino 608*e4b17023SJohn Marino tuple& 609*e4b17023SJohn Marino operator=(tuple&& __in) 610*e4b17023SJohn Marino noexcept(is_nothrow_move_assignable<_Inherited>::value) 611*e4b17023SJohn Marino { 612*e4b17023SJohn Marino static_cast<_Inherited&>(*this) = std::move(__in); 613*e4b17023SJohn Marino return *this; 614*e4b17023SJohn Marino } 615*e4b17023SJohn Marino 616*e4b17023SJohn Marino template<typename _U1, typename _U2> 617*e4b17023SJohn Marino tuple& 618*e4b17023SJohn Marino operator=(const tuple<_U1, _U2>& __in) 619*e4b17023SJohn Marino { 620*e4b17023SJohn Marino static_cast<_Inherited&>(*this) = __in; 621*e4b17023SJohn Marino return *this; 622*e4b17023SJohn Marino } 623*e4b17023SJohn Marino 624*e4b17023SJohn Marino template<typename _U1, typename _U2> 625*e4b17023SJohn Marino tuple& 626*e4b17023SJohn Marino operator=(tuple<_U1, _U2>&& __in) 627*e4b17023SJohn Marino { 628*e4b17023SJohn Marino static_cast<_Inherited&>(*this) = std::move(__in); 629*e4b17023SJohn Marino return *this; 630*e4b17023SJohn Marino } 631*e4b17023SJohn Marino 632*e4b17023SJohn Marino template<typename _U1, typename _U2> 633*e4b17023SJohn Marino tuple& 634*e4b17023SJohn Marino operator=(const pair<_U1, _U2>& __in) 635*e4b17023SJohn Marino { 636*e4b17023SJohn Marino this->_M_head(*this) = __in.first; 637*e4b17023SJohn Marino this->_M_tail(*this)._M_head(*this) = __in.second; 638*e4b17023SJohn Marino return *this; 639*e4b17023SJohn Marino } 640*e4b17023SJohn Marino 641*e4b17023SJohn Marino template<typename _U1, typename _U2> 642*e4b17023SJohn Marino tuple& 643*e4b17023SJohn Marino operator=(pair<_U1, _U2>&& __in) 644*e4b17023SJohn Marino { 645*e4b17023SJohn Marino this->_M_head(*this) = std::forward<_U1>(__in.first); 646*e4b17023SJohn Marino this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 647*e4b17023SJohn Marino return *this; 648*e4b17023SJohn Marino } 649*e4b17023SJohn Marino 650*e4b17023SJohn Marino void 651*e4b17023SJohn Marino swap(tuple& __in) 652*e4b17023SJohn Marino noexcept(noexcept(__in._M_swap(__in))) 653*e4b17023SJohn Marino { _Inherited::_M_swap(__in); } 654*e4b17023SJohn Marino }; 655*e4b17023SJohn Marino 656*e4b17023SJohn Marino 657*e4b17023SJohn Marino /// Gives the type of the ith element of a given tuple type. 658*e4b17023SJohn Marino template<std::size_t __i, typename _Tp> 659*e4b17023SJohn Marino struct tuple_element; 660*e4b17023SJohn Marino 661*e4b17023SJohn Marino /** 662*e4b17023SJohn Marino * Recursive case for tuple_element: strip off the first element in 663*e4b17023SJohn Marino * the tuple and retrieve the (i-1)th element of the remaining tuple. 664*e4b17023SJohn Marino */ 665*e4b17023SJohn Marino template<std::size_t __i, typename _Head, typename... _Tail> 666*e4b17023SJohn Marino struct tuple_element<__i, tuple<_Head, _Tail...> > 667*e4b17023SJohn Marino : tuple_element<__i - 1, tuple<_Tail...> > { }; 668*e4b17023SJohn Marino 669*e4b17023SJohn Marino /** 670*e4b17023SJohn Marino * Basis case for tuple_element: The first element is the one we're seeking. 671*e4b17023SJohn Marino */ 672*e4b17023SJohn Marino template<typename _Head, typename... _Tail> 673*e4b17023SJohn Marino struct tuple_element<0, tuple<_Head, _Tail...> > 674*e4b17023SJohn Marino { 675*e4b17023SJohn Marino typedef _Head type; 676*e4b17023SJohn Marino }; 677*e4b17023SJohn Marino 678*e4b17023SJohn Marino template<std::size_t __i, typename _Tp> 679*e4b17023SJohn Marino struct tuple_element<__i, const _Tp> 680*e4b17023SJohn Marino { 681*e4b17023SJohn Marino typedef typename 682*e4b17023SJohn Marino add_const<typename tuple_element<__i, _Tp>::type>::type type; 683*e4b17023SJohn Marino }; 684*e4b17023SJohn Marino 685*e4b17023SJohn Marino template<std::size_t __i, typename _Tp> 686*e4b17023SJohn Marino struct tuple_element<__i, volatile _Tp> 687*e4b17023SJohn Marino { 688*e4b17023SJohn Marino typedef typename 689*e4b17023SJohn Marino add_volatile<typename tuple_element<__i, _Tp>::type>::type type; 690*e4b17023SJohn Marino }; 691*e4b17023SJohn Marino 692*e4b17023SJohn Marino template<std::size_t __i, typename _Tp> 693*e4b17023SJohn Marino struct tuple_element<__i, const volatile _Tp> 694*e4b17023SJohn Marino { 695*e4b17023SJohn Marino typedef typename 696*e4b17023SJohn Marino add_cv<typename tuple_element<__i, _Tp>::type>::type type; 697*e4b17023SJohn Marino }; 698*e4b17023SJohn Marino 699*e4b17023SJohn Marino /// Finds the size of a given tuple type. 700*e4b17023SJohn Marino template<typename _Tp> 701*e4b17023SJohn Marino struct tuple_size; 702*e4b17023SJohn Marino 703*e4b17023SJohn Marino template<typename _Tp> 704*e4b17023SJohn Marino struct tuple_size<const _Tp> 705*e4b17023SJohn Marino : public integral_constant< 706*e4b17023SJohn Marino typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, 707*e4b17023SJohn Marino tuple_size<_Tp>::value> { }; 708*e4b17023SJohn Marino 709*e4b17023SJohn Marino template<typename _Tp> 710*e4b17023SJohn Marino struct tuple_size<volatile _Tp> 711*e4b17023SJohn Marino : public integral_constant< 712*e4b17023SJohn Marino typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, 713*e4b17023SJohn Marino tuple_size<_Tp>::value> { }; 714*e4b17023SJohn Marino 715*e4b17023SJohn Marino template<typename _Tp> 716*e4b17023SJohn Marino struct tuple_size<const volatile _Tp> 717*e4b17023SJohn Marino : public integral_constant< 718*e4b17023SJohn Marino typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, 719*e4b17023SJohn Marino tuple_size<_Tp>::value> { }; 720*e4b17023SJohn Marino 721*e4b17023SJohn Marino /// class tuple_size 722*e4b17023SJohn Marino template<typename... _Elements> 723*e4b17023SJohn Marino struct tuple_size<tuple<_Elements...>> 724*e4b17023SJohn Marino : public integral_constant<std::size_t, sizeof...(_Elements)> { }; 725*e4b17023SJohn Marino 726*e4b17023SJohn Marino template<std::size_t __i, typename _Head, typename... _Tail> 727*e4b17023SJohn Marino constexpr typename __add_ref<_Head>::type 728*e4b17023SJohn Marino __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 729*e4b17023SJohn Marino { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 730*e4b17023SJohn Marino 731*e4b17023SJohn Marino template<std::size_t __i, typename _Head, typename... _Tail> 732*e4b17023SJohn Marino constexpr typename __add_c_ref<_Head>::type 733*e4b17023SJohn Marino __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 734*e4b17023SJohn Marino { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 735*e4b17023SJohn Marino 736*e4b17023SJohn Marino // Return a reference (const reference, rvalue reference) to the ith element 737*e4b17023SJohn Marino // of a tuple. Any const or non-const ref elements are returned with their 738*e4b17023SJohn Marino // original type. 739*e4b17023SJohn Marino template<std::size_t __i, typename... _Elements> 740*e4b17023SJohn Marino constexpr typename __add_ref< 741*e4b17023SJohn Marino typename tuple_element<__i, tuple<_Elements...>>::type 742*e4b17023SJohn Marino >::type 743*e4b17023SJohn Marino get(tuple<_Elements...>& __t) noexcept 744*e4b17023SJohn Marino { return __get_helper<__i>(__t); } 745*e4b17023SJohn Marino 746*e4b17023SJohn Marino template<std::size_t __i, typename... _Elements> 747*e4b17023SJohn Marino constexpr typename __add_c_ref< 748*e4b17023SJohn Marino typename tuple_element<__i, tuple<_Elements...>>::type 749*e4b17023SJohn Marino >::type 750*e4b17023SJohn Marino get(const tuple<_Elements...>& __t) noexcept 751*e4b17023SJohn Marino { return __get_helper<__i>(__t); } 752*e4b17023SJohn Marino 753*e4b17023SJohn Marino template<std::size_t __i, typename... _Elements> 754*e4b17023SJohn Marino constexpr typename __add_r_ref< 755*e4b17023SJohn Marino typename tuple_element<__i, tuple<_Elements...>>::type 756*e4b17023SJohn Marino >::type 757*e4b17023SJohn Marino get(tuple<_Elements...>&& __t) noexcept 758*e4b17023SJohn Marino { return std::forward<typename tuple_element<__i, 759*e4b17023SJohn Marino tuple<_Elements...>>::type&&>(get<__i>(__t)); } 760*e4b17023SJohn Marino 761*e4b17023SJohn Marino // This class helps construct the various comparison operations on tuples 762*e4b17023SJohn Marino template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j, 763*e4b17023SJohn Marino typename _Tp, typename _Up> 764*e4b17023SJohn Marino struct __tuple_compare; 765*e4b17023SJohn Marino 766*e4b17023SJohn Marino template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up> 767*e4b17023SJohn Marino struct __tuple_compare<0, __i, __j, _Tp, _Up> 768*e4b17023SJohn Marino { 769*e4b17023SJohn Marino static bool 770*e4b17023SJohn Marino __eq(const _Tp& __t, const _Up& __u) 771*e4b17023SJohn Marino { 772*e4b17023SJohn Marino return (get<__i>(__t) == get<__i>(__u) && 773*e4b17023SJohn Marino __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u)); 774*e4b17023SJohn Marino } 775*e4b17023SJohn Marino 776*e4b17023SJohn Marino static bool 777*e4b17023SJohn Marino __less(const _Tp& __t, const _Up& __u) 778*e4b17023SJohn Marino { 779*e4b17023SJohn Marino return ((get<__i>(__t) < get<__i>(__u)) 780*e4b17023SJohn Marino || !(get<__i>(__u) < get<__i>(__t)) && 781*e4b17023SJohn Marino __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u)); 782*e4b17023SJohn Marino } 783*e4b17023SJohn Marino }; 784*e4b17023SJohn Marino 785*e4b17023SJohn Marino template<std::size_t __i, typename _Tp, typename _Up> 786*e4b17023SJohn Marino struct __tuple_compare<0, __i, __i, _Tp, _Up> 787*e4b17023SJohn Marino { 788*e4b17023SJohn Marino static bool 789*e4b17023SJohn Marino __eq(const _Tp&, const _Up&) { return true; } 790*e4b17023SJohn Marino 791*e4b17023SJohn Marino static bool 792*e4b17023SJohn Marino __less(const _Tp&, const _Up&) { return false; } 793*e4b17023SJohn Marino }; 794*e4b17023SJohn Marino 795*e4b17023SJohn Marino template<typename... _TElements, typename... _UElements> 796*e4b17023SJohn Marino bool 797*e4b17023SJohn Marino operator==(const tuple<_TElements...>& __t, 798*e4b17023SJohn Marino const tuple<_UElements...>& __u) 799*e4b17023SJohn Marino { 800*e4b17023SJohn Marino typedef tuple<_TElements...> _Tp; 801*e4b17023SJohn Marino typedef tuple<_UElements...> _Up; 802*e4b17023SJohn Marino return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 803*e4b17023SJohn Marino 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); 804*e4b17023SJohn Marino } 805*e4b17023SJohn Marino 806*e4b17023SJohn Marino template<typename... _TElements, typename... _UElements> 807*e4b17023SJohn Marino bool 808*e4b17023SJohn Marino operator<(const tuple<_TElements...>& __t, 809*e4b17023SJohn Marino const tuple<_UElements...>& __u) 810*e4b17023SJohn Marino { 811*e4b17023SJohn Marino typedef tuple<_TElements...> _Tp; 812*e4b17023SJohn Marino typedef tuple<_UElements...> _Up; 813*e4b17023SJohn Marino return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 814*e4b17023SJohn Marino 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); 815*e4b17023SJohn Marino } 816*e4b17023SJohn Marino 817*e4b17023SJohn Marino template<typename... _TElements, typename... _UElements> 818*e4b17023SJohn Marino inline bool 819*e4b17023SJohn Marino operator!=(const tuple<_TElements...>& __t, 820*e4b17023SJohn Marino const tuple<_UElements...>& __u) 821*e4b17023SJohn Marino { return !(__t == __u); } 822*e4b17023SJohn Marino 823*e4b17023SJohn Marino template<typename... _TElements, typename... _UElements> 824*e4b17023SJohn Marino inline bool 825*e4b17023SJohn Marino operator>(const tuple<_TElements...>& __t, 826*e4b17023SJohn Marino const tuple<_UElements...>& __u) 827*e4b17023SJohn Marino { return __u < __t; } 828*e4b17023SJohn Marino 829*e4b17023SJohn Marino template<typename... _TElements, typename... _UElements> 830*e4b17023SJohn Marino inline bool 831*e4b17023SJohn Marino operator<=(const tuple<_TElements...>& __t, 832*e4b17023SJohn Marino const tuple<_UElements...>& __u) 833*e4b17023SJohn Marino { return !(__u < __t); } 834*e4b17023SJohn Marino 835*e4b17023SJohn Marino template<typename... _TElements, typename... _UElements> 836*e4b17023SJohn Marino inline bool 837*e4b17023SJohn Marino operator>=(const tuple<_TElements...>& __t, 838*e4b17023SJohn Marino const tuple<_UElements...>& __u) 839*e4b17023SJohn Marino { return !(__t < __u); } 840*e4b17023SJohn Marino 841*e4b17023SJohn Marino // NB: DR 705. 842*e4b17023SJohn Marino template<typename... _Elements> 843*e4b17023SJohn Marino constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 844*e4b17023SJohn Marino make_tuple(_Elements&&... __args) 845*e4b17023SJohn Marino { 846*e4b17023SJohn Marino typedef tuple<typename __decay_and_strip<_Elements>::__type...> 847*e4b17023SJohn Marino __result_type; 848*e4b17023SJohn Marino return __result_type(std::forward<_Elements>(__args)...); 849*e4b17023SJohn Marino } 850*e4b17023SJohn Marino 851*e4b17023SJohn Marino template<typename... _Elements> 852*e4b17023SJohn Marino constexpr tuple<_Elements&&...> 853*e4b17023SJohn Marino forward_as_tuple(_Elements&&... __args) noexcept 854*e4b17023SJohn Marino { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 855*e4b17023SJohn Marino 856*e4b17023SJohn Marino 857*e4b17023SJohn Marino template<typename, std::size_t> struct array; 858*e4b17023SJohn Marino 859*e4b17023SJohn Marino template<std::size_t _Int, typename _Tp, std::size_t _Nm> 860*e4b17023SJohn Marino constexpr _Tp& get(array<_Tp, _Nm>&) noexcept; 861*e4b17023SJohn Marino 862*e4b17023SJohn Marino template<std::size_t _Int, typename _Tp, std::size_t _Nm> 863*e4b17023SJohn Marino constexpr _Tp&& get(array<_Tp, _Nm>&&) noexcept; 864*e4b17023SJohn Marino 865*e4b17023SJohn Marino template<std::size_t _Int, typename _Tp, std::size_t _Nm> 866*e4b17023SJohn Marino constexpr const _Tp& get(const array<_Tp, _Nm>&) noexcept; 867*e4b17023SJohn Marino 868*e4b17023SJohn Marino template<typename> 869*e4b17023SJohn Marino struct __is_tuple_like_impl : false_type 870*e4b17023SJohn Marino { }; 871*e4b17023SJohn Marino 872*e4b17023SJohn Marino template<typename... _Tps> 873*e4b17023SJohn Marino struct __is_tuple_like_impl<tuple<_Tps...>> : true_type 874*e4b17023SJohn Marino { }; 875*e4b17023SJohn Marino 876*e4b17023SJohn Marino template<typename _T1, typename _T2> 877*e4b17023SJohn Marino struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type 878*e4b17023SJohn Marino { }; 879*e4b17023SJohn Marino 880*e4b17023SJohn Marino template<typename _Tp, std::size_t _Nm> 881*e4b17023SJohn Marino struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type 882*e4b17023SJohn Marino { }; 883*e4b17023SJohn Marino 884*e4b17023SJohn Marino // Internal type trait that allows us to sfinae-protect tuple_cat. 885*e4b17023SJohn Marino template<typename _Tp> 886*e4b17023SJohn Marino struct __is_tuple_like 887*e4b17023SJohn Marino : public __is_tuple_like_impl<typename std::remove_cv 888*e4b17023SJohn Marino <typename std::remove_reference<_Tp>::type>::type>::type 889*e4b17023SJohn Marino { }; 890*e4b17023SJohn Marino 891*e4b17023SJohn Marino // Stores a tuple of indices. Also used by bind() to extract the elements 892*e4b17023SJohn Marino // in a tuple. 893*e4b17023SJohn Marino template<std::size_t... _Indexes> 894*e4b17023SJohn Marino struct _Index_tuple 895*e4b17023SJohn Marino { 896*e4b17023SJohn Marino typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next; 897*e4b17023SJohn Marino }; 898*e4b17023SJohn Marino 899*e4b17023SJohn Marino // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. 900*e4b17023SJohn Marino template<std::size_t _Num> 901*e4b17023SJohn Marino struct _Build_index_tuple 902*e4b17023SJohn Marino { 903*e4b17023SJohn Marino typedef typename _Build_index_tuple<_Num - 1>::__type::__next __type; 904*e4b17023SJohn Marino }; 905*e4b17023SJohn Marino 906*e4b17023SJohn Marino template<> 907*e4b17023SJohn Marino struct _Build_index_tuple<0> 908*e4b17023SJohn Marino { 909*e4b17023SJohn Marino typedef _Index_tuple<> __type; 910*e4b17023SJohn Marino }; 911*e4b17023SJohn Marino 912*e4b17023SJohn Marino template<std::size_t, typename, typename, std::size_t> 913*e4b17023SJohn Marino struct __make_tuple_impl; 914*e4b17023SJohn Marino 915*e4b17023SJohn Marino template<std::size_t _Idx, typename _Tuple, typename... _Tp, 916*e4b17023SJohn Marino std::size_t _Nm> 917*e4b17023SJohn Marino struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 918*e4b17023SJohn Marino { 919*e4b17023SJohn Marino typedef typename __make_tuple_impl<_Idx + 1, tuple<_Tp..., 920*e4b17023SJohn Marino typename std::tuple_element<_Idx, _Tuple>::type>, _Tuple, _Nm>::__type 921*e4b17023SJohn Marino __type; 922*e4b17023SJohn Marino }; 923*e4b17023SJohn Marino 924*e4b17023SJohn Marino template<std::size_t _Nm, typename _Tuple, typename... _Tp> 925*e4b17023SJohn Marino struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 926*e4b17023SJohn Marino { 927*e4b17023SJohn Marino typedef tuple<_Tp...> __type; 928*e4b17023SJohn Marino }; 929*e4b17023SJohn Marino 930*e4b17023SJohn Marino template<typename _Tuple> 931*e4b17023SJohn Marino struct __do_make_tuple 932*e4b17023SJohn Marino : public __make_tuple_impl<0, tuple<>, _Tuple, 933*e4b17023SJohn Marino std::tuple_size<_Tuple>::value> 934*e4b17023SJohn Marino { }; 935*e4b17023SJohn Marino 936*e4b17023SJohn Marino // Returns the std::tuple equivalent of a tuple-like type. 937*e4b17023SJohn Marino template<typename _Tuple> 938*e4b17023SJohn Marino struct __make_tuple 939*e4b17023SJohn Marino : public __do_make_tuple<typename std::remove_cv 940*e4b17023SJohn Marino <typename std::remove_reference<_Tuple>::type>::type> 941*e4b17023SJohn Marino { }; 942*e4b17023SJohn Marino 943*e4b17023SJohn Marino // Combines several std::tuple's into a single one. 944*e4b17023SJohn Marino template<typename...> 945*e4b17023SJohn Marino struct __combine_tuples; 946*e4b17023SJohn Marino 947*e4b17023SJohn Marino template<> 948*e4b17023SJohn Marino struct __combine_tuples<> 949*e4b17023SJohn Marino { 950*e4b17023SJohn Marino typedef tuple<> __type; 951*e4b17023SJohn Marino }; 952*e4b17023SJohn Marino 953*e4b17023SJohn Marino template<typename... _Ts> 954*e4b17023SJohn Marino struct __combine_tuples<tuple<_Ts...>> 955*e4b17023SJohn Marino { 956*e4b17023SJohn Marino typedef tuple<_Ts...> __type; 957*e4b17023SJohn Marino }; 958*e4b17023SJohn Marino 959*e4b17023SJohn Marino template<typename... _T1s, typename... _T2s, typename... _Rem> 960*e4b17023SJohn Marino struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 961*e4b17023SJohn Marino { 962*e4b17023SJohn Marino typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 963*e4b17023SJohn Marino _Rem...>::__type __type; 964*e4b17023SJohn Marino }; 965*e4b17023SJohn Marino 966*e4b17023SJohn Marino // Computes the result type of tuple_cat given a set of tuple-like types. 967*e4b17023SJohn Marino template<typename... _Tpls> 968*e4b17023SJohn Marino struct __tuple_cat_result 969*e4b17023SJohn Marino { 970*e4b17023SJohn Marino typedef typename __combine_tuples 971*e4b17023SJohn Marino <typename __make_tuple<_Tpls>::__type...>::__type __type; 972*e4b17023SJohn Marino }; 973*e4b17023SJohn Marino 974*e4b17023SJohn Marino // Helper to determine the index set for the first tuple-like 975*e4b17023SJohn Marino // type of a given set. 976*e4b17023SJohn Marino template<typename...> 977*e4b17023SJohn Marino struct __make_1st_indices; 978*e4b17023SJohn Marino 979*e4b17023SJohn Marino template<> 980*e4b17023SJohn Marino struct __make_1st_indices<> 981*e4b17023SJohn Marino { 982*e4b17023SJohn Marino typedef std::_Index_tuple<> __type; 983*e4b17023SJohn Marino }; 984*e4b17023SJohn Marino 985*e4b17023SJohn Marino template<typename _Tp, typename... _Tpls> 986*e4b17023SJohn Marino struct __make_1st_indices<_Tp, _Tpls...> 987*e4b17023SJohn Marino { 988*e4b17023SJohn Marino typedef typename std::_Build_index_tuple<std::tuple_size< 989*e4b17023SJohn Marino typename std::remove_reference<_Tp>::type>::value>::__type __type; 990*e4b17023SJohn Marino }; 991*e4b17023SJohn Marino 992*e4b17023SJohn Marino // Performs the actual concatenation by step-wise expanding tuple-like 993*e4b17023SJohn Marino // objects into the elements, which are finally forwarded into the 994*e4b17023SJohn Marino // result tuple. 995*e4b17023SJohn Marino template<typename _Ret, typename _Indices, typename... _Tpls> 996*e4b17023SJohn Marino struct __tuple_concater; 997*e4b17023SJohn Marino 998*e4b17023SJohn Marino template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> 999*e4b17023SJohn Marino struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> 1000*e4b17023SJohn Marino { 1001*e4b17023SJohn Marino template<typename... _Us> 1002*e4b17023SJohn Marino static constexpr _Ret 1003*e4b17023SJohn Marino _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 1004*e4b17023SJohn Marino { 1005*e4b17023SJohn Marino typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1006*e4b17023SJohn Marino typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 1007*e4b17023SJohn Marino return __next::_S_do(std::forward<_Tpls>(__tps)..., 1008*e4b17023SJohn Marino std::forward<_Us>(__us)..., 1009*e4b17023SJohn Marino std::get<_Is>(std::forward<_Tp>(__tp))...); 1010*e4b17023SJohn Marino } 1011*e4b17023SJohn Marino }; 1012*e4b17023SJohn Marino 1013*e4b17023SJohn Marino template<typename _Ret> 1014*e4b17023SJohn Marino struct __tuple_concater<_Ret, std::_Index_tuple<>> 1015*e4b17023SJohn Marino { 1016*e4b17023SJohn Marino template<typename... _Us> 1017*e4b17023SJohn Marino static constexpr _Ret 1018*e4b17023SJohn Marino _S_do(_Us&&... __us) 1019*e4b17023SJohn Marino { 1020*e4b17023SJohn Marino return _Ret(std::forward<_Us>(__us)...); 1021*e4b17023SJohn Marino } 1022*e4b17023SJohn Marino }; 1023*e4b17023SJohn Marino 1024*e4b17023SJohn Marino template<typename... _Tpls, typename = typename 1025*e4b17023SJohn Marino enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 1026*e4b17023SJohn Marino constexpr auto 1027*e4b17023SJohn Marino tuple_cat(_Tpls&&... __tpls) 1028*e4b17023SJohn Marino -> typename __tuple_cat_result<_Tpls...>::__type 1029*e4b17023SJohn Marino { 1030*e4b17023SJohn Marino typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 1031*e4b17023SJohn Marino typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1032*e4b17023SJohn Marino typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 1033*e4b17023SJohn Marino return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 1034*e4b17023SJohn Marino } 1035*e4b17023SJohn Marino 1036*e4b17023SJohn Marino template<typename... _Elements> 1037*e4b17023SJohn Marino inline tuple<_Elements&...> 1038*e4b17023SJohn Marino tie(_Elements&... __args) noexcept 1039*e4b17023SJohn Marino { return tuple<_Elements&...>(__args...); } 1040*e4b17023SJohn Marino 1041*e4b17023SJohn Marino template<typename... _Elements> 1042*e4b17023SJohn Marino inline void 1043*e4b17023SJohn Marino swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 1044*e4b17023SJohn Marino noexcept(noexcept(__x.swap(__y))) 1045*e4b17023SJohn Marino { __x.swap(__y); } 1046*e4b17023SJohn Marino 1047*e4b17023SJohn Marino // A class (and instance) which can be used in 'tie' when an element 1048*e4b17023SJohn Marino // of a tuple is not required 1049*e4b17023SJohn Marino struct _Swallow_assign 1050*e4b17023SJohn Marino { 1051*e4b17023SJohn Marino template<class _Tp> 1052*e4b17023SJohn Marino const _Swallow_assign& 1053*e4b17023SJohn Marino operator=(const _Tp&) const 1054*e4b17023SJohn Marino { return *this; } 1055*e4b17023SJohn Marino }; 1056*e4b17023SJohn Marino 1057*e4b17023SJohn Marino const _Swallow_assign ignore{}; 1058*e4b17023SJohn Marino 1059*e4b17023SJohn Marino /// Partial specialization for tuples 1060*e4b17023SJohn Marino template<typename... _Types, typename _Alloc> 1061*e4b17023SJohn Marino struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 1062*e4b17023SJohn Marino 1063*e4b17023SJohn Marino // See stl_pair.h... 1064*e4b17023SJohn Marino template<class _T1, class _T2> 1065*e4b17023SJohn Marino template<typename... _Args1, typename... _Args2> 1066*e4b17023SJohn Marino inline 1067*e4b17023SJohn Marino pair<_T1, _T2>:: 1068*e4b17023SJohn Marino pair(piecewise_construct_t, 1069*e4b17023SJohn Marino tuple<_Args1...> __first, tuple<_Args2...> __second) 1070*e4b17023SJohn Marino : pair(__first, __second, 1071*e4b17023SJohn Marino typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 1072*e4b17023SJohn Marino typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 1073*e4b17023SJohn Marino { } 1074*e4b17023SJohn Marino 1075*e4b17023SJohn Marino template<class _T1, class _T2> 1076*e4b17023SJohn Marino template<typename... _Args1, std::size_t... _Indexes1, 1077*e4b17023SJohn Marino typename... _Args2, std::size_t... _Indexes2> 1078*e4b17023SJohn Marino inline 1079*e4b17023SJohn Marino pair<_T1, _T2>:: 1080*e4b17023SJohn Marino pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 1081*e4b17023SJohn Marino _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 1082*e4b17023SJohn Marino : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 1083*e4b17023SJohn Marino second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 1084*e4b17023SJohn Marino { } 1085*e4b17023SJohn Marino 1086*e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION 1087*e4b17023SJohn Marino} // namespace 1088*e4b17023SJohn Marino 1089*e4b17023SJohn Marino#endif // __GXX_EXPERIMENTAL_CXX0X__ 1090*e4b17023SJohn Marino 1091*e4b17023SJohn Marino#endif // _GLIBCXX_TUPLE 1092