1*38fd1498Szrj// <tuple> -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj// Copyright (C) 2007-2018 Free Software Foundation, Inc. 4*38fd1498Szrj// 5*38fd1498Szrj// This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj// software; you can redistribute it and/or modify it under the 7*38fd1498Szrj// terms of the GNU General Public License as published by the 8*38fd1498Szrj// Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj// any later version. 10*38fd1498Szrj 11*38fd1498Szrj// This library is distributed in the hope that it will be useful, 12*38fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj// GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj// permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj// 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj// You should have received a copy of the GNU General Public License and 21*38fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj// <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj/** @file include/tuple 26*38fd1498Szrj * This is a Standard C++ Library header. 27*38fd1498Szrj */ 28*38fd1498Szrj 29*38fd1498Szrj#ifndef _GLIBCXX_TUPLE 30*38fd1498Szrj#define _GLIBCXX_TUPLE 1 31*38fd1498Szrj 32*38fd1498Szrj#pragma GCC system_header 33*38fd1498Szrj 34*38fd1498Szrj#if __cplusplus < 201103L 35*38fd1498Szrj# include <bits/c++0x_warning.h> 36*38fd1498Szrj#else 37*38fd1498Szrj 38*38fd1498Szrj#include <utility> 39*38fd1498Szrj#include <array> 40*38fd1498Szrj#include <bits/uses_allocator.h> 41*38fd1498Szrj#include <bits/invoke.h> 42*38fd1498Szrj 43*38fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default) 44*38fd1498Szrj{ 45*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION 46*38fd1498Szrj 47*38fd1498Szrj /** 48*38fd1498Szrj * @addtogroup utilities 49*38fd1498Szrj * @{ 50*38fd1498Szrj */ 51*38fd1498Szrj 52*38fd1498Szrj template<typename... _Elements> 53*38fd1498Szrj class tuple; 54*38fd1498Szrj 55*38fd1498Szrj template<typename _Tp> 56*38fd1498Szrj struct __is_empty_non_tuple : is_empty<_Tp> { }; 57*38fd1498Szrj 58*38fd1498Szrj // Using EBO for elements that are tuples causes ambiguous base errors. 59*38fd1498Szrj template<typename _El0, typename... _El> 60*38fd1498Szrj struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { }; 61*38fd1498Szrj 62*38fd1498Szrj // Use the Empty Base-class Optimization for empty, non-final types. 63*38fd1498Szrj template<typename _Tp> 64*38fd1498Szrj using __empty_not_final 65*38fd1498Szrj = typename conditional<__is_final(_Tp), false_type, 66*38fd1498Szrj __is_empty_non_tuple<_Tp>>::type; 67*38fd1498Szrj 68*38fd1498Szrj template<std::size_t _Idx, typename _Head, 69*38fd1498Szrj bool = __empty_not_final<_Head>::value> 70*38fd1498Szrj struct _Head_base; 71*38fd1498Szrj 72*38fd1498Szrj template<std::size_t _Idx, typename _Head> 73*38fd1498Szrj struct _Head_base<_Idx, _Head, true> 74*38fd1498Szrj : public _Head 75*38fd1498Szrj { 76*38fd1498Szrj constexpr _Head_base() 77*38fd1498Szrj : _Head() { } 78*38fd1498Szrj 79*38fd1498Szrj constexpr _Head_base(const _Head& __h) 80*38fd1498Szrj : _Head(__h) { } 81*38fd1498Szrj 82*38fd1498Szrj constexpr _Head_base(const _Head_base&) = default; 83*38fd1498Szrj constexpr _Head_base(_Head_base&&) = default; 84*38fd1498Szrj 85*38fd1498Szrj template<typename _UHead> 86*38fd1498Szrj constexpr _Head_base(_UHead&& __h) 87*38fd1498Szrj : _Head(std::forward<_UHead>(__h)) { } 88*38fd1498Szrj 89*38fd1498Szrj _Head_base(allocator_arg_t, __uses_alloc0) 90*38fd1498Szrj : _Head() { } 91*38fd1498Szrj 92*38fd1498Szrj template<typename _Alloc> 93*38fd1498Szrj _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 94*38fd1498Szrj : _Head(allocator_arg, *__a._M_a) { } 95*38fd1498Szrj 96*38fd1498Szrj template<typename _Alloc> 97*38fd1498Szrj _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 98*38fd1498Szrj : _Head(*__a._M_a) { } 99*38fd1498Szrj 100*38fd1498Szrj template<typename _UHead> 101*38fd1498Szrj _Head_base(__uses_alloc0, _UHead&& __uhead) 102*38fd1498Szrj : _Head(std::forward<_UHead>(__uhead)) { } 103*38fd1498Szrj 104*38fd1498Szrj template<typename _Alloc, typename _UHead> 105*38fd1498Szrj _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 106*38fd1498Szrj : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } 107*38fd1498Szrj 108*38fd1498Szrj template<typename _Alloc, typename _UHead> 109*38fd1498Szrj _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 110*38fd1498Szrj : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } 111*38fd1498Szrj 112*38fd1498Szrj static constexpr _Head& 113*38fd1498Szrj _M_head(_Head_base& __b) noexcept { return __b; } 114*38fd1498Szrj 115*38fd1498Szrj static constexpr const _Head& 116*38fd1498Szrj _M_head(const _Head_base& __b) noexcept { return __b; } 117*38fd1498Szrj }; 118*38fd1498Szrj 119*38fd1498Szrj template<std::size_t _Idx, typename _Head> 120*38fd1498Szrj struct _Head_base<_Idx, _Head, false> 121*38fd1498Szrj { 122*38fd1498Szrj constexpr _Head_base() 123*38fd1498Szrj : _M_head_impl() { } 124*38fd1498Szrj 125*38fd1498Szrj constexpr _Head_base(const _Head& __h) 126*38fd1498Szrj : _M_head_impl(__h) { } 127*38fd1498Szrj 128*38fd1498Szrj constexpr _Head_base(const _Head_base&) = default; 129*38fd1498Szrj constexpr _Head_base(_Head_base&&) = default; 130*38fd1498Szrj 131*38fd1498Szrj template<typename _UHead> 132*38fd1498Szrj constexpr _Head_base(_UHead&& __h) 133*38fd1498Szrj : _M_head_impl(std::forward<_UHead>(__h)) { } 134*38fd1498Szrj 135*38fd1498Szrj _Head_base(allocator_arg_t, __uses_alloc0) 136*38fd1498Szrj : _M_head_impl() { } 137*38fd1498Szrj 138*38fd1498Szrj template<typename _Alloc> 139*38fd1498Szrj _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 140*38fd1498Szrj : _M_head_impl(allocator_arg, *__a._M_a) { } 141*38fd1498Szrj 142*38fd1498Szrj template<typename _Alloc> 143*38fd1498Szrj _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 144*38fd1498Szrj : _M_head_impl(*__a._M_a) { } 145*38fd1498Szrj 146*38fd1498Szrj template<typename _UHead> 147*38fd1498Szrj _Head_base(__uses_alloc0, _UHead&& __uhead) 148*38fd1498Szrj : _M_head_impl(std::forward<_UHead>(__uhead)) { } 149*38fd1498Szrj 150*38fd1498Szrj template<typename _Alloc, typename _UHead> 151*38fd1498Szrj _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 152*38fd1498Szrj : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) 153*38fd1498Szrj { } 154*38fd1498Szrj 155*38fd1498Szrj template<typename _Alloc, typename _UHead> 156*38fd1498Szrj _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 157*38fd1498Szrj : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } 158*38fd1498Szrj 159*38fd1498Szrj static constexpr _Head& 160*38fd1498Szrj _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } 161*38fd1498Szrj 162*38fd1498Szrj static constexpr const _Head& 163*38fd1498Szrj _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } 164*38fd1498Szrj 165*38fd1498Szrj _Head _M_head_impl; 166*38fd1498Szrj }; 167*38fd1498Szrj 168*38fd1498Szrj /** 169*38fd1498Szrj * Contains the actual implementation of the @c tuple template, stored 170*38fd1498Szrj * as a recursive inheritance hierarchy from the first element (most 171*38fd1498Szrj * derived class) to the last (least derived class). The @c Idx 172*38fd1498Szrj * parameter gives the 0-based index of the element stored at this 173*38fd1498Szrj * point in the hierarchy; we use it to implement a constant-time 174*38fd1498Szrj * get() operation. 175*38fd1498Szrj */ 176*38fd1498Szrj template<std::size_t _Idx, typename... _Elements> 177*38fd1498Szrj struct _Tuple_impl; 178*38fd1498Szrj 179*38fd1498Szrj /** 180*38fd1498Szrj * Recursive tuple implementation. Here we store the @c Head element 181*38fd1498Szrj * and derive from a @c Tuple_impl containing the remaining elements 182*38fd1498Szrj * (which contains the @c Tail). 183*38fd1498Szrj */ 184*38fd1498Szrj template<std::size_t _Idx, typename _Head, typename... _Tail> 185*38fd1498Szrj struct _Tuple_impl<_Idx, _Head, _Tail...> 186*38fd1498Szrj : public _Tuple_impl<_Idx + 1, _Tail...>, 187*38fd1498Szrj private _Head_base<_Idx, _Head> 188*38fd1498Szrj { 189*38fd1498Szrj template<std::size_t, typename...> friend class _Tuple_impl; 190*38fd1498Szrj 191*38fd1498Szrj typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; 192*38fd1498Szrj typedef _Head_base<_Idx, _Head> _Base; 193*38fd1498Szrj 194*38fd1498Szrj static constexpr _Head& 195*38fd1498Szrj _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 196*38fd1498Szrj 197*38fd1498Szrj static constexpr const _Head& 198*38fd1498Szrj _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 199*38fd1498Szrj 200*38fd1498Szrj static constexpr _Inherited& 201*38fd1498Szrj _M_tail(_Tuple_impl& __t) noexcept { return __t; } 202*38fd1498Szrj 203*38fd1498Szrj static constexpr const _Inherited& 204*38fd1498Szrj _M_tail(const _Tuple_impl& __t) noexcept { return __t; } 205*38fd1498Szrj 206*38fd1498Szrj constexpr _Tuple_impl() 207*38fd1498Szrj : _Inherited(), _Base() { } 208*38fd1498Szrj 209*38fd1498Szrj explicit 210*38fd1498Szrj constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) 211*38fd1498Szrj : _Inherited(__tail...), _Base(__head) { } 212*38fd1498Szrj 213*38fd1498Szrj template<typename _UHead, typename... _UTail, typename = typename 214*38fd1498Szrj enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> 215*38fd1498Szrj explicit 216*38fd1498Szrj constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail) 217*38fd1498Szrj : _Inherited(std::forward<_UTail>(__tail)...), 218*38fd1498Szrj _Base(std::forward<_UHead>(__head)) { } 219*38fd1498Szrj 220*38fd1498Szrj constexpr _Tuple_impl(const _Tuple_impl&) = default; 221*38fd1498Szrj 222*38fd1498Szrj constexpr 223*38fd1498Szrj _Tuple_impl(_Tuple_impl&& __in) 224*38fd1498Szrj noexcept(__and_<is_nothrow_move_constructible<_Head>, 225*38fd1498Szrj is_nothrow_move_constructible<_Inherited>>::value) 226*38fd1498Szrj : _Inherited(std::move(_M_tail(__in))), 227*38fd1498Szrj _Base(std::forward<_Head>(_M_head(__in))) { } 228*38fd1498Szrj 229*38fd1498Szrj template<typename... _UElements> 230*38fd1498Szrj constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) 231*38fd1498Szrj : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 232*38fd1498Szrj _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } 233*38fd1498Szrj 234*38fd1498Szrj template<typename _UHead, typename... _UTails> 235*38fd1498Szrj constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 236*38fd1498Szrj : _Inherited(std::move 237*38fd1498Szrj (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 238*38fd1498Szrj _Base(std::forward<_UHead> 239*38fd1498Szrj (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } 240*38fd1498Szrj 241*38fd1498Szrj template<typename _Alloc> 242*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 243*38fd1498Szrj : _Inherited(__tag, __a), 244*38fd1498Szrj _Base(__tag, __use_alloc<_Head>(__a)) { } 245*38fd1498Szrj 246*38fd1498Szrj template<typename _Alloc> 247*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 248*38fd1498Szrj const _Head& __head, const _Tail&... __tail) 249*38fd1498Szrj : _Inherited(__tag, __a, __tail...), 250*38fd1498Szrj _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } 251*38fd1498Szrj 252*38fd1498Szrj template<typename _Alloc, typename _UHead, typename... _UTail, 253*38fd1498Szrj typename = typename enable_if<sizeof...(_Tail) 254*38fd1498Szrj == sizeof...(_UTail)>::type> 255*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 256*38fd1498Szrj _UHead&& __head, _UTail&&... __tail) 257*38fd1498Szrj : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), 258*38fd1498Szrj _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 259*38fd1498Szrj std::forward<_UHead>(__head)) { } 260*38fd1498Szrj 261*38fd1498Szrj template<typename _Alloc> 262*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 263*38fd1498Szrj const _Tuple_impl& __in) 264*38fd1498Szrj : _Inherited(__tag, __a, _M_tail(__in)), 265*38fd1498Szrj _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } 266*38fd1498Szrj 267*38fd1498Szrj template<typename _Alloc> 268*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 269*38fd1498Szrj _Tuple_impl&& __in) 270*38fd1498Szrj : _Inherited(__tag, __a, std::move(_M_tail(__in))), 271*38fd1498Szrj _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 272*38fd1498Szrj std::forward<_Head>(_M_head(__in))) { } 273*38fd1498Szrj 274*38fd1498Szrj template<typename _Alloc, typename... _UElements> 275*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 276*38fd1498Szrj const _Tuple_impl<_Idx, _UElements...>& __in) 277*38fd1498Szrj : _Inherited(__tag, __a, 278*38fd1498Szrj _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 279*38fd1498Szrj _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 280*38fd1498Szrj _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } 281*38fd1498Szrj 282*38fd1498Szrj template<typename _Alloc, typename _UHead, typename... _UTails> 283*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 284*38fd1498Szrj _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 285*38fd1498Szrj : _Inherited(__tag, __a, std::move 286*38fd1498Szrj (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 287*38fd1498Szrj _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 288*38fd1498Szrj std::forward<_UHead> 289*38fd1498Szrj (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } 290*38fd1498Szrj 291*38fd1498Szrj _Tuple_impl& 292*38fd1498Szrj operator=(const _Tuple_impl& __in) 293*38fd1498Szrj { 294*38fd1498Szrj _M_head(*this) = _M_head(__in); 295*38fd1498Szrj _M_tail(*this) = _M_tail(__in); 296*38fd1498Szrj return *this; 297*38fd1498Szrj } 298*38fd1498Szrj 299*38fd1498Szrj _Tuple_impl& 300*38fd1498Szrj operator=(_Tuple_impl&& __in) 301*38fd1498Szrj noexcept(__and_<is_nothrow_move_assignable<_Head>, 302*38fd1498Szrj is_nothrow_move_assignable<_Inherited>>::value) 303*38fd1498Szrj { 304*38fd1498Szrj _M_head(*this) = std::forward<_Head>(_M_head(__in)); 305*38fd1498Szrj _M_tail(*this) = std::move(_M_tail(__in)); 306*38fd1498Szrj return *this; 307*38fd1498Szrj } 308*38fd1498Szrj 309*38fd1498Szrj template<typename... _UElements> 310*38fd1498Szrj _Tuple_impl& 311*38fd1498Szrj operator=(const _Tuple_impl<_Idx, _UElements...>& __in) 312*38fd1498Szrj { 313*38fd1498Szrj _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); 314*38fd1498Szrj _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in); 315*38fd1498Szrj return *this; 316*38fd1498Szrj } 317*38fd1498Szrj 318*38fd1498Szrj template<typename _UHead, typename... _UTails> 319*38fd1498Szrj _Tuple_impl& 320*38fd1498Szrj operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 321*38fd1498Szrj { 322*38fd1498Szrj _M_head(*this) = std::forward<_UHead> 323*38fd1498Szrj (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); 324*38fd1498Szrj _M_tail(*this) = std::move 325*38fd1498Szrj (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)); 326*38fd1498Szrj return *this; 327*38fd1498Szrj } 328*38fd1498Szrj 329*38fd1498Szrj protected: 330*38fd1498Szrj void 331*38fd1498Szrj _M_swap(_Tuple_impl& __in) 332*38fd1498Szrj noexcept(__is_nothrow_swappable<_Head>::value 333*38fd1498Szrj && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) 334*38fd1498Szrj { 335*38fd1498Szrj using std::swap; 336*38fd1498Szrj swap(_M_head(*this), _M_head(__in)); 337*38fd1498Szrj _Inherited::_M_swap(_M_tail(__in)); 338*38fd1498Szrj } 339*38fd1498Szrj }; 340*38fd1498Szrj 341*38fd1498Szrj // Basis case of inheritance recursion. 342*38fd1498Szrj template<std::size_t _Idx, typename _Head> 343*38fd1498Szrj struct _Tuple_impl<_Idx, _Head> 344*38fd1498Szrj : private _Head_base<_Idx, _Head> 345*38fd1498Szrj { 346*38fd1498Szrj template<std::size_t, typename...> friend class _Tuple_impl; 347*38fd1498Szrj 348*38fd1498Szrj typedef _Head_base<_Idx, _Head> _Base; 349*38fd1498Szrj 350*38fd1498Szrj static constexpr _Head& 351*38fd1498Szrj _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 352*38fd1498Szrj 353*38fd1498Szrj static constexpr const _Head& 354*38fd1498Szrj _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 355*38fd1498Szrj 356*38fd1498Szrj constexpr _Tuple_impl() 357*38fd1498Szrj : _Base() { } 358*38fd1498Szrj 359*38fd1498Szrj explicit 360*38fd1498Szrj constexpr _Tuple_impl(const _Head& __head) 361*38fd1498Szrj : _Base(__head) { } 362*38fd1498Szrj 363*38fd1498Szrj template<typename _UHead> 364*38fd1498Szrj explicit 365*38fd1498Szrj constexpr _Tuple_impl(_UHead&& __head) 366*38fd1498Szrj : _Base(std::forward<_UHead>(__head)) { } 367*38fd1498Szrj 368*38fd1498Szrj constexpr _Tuple_impl(const _Tuple_impl&) = default; 369*38fd1498Szrj 370*38fd1498Szrj constexpr 371*38fd1498Szrj _Tuple_impl(_Tuple_impl&& __in) 372*38fd1498Szrj noexcept(is_nothrow_move_constructible<_Head>::value) 373*38fd1498Szrj : _Base(std::forward<_Head>(_M_head(__in))) { } 374*38fd1498Szrj 375*38fd1498Szrj template<typename _UHead> 376*38fd1498Szrj constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) 377*38fd1498Szrj : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } 378*38fd1498Szrj 379*38fd1498Szrj template<typename _UHead> 380*38fd1498Szrj constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) 381*38fd1498Szrj : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 382*38fd1498Szrj { } 383*38fd1498Szrj 384*38fd1498Szrj template<typename _Alloc> 385*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 386*38fd1498Szrj : _Base(__tag, __use_alloc<_Head>(__a)) { } 387*38fd1498Szrj 388*38fd1498Szrj template<typename _Alloc> 389*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 390*38fd1498Szrj const _Head& __head) 391*38fd1498Szrj : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } 392*38fd1498Szrj 393*38fd1498Szrj template<typename _Alloc, typename _UHead> 394*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 395*38fd1498Szrj _UHead&& __head) 396*38fd1498Szrj : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 397*38fd1498Szrj std::forward<_UHead>(__head)) { } 398*38fd1498Szrj 399*38fd1498Szrj template<typename _Alloc> 400*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 401*38fd1498Szrj const _Tuple_impl& __in) 402*38fd1498Szrj : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } 403*38fd1498Szrj 404*38fd1498Szrj template<typename _Alloc> 405*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 406*38fd1498Szrj _Tuple_impl&& __in) 407*38fd1498Szrj : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 408*38fd1498Szrj std::forward<_Head>(_M_head(__in))) { } 409*38fd1498Szrj 410*38fd1498Szrj template<typename _Alloc, typename _UHead> 411*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 412*38fd1498Szrj const _Tuple_impl<_Idx, _UHead>& __in) 413*38fd1498Szrj : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 414*38fd1498Szrj _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } 415*38fd1498Szrj 416*38fd1498Szrj template<typename _Alloc, typename _UHead> 417*38fd1498Szrj _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 418*38fd1498Szrj _Tuple_impl<_Idx, _UHead>&& __in) 419*38fd1498Szrj : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 420*38fd1498Szrj std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 421*38fd1498Szrj { } 422*38fd1498Szrj 423*38fd1498Szrj _Tuple_impl& 424*38fd1498Szrj operator=(const _Tuple_impl& __in) 425*38fd1498Szrj { 426*38fd1498Szrj _M_head(*this) = _M_head(__in); 427*38fd1498Szrj return *this; 428*38fd1498Szrj } 429*38fd1498Szrj 430*38fd1498Szrj _Tuple_impl& 431*38fd1498Szrj operator=(_Tuple_impl&& __in) 432*38fd1498Szrj noexcept(is_nothrow_move_assignable<_Head>::value) 433*38fd1498Szrj { 434*38fd1498Szrj _M_head(*this) = std::forward<_Head>(_M_head(__in)); 435*38fd1498Szrj return *this; 436*38fd1498Szrj } 437*38fd1498Szrj 438*38fd1498Szrj template<typename _UHead> 439*38fd1498Szrj _Tuple_impl& 440*38fd1498Szrj operator=(const _Tuple_impl<_Idx, _UHead>& __in) 441*38fd1498Szrj { 442*38fd1498Szrj _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); 443*38fd1498Szrj return *this; 444*38fd1498Szrj } 445*38fd1498Szrj 446*38fd1498Szrj template<typename _UHead> 447*38fd1498Szrj _Tuple_impl& 448*38fd1498Szrj operator=(_Tuple_impl<_Idx, _UHead>&& __in) 449*38fd1498Szrj { 450*38fd1498Szrj _M_head(*this) 451*38fd1498Szrj = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); 452*38fd1498Szrj return *this; 453*38fd1498Szrj } 454*38fd1498Szrj 455*38fd1498Szrj protected: 456*38fd1498Szrj void 457*38fd1498Szrj _M_swap(_Tuple_impl& __in) 458*38fd1498Szrj noexcept(__is_nothrow_swappable<_Head>::value) 459*38fd1498Szrj { 460*38fd1498Szrj using std::swap; 461*38fd1498Szrj swap(_M_head(*this), _M_head(__in)); 462*38fd1498Szrj } 463*38fd1498Szrj }; 464*38fd1498Szrj 465*38fd1498Szrj // Concept utility functions, reused in conditionally-explicit 466*38fd1498Szrj // constructors. 467*38fd1498Szrj template<bool, typename... _Elements> 468*38fd1498Szrj struct _TC 469*38fd1498Szrj { 470*38fd1498Szrj template<typename... _UElements> 471*38fd1498Szrj static constexpr bool _ConstructibleTuple() 472*38fd1498Szrj { 473*38fd1498Szrj return __and_<is_constructible<_Elements, const _UElements&>...>::value; 474*38fd1498Szrj } 475*38fd1498Szrj 476*38fd1498Szrj template<typename... _UElements> 477*38fd1498Szrj static constexpr bool _ImplicitlyConvertibleTuple() 478*38fd1498Szrj { 479*38fd1498Szrj return __and_<is_convertible<const _UElements&, _Elements>...>::value; 480*38fd1498Szrj } 481*38fd1498Szrj 482*38fd1498Szrj template<typename... _UElements> 483*38fd1498Szrj static constexpr bool _MoveConstructibleTuple() 484*38fd1498Szrj { 485*38fd1498Szrj return __and_<is_constructible<_Elements, _UElements&&>...>::value; 486*38fd1498Szrj } 487*38fd1498Szrj 488*38fd1498Szrj template<typename... _UElements> 489*38fd1498Szrj static constexpr bool _ImplicitlyMoveConvertibleTuple() 490*38fd1498Szrj { 491*38fd1498Szrj return __and_<is_convertible<_UElements&&, _Elements>...>::value; 492*38fd1498Szrj } 493*38fd1498Szrj 494*38fd1498Szrj template<typename _SrcTuple> 495*38fd1498Szrj static constexpr bool _NonNestedTuple() 496*38fd1498Szrj { 497*38fd1498Szrj return __and_<__not_<is_same<tuple<_Elements...>, 498*38fd1498Szrj typename remove_cv< 499*38fd1498Szrj typename remove_reference<_SrcTuple>::type 500*38fd1498Szrj >::type>>, 501*38fd1498Szrj __not_<is_convertible<_SrcTuple, _Elements...>>, 502*38fd1498Szrj __not_<is_constructible<_Elements..., _SrcTuple>> 503*38fd1498Szrj >::value; 504*38fd1498Szrj } 505*38fd1498Szrj template<typename... _UElements> 506*38fd1498Szrj static constexpr bool _NotSameTuple() 507*38fd1498Szrj { 508*38fd1498Szrj return __not_<is_same<tuple<_Elements...>, 509*38fd1498Szrj typename remove_const< 510*38fd1498Szrj typename remove_reference<_UElements...>::type 511*38fd1498Szrj >::type>>::value; 512*38fd1498Szrj } 513*38fd1498Szrj }; 514*38fd1498Szrj 515*38fd1498Szrj template<typename... _Elements> 516*38fd1498Szrj struct _TC<false, _Elements...> 517*38fd1498Szrj { 518*38fd1498Szrj template<typename... _UElements> 519*38fd1498Szrj static constexpr bool _ConstructibleTuple() 520*38fd1498Szrj { 521*38fd1498Szrj return false; 522*38fd1498Szrj } 523*38fd1498Szrj 524*38fd1498Szrj template<typename... _UElements> 525*38fd1498Szrj static constexpr bool _ImplicitlyConvertibleTuple() 526*38fd1498Szrj { 527*38fd1498Szrj return false; 528*38fd1498Szrj } 529*38fd1498Szrj 530*38fd1498Szrj template<typename... _UElements> 531*38fd1498Szrj static constexpr bool _MoveConstructibleTuple() 532*38fd1498Szrj { 533*38fd1498Szrj return false; 534*38fd1498Szrj } 535*38fd1498Szrj 536*38fd1498Szrj template<typename... _UElements> 537*38fd1498Szrj static constexpr bool _ImplicitlyMoveConvertibleTuple() 538*38fd1498Szrj { 539*38fd1498Szrj return false; 540*38fd1498Szrj } 541*38fd1498Szrj 542*38fd1498Szrj template<typename... _UElements> 543*38fd1498Szrj static constexpr bool _NonNestedTuple() 544*38fd1498Szrj { 545*38fd1498Szrj return true; 546*38fd1498Szrj } 547*38fd1498Szrj template<typename... _UElements> 548*38fd1498Szrj static constexpr bool _NotSameTuple() 549*38fd1498Szrj { 550*38fd1498Szrj return true; 551*38fd1498Szrj } 552*38fd1498Szrj }; 553*38fd1498Szrj 554*38fd1498Szrj /// Primary class template, tuple 555*38fd1498Szrj template<typename... _Elements> 556*38fd1498Szrj class tuple : public _Tuple_impl<0, _Elements...> 557*38fd1498Szrj { 558*38fd1498Szrj typedef _Tuple_impl<0, _Elements...> _Inherited; 559*38fd1498Szrj 560*38fd1498Szrj // Used for constraining the default constructor so 561*38fd1498Szrj // that it becomes dependent on the constraints. 562*38fd1498Szrj template<typename _Dummy> 563*38fd1498Szrj struct _TC2 564*38fd1498Szrj { 565*38fd1498Szrj static constexpr bool _DefaultConstructibleTuple() 566*38fd1498Szrj { 567*38fd1498Szrj return __and_<is_default_constructible<_Elements>...>::value; 568*38fd1498Szrj } 569*38fd1498Szrj static constexpr bool _ImplicitlyDefaultConstructibleTuple() 570*38fd1498Szrj { 571*38fd1498Szrj return __and_<__is_implicitly_default_constructible<_Elements>...> 572*38fd1498Szrj ::value; 573*38fd1498Szrj } 574*38fd1498Szrj }; 575*38fd1498Szrj 576*38fd1498Szrj public: 577*38fd1498Szrj template<typename _Dummy = void, 578*38fd1498Szrj typename enable_if<_TC2<_Dummy>:: 579*38fd1498Szrj _ImplicitlyDefaultConstructibleTuple(), 580*38fd1498Szrj bool>::type = true> 581*38fd1498Szrj constexpr tuple() 582*38fd1498Szrj : _Inherited() { } 583*38fd1498Szrj 584*38fd1498Szrj template<typename _Dummy = void, 585*38fd1498Szrj typename enable_if<_TC2<_Dummy>:: 586*38fd1498Szrj _DefaultConstructibleTuple() 587*38fd1498Szrj && 588*38fd1498Szrj !_TC2<_Dummy>:: 589*38fd1498Szrj _ImplicitlyDefaultConstructibleTuple(), 590*38fd1498Szrj bool>::type = false> 591*38fd1498Szrj explicit constexpr tuple() 592*38fd1498Szrj : _Inherited() { } 593*38fd1498Szrj 594*38fd1498Szrj // Shortcut for the cases where constructors taking _Elements... 595*38fd1498Szrj // need to be constrained. 596*38fd1498Szrj template<typename _Dummy> using _TCC = 597*38fd1498Szrj _TC<is_same<_Dummy, void>::value, 598*38fd1498Szrj _Elements...>; 599*38fd1498Szrj 600*38fd1498Szrj template<typename _Dummy = void, 601*38fd1498Szrj typename enable_if< 602*38fd1498Szrj _TCC<_Dummy>::template 603*38fd1498Szrj _ConstructibleTuple<_Elements...>() 604*38fd1498Szrj && _TCC<_Dummy>::template 605*38fd1498Szrj _ImplicitlyConvertibleTuple<_Elements...>() 606*38fd1498Szrj && (sizeof...(_Elements) >= 1), 607*38fd1498Szrj bool>::type=true> 608*38fd1498Szrj constexpr tuple(const _Elements&... __elements) 609*38fd1498Szrj : _Inherited(__elements...) { } 610*38fd1498Szrj 611*38fd1498Szrj template<typename _Dummy = void, 612*38fd1498Szrj typename enable_if< 613*38fd1498Szrj _TCC<_Dummy>::template 614*38fd1498Szrj _ConstructibleTuple<_Elements...>() 615*38fd1498Szrj && !_TCC<_Dummy>::template 616*38fd1498Szrj _ImplicitlyConvertibleTuple<_Elements...>() 617*38fd1498Szrj && (sizeof...(_Elements) >= 1), 618*38fd1498Szrj bool>::type=false> 619*38fd1498Szrj explicit constexpr tuple(const _Elements&... __elements) 620*38fd1498Szrj : _Inherited(__elements...) { } 621*38fd1498Szrj 622*38fd1498Szrj // Shortcut for the cases where constructors taking _UElements... 623*38fd1498Szrj // need to be constrained. 624*38fd1498Szrj template<typename... _UElements> using _TMC = 625*38fd1498Szrj _TC<(sizeof...(_Elements) == sizeof...(_UElements)) 626*38fd1498Szrj && (_TC<(sizeof...(_UElements)==1), _Elements...>:: 627*38fd1498Szrj template _NotSameTuple<_UElements...>()), 628*38fd1498Szrj _Elements...>; 629*38fd1498Szrj 630*38fd1498Szrj // Shortcut for the cases where constructors taking tuple<_UElements...> 631*38fd1498Szrj // need to be constrained. 632*38fd1498Szrj template<typename... _UElements> using _TMCT = 633*38fd1498Szrj _TC<(sizeof...(_Elements) == sizeof...(_UElements)) 634*38fd1498Szrj && !is_same<tuple<_Elements...>, 635*38fd1498Szrj tuple<_UElements...>>::value, 636*38fd1498Szrj _Elements...>; 637*38fd1498Szrj 638*38fd1498Szrj template<typename... _UElements, typename 639*38fd1498Szrj enable_if< 640*38fd1498Szrj _TMC<_UElements...>::template 641*38fd1498Szrj _MoveConstructibleTuple<_UElements...>() 642*38fd1498Szrj && _TMC<_UElements...>::template 643*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_UElements...>() 644*38fd1498Szrj && (sizeof...(_Elements) >= 1), 645*38fd1498Szrj bool>::type=true> 646*38fd1498Szrj constexpr tuple(_UElements&&... __elements) 647*38fd1498Szrj : _Inherited(std::forward<_UElements>(__elements)...) { } 648*38fd1498Szrj 649*38fd1498Szrj template<typename... _UElements, typename 650*38fd1498Szrj enable_if< 651*38fd1498Szrj _TMC<_UElements...>::template 652*38fd1498Szrj _MoveConstructibleTuple<_UElements...>() 653*38fd1498Szrj && !_TMC<_UElements...>::template 654*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_UElements...>() 655*38fd1498Szrj && (sizeof...(_Elements) >= 1), 656*38fd1498Szrj bool>::type=false> 657*38fd1498Szrj explicit constexpr tuple(_UElements&&... __elements) 658*38fd1498Szrj : _Inherited(std::forward<_UElements>(__elements)...) { } 659*38fd1498Szrj 660*38fd1498Szrj constexpr tuple(const tuple&) = default; 661*38fd1498Szrj 662*38fd1498Szrj constexpr tuple(tuple&&) = default; 663*38fd1498Szrj 664*38fd1498Szrj // Shortcut for the cases where constructors taking tuples 665*38fd1498Szrj // must avoid creating temporaries. 666*38fd1498Szrj template<typename _Dummy> using _TNTC = 667*38fd1498Szrj _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1, 668*38fd1498Szrj _Elements...>; 669*38fd1498Szrj 670*38fd1498Szrj template<typename... _UElements, typename _Dummy = void, typename 671*38fd1498Szrj enable_if<_TMCT<_UElements...>::template 672*38fd1498Szrj _ConstructibleTuple<_UElements...>() 673*38fd1498Szrj && _TMCT<_UElements...>::template 674*38fd1498Szrj _ImplicitlyConvertibleTuple<_UElements...>() 675*38fd1498Szrj && _TNTC<_Dummy>::template 676*38fd1498Szrj _NonNestedTuple<const tuple<_UElements...>&>(), 677*38fd1498Szrj bool>::type=true> 678*38fd1498Szrj constexpr tuple(const tuple<_UElements...>& __in) 679*38fd1498Szrj : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 680*38fd1498Szrj { } 681*38fd1498Szrj 682*38fd1498Szrj template<typename... _UElements, typename _Dummy = void, typename 683*38fd1498Szrj enable_if<_TMCT<_UElements...>::template 684*38fd1498Szrj _ConstructibleTuple<_UElements...>() 685*38fd1498Szrj && !_TMCT<_UElements...>::template 686*38fd1498Szrj _ImplicitlyConvertibleTuple<_UElements...>() 687*38fd1498Szrj && _TNTC<_Dummy>::template 688*38fd1498Szrj _NonNestedTuple<const tuple<_UElements...>&>(), 689*38fd1498Szrj bool>::type=false> 690*38fd1498Szrj explicit constexpr tuple(const tuple<_UElements...>& __in) 691*38fd1498Szrj : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 692*38fd1498Szrj { } 693*38fd1498Szrj 694*38fd1498Szrj template<typename... _UElements, typename _Dummy = void, typename 695*38fd1498Szrj enable_if<_TMCT<_UElements...>::template 696*38fd1498Szrj _MoveConstructibleTuple<_UElements...>() 697*38fd1498Szrj && _TMCT<_UElements...>::template 698*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_UElements...>() 699*38fd1498Szrj && _TNTC<_Dummy>::template 700*38fd1498Szrj _NonNestedTuple<tuple<_UElements...>&&>(), 701*38fd1498Szrj bool>::type=true> 702*38fd1498Szrj constexpr tuple(tuple<_UElements...>&& __in) 703*38fd1498Szrj : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 704*38fd1498Szrj 705*38fd1498Szrj template<typename... _UElements, typename _Dummy = void, typename 706*38fd1498Szrj enable_if<_TMCT<_UElements...>::template 707*38fd1498Szrj _MoveConstructibleTuple<_UElements...>() 708*38fd1498Szrj && !_TMCT<_UElements...>::template 709*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_UElements...>() 710*38fd1498Szrj && _TNTC<_Dummy>::template 711*38fd1498Szrj _NonNestedTuple<tuple<_UElements...>&&>(), 712*38fd1498Szrj bool>::type=false> 713*38fd1498Szrj explicit constexpr tuple(tuple<_UElements...>&& __in) 714*38fd1498Szrj : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 715*38fd1498Szrj 716*38fd1498Szrj // Allocator-extended constructors. 717*38fd1498Szrj 718*38fd1498Szrj template<typename _Alloc> 719*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a) 720*38fd1498Szrj : _Inherited(__tag, __a) { } 721*38fd1498Szrj 722*38fd1498Szrj template<typename _Alloc, typename _Dummy = void, 723*38fd1498Szrj typename enable_if< 724*38fd1498Szrj _TCC<_Dummy>::template 725*38fd1498Szrj _ConstructibleTuple<_Elements...>() 726*38fd1498Szrj && _TCC<_Dummy>::template 727*38fd1498Szrj _ImplicitlyConvertibleTuple<_Elements...>(), 728*38fd1498Szrj bool>::type=true> 729*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, 730*38fd1498Szrj const _Elements&... __elements) 731*38fd1498Szrj : _Inherited(__tag, __a, __elements...) { } 732*38fd1498Szrj 733*38fd1498Szrj template<typename _Alloc, typename _Dummy = void, 734*38fd1498Szrj typename enable_if< 735*38fd1498Szrj _TCC<_Dummy>::template 736*38fd1498Szrj _ConstructibleTuple<_Elements...>() 737*38fd1498Szrj && !_TCC<_Dummy>::template 738*38fd1498Szrj _ImplicitlyConvertibleTuple<_Elements...>(), 739*38fd1498Szrj bool>::type=false> 740*38fd1498Szrj explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 741*38fd1498Szrj const _Elements&... __elements) 742*38fd1498Szrj : _Inherited(__tag, __a, __elements...) { } 743*38fd1498Szrj 744*38fd1498Szrj template<typename _Alloc, typename... _UElements, typename 745*38fd1498Szrj enable_if<_TMC<_UElements...>::template 746*38fd1498Szrj _MoveConstructibleTuple<_UElements...>() 747*38fd1498Szrj && _TMC<_UElements...>::template 748*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_UElements...>(), 749*38fd1498Szrj bool>::type=true> 750*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, 751*38fd1498Szrj _UElements&&... __elements) 752*38fd1498Szrj : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 753*38fd1498Szrj { } 754*38fd1498Szrj 755*38fd1498Szrj template<typename _Alloc, typename... _UElements, typename 756*38fd1498Szrj enable_if<_TMC<_UElements...>::template 757*38fd1498Szrj _MoveConstructibleTuple<_UElements...>() 758*38fd1498Szrj && !_TMC<_UElements...>::template 759*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_UElements...>(), 760*38fd1498Szrj bool>::type=false> 761*38fd1498Szrj explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 762*38fd1498Szrj _UElements&&... __elements) 763*38fd1498Szrj : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 764*38fd1498Szrj { } 765*38fd1498Szrj 766*38fd1498Szrj template<typename _Alloc> 767*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 768*38fd1498Szrj : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 769*38fd1498Szrj 770*38fd1498Szrj template<typename _Alloc> 771*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 772*38fd1498Szrj : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 773*38fd1498Szrj 774*38fd1498Szrj template<typename _Alloc, typename _Dummy = void, 775*38fd1498Szrj typename... _UElements, typename 776*38fd1498Szrj enable_if<_TMCT<_UElements...>::template 777*38fd1498Szrj _ConstructibleTuple<_UElements...>() 778*38fd1498Szrj && _TMCT<_UElements...>::template 779*38fd1498Szrj _ImplicitlyConvertibleTuple<_UElements...>() 780*38fd1498Szrj && _TNTC<_Dummy>::template 781*38fd1498Szrj _NonNestedTuple<tuple<_UElements...>&&>(), 782*38fd1498Szrj bool>::type=true> 783*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, 784*38fd1498Szrj const tuple<_UElements...>& __in) 785*38fd1498Szrj : _Inherited(__tag, __a, 786*38fd1498Szrj static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 787*38fd1498Szrj { } 788*38fd1498Szrj 789*38fd1498Szrj template<typename _Alloc, typename _Dummy = void, 790*38fd1498Szrj typename... _UElements, typename 791*38fd1498Szrj enable_if<_TMCT<_UElements...>::template 792*38fd1498Szrj _ConstructibleTuple<_UElements...>() 793*38fd1498Szrj && !_TMCT<_UElements...>::template 794*38fd1498Szrj _ImplicitlyConvertibleTuple<_UElements...>() 795*38fd1498Szrj && _TNTC<_Dummy>::template 796*38fd1498Szrj _NonNestedTuple<tuple<_UElements...>&&>(), 797*38fd1498Szrj bool>::type=false> 798*38fd1498Szrj explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 799*38fd1498Szrj const tuple<_UElements...>& __in) 800*38fd1498Szrj : _Inherited(__tag, __a, 801*38fd1498Szrj static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 802*38fd1498Szrj { } 803*38fd1498Szrj 804*38fd1498Szrj template<typename _Alloc, typename _Dummy = void, 805*38fd1498Szrj typename... _UElements, typename 806*38fd1498Szrj enable_if<_TMCT<_UElements...>::template 807*38fd1498Szrj _MoveConstructibleTuple<_UElements...>() 808*38fd1498Szrj && _TMCT<_UElements...>::template 809*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_UElements...>() 810*38fd1498Szrj && _TNTC<_Dummy>::template 811*38fd1498Szrj _NonNestedTuple<tuple<_UElements...>&&>(), 812*38fd1498Szrj bool>::type=true> 813*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, 814*38fd1498Szrj tuple<_UElements...>&& __in) 815*38fd1498Szrj : _Inherited(__tag, __a, 816*38fd1498Szrj static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 817*38fd1498Szrj { } 818*38fd1498Szrj 819*38fd1498Szrj template<typename _Alloc, typename _Dummy = void, 820*38fd1498Szrj typename... _UElements, typename 821*38fd1498Szrj enable_if<_TMCT<_UElements...>::template 822*38fd1498Szrj _MoveConstructibleTuple<_UElements...>() 823*38fd1498Szrj && !_TMCT<_UElements...>::template 824*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_UElements...>() 825*38fd1498Szrj && _TNTC<_Dummy>::template 826*38fd1498Szrj _NonNestedTuple<tuple<_UElements...>&&>(), 827*38fd1498Szrj bool>::type=false> 828*38fd1498Szrj explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 829*38fd1498Szrj tuple<_UElements...>&& __in) 830*38fd1498Szrj : _Inherited(__tag, __a, 831*38fd1498Szrj static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 832*38fd1498Szrj { } 833*38fd1498Szrj 834*38fd1498Szrj tuple& 835*38fd1498Szrj operator=(const tuple& __in) 836*38fd1498Szrj { 837*38fd1498Szrj static_cast<_Inherited&>(*this) = __in; 838*38fd1498Szrj return *this; 839*38fd1498Szrj } 840*38fd1498Szrj 841*38fd1498Szrj tuple& 842*38fd1498Szrj operator=(tuple&& __in) 843*38fd1498Szrj noexcept(is_nothrow_move_assignable<_Inherited>::value) 844*38fd1498Szrj { 845*38fd1498Szrj static_cast<_Inherited&>(*this) = std::move(__in); 846*38fd1498Szrj return *this; 847*38fd1498Szrj } 848*38fd1498Szrj 849*38fd1498Szrj template<typename... _UElements> 850*38fd1498Szrj typename 851*38fd1498Szrj enable_if<sizeof...(_UElements) 852*38fd1498Szrj == sizeof...(_Elements), tuple&>::type 853*38fd1498Szrj operator=(const tuple<_UElements...>& __in) 854*38fd1498Szrj { 855*38fd1498Szrj static_cast<_Inherited&>(*this) = __in; 856*38fd1498Szrj return *this; 857*38fd1498Szrj } 858*38fd1498Szrj 859*38fd1498Szrj template<typename... _UElements> 860*38fd1498Szrj typename 861*38fd1498Szrj enable_if<sizeof...(_UElements) 862*38fd1498Szrj == sizeof...(_Elements), tuple&>::type 863*38fd1498Szrj operator=(tuple<_UElements...>&& __in) 864*38fd1498Szrj { 865*38fd1498Szrj static_cast<_Inherited&>(*this) = std::move(__in); 866*38fd1498Szrj return *this; 867*38fd1498Szrj } 868*38fd1498Szrj 869*38fd1498Szrj void 870*38fd1498Szrj swap(tuple& __in) 871*38fd1498Szrj noexcept(noexcept(__in._M_swap(__in))) 872*38fd1498Szrj { _Inherited::_M_swap(__in); } 873*38fd1498Szrj }; 874*38fd1498Szrj 875*38fd1498Szrj#if __cpp_deduction_guides >= 201606 876*38fd1498Szrj template<typename... _UTypes> 877*38fd1498Szrj tuple(_UTypes...) -> tuple<_UTypes...>; 878*38fd1498Szrj template<typename _T1, typename _T2> 879*38fd1498Szrj tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>; 880*38fd1498Szrj template<typename _Alloc, typename... _UTypes> 881*38fd1498Szrj tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>; 882*38fd1498Szrj template<typename _Alloc, typename _T1, typename _T2> 883*38fd1498Szrj tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>; 884*38fd1498Szrj template<typename _Alloc, typename... _UTypes> 885*38fd1498Szrj tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>; 886*38fd1498Szrj#endif 887*38fd1498Szrj 888*38fd1498Szrj // Explicit specialization, zero-element tuple. 889*38fd1498Szrj template<> 890*38fd1498Szrj class tuple<> 891*38fd1498Szrj { 892*38fd1498Szrj public: 893*38fd1498Szrj void swap(tuple&) noexcept { /* no-op */ } 894*38fd1498Szrj // We need the default since we're going to define no-op 895*38fd1498Szrj // allocator constructors. 896*38fd1498Szrj tuple() = default; 897*38fd1498Szrj // No-op allocator constructors. 898*38fd1498Szrj template<typename _Alloc> 899*38fd1498Szrj tuple(allocator_arg_t, const _Alloc&) { } 900*38fd1498Szrj template<typename _Alloc> 901*38fd1498Szrj tuple(allocator_arg_t, const _Alloc&, const tuple&) { } 902*38fd1498Szrj }; 903*38fd1498Szrj 904*38fd1498Szrj /// Partial specialization, 2-element tuple. 905*38fd1498Szrj /// Includes construction and assignment from a pair. 906*38fd1498Szrj template<typename _T1, typename _T2> 907*38fd1498Szrj class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 908*38fd1498Szrj { 909*38fd1498Szrj typedef _Tuple_impl<0, _T1, _T2> _Inherited; 910*38fd1498Szrj 911*38fd1498Szrj public: 912*38fd1498Szrj template <typename _U1 = _T1, 913*38fd1498Szrj typename _U2 = _T2, 914*38fd1498Szrj typename enable_if<__and_< 915*38fd1498Szrj __is_implicitly_default_constructible<_U1>, 916*38fd1498Szrj __is_implicitly_default_constructible<_U2>> 917*38fd1498Szrj ::value, bool>::type = true> 918*38fd1498Szrj 919*38fd1498Szrj constexpr tuple() 920*38fd1498Szrj : _Inherited() { } 921*38fd1498Szrj 922*38fd1498Szrj template <typename _U1 = _T1, 923*38fd1498Szrj typename _U2 = _T2, 924*38fd1498Szrj typename enable_if< 925*38fd1498Szrj __and_< 926*38fd1498Szrj is_default_constructible<_U1>, 927*38fd1498Szrj is_default_constructible<_U2>, 928*38fd1498Szrj __not_< 929*38fd1498Szrj __and_<__is_implicitly_default_constructible<_U1>, 930*38fd1498Szrj __is_implicitly_default_constructible<_U2>>>> 931*38fd1498Szrj ::value, bool>::type = false> 932*38fd1498Szrj 933*38fd1498Szrj explicit constexpr tuple() 934*38fd1498Szrj : _Inherited() { } 935*38fd1498Szrj 936*38fd1498Szrj // Shortcut for the cases where constructors taking _T1, _T2 937*38fd1498Szrj // need to be constrained. 938*38fd1498Szrj template<typename _Dummy> using _TCC = 939*38fd1498Szrj _TC<is_same<_Dummy, void>::value, _T1, _T2>; 940*38fd1498Szrj 941*38fd1498Szrj template<typename _Dummy = void, typename 942*38fd1498Szrj enable_if<_TCC<_Dummy>::template 943*38fd1498Szrj _ConstructibleTuple<_T1, _T2>() 944*38fd1498Szrj && _TCC<_Dummy>::template 945*38fd1498Szrj _ImplicitlyConvertibleTuple<_T1, _T2>(), 946*38fd1498Szrj bool>::type = true> 947*38fd1498Szrj constexpr tuple(const _T1& __a1, const _T2& __a2) 948*38fd1498Szrj : _Inherited(__a1, __a2) { } 949*38fd1498Szrj 950*38fd1498Szrj template<typename _Dummy = void, typename 951*38fd1498Szrj enable_if<_TCC<_Dummy>::template 952*38fd1498Szrj _ConstructibleTuple<_T1, _T2>() 953*38fd1498Szrj && !_TCC<_Dummy>::template 954*38fd1498Szrj _ImplicitlyConvertibleTuple<_T1, _T2>(), 955*38fd1498Szrj bool>::type = false> 956*38fd1498Szrj explicit constexpr tuple(const _T1& __a1, const _T2& __a2) 957*38fd1498Szrj : _Inherited(__a1, __a2) { } 958*38fd1498Szrj 959*38fd1498Szrj // Shortcut for the cases where constructors taking _U1, _U2 960*38fd1498Szrj // need to be constrained. 961*38fd1498Szrj using _TMC = _TC<true, _T1, _T2>; 962*38fd1498Szrj 963*38fd1498Szrj template<typename _U1, typename _U2, typename 964*38fd1498Szrj enable_if<_TMC::template 965*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 966*38fd1498Szrj && _TMC::template 967*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>() 968*38fd1498Szrj && !is_same<typename decay<_U1>::type, 969*38fd1498Szrj allocator_arg_t>::value, 970*38fd1498Szrj bool>::type = true> 971*38fd1498Szrj constexpr tuple(_U1&& __a1, _U2&& __a2) 972*38fd1498Szrj : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 973*38fd1498Szrj 974*38fd1498Szrj template<typename _U1, typename _U2, typename 975*38fd1498Szrj enable_if<_TMC::template 976*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 977*38fd1498Szrj && !_TMC::template 978*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>() 979*38fd1498Szrj && !is_same<typename decay<_U1>::type, 980*38fd1498Szrj allocator_arg_t>::value, 981*38fd1498Szrj bool>::type = false> 982*38fd1498Szrj explicit constexpr tuple(_U1&& __a1, _U2&& __a2) 983*38fd1498Szrj : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 984*38fd1498Szrj 985*38fd1498Szrj constexpr tuple(const tuple&) = default; 986*38fd1498Szrj 987*38fd1498Szrj constexpr tuple(tuple&&) = default; 988*38fd1498Szrj 989*38fd1498Szrj template<typename _U1, typename _U2, typename 990*38fd1498Szrj enable_if<_TMC::template 991*38fd1498Szrj _ConstructibleTuple<_U1, _U2>() 992*38fd1498Szrj && _TMC::template 993*38fd1498Szrj _ImplicitlyConvertibleTuple<_U1, _U2>(), 994*38fd1498Szrj bool>::type = true> 995*38fd1498Szrj constexpr tuple(const tuple<_U1, _U2>& __in) 996*38fd1498Szrj : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 997*38fd1498Szrj 998*38fd1498Szrj template<typename _U1, typename _U2, typename 999*38fd1498Szrj enable_if<_TMC::template 1000*38fd1498Szrj _ConstructibleTuple<_U1, _U2>() 1001*38fd1498Szrj && !_TMC::template 1002*38fd1498Szrj _ImplicitlyConvertibleTuple<_U1, _U2>(), 1003*38fd1498Szrj bool>::type = false> 1004*38fd1498Szrj explicit constexpr tuple(const tuple<_U1, _U2>& __in) 1005*38fd1498Szrj : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 1006*38fd1498Szrj 1007*38fd1498Szrj template<typename _U1, typename _U2, typename 1008*38fd1498Szrj enable_if<_TMC::template 1009*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 1010*38fd1498Szrj && _TMC::template 1011*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 1012*38fd1498Szrj bool>::type = true> 1013*38fd1498Szrj constexpr tuple(tuple<_U1, _U2>&& __in) 1014*38fd1498Szrj : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 1015*38fd1498Szrj 1016*38fd1498Szrj template<typename _U1, typename _U2, typename 1017*38fd1498Szrj enable_if<_TMC::template 1018*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 1019*38fd1498Szrj && !_TMC::template 1020*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 1021*38fd1498Szrj bool>::type = false> 1022*38fd1498Szrj explicit constexpr tuple(tuple<_U1, _U2>&& __in) 1023*38fd1498Szrj : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 1024*38fd1498Szrj 1025*38fd1498Szrj template<typename _U1, typename _U2, typename 1026*38fd1498Szrj enable_if<_TMC::template 1027*38fd1498Szrj _ConstructibleTuple<_U1, _U2>() 1028*38fd1498Szrj && _TMC::template 1029*38fd1498Szrj _ImplicitlyConvertibleTuple<_U1, _U2>(), 1030*38fd1498Szrj bool>::type = true> 1031*38fd1498Szrj constexpr tuple(const pair<_U1, _U2>& __in) 1032*38fd1498Szrj : _Inherited(__in.first, __in.second) { } 1033*38fd1498Szrj 1034*38fd1498Szrj template<typename _U1, typename _U2, typename 1035*38fd1498Szrj enable_if<_TMC::template 1036*38fd1498Szrj _ConstructibleTuple<_U1, _U2>() 1037*38fd1498Szrj && !_TMC::template 1038*38fd1498Szrj _ImplicitlyConvertibleTuple<_U1, _U2>(), 1039*38fd1498Szrj bool>::type = false> 1040*38fd1498Szrj explicit constexpr tuple(const pair<_U1, _U2>& __in) 1041*38fd1498Szrj : _Inherited(__in.first, __in.second) { } 1042*38fd1498Szrj 1043*38fd1498Szrj template<typename _U1, typename _U2, typename 1044*38fd1498Szrj enable_if<_TMC::template 1045*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 1046*38fd1498Szrj && _TMC::template 1047*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 1048*38fd1498Szrj bool>::type = true> 1049*38fd1498Szrj constexpr tuple(pair<_U1, _U2>&& __in) 1050*38fd1498Szrj : _Inherited(std::forward<_U1>(__in.first), 1051*38fd1498Szrj std::forward<_U2>(__in.second)) { } 1052*38fd1498Szrj 1053*38fd1498Szrj template<typename _U1, typename _U2, typename 1054*38fd1498Szrj enable_if<_TMC::template 1055*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 1056*38fd1498Szrj && !_TMC::template 1057*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 1058*38fd1498Szrj bool>::type = false> 1059*38fd1498Szrj explicit constexpr tuple(pair<_U1, _U2>&& __in) 1060*38fd1498Szrj : _Inherited(std::forward<_U1>(__in.first), 1061*38fd1498Szrj std::forward<_U2>(__in.second)) { } 1062*38fd1498Szrj 1063*38fd1498Szrj // Allocator-extended constructors. 1064*38fd1498Szrj 1065*38fd1498Szrj template<typename _Alloc> 1066*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a) 1067*38fd1498Szrj : _Inherited(__tag, __a) { } 1068*38fd1498Szrj 1069*38fd1498Szrj template<typename _Alloc, typename _Dummy = void, 1070*38fd1498Szrj typename enable_if< 1071*38fd1498Szrj _TCC<_Dummy>::template 1072*38fd1498Szrj _ConstructibleTuple<_T1, _T2>() 1073*38fd1498Szrj && _TCC<_Dummy>::template 1074*38fd1498Szrj _ImplicitlyConvertibleTuple<_T1, _T2>(), 1075*38fd1498Szrj bool>::type=true> 1076*38fd1498Szrj 1077*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, 1078*38fd1498Szrj const _T1& __a1, const _T2& __a2) 1079*38fd1498Szrj : _Inherited(__tag, __a, __a1, __a2) { } 1080*38fd1498Szrj 1081*38fd1498Szrj template<typename _Alloc, typename _Dummy = void, 1082*38fd1498Szrj typename enable_if< 1083*38fd1498Szrj _TCC<_Dummy>::template 1084*38fd1498Szrj _ConstructibleTuple<_T1, _T2>() 1085*38fd1498Szrj && !_TCC<_Dummy>::template 1086*38fd1498Szrj _ImplicitlyConvertibleTuple<_T1, _T2>(), 1087*38fd1498Szrj bool>::type=false> 1088*38fd1498Szrj 1089*38fd1498Szrj explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 1090*38fd1498Szrj const _T1& __a1, const _T2& __a2) 1091*38fd1498Szrj : _Inherited(__tag, __a, __a1, __a2) { } 1092*38fd1498Szrj 1093*38fd1498Szrj template<typename _Alloc, typename _U1, typename _U2, typename 1094*38fd1498Szrj enable_if<_TMC::template 1095*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 1096*38fd1498Szrj && _TMC::template 1097*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 1098*38fd1498Szrj bool>::type = true> 1099*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 1100*38fd1498Szrj : _Inherited(__tag, __a, std::forward<_U1>(__a1), 1101*38fd1498Szrj std::forward<_U2>(__a2)) { } 1102*38fd1498Szrj 1103*38fd1498Szrj template<typename _Alloc, typename _U1, typename _U2, typename 1104*38fd1498Szrj enable_if<_TMC::template 1105*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 1106*38fd1498Szrj && !_TMC::template 1107*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 1108*38fd1498Szrj bool>::type = false> 1109*38fd1498Szrj explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 1110*38fd1498Szrj _U1&& __a1, _U2&& __a2) 1111*38fd1498Szrj : _Inherited(__tag, __a, std::forward<_U1>(__a1), 1112*38fd1498Szrj std::forward<_U2>(__a2)) { } 1113*38fd1498Szrj 1114*38fd1498Szrj template<typename _Alloc> 1115*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 1116*38fd1498Szrj : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 1117*38fd1498Szrj 1118*38fd1498Szrj template<typename _Alloc> 1119*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 1120*38fd1498Szrj : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 1121*38fd1498Szrj 1122*38fd1498Szrj template<typename _Alloc, typename _U1, typename _U2, typename 1123*38fd1498Szrj enable_if<_TMC::template 1124*38fd1498Szrj _ConstructibleTuple<_U1, _U2>() 1125*38fd1498Szrj && _TMC::template 1126*38fd1498Szrj _ImplicitlyConvertibleTuple<_U1, _U2>(), 1127*38fd1498Szrj bool>::type = true> 1128*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, 1129*38fd1498Szrj const tuple<_U1, _U2>& __in) 1130*38fd1498Szrj : _Inherited(__tag, __a, 1131*38fd1498Szrj static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 1132*38fd1498Szrj { } 1133*38fd1498Szrj 1134*38fd1498Szrj template<typename _Alloc, typename _U1, typename _U2, typename 1135*38fd1498Szrj enable_if<_TMC::template 1136*38fd1498Szrj _ConstructibleTuple<_U1, _U2>() 1137*38fd1498Szrj && !_TMC::template 1138*38fd1498Szrj _ImplicitlyConvertibleTuple<_U1, _U2>(), 1139*38fd1498Szrj bool>::type = false> 1140*38fd1498Szrj explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 1141*38fd1498Szrj const tuple<_U1, _U2>& __in) 1142*38fd1498Szrj : _Inherited(__tag, __a, 1143*38fd1498Szrj static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 1144*38fd1498Szrj { } 1145*38fd1498Szrj 1146*38fd1498Szrj template<typename _Alloc, typename _U1, typename _U2, typename 1147*38fd1498Szrj enable_if<_TMC::template 1148*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 1149*38fd1498Szrj && _TMC::template 1150*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 1151*38fd1498Szrj bool>::type = true> 1152*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 1153*38fd1498Szrj : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 1154*38fd1498Szrj { } 1155*38fd1498Szrj 1156*38fd1498Szrj template<typename _Alloc, typename _U1, typename _U2, typename 1157*38fd1498Szrj enable_if<_TMC::template 1158*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 1159*38fd1498Szrj && !_TMC::template 1160*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 1161*38fd1498Szrj bool>::type = false> 1162*38fd1498Szrj explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 1163*38fd1498Szrj tuple<_U1, _U2>&& __in) 1164*38fd1498Szrj : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 1165*38fd1498Szrj { } 1166*38fd1498Szrj 1167*38fd1498Szrj template<typename _Alloc, typename _U1, typename _U2, typename 1168*38fd1498Szrj enable_if<_TMC::template 1169*38fd1498Szrj _ConstructibleTuple<_U1, _U2>() 1170*38fd1498Szrj && _TMC::template 1171*38fd1498Szrj _ImplicitlyConvertibleTuple<_U1, _U2>(), 1172*38fd1498Szrj bool>::type = true> 1173*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, 1174*38fd1498Szrj const pair<_U1, _U2>& __in) 1175*38fd1498Szrj : _Inherited(__tag, __a, __in.first, __in.second) { } 1176*38fd1498Szrj 1177*38fd1498Szrj template<typename _Alloc, typename _U1, typename _U2, typename 1178*38fd1498Szrj enable_if<_TMC::template 1179*38fd1498Szrj _ConstructibleTuple<_U1, _U2>() 1180*38fd1498Szrj && !_TMC::template 1181*38fd1498Szrj _ImplicitlyConvertibleTuple<_U1, _U2>(), 1182*38fd1498Szrj bool>::type = false> 1183*38fd1498Szrj explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 1184*38fd1498Szrj const pair<_U1, _U2>& __in) 1185*38fd1498Szrj : _Inherited(__tag, __a, __in.first, __in.second) { } 1186*38fd1498Szrj 1187*38fd1498Szrj template<typename _Alloc, typename _U1, typename _U2, typename 1188*38fd1498Szrj enable_if<_TMC::template 1189*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 1190*38fd1498Szrj && _TMC::template 1191*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 1192*38fd1498Szrj bool>::type = true> 1193*38fd1498Szrj tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 1194*38fd1498Szrj : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 1195*38fd1498Szrj std::forward<_U2>(__in.second)) { } 1196*38fd1498Szrj 1197*38fd1498Szrj template<typename _Alloc, typename _U1, typename _U2, typename 1198*38fd1498Szrj enable_if<_TMC::template 1199*38fd1498Szrj _MoveConstructibleTuple<_U1, _U2>() 1200*38fd1498Szrj && !_TMC::template 1201*38fd1498Szrj _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 1202*38fd1498Szrj bool>::type = false> 1203*38fd1498Szrj explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 1204*38fd1498Szrj pair<_U1, _U2>&& __in) 1205*38fd1498Szrj : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 1206*38fd1498Szrj std::forward<_U2>(__in.second)) { } 1207*38fd1498Szrj 1208*38fd1498Szrj tuple& 1209*38fd1498Szrj operator=(const tuple& __in) 1210*38fd1498Szrj { 1211*38fd1498Szrj static_cast<_Inherited&>(*this) = __in; 1212*38fd1498Szrj return *this; 1213*38fd1498Szrj } 1214*38fd1498Szrj 1215*38fd1498Szrj tuple& 1216*38fd1498Szrj operator=(tuple&& __in) 1217*38fd1498Szrj noexcept(is_nothrow_move_assignable<_Inherited>::value) 1218*38fd1498Szrj { 1219*38fd1498Szrj static_cast<_Inherited&>(*this) = std::move(__in); 1220*38fd1498Szrj return *this; 1221*38fd1498Szrj } 1222*38fd1498Szrj 1223*38fd1498Szrj template<typename _U1, typename _U2> 1224*38fd1498Szrj tuple& 1225*38fd1498Szrj operator=(const tuple<_U1, _U2>& __in) 1226*38fd1498Szrj { 1227*38fd1498Szrj static_cast<_Inherited&>(*this) = __in; 1228*38fd1498Szrj return *this; 1229*38fd1498Szrj } 1230*38fd1498Szrj 1231*38fd1498Szrj template<typename _U1, typename _U2> 1232*38fd1498Szrj tuple& 1233*38fd1498Szrj operator=(tuple<_U1, _U2>&& __in) 1234*38fd1498Szrj { 1235*38fd1498Szrj static_cast<_Inherited&>(*this) = std::move(__in); 1236*38fd1498Szrj return *this; 1237*38fd1498Szrj } 1238*38fd1498Szrj 1239*38fd1498Szrj template<typename _U1, typename _U2> 1240*38fd1498Szrj tuple& 1241*38fd1498Szrj operator=(const pair<_U1, _U2>& __in) 1242*38fd1498Szrj { 1243*38fd1498Szrj this->_M_head(*this) = __in.first; 1244*38fd1498Szrj this->_M_tail(*this)._M_head(*this) = __in.second; 1245*38fd1498Szrj return *this; 1246*38fd1498Szrj } 1247*38fd1498Szrj 1248*38fd1498Szrj template<typename _U1, typename _U2> 1249*38fd1498Szrj tuple& 1250*38fd1498Szrj operator=(pair<_U1, _U2>&& __in) 1251*38fd1498Szrj { 1252*38fd1498Szrj this->_M_head(*this) = std::forward<_U1>(__in.first); 1253*38fd1498Szrj this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 1254*38fd1498Szrj return *this; 1255*38fd1498Szrj } 1256*38fd1498Szrj 1257*38fd1498Szrj void 1258*38fd1498Szrj swap(tuple& __in) 1259*38fd1498Szrj noexcept(noexcept(__in._M_swap(__in))) 1260*38fd1498Szrj { _Inherited::_M_swap(__in); } 1261*38fd1498Szrj }; 1262*38fd1498Szrj 1263*38fd1498Szrj 1264*38fd1498Szrj /// class tuple_size 1265*38fd1498Szrj template<typename... _Elements> 1266*38fd1498Szrj struct tuple_size<tuple<_Elements...>> 1267*38fd1498Szrj : public integral_constant<std::size_t, sizeof...(_Elements)> { }; 1268*38fd1498Szrj 1269*38fd1498Szrj#if __cplusplus > 201402L 1270*38fd1498Szrj template <typename _Tp> 1271*38fd1498Szrj inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; 1272*38fd1498Szrj#endif 1273*38fd1498Szrj 1274*38fd1498Szrj /** 1275*38fd1498Szrj * Recursive case for tuple_element: strip off the first element in 1276*38fd1498Szrj * the tuple and retrieve the (i-1)th element of the remaining tuple. 1277*38fd1498Szrj */ 1278*38fd1498Szrj template<std::size_t __i, typename _Head, typename... _Tail> 1279*38fd1498Szrj struct tuple_element<__i, tuple<_Head, _Tail...> > 1280*38fd1498Szrj : tuple_element<__i - 1, tuple<_Tail...> > { }; 1281*38fd1498Szrj 1282*38fd1498Szrj /** 1283*38fd1498Szrj * Basis case for tuple_element: The first element is the one we're seeking. 1284*38fd1498Szrj */ 1285*38fd1498Szrj template<typename _Head, typename... _Tail> 1286*38fd1498Szrj struct tuple_element<0, tuple<_Head, _Tail...> > 1287*38fd1498Szrj { 1288*38fd1498Szrj typedef _Head type; 1289*38fd1498Szrj }; 1290*38fd1498Szrj 1291*38fd1498Szrj /** 1292*38fd1498Szrj * Error case for tuple_element: invalid index. 1293*38fd1498Szrj */ 1294*38fd1498Szrj template<size_t __i> 1295*38fd1498Szrj struct tuple_element<__i, tuple<>> 1296*38fd1498Szrj { 1297*38fd1498Szrj static_assert(__i < tuple_size<tuple<>>::value, 1298*38fd1498Szrj "tuple index is in range"); 1299*38fd1498Szrj }; 1300*38fd1498Szrj 1301*38fd1498Szrj template<std::size_t __i, typename _Head, typename... _Tail> 1302*38fd1498Szrj constexpr _Head& 1303*38fd1498Szrj __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 1304*38fd1498Szrj { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 1305*38fd1498Szrj 1306*38fd1498Szrj template<std::size_t __i, typename _Head, typename... _Tail> 1307*38fd1498Szrj constexpr const _Head& 1308*38fd1498Szrj __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 1309*38fd1498Szrj { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 1310*38fd1498Szrj 1311*38fd1498Szrj /// Return a reference to the ith element of a tuple. 1312*38fd1498Szrj template<std::size_t __i, typename... _Elements> 1313*38fd1498Szrj constexpr __tuple_element_t<__i, tuple<_Elements...>>& 1314*38fd1498Szrj get(tuple<_Elements...>& __t) noexcept 1315*38fd1498Szrj { return std::__get_helper<__i>(__t); } 1316*38fd1498Szrj 1317*38fd1498Szrj /// Return a const reference to the ith element of a const tuple. 1318*38fd1498Szrj template<std::size_t __i, typename... _Elements> 1319*38fd1498Szrj constexpr const __tuple_element_t<__i, tuple<_Elements...>>& 1320*38fd1498Szrj get(const tuple<_Elements...>& __t) noexcept 1321*38fd1498Szrj { return std::__get_helper<__i>(__t); } 1322*38fd1498Szrj 1323*38fd1498Szrj /// Return an rvalue reference to the ith element of a tuple rvalue. 1324*38fd1498Szrj template<std::size_t __i, typename... _Elements> 1325*38fd1498Szrj constexpr __tuple_element_t<__i, tuple<_Elements...>>&& 1326*38fd1498Szrj get(tuple<_Elements...>&& __t) noexcept 1327*38fd1498Szrj { 1328*38fd1498Szrj typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 1329*38fd1498Szrj return std::forward<__element_type&&>(std::get<__i>(__t)); 1330*38fd1498Szrj } 1331*38fd1498Szrj 1332*38fd1498Szrj /// Return a const rvalue reference to the ith element of a const tuple rvalue. 1333*38fd1498Szrj template<std::size_t __i, typename... _Elements> 1334*38fd1498Szrj constexpr const __tuple_element_t<__i, tuple<_Elements...>>&& 1335*38fd1498Szrj get(const tuple<_Elements...>&& __t) noexcept 1336*38fd1498Szrj { 1337*38fd1498Szrj typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 1338*38fd1498Szrj return std::forward<const __element_type&&>(std::get<__i>(__t)); 1339*38fd1498Szrj } 1340*38fd1498Szrj 1341*38fd1498Szrj#if __cplusplus > 201103L 1342*38fd1498Szrj 1343*38fd1498Szrj#define __cpp_lib_tuples_by_type 201304 1344*38fd1498Szrj 1345*38fd1498Szrj template<typename _Head, size_t __i, typename... _Tail> 1346*38fd1498Szrj constexpr _Head& 1347*38fd1498Szrj __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 1348*38fd1498Szrj { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 1349*38fd1498Szrj 1350*38fd1498Szrj template<typename _Head, size_t __i, typename... _Tail> 1351*38fd1498Szrj constexpr const _Head& 1352*38fd1498Szrj __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 1353*38fd1498Szrj { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 1354*38fd1498Szrj 1355*38fd1498Szrj /// Return a reference to the unique element of type _Tp of a tuple. 1356*38fd1498Szrj template <typename _Tp, typename... _Types> 1357*38fd1498Szrj constexpr _Tp& 1358*38fd1498Szrj get(tuple<_Types...>& __t) noexcept 1359*38fd1498Szrj { return std::__get_helper2<_Tp>(__t); } 1360*38fd1498Szrj 1361*38fd1498Szrj /// Return a reference to the unique element of type _Tp of a tuple rvalue. 1362*38fd1498Szrj template <typename _Tp, typename... _Types> 1363*38fd1498Szrj constexpr _Tp&& 1364*38fd1498Szrj get(tuple<_Types...>&& __t) noexcept 1365*38fd1498Szrj { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } 1366*38fd1498Szrj 1367*38fd1498Szrj /// Return a const reference to the unique element of type _Tp of a tuple. 1368*38fd1498Szrj template <typename _Tp, typename... _Types> 1369*38fd1498Szrj constexpr const _Tp& 1370*38fd1498Szrj get(const tuple<_Types...>& __t) noexcept 1371*38fd1498Szrj { return std::__get_helper2<_Tp>(__t); } 1372*38fd1498Szrj 1373*38fd1498Szrj /// Return a const reference to the unique element of type _Tp of 1374*38fd1498Szrj /// a const tuple rvalue. 1375*38fd1498Szrj template <typename _Tp, typename... _Types> 1376*38fd1498Szrj constexpr const _Tp&& 1377*38fd1498Szrj get(const tuple<_Types...>&& __t) noexcept 1378*38fd1498Szrj { return std::forward<const _Tp&&>(std::__get_helper2<_Tp>(__t)); } 1379*38fd1498Szrj#endif 1380*38fd1498Szrj 1381*38fd1498Szrj // This class performs the comparison operations on tuples 1382*38fd1498Szrj template<typename _Tp, typename _Up, size_t __i, size_t __size> 1383*38fd1498Szrj struct __tuple_compare 1384*38fd1498Szrj { 1385*38fd1498Szrj static constexpr bool 1386*38fd1498Szrj __eq(const _Tp& __t, const _Up& __u) 1387*38fd1498Szrj { 1388*38fd1498Szrj return bool(std::get<__i>(__t) == std::get<__i>(__u)) 1389*38fd1498Szrj && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); 1390*38fd1498Szrj } 1391*38fd1498Szrj 1392*38fd1498Szrj static constexpr bool 1393*38fd1498Szrj __less(const _Tp& __t, const _Up& __u) 1394*38fd1498Szrj { 1395*38fd1498Szrj return bool(std::get<__i>(__t) < std::get<__i>(__u)) 1396*38fd1498Szrj || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) 1397*38fd1498Szrj && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); 1398*38fd1498Szrj } 1399*38fd1498Szrj }; 1400*38fd1498Szrj 1401*38fd1498Szrj template<typename _Tp, typename _Up, size_t __size> 1402*38fd1498Szrj struct __tuple_compare<_Tp, _Up, __size, __size> 1403*38fd1498Szrj { 1404*38fd1498Szrj static constexpr bool 1405*38fd1498Szrj __eq(const _Tp&, const _Up&) { return true; } 1406*38fd1498Szrj 1407*38fd1498Szrj static constexpr bool 1408*38fd1498Szrj __less(const _Tp&, const _Up&) { return false; } 1409*38fd1498Szrj }; 1410*38fd1498Szrj 1411*38fd1498Szrj template<typename... _TElements, typename... _UElements> 1412*38fd1498Szrj constexpr bool 1413*38fd1498Szrj operator==(const tuple<_TElements...>& __t, 1414*38fd1498Szrj const tuple<_UElements...>& __u) 1415*38fd1498Szrj { 1416*38fd1498Szrj static_assert(sizeof...(_TElements) == sizeof...(_UElements), 1417*38fd1498Szrj "tuple objects can only be compared if they have equal sizes."); 1418*38fd1498Szrj using __compare = __tuple_compare<tuple<_TElements...>, 1419*38fd1498Szrj tuple<_UElements...>, 1420*38fd1498Szrj 0, sizeof...(_TElements)>; 1421*38fd1498Szrj return __compare::__eq(__t, __u); 1422*38fd1498Szrj } 1423*38fd1498Szrj 1424*38fd1498Szrj template<typename... _TElements, typename... _UElements> 1425*38fd1498Szrj constexpr bool 1426*38fd1498Szrj operator<(const tuple<_TElements...>& __t, 1427*38fd1498Szrj const tuple<_UElements...>& __u) 1428*38fd1498Szrj { 1429*38fd1498Szrj static_assert(sizeof...(_TElements) == sizeof...(_UElements), 1430*38fd1498Szrj "tuple objects can only be compared if they have equal sizes."); 1431*38fd1498Szrj using __compare = __tuple_compare<tuple<_TElements...>, 1432*38fd1498Szrj tuple<_UElements...>, 1433*38fd1498Szrj 0, sizeof...(_TElements)>; 1434*38fd1498Szrj return __compare::__less(__t, __u); 1435*38fd1498Szrj } 1436*38fd1498Szrj 1437*38fd1498Szrj template<typename... _TElements, typename... _UElements> 1438*38fd1498Szrj constexpr bool 1439*38fd1498Szrj operator!=(const tuple<_TElements...>& __t, 1440*38fd1498Szrj const tuple<_UElements...>& __u) 1441*38fd1498Szrj { return !(__t == __u); } 1442*38fd1498Szrj 1443*38fd1498Szrj template<typename... _TElements, typename... _UElements> 1444*38fd1498Szrj constexpr bool 1445*38fd1498Szrj operator>(const tuple<_TElements...>& __t, 1446*38fd1498Szrj const tuple<_UElements...>& __u) 1447*38fd1498Szrj { return __u < __t; } 1448*38fd1498Szrj 1449*38fd1498Szrj template<typename... _TElements, typename... _UElements> 1450*38fd1498Szrj constexpr bool 1451*38fd1498Szrj operator<=(const tuple<_TElements...>& __t, 1452*38fd1498Szrj const tuple<_UElements...>& __u) 1453*38fd1498Szrj { return !(__u < __t); } 1454*38fd1498Szrj 1455*38fd1498Szrj template<typename... _TElements, typename... _UElements> 1456*38fd1498Szrj constexpr bool 1457*38fd1498Szrj operator>=(const tuple<_TElements...>& __t, 1458*38fd1498Szrj const tuple<_UElements...>& __u) 1459*38fd1498Szrj { return !(__t < __u); } 1460*38fd1498Szrj 1461*38fd1498Szrj // NB: DR 705. 1462*38fd1498Szrj template<typename... _Elements> 1463*38fd1498Szrj constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 1464*38fd1498Szrj make_tuple(_Elements&&... __args) 1465*38fd1498Szrj { 1466*38fd1498Szrj typedef tuple<typename __decay_and_strip<_Elements>::__type...> 1467*38fd1498Szrj __result_type; 1468*38fd1498Szrj return __result_type(std::forward<_Elements>(__args)...); 1469*38fd1498Szrj } 1470*38fd1498Szrj 1471*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 1472*38fd1498Szrj // 2275. Why is forward_as_tuple not constexpr? 1473*38fd1498Szrj template<typename... _Elements> 1474*38fd1498Szrj constexpr tuple<_Elements&&...> 1475*38fd1498Szrj forward_as_tuple(_Elements&&... __args) noexcept 1476*38fd1498Szrj { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 1477*38fd1498Szrj 1478*38fd1498Szrj template<size_t, typename, typename, size_t> 1479*38fd1498Szrj struct __make_tuple_impl; 1480*38fd1498Szrj 1481*38fd1498Szrj template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> 1482*38fd1498Szrj struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 1483*38fd1498Szrj : __make_tuple_impl<_Idx + 1, 1484*38fd1498Szrj tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, 1485*38fd1498Szrj _Tuple, _Nm> 1486*38fd1498Szrj { }; 1487*38fd1498Szrj 1488*38fd1498Szrj template<std::size_t _Nm, typename _Tuple, typename... _Tp> 1489*38fd1498Szrj struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 1490*38fd1498Szrj { 1491*38fd1498Szrj typedef tuple<_Tp...> __type; 1492*38fd1498Szrj }; 1493*38fd1498Szrj 1494*38fd1498Szrj template<typename _Tuple> 1495*38fd1498Szrj struct __do_make_tuple 1496*38fd1498Szrj : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value> 1497*38fd1498Szrj { }; 1498*38fd1498Szrj 1499*38fd1498Szrj // Returns the std::tuple equivalent of a tuple-like type. 1500*38fd1498Szrj template<typename _Tuple> 1501*38fd1498Szrj struct __make_tuple 1502*38fd1498Szrj : public __do_make_tuple<typename std::remove_cv 1503*38fd1498Szrj <typename std::remove_reference<_Tuple>::type>::type> 1504*38fd1498Szrj { }; 1505*38fd1498Szrj 1506*38fd1498Szrj // Combines several std::tuple's into a single one. 1507*38fd1498Szrj template<typename...> 1508*38fd1498Szrj struct __combine_tuples; 1509*38fd1498Szrj 1510*38fd1498Szrj template<> 1511*38fd1498Szrj struct __combine_tuples<> 1512*38fd1498Szrj { 1513*38fd1498Szrj typedef tuple<> __type; 1514*38fd1498Szrj }; 1515*38fd1498Szrj 1516*38fd1498Szrj template<typename... _Ts> 1517*38fd1498Szrj struct __combine_tuples<tuple<_Ts...>> 1518*38fd1498Szrj { 1519*38fd1498Szrj typedef tuple<_Ts...> __type; 1520*38fd1498Szrj }; 1521*38fd1498Szrj 1522*38fd1498Szrj template<typename... _T1s, typename... _T2s, typename... _Rem> 1523*38fd1498Szrj struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 1524*38fd1498Szrj { 1525*38fd1498Szrj typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 1526*38fd1498Szrj _Rem...>::__type __type; 1527*38fd1498Szrj }; 1528*38fd1498Szrj 1529*38fd1498Szrj // Computes the result type of tuple_cat given a set of tuple-like types. 1530*38fd1498Szrj template<typename... _Tpls> 1531*38fd1498Szrj struct __tuple_cat_result 1532*38fd1498Szrj { 1533*38fd1498Szrj typedef typename __combine_tuples 1534*38fd1498Szrj <typename __make_tuple<_Tpls>::__type...>::__type __type; 1535*38fd1498Szrj }; 1536*38fd1498Szrj 1537*38fd1498Szrj // Helper to determine the index set for the first tuple-like 1538*38fd1498Szrj // type of a given set. 1539*38fd1498Szrj template<typename...> 1540*38fd1498Szrj struct __make_1st_indices; 1541*38fd1498Szrj 1542*38fd1498Szrj template<> 1543*38fd1498Szrj struct __make_1st_indices<> 1544*38fd1498Szrj { 1545*38fd1498Szrj typedef std::_Index_tuple<> __type; 1546*38fd1498Szrj }; 1547*38fd1498Szrj 1548*38fd1498Szrj template<typename _Tp, typename... _Tpls> 1549*38fd1498Szrj struct __make_1st_indices<_Tp, _Tpls...> 1550*38fd1498Szrj { 1551*38fd1498Szrj typedef typename std::_Build_index_tuple<std::tuple_size< 1552*38fd1498Szrj typename std::remove_reference<_Tp>::type>::value>::__type __type; 1553*38fd1498Szrj }; 1554*38fd1498Szrj 1555*38fd1498Szrj // Performs the actual concatenation by step-wise expanding tuple-like 1556*38fd1498Szrj // objects into the elements, which are finally forwarded into the 1557*38fd1498Szrj // result tuple. 1558*38fd1498Szrj template<typename _Ret, typename _Indices, typename... _Tpls> 1559*38fd1498Szrj struct __tuple_concater; 1560*38fd1498Szrj 1561*38fd1498Szrj template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> 1562*38fd1498Szrj struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> 1563*38fd1498Szrj { 1564*38fd1498Szrj template<typename... _Us> 1565*38fd1498Szrj static constexpr _Ret 1566*38fd1498Szrj _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 1567*38fd1498Szrj { 1568*38fd1498Szrj typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1569*38fd1498Szrj typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 1570*38fd1498Szrj return __next::_S_do(std::forward<_Tpls>(__tps)..., 1571*38fd1498Szrj std::forward<_Us>(__us)..., 1572*38fd1498Szrj std::get<_Is>(std::forward<_Tp>(__tp))...); 1573*38fd1498Szrj } 1574*38fd1498Szrj }; 1575*38fd1498Szrj 1576*38fd1498Szrj template<typename _Ret> 1577*38fd1498Szrj struct __tuple_concater<_Ret, std::_Index_tuple<>> 1578*38fd1498Szrj { 1579*38fd1498Szrj template<typename... _Us> 1580*38fd1498Szrj static constexpr _Ret 1581*38fd1498Szrj _S_do(_Us&&... __us) 1582*38fd1498Szrj { 1583*38fd1498Szrj return _Ret(std::forward<_Us>(__us)...); 1584*38fd1498Szrj } 1585*38fd1498Szrj }; 1586*38fd1498Szrj 1587*38fd1498Szrj /// tuple_cat 1588*38fd1498Szrj template<typename... _Tpls, typename = typename 1589*38fd1498Szrj enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 1590*38fd1498Szrj constexpr auto 1591*38fd1498Szrj tuple_cat(_Tpls&&... __tpls) 1592*38fd1498Szrj -> typename __tuple_cat_result<_Tpls...>::__type 1593*38fd1498Szrj { 1594*38fd1498Szrj typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 1595*38fd1498Szrj typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1596*38fd1498Szrj typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 1597*38fd1498Szrj return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 1598*38fd1498Szrj } 1599*38fd1498Szrj 1600*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 1601*38fd1498Szrj // 2301. Why is tie not constexpr? 1602*38fd1498Szrj /// tie 1603*38fd1498Szrj template<typename... _Elements> 1604*38fd1498Szrj constexpr tuple<_Elements&...> 1605*38fd1498Szrj tie(_Elements&... __args) noexcept 1606*38fd1498Szrj { return tuple<_Elements&...>(__args...); } 1607*38fd1498Szrj 1608*38fd1498Szrj /// swap 1609*38fd1498Szrj template<typename... _Elements> 1610*38fd1498Szrj inline 1611*38fd1498Szrj#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 1612*38fd1498Szrj // Constrained free swap overload, see p0185r1 1613*38fd1498Szrj typename enable_if<__and_<__is_swappable<_Elements>...>::value 1614*38fd1498Szrj >::type 1615*38fd1498Szrj#else 1616*38fd1498Szrj void 1617*38fd1498Szrj#endif 1618*38fd1498Szrj swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 1619*38fd1498Szrj noexcept(noexcept(__x.swap(__y))) 1620*38fd1498Szrj { __x.swap(__y); } 1621*38fd1498Szrj 1622*38fd1498Szrj#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 1623*38fd1498Szrj template<typename... _Elements> 1624*38fd1498Szrj typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type 1625*38fd1498Szrj swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete; 1626*38fd1498Szrj#endif 1627*38fd1498Szrj 1628*38fd1498Szrj // A class (and instance) which can be used in 'tie' when an element 1629*38fd1498Szrj // of a tuple is not required. 1630*38fd1498Szrj // _GLIBCXX14_CONSTEXPR 1631*38fd1498Szrj // 2933. PR for LWG 2773 could be clearer 1632*38fd1498Szrj struct _Swallow_assign 1633*38fd1498Szrj { 1634*38fd1498Szrj template<class _Tp> 1635*38fd1498Szrj _GLIBCXX14_CONSTEXPR const _Swallow_assign& 1636*38fd1498Szrj operator=(const _Tp&) const 1637*38fd1498Szrj { return *this; } 1638*38fd1498Szrj }; 1639*38fd1498Szrj 1640*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 1641*38fd1498Szrj // 2773. Making std::ignore constexpr 1642*38fd1498Szrj _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{}; 1643*38fd1498Szrj 1644*38fd1498Szrj /// Partial specialization for tuples 1645*38fd1498Szrj template<typename... _Types, typename _Alloc> 1646*38fd1498Szrj struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 1647*38fd1498Szrj 1648*38fd1498Szrj // See stl_pair.h... 1649*38fd1498Szrj template<class _T1, class _T2> 1650*38fd1498Szrj template<typename... _Args1, typename... _Args2> 1651*38fd1498Szrj inline 1652*38fd1498Szrj pair<_T1, _T2>:: 1653*38fd1498Szrj pair(piecewise_construct_t, 1654*38fd1498Szrj tuple<_Args1...> __first, tuple<_Args2...> __second) 1655*38fd1498Szrj : pair(__first, __second, 1656*38fd1498Szrj typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 1657*38fd1498Szrj typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 1658*38fd1498Szrj { } 1659*38fd1498Szrj 1660*38fd1498Szrj template<class _T1, class _T2> 1661*38fd1498Szrj template<typename... _Args1, std::size_t... _Indexes1, 1662*38fd1498Szrj typename... _Args2, std::size_t... _Indexes2> 1663*38fd1498Szrj inline 1664*38fd1498Szrj pair<_T1, _T2>:: 1665*38fd1498Szrj pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 1666*38fd1498Szrj _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 1667*38fd1498Szrj : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 1668*38fd1498Szrj second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 1669*38fd1498Szrj { } 1670*38fd1498Szrj 1671*38fd1498Szrj#if __cplusplus > 201402L 1672*38fd1498Szrj# define __cpp_lib_apply 201603 1673*38fd1498Szrj 1674*38fd1498Szrj template <typename _Fn, typename _Tuple, size_t... _Idx> 1675*38fd1498Szrj constexpr decltype(auto) 1676*38fd1498Szrj __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>) 1677*38fd1498Szrj { 1678*38fd1498Szrj return std::__invoke(std::forward<_Fn>(__f), 1679*38fd1498Szrj std::get<_Idx>(std::forward<_Tuple>(__t))...); 1680*38fd1498Szrj } 1681*38fd1498Szrj 1682*38fd1498Szrj template <typename _Fn, typename _Tuple> 1683*38fd1498Szrj constexpr decltype(auto) 1684*38fd1498Szrj apply(_Fn&& __f, _Tuple&& __t) 1685*38fd1498Szrj { 1686*38fd1498Szrj using _Indices = make_index_sequence<tuple_size_v<decay_t<_Tuple>>>; 1687*38fd1498Szrj return std::__apply_impl(std::forward<_Fn>(__f), 1688*38fd1498Szrj std::forward<_Tuple>(__t), 1689*38fd1498Szrj _Indices{}); 1690*38fd1498Szrj } 1691*38fd1498Szrj 1692*38fd1498Szrj#define __cpp_lib_make_from_tuple 201606 1693*38fd1498Szrj 1694*38fd1498Szrj template <typename _Tp, typename _Tuple, size_t... _Idx> 1695*38fd1498Szrj constexpr _Tp 1696*38fd1498Szrj __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>) 1697*38fd1498Szrj { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); } 1698*38fd1498Szrj 1699*38fd1498Szrj template <typename _Tp, typename _Tuple> 1700*38fd1498Szrj constexpr _Tp 1701*38fd1498Szrj make_from_tuple(_Tuple&& __t) 1702*38fd1498Szrj { 1703*38fd1498Szrj return __make_from_tuple_impl<_Tp>( 1704*38fd1498Szrj std::forward<_Tuple>(__t), 1705*38fd1498Szrj make_index_sequence<tuple_size_v<decay_t<_Tuple>>>{}); 1706*38fd1498Szrj } 1707*38fd1498Szrj#endif // C++17 1708*38fd1498Szrj 1709*38fd1498Szrj /// @} 1710*38fd1498Szrj 1711*38fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION 1712*38fd1498Szrj} // namespace std 1713*38fd1498Szrj 1714*38fd1498Szrj#endif // C++11 1715*38fd1498Szrj 1716*38fd1498Szrj#endif // _GLIBCXX_TUPLE 1717