14fee23f9Smrg// <tuple> -*- C++ -*- 24fee23f9Smrg 3b1e83836Smrg// Copyright (C) 2007-2022 Free Software Foundation, Inc. 44fee23f9Smrg// 54fee23f9Smrg// This file is part of the GNU ISO C++ Library. This library is free 64fee23f9Smrg// software; you can redistribute it and/or modify it under the 74fee23f9Smrg// terms of the GNU General Public License as published by the 84fee23f9Smrg// Free Software Foundation; either version 3, or (at your option) 94fee23f9Smrg// any later version. 104fee23f9Smrg 114fee23f9Smrg// This library is distributed in the hope that it will be useful, 124fee23f9Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 134fee23f9Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144fee23f9Smrg// GNU General Public License for more details. 154fee23f9Smrg 164fee23f9Smrg// Under Section 7 of GPL version 3, you are granted additional 174fee23f9Smrg// permissions described in the GCC Runtime Library Exception, version 184fee23f9Smrg// 3.1, as published by the Free Software Foundation. 194fee23f9Smrg 204fee23f9Smrg// You should have received a copy of the GNU General Public License and 214fee23f9Smrg// a copy of the GCC Runtime Library Exception along with this program; 224fee23f9Smrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 234fee23f9Smrg// <http://www.gnu.org/licenses/>. 244fee23f9Smrg 254fee23f9Smrg/** @file include/tuple 264fee23f9Smrg * This is a Standard C++ Library header. 274fee23f9Smrg */ 284fee23f9Smrg 294fee23f9Smrg#ifndef _GLIBCXX_TUPLE 304fee23f9Smrg#define _GLIBCXX_TUPLE 1 314fee23f9Smrg 324fee23f9Smrg#pragma GCC system_header 334fee23f9Smrg 3448fb7bfaSmrg#if __cplusplus < 201103L 354fee23f9Smrg# include <bits/c++0x_warning.h> 364fee23f9Smrg#else 374fee23f9Smrg 38b1e83836Smrg#include <bits/stl_pair.h> // for std::pair 39b1e83836Smrg#include <bits/uses_allocator.h> // for std::allocator_arg_t 40b1e83836Smrg#include <bits/utility.h> // for std::get, std::tuple_size etc. 41b1e83836Smrg#include <bits/invoke.h> // for std::__invoke 42fb8a8121Smrg#if __cplusplus > 201703L 43fb8a8121Smrg# include <compare> 44fb8a8121Smrg# define __cpp_lib_constexpr_tuple 201811L 45fb8a8121Smrg#endif 464fee23f9Smrg 4748fb7bfaSmrgnamespace std _GLIBCXX_VISIBILITY(default) 484fee23f9Smrg{ 4948fb7bfaSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 5048fb7bfaSmrg 5148fb7bfaSmrg /** 5248fb7bfaSmrg * @addtogroup utilities 5348fb7bfaSmrg * @{ 5448fb7bfaSmrg */ 5548fb7bfaSmrg 56b17d1066Smrg template<typename... _Elements> 57b17d1066Smrg class tuple; 58b17d1066Smrg 59b17d1066Smrg template<typename _Tp> 60b17d1066Smrg struct __is_empty_non_tuple : is_empty<_Tp> { }; 61b17d1066Smrg 62b17d1066Smrg // Using EBO for elements that are tuples causes ambiguous base errors. 63b17d1066Smrg template<typename _El0, typename... _El> 64b17d1066Smrg struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { }; 65b17d1066Smrg 66b17d1066Smrg // Use the Empty Base-class Optimization for empty, non-final types. 67b17d1066Smrg template<typename _Tp> 68b17d1066Smrg using __empty_not_final 69b1e83836Smrg = __conditional_t<__is_final(_Tp), false_type, 70b1e83836Smrg __is_empty_non_tuple<_Tp>>; 71b17d1066Smrg 72b1e83836Smrg template<size_t _Idx, typename _Head, 73b17d1066Smrg bool = __empty_not_final<_Head>::value> 744fee23f9Smrg struct _Head_base; 754fee23f9Smrg 76b1e83836Smrg#if __has_cpp_attribute(__no_unique_address__) 77b1e83836Smrg template<size_t _Idx, typename _Head> 78b1e83836Smrg struct _Head_base<_Idx, _Head, true> 79b1e83836Smrg { 80b1e83836Smrg constexpr _Head_base() 81b1e83836Smrg : _M_head_impl() { } 82b1e83836Smrg 83b1e83836Smrg constexpr _Head_base(const _Head& __h) 84b1e83836Smrg : _M_head_impl(__h) { } 85b1e83836Smrg 86b1e83836Smrg constexpr _Head_base(const _Head_base&) = default; 87b1e83836Smrg constexpr _Head_base(_Head_base&&) = default; 88b1e83836Smrg 89b1e83836Smrg template<typename _UHead> 90b1e83836Smrg constexpr _Head_base(_UHead&& __h) 91b1e83836Smrg : _M_head_impl(std::forward<_UHead>(__h)) { } 92b1e83836Smrg 93b1e83836Smrg _GLIBCXX20_CONSTEXPR 94b1e83836Smrg _Head_base(allocator_arg_t, __uses_alloc0) 95b1e83836Smrg : _M_head_impl() { } 96b1e83836Smrg 97b1e83836Smrg template<typename _Alloc> 98b1e83836Smrg _GLIBCXX20_CONSTEXPR 99b1e83836Smrg _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 100b1e83836Smrg : _M_head_impl(allocator_arg, *__a._M_a) { } 101b1e83836Smrg 102b1e83836Smrg template<typename _Alloc> 103b1e83836Smrg _GLIBCXX20_CONSTEXPR 104b1e83836Smrg _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 105b1e83836Smrg : _M_head_impl(*__a._M_a) { } 106b1e83836Smrg 107b1e83836Smrg template<typename _UHead> 108b1e83836Smrg _GLIBCXX20_CONSTEXPR 109b1e83836Smrg _Head_base(__uses_alloc0, _UHead&& __uhead) 110b1e83836Smrg : _M_head_impl(std::forward<_UHead>(__uhead)) { } 111b1e83836Smrg 112b1e83836Smrg template<typename _Alloc, typename _UHead> 113b1e83836Smrg _GLIBCXX20_CONSTEXPR 114b1e83836Smrg _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 115b1e83836Smrg : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) 116b1e83836Smrg { } 117b1e83836Smrg 118b1e83836Smrg template<typename _Alloc, typename _UHead> 119b1e83836Smrg _GLIBCXX20_CONSTEXPR 120b1e83836Smrg _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 121b1e83836Smrg : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } 122b1e83836Smrg 123b1e83836Smrg static constexpr _Head& 124b1e83836Smrg _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } 125b1e83836Smrg 126b1e83836Smrg static constexpr const _Head& 127b1e83836Smrg _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } 128b1e83836Smrg 129b1e83836Smrg [[__no_unique_address__]] _Head _M_head_impl; 130b1e83836Smrg }; 131b1e83836Smrg#else 132b1e83836Smrg template<size_t _Idx, typename _Head> 1334fee23f9Smrg struct _Head_base<_Idx, _Head, true> 1344fee23f9Smrg : public _Head 1354fee23f9Smrg { 13648fb7bfaSmrg constexpr _Head_base() 1374fee23f9Smrg : _Head() { } 1384fee23f9Smrg 13948fb7bfaSmrg constexpr _Head_base(const _Head& __h) 1404fee23f9Smrg : _Head(__h) { } 1414fee23f9Smrg 1426012017cSmrg constexpr _Head_base(const _Head_base&) = default; 1436012017cSmrg constexpr _Head_base(_Head_base&&) = default; 1446012017cSmrg 1456012017cSmrg template<typename _UHead> 14648fb7bfaSmrg constexpr _Head_base(_UHead&& __h) 1474fee23f9Smrg : _Head(std::forward<_UHead>(__h)) { } 1484fee23f9Smrg 149a448f87cSmrg _GLIBCXX20_CONSTEXPR 1506012017cSmrg _Head_base(allocator_arg_t, __uses_alloc0) 15148fb7bfaSmrg : _Head() { } 1524fee23f9Smrg 15348fb7bfaSmrg template<typename _Alloc> 154a448f87cSmrg _GLIBCXX20_CONSTEXPR 1556012017cSmrg _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 15648fb7bfaSmrg : _Head(allocator_arg, *__a._M_a) { } 15748fb7bfaSmrg 15848fb7bfaSmrg template<typename _Alloc> 159a448f87cSmrg _GLIBCXX20_CONSTEXPR 1606012017cSmrg _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 16148fb7bfaSmrg : _Head(*__a._M_a) { } 16248fb7bfaSmrg 16348fb7bfaSmrg template<typename _UHead> 164a448f87cSmrg _GLIBCXX20_CONSTEXPR 16548fb7bfaSmrg _Head_base(__uses_alloc0, _UHead&& __uhead) 16648fb7bfaSmrg : _Head(std::forward<_UHead>(__uhead)) { } 16748fb7bfaSmrg 16848fb7bfaSmrg template<typename _Alloc, typename _UHead> 169a448f87cSmrg _GLIBCXX20_CONSTEXPR 17048fb7bfaSmrg _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 17148fb7bfaSmrg : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } 17248fb7bfaSmrg 17348fb7bfaSmrg template<typename _Alloc, typename _UHead> 174a448f87cSmrg _GLIBCXX20_CONSTEXPR 17548fb7bfaSmrg _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 17648fb7bfaSmrg : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } 17748fb7bfaSmrg 17848fb7bfaSmrg static constexpr _Head& 17948fb7bfaSmrg _M_head(_Head_base& __b) noexcept { return __b; } 18048fb7bfaSmrg 18148fb7bfaSmrg static constexpr const _Head& 18248fb7bfaSmrg _M_head(const _Head_base& __b) noexcept { return __b; } 1834fee23f9Smrg }; 184b1e83836Smrg#endif 1854fee23f9Smrg 186b1e83836Smrg template<size_t _Idx, typename _Head> 1874fee23f9Smrg struct _Head_base<_Idx, _Head, false> 1884fee23f9Smrg { 18948fb7bfaSmrg constexpr _Head_base() 1904fee23f9Smrg : _M_head_impl() { } 1914fee23f9Smrg 19248fb7bfaSmrg constexpr _Head_base(const _Head& __h) 1934fee23f9Smrg : _M_head_impl(__h) { } 1944fee23f9Smrg 1956012017cSmrg constexpr _Head_base(const _Head_base&) = default; 1966012017cSmrg constexpr _Head_base(_Head_base&&) = default; 1976012017cSmrg 1986012017cSmrg template<typename _UHead> 19948fb7bfaSmrg constexpr _Head_base(_UHead&& __h) 2004fee23f9Smrg : _M_head_impl(std::forward<_UHead>(__h)) { } 2014fee23f9Smrg 202fb8a8121Smrg _GLIBCXX20_CONSTEXPR 2036012017cSmrg _Head_base(allocator_arg_t, __uses_alloc0) 20448fb7bfaSmrg : _M_head_impl() { } 2054fee23f9Smrg 20648fb7bfaSmrg template<typename _Alloc> 207a448f87cSmrg _GLIBCXX20_CONSTEXPR 2086012017cSmrg _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 20948fb7bfaSmrg : _M_head_impl(allocator_arg, *__a._M_a) { } 21048fb7bfaSmrg 21148fb7bfaSmrg template<typename _Alloc> 212a448f87cSmrg _GLIBCXX20_CONSTEXPR 2136012017cSmrg _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 21448fb7bfaSmrg : _M_head_impl(*__a._M_a) { } 21548fb7bfaSmrg 21648fb7bfaSmrg template<typename _UHead> 217fb8a8121Smrg _GLIBCXX20_CONSTEXPR 21848fb7bfaSmrg _Head_base(__uses_alloc0, _UHead&& __uhead) 21948fb7bfaSmrg : _M_head_impl(std::forward<_UHead>(__uhead)) { } 22048fb7bfaSmrg 22148fb7bfaSmrg template<typename _Alloc, typename _UHead> 222a448f87cSmrg _GLIBCXX20_CONSTEXPR 22348fb7bfaSmrg _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 22448fb7bfaSmrg : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) 22548fb7bfaSmrg { } 22648fb7bfaSmrg 22748fb7bfaSmrg template<typename _Alloc, typename _UHead> 228a448f87cSmrg _GLIBCXX20_CONSTEXPR 22948fb7bfaSmrg _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 23048fb7bfaSmrg : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } 23148fb7bfaSmrg 23248fb7bfaSmrg static constexpr _Head& 23348fb7bfaSmrg _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } 23448fb7bfaSmrg 23548fb7bfaSmrg static constexpr const _Head& 23648fb7bfaSmrg _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } 2374fee23f9Smrg 2384fee23f9Smrg _Head _M_head_impl; 2394fee23f9Smrg }; 2404fee23f9Smrg 2414fee23f9Smrg /** 2424fee23f9Smrg * Contains the actual implementation of the @c tuple template, stored 2434fee23f9Smrg * as a recursive inheritance hierarchy from the first element (most 2444fee23f9Smrg * derived class) to the last (least derived class). The @c Idx 2454fee23f9Smrg * parameter gives the 0-based index of the element stored at this 2464fee23f9Smrg * point in the hierarchy; we use it to implement a constant-time 2474fee23f9Smrg * get() operation. 2484fee23f9Smrg */ 249b1e83836Smrg template<size_t _Idx, typename... _Elements> 2504fee23f9Smrg struct _Tuple_impl; 2514fee23f9Smrg 2524fee23f9Smrg /** 2534fee23f9Smrg * Recursive tuple implementation. Here we store the @c Head element 2544fee23f9Smrg * and derive from a @c Tuple_impl containing the remaining elements 2554fee23f9Smrg * (which contains the @c Tail). 2564fee23f9Smrg */ 257b1e83836Smrg template<size_t _Idx, typename _Head, typename... _Tail> 2584fee23f9Smrg struct _Tuple_impl<_Idx, _Head, _Tail...> 2594fee23f9Smrg : public _Tuple_impl<_Idx + 1, _Tail...>, 260b17d1066Smrg private _Head_base<_Idx, _Head> 2614fee23f9Smrg { 262b1e83836Smrg template<size_t, typename...> friend struct _Tuple_impl; 26348fb7bfaSmrg 2644fee23f9Smrg typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; 265b17d1066Smrg typedef _Head_base<_Idx, _Head> _Base; 2664fee23f9Smrg 26748fb7bfaSmrg static constexpr _Head& 26848fb7bfaSmrg _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 2694fee23f9Smrg 27048fb7bfaSmrg static constexpr const _Head& 27148fb7bfaSmrg _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 2724fee23f9Smrg 27348fb7bfaSmrg static constexpr _Inherited& 27448fb7bfaSmrg _M_tail(_Tuple_impl& __t) noexcept { return __t; } 27548fb7bfaSmrg 27648fb7bfaSmrg static constexpr const _Inherited& 27748fb7bfaSmrg _M_tail(const _Tuple_impl& __t) noexcept { return __t; } 27848fb7bfaSmrg 27948fb7bfaSmrg constexpr _Tuple_impl() 2804fee23f9Smrg : _Inherited(), _Base() { } 2814fee23f9Smrg 282b1e83836Smrg explicit constexpr 283b1e83836Smrg _Tuple_impl(const _Head& __head, const _Tail&... __tail) 284b1e83836Smrg : _Inherited(__tail...), _Base(__head) 285b1e83836Smrg { } 2864fee23f9Smrg 287b1e83836Smrg template<typename _UHead, typename... _UTail, 288b1e83836Smrg typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>> 289b1e83836Smrg explicit constexpr 290b1e83836Smrg _Tuple_impl(_UHead&& __head, _UTail&&... __tail) 2914fee23f9Smrg : _Inherited(std::forward<_UTail>(__tail)...), 292b1e83836Smrg _Base(std::forward<_UHead>(__head)) 293b1e83836Smrg { } 2944fee23f9Smrg 29548fb7bfaSmrg constexpr _Tuple_impl(const _Tuple_impl&) = default; 2964fee23f9Smrg 297181254a7Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 298181254a7Smrg // 2729. Missing SFINAE on std::pair::operator= 299181254a7Smrg _Tuple_impl& operator=(const _Tuple_impl&) = delete; 300181254a7Smrg 301b1e83836Smrg _Tuple_impl(_Tuple_impl&&) = default; 3024fee23f9Smrg 3034fee23f9Smrg template<typename... _UElements> 304b1e83836Smrg constexpr 305b1e83836Smrg _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) 30648fb7bfaSmrg : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 307b1e83836Smrg _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) 308b1e83836Smrg { } 3094fee23f9Smrg 31048fb7bfaSmrg template<typename _UHead, typename... _UTails> 311b1e83836Smrg constexpr 312b1e83836Smrg _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 31348fb7bfaSmrg : _Inherited(std::move 31448fb7bfaSmrg (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 31548fb7bfaSmrg _Base(std::forward<_UHead> 316b1e83836Smrg (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) 317b1e83836Smrg { } 31848fb7bfaSmrg 31948fb7bfaSmrg template<typename _Alloc> 320fb8a8121Smrg _GLIBCXX20_CONSTEXPR 32148fb7bfaSmrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 32248fb7bfaSmrg : _Inherited(__tag, __a), 323b1e83836Smrg _Base(__tag, __use_alloc<_Head>(__a)) 324b1e83836Smrg { } 32548fb7bfaSmrg 32648fb7bfaSmrg template<typename _Alloc> 327a448f87cSmrg _GLIBCXX20_CONSTEXPR 32848fb7bfaSmrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 32948fb7bfaSmrg const _Head& __head, const _Tail&... __tail) 33048fb7bfaSmrg : _Inherited(__tag, __a, __tail...), 331b1e83836Smrg _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) 332b1e83836Smrg { } 33348fb7bfaSmrg 33448fb7bfaSmrg template<typename _Alloc, typename _UHead, typename... _UTail, 335b1e83836Smrg typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>> 336fb8a8121Smrg _GLIBCXX20_CONSTEXPR 33748fb7bfaSmrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 33848fb7bfaSmrg _UHead&& __head, _UTail&&... __tail) 33948fb7bfaSmrg : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), 34048fb7bfaSmrg _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 341b1e83836Smrg std::forward<_UHead>(__head)) 342b1e83836Smrg { } 34348fb7bfaSmrg 34448fb7bfaSmrg template<typename _Alloc> 345fb8a8121Smrg _GLIBCXX20_CONSTEXPR 34648fb7bfaSmrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 34748fb7bfaSmrg const _Tuple_impl& __in) 34848fb7bfaSmrg : _Inherited(__tag, __a, _M_tail(__in)), 349b1e83836Smrg _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) 350b1e83836Smrg { } 35148fb7bfaSmrg 35248fb7bfaSmrg template<typename _Alloc> 353fb8a8121Smrg _GLIBCXX20_CONSTEXPR 35448fb7bfaSmrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 35548fb7bfaSmrg _Tuple_impl&& __in) 35648fb7bfaSmrg : _Inherited(__tag, __a, std::move(_M_tail(__in))), 35748fb7bfaSmrg _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 358b1e83836Smrg std::forward<_Head>(_M_head(__in))) 359b1e83836Smrg { } 36048fb7bfaSmrg 361fb8a8121Smrg template<typename _Alloc, typename _UHead, typename... _UTails> 362fb8a8121Smrg _GLIBCXX20_CONSTEXPR 36348fb7bfaSmrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 364fb8a8121Smrg const _Tuple_impl<_Idx, _UHead, _UTails...>& __in) 36548fb7bfaSmrg : _Inherited(__tag, __a, 366fb8a8121Smrg _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)), 367fb8a8121Smrg _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), 368b1e83836Smrg _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)) 369b1e83836Smrg { } 37048fb7bfaSmrg 37148fb7bfaSmrg template<typename _Alloc, typename _UHead, typename... _UTails> 372fb8a8121Smrg _GLIBCXX20_CONSTEXPR 37348fb7bfaSmrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 37448fb7bfaSmrg _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 37548fb7bfaSmrg : _Inherited(__tag, __a, std::move 37648fb7bfaSmrg (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 37748fb7bfaSmrg _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 37848fb7bfaSmrg std::forward<_UHead> 379b1e83836Smrg (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) 380b1e83836Smrg { } 3814fee23f9Smrg 3824fee23f9Smrg template<typename... _UElements> 383fb8a8121Smrg _GLIBCXX20_CONSTEXPR 384181254a7Smrg void 385181254a7Smrg _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in) 3864fee23f9Smrg { 38748fb7bfaSmrg _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); 388181254a7Smrg _M_tail(*this)._M_assign( 389181254a7Smrg _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)); 3904fee23f9Smrg } 3914fee23f9Smrg 39248fb7bfaSmrg template<typename _UHead, typename... _UTails> 393fb8a8121Smrg _GLIBCXX20_CONSTEXPR 394181254a7Smrg void 395181254a7Smrg _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 3964fee23f9Smrg { 39748fb7bfaSmrg _M_head(*this) = std::forward<_UHead> 39848fb7bfaSmrg (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); 399181254a7Smrg _M_tail(*this)._M_assign( 400181254a7Smrg std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))); 4014fee23f9Smrg } 4024fee23f9Smrg 4034fee23f9Smrg protected: 404fb8a8121Smrg _GLIBCXX20_CONSTEXPR 4054fee23f9Smrg void 40648fb7bfaSmrg _M_swap(_Tuple_impl& __in) 4074fee23f9Smrg { 40848fb7bfaSmrg using std::swap; 40948fb7bfaSmrg swap(_M_head(*this), _M_head(__in)); 41048fb7bfaSmrg _Inherited::_M_swap(_M_tail(__in)); 4114fee23f9Smrg } 4124fee23f9Smrg }; 4134fee23f9Smrg 4144d5abbe8Smrg // Basis case of inheritance recursion. 415b1e83836Smrg template<size_t _Idx, typename _Head> 4164d5abbe8Smrg struct _Tuple_impl<_Idx, _Head> 417b17d1066Smrg : private _Head_base<_Idx, _Head> 4184d5abbe8Smrg { 419b1e83836Smrg template<size_t, typename...> friend struct _Tuple_impl; 4204d5abbe8Smrg 421b17d1066Smrg typedef _Head_base<_Idx, _Head> _Base; 4224d5abbe8Smrg 4234d5abbe8Smrg static constexpr _Head& 4244d5abbe8Smrg _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 4254d5abbe8Smrg 4264d5abbe8Smrg static constexpr const _Head& 4274d5abbe8Smrg _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 4284d5abbe8Smrg 429b1e83836Smrg constexpr 430b1e83836Smrg _Tuple_impl() 4314d5abbe8Smrg : _Base() { } 4324d5abbe8Smrg 433b1e83836Smrg explicit constexpr 434b1e83836Smrg _Tuple_impl(const _Head& __head) 435b1e83836Smrg : _Base(__head) 436b1e83836Smrg { } 4374d5abbe8Smrg 4384d5abbe8Smrg template<typename _UHead> 439b1e83836Smrg explicit constexpr 440b1e83836Smrg _Tuple_impl(_UHead&& __head) 441b1e83836Smrg : _Base(std::forward<_UHead>(__head)) 442b1e83836Smrg { } 4434d5abbe8Smrg 4444d5abbe8Smrg constexpr _Tuple_impl(const _Tuple_impl&) = default; 4454d5abbe8Smrg 446181254a7Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 447181254a7Smrg // 2729. Missing SFINAE on std::pair::operator= 448181254a7Smrg _Tuple_impl& operator=(const _Tuple_impl&) = delete; 449181254a7Smrg 450b1e83836Smrg#if _GLIBCXX_INLINE_VERSION 451b1e83836Smrg _Tuple_impl(_Tuple_impl&&) = default; 452b1e83836Smrg#else 4534d5abbe8Smrg constexpr 4544d5abbe8Smrg _Tuple_impl(_Tuple_impl&& __in) 4554d5abbe8Smrg noexcept(is_nothrow_move_constructible<_Head>::value) 456b1e83836Smrg : _Base(static_cast<_Base&&>(__in)) 457b1e83836Smrg { } 458b1e83836Smrg#endif 4594d5abbe8Smrg 4604d5abbe8Smrg template<typename _UHead> 461b1e83836Smrg constexpr 462b1e83836Smrg _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) 463b1e83836Smrg : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) 464b1e83836Smrg { } 4654d5abbe8Smrg 4664d5abbe8Smrg template<typename _UHead> 467b1e83836Smrg constexpr 468b1e83836Smrg _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) 4694d5abbe8Smrg : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 4704d5abbe8Smrg { } 4714d5abbe8Smrg 4724d5abbe8Smrg template<typename _Alloc> 473fb8a8121Smrg _GLIBCXX20_CONSTEXPR 4744d5abbe8Smrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 475b1e83836Smrg : _Base(__tag, __use_alloc<_Head>(__a)) 476b1e83836Smrg { } 4774d5abbe8Smrg 4784d5abbe8Smrg template<typename _Alloc> 479a448f87cSmrg _GLIBCXX20_CONSTEXPR 4804d5abbe8Smrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 4814d5abbe8Smrg const _Head& __head) 482b1e83836Smrg : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), __head) 483b1e83836Smrg { } 4844d5abbe8Smrg 4854d5abbe8Smrg template<typename _Alloc, typename _UHead> 486fb8a8121Smrg _GLIBCXX20_CONSTEXPR 4874d5abbe8Smrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 4884d5abbe8Smrg _UHead&& __head) 4894d5abbe8Smrg : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 490b1e83836Smrg std::forward<_UHead>(__head)) 491b1e83836Smrg { } 4924d5abbe8Smrg 4934d5abbe8Smrg template<typename _Alloc> 494fb8a8121Smrg _GLIBCXX20_CONSTEXPR 4954d5abbe8Smrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 4964d5abbe8Smrg const _Tuple_impl& __in) 497b1e83836Smrg : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), _M_head(__in)) 498b1e83836Smrg { } 4994d5abbe8Smrg 5004d5abbe8Smrg template<typename _Alloc> 501fb8a8121Smrg _GLIBCXX20_CONSTEXPR 5024d5abbe8Smrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 5034d5abbe8Smrg _Tuple_impl&& __in) 5044d5abbe8Smrg : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 505b1e83836Smrg std::forward<_Head>(_M_head(__in))) 506b1e83836Smrg { } 5074d5abbe8Smrg 5084d5abbe8Smrg template<typename _Alloc, typename _UHead> 509fb8a8121Smrg _GLIBCXX20_CONSTEXPR 5104d5abbe8Smrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 5114d5abbe8Smrg const _Tuple_impl<_Idx, _UHead>& __in) 512fb8a8121Smrg : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), 513b1e83836Smrg _Tuple_impl<_Idx, _UHead>::_M_head(__in)) 514b1e83836Smrg { } 5154d5abbe8Smrg 5164d5abbe8Smrg template<typename _Alloc, typename _UHead> 517fb8a8121Smrg _GLIBCXX20_CONSTEXPR 5184d5abbe8Smrg _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 5194d5abbe8Smrg _Tuple_impl<_Idx, _UHead>&& __in) 5204d5abbe8Smrg : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 5214d5abbe8Smrg std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 5224d5abbe8Smrg { } 5234d5abbe8Smrg 5244d5abbe8Smrg template<typename _UHead> 525fb8a8121Smrg _GLIBCXX20_CONSTEXPR 526181254a7Smrg void 527181254a7Smrg _M_assign(const _Tuple_impl<_Idx, _UHead>& __in) 5284d5abbe8Smrg { 5294d5abbe8Smrg _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); 5304d5abbe8Smrg } 5314d5abbe8Smrg 5324d5abbe8Smrg template<typename _UHead> 533fb8a8121Smrg _GLIBCXX20_CONSTEXPR 534181254a7Smrg void 535181254a7Smrg _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) 5364d5abbe8Smrg { 5374d5abbe8Smrg _M_head(*this) 5384d5abbe8Smrg = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); 5394d5abbe8Smrg } 5404d5abbe8Smrg 5414d5abbe8Smrg protected: 542fb8a8121Smrg _GLIBCXX20_CONSTEXPR 5434d5abbe8Smrg void 5444d5abbe8Smrg _M_swap(_Tuple_impl& __in) 5454d5abbe8Smrg { 5464d5abbe8Smrg using std::swap; 5474d5abbe8Smrg swap(_M_head(*this), _M_head(__in)); 5484d5abbe8Smrg } 5494d5abbe8Smrg }; 5504d5abbe8Smrg 551f9a78e0eSmrg // Concept utility functions, reused in conditionally-explicit 552f9a78e0eSmrg // constructors. 553fb8a8121Smrg template<bool, typename... _Types> 554fb8a8121Smrg struct _TupleConstraints 555f9a78e0eSmrg { 556fb8a8121Smrg // Constraint for a non-explicit constructor. 557fb8a8121Smrg // True iff each Ti in _Types... can be constructed from Ui in _UTypes... 558fb8a8121Smrg // and every Ui is implicitly convertible to Ti. 559fb8a8121Smrg template<typename... _UTypes> 560fb8a8121Smrg static constexpr bool __is_implicitly_constructible() 561f9a78e0eSmrg { 562fb8a8121Smrg return __and_<is_constructible<_Types, _UTypes>..., 563fb8a8121Smrg is_convertible<_UTypes, _Types>... 564f9a78e0eSmrg >::value; 565f9a78e0eSmrg } 566181254a7Smrg 567fb8a8121Smrg // Constraint for a non-explicit constructor. 568fb8a8121Smrg // True iff each Ti in _Types... can be constructed from Ui in _UTypes... 569fb8a8121Smrg // but not every Ui is implicitly convertible to Ti. 570fb8a8121Smrg template<typename... _UTypes> 571fb8a8121Smrg static constexpr bool __is_explicitly_constructible() 572f9a78e0eSmrg { 573fb8a8121Smrg return __and_<is_constructible<_Types, _UTypes>..., 574fb8a8121Smrg __not_<__and_<is_convertible<_UTypes, _Types>...>> 575fb8a8121Smrg >::value; 576fb8a8121Smrg } 577fb8a8121Smrg 578fb8a8121Smrg static constexpr bool __is_implicitly_default_constructible() 579fb8a8121Smrg { 580fb8a8121Smrg return __and_<std::__is_implicitly_default_constructible<_Types>... 581fb8a8121Smrg >::value; 582fb8a8121Smrg } 583fb8a8121Smrg 584fb8a8121Smrg static constexpr bool __is_explicitly_default_constructible() 585fb8a8121Smrg { 586fb8a8121Smrg return __and_<is_default_constructible<_Types>..., 587fb8a8121Smrg __not_<__and_< 588fb8a8121Smrg std::__is_implicitly_default_constructible<_Types>...> 589fb8a8121Smrg >>::value; 590f9a78e0eSmrg } 591f9a78e0eSmrg }; 592f9a78e0eSmrg 593fb8a8121Smrg // Partial specialization used when a required precondition isn't met, 594fb8a8121Smrg // e.g. when sizeof...(_Types) != sizeof...(_UTypes). 595fb8a8121Smrg template<typename... _Types> 596fb8a8121Smrg struct _TupleConstraints<false, _Types...> 597f9a78e0eSmrg { 598fb8a8121Smrg template<typename... _UTypes> 599fb8a8121Smrg static constexpr bool __is_implicitly_constructible() 600fb8a8121Smrg { return false; } 601f9a78e0eSmrg 602fb8a8121Smrg template<typename... _UTypes> 603fb8a8121Smrg static constexpr bool __is_explicitly_constructible() 604fb8a8121Smrg { return false; } 605f9a78e0eSmrg }; 606f9a78e0eSmrg 60748fb7bfaSmrg /// Primary class template, tuple 6084fee23f9Smrg template<typename... _Elements> 6094fee23f9Smrg class tuple : public _Tuple_impl<0, _Elements...> 6104fee23f9Smrg { 6114fee23f9Smrg typedef _Tuple_impl<0, _Elements...> _Inherited; 6124fee23f9Smrg 613fb8a8121Smrg template<bool _Cond> 614fb8a8121Smrg using _TCC = _TupleConstraints<_Cond, _Elements...>; 615fb8a8121Smrg 616fb8a8121Smrg // Constraint for non-explicit default constructor 617fb8a8121Smrg template<bool _Dummy> 618fb8a8121Smrg using _ImplicitDefaultCtor = __enable_if_t< 619fb8a8121Smrg _TCC<_Dummy>::__is_implicitly_default_constructible(), 620fb8a8121Smrg bool>; 621fb8a8121Smrg 622fb8a8121Smrg // Constraint for explicit default constructor 623fb8a8121Smrg template<bool _Dummy> 624fb8a8121Smrg using _ExplicitDefaultCtor = __enable_if_t< 625fb8a8121Smrg _TCC<_Dummy>::__is_explicitly_default_constructible(), 626fb8a8121Smrg bool>; 627fb8a8121Smrg 628fb8a8121Smrg // Constraint for non-explicit constructors 629fb8a8121Smrg template<bool _Cond, typename... _Args> 630fb8a8121Smrg using _ImplicitCtor = __enable_if_t< 631fb8a8121Smrg _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(), 632fb8a8121Smrg bool>; 633fb8a8121Smrg 634fb8a8121Smrg // Constraint for non-explicit constructors 635fb8a8121Smrg template<bool _Cond, typename... _Args> 636fb8a8121Smrg using _ExplicitCtor = __enable_if_t< 637fb8a8121Smrg _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(), 638fb8a8121Smrg bool>; 639f9a78e0eSmrg 640181254a7Smrg template<typename... _UElements> 641181254a7Smrg static constexpr 642181254a7Smrg __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool> 643181254a7Smrg __assignable() 644181254a7Smrg { return __and_<is_assignable<_Elements&, _UElements>...>::value; } 645181254a7Smrg 646fb8a8121Smrg // Condition for noexcept-specifier of an assignment operator. 647181254a7Smrg template<typename... _UElements> 648181254a7Smrg static constexpr bool __nothrow_assignable() 649181254a7Smrg { 650181254a7Smrg return 651181254a7Smrg __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value; 652181254a7Smrg } 653181254a7Smrg 654fb8a8121Smrg // Condition for noexcept-specifier of a constructor. 655fb8a8121Smrg template<typename... _UElements> 656fb8a8121Smrg static constexpr bool __nothrow_constructible() 657fb8a8121Smrg { 658fb8a8121Smrg return 659fb8a8121Smrg __and_<is_nothrow_constructible<_Elements, _UElements>...>::value; 660fb8a8121Smrg } 661fb8a8121Smrg 662fb8a8121Smrg // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1. 663fb8a8121Smrg template<typename _Up> 664fb8a8121Smrg static constexpr bool __valid_args() 665fb8a8121Smrg { 666fb8a8121Smrg return sizeof...(_Elements) == 1 667fb8a8121Smrg && !is_same<tuple, __remove_cvref_t<_Up>>::value; 668fb8a8121Smrg } 669fb8a8121Smrg 670fb8a8121Smrg // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1. 671fb8a8121Smrg template<typename, typename, typename... _Tail> 672fb8a8121Smrg static constexpr bool __valid_args() 673fb8a8121Smrg { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); } 674fb8a8121Smrg 675fb8a8121Smrg /* Constraint for constructors with a tuple<UTypes...> parameter ensures 676fb8a8121Smrg * that the constructor is only viable when it would not interfere with 677fb8a8121Smrg * tuple(UTypes&&...) or tuple(const tuple&) or tuple(tuple&&). 678fb8a8121Smrg * Such constructors are only viable if: 679fb8a8121Smrg * either sizeof...(Types) != 1, 680fb8a8121Smrg * or (when Types... expands to T and UTypes... expands to U) 681fb8a8121Smrg * is_convertible_v<TUPLE, T>, is_constructible_v<T, TUPLE>, 682fb8a8121Smrg * and is_same_v<T, U> are all false. 683fb8a8121Smrg */ 684fb8a8121Smrg template<typename _Tuple, typename = tuple, 685fb8a8121Smrg typename = __remove_cvref_t<_Tuple>> 686fb8a8121Smrg struct _UseOtherCtor 687fb8a8121Smrg : false_type 688fb8a8121Smrg { }; 689fb8a8121Smrg // If TUPLE is convertible to the single element in *this, 690fb8a8121Smrg // then TUPLE should match tuple(UTypes&&...) instead. 691fb8a8121Smrg template<typename _Tuple, typename _Tp, typename _Up> 692fb8a8121Smrg struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>> 693fb8a8121Smrg : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>> 694fb8a8121Smrg { }; 695fb8a8121Smrg // If TUPLE and *this each have a single element of the same type, 696fb8a8121Smrg // then TUPLE should match a copy/move constructor instead. 697fb8a8121Smrg template<typename _Tuple, typename _Tp> 698fb8a8121Smrg struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>> 699fb8a8121Smrg : true_type 700fb8a8121Smrg { }; 701fb8a8121Smrg 702fb8a8121Smrg // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1 703fb8a8121Smrg // and the single element in Types can be initialized from TUPLE, 704fb8a8121Smrg // or is the same type as tuple_element_t<0, TUPLE>. 705fb8a8121Smrg template<typename _Tuple> 706fb8a8121Smrg static constexpr bool __use_other_ctor() 707fb8a8121Smrg { return _UseOtherCtor<_Tuple>::value; } 708fb8a8121Smrg 7094fee23f9Smrg public: 710f9a78e0eSmrg template<typename _Dummy = void, 711fb8a8121Smrg _ImplicitDefaultCtor<is_void<_Dummy>::value> = true> 712fb8a8121Smrg constexpr 713fb8a8121Smrg tuple() 714fb8a8121Smrg noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value) 7154fee23f9Smrg : _Inherited() { } 7164fee23f9Smrg 717f9a78e0eSmrg template<typename _Dummy = void, 718fb8a8121Smrg _ExplicitDefaultCtor<is_void<_Dummy>::value> = false> 719fb8a8121Smrg explicit constexpr 720fb8a8121Smrg tuple() 721fb8a8121Smrg noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value) 722f9a78e0eSmrg : _Inherited() { } 723f9a78e0eSmrg 724fb8a8121Smrg template<bool _NotEmpty = (sizeof...(_Elements) >= 1), 725fb8a8121Smrg _ImplicitCtor<_NotEmpty, const _Elements&...> = true> 726fb8a8121Smrg constexpr 727fb8a8121Smrg tuple(const _Elements&... __elements) 728fb8a8121Smrg noexcept(__nothrow_constructible<const _Elements&...>()) 7294fee23f9Smrg : _Inherited(__elements...) { } 7304fee23f9Smrg 731fb8a8121Smrg template<bool _NotEmpty = (sizeof...(_Elements) >= 1), 732fb8a8121Smrg _ExplicitCtor<_NotEmpty, const _Elements&...> = false> 733fb8a8121Smrg explicit constexpr 734fb8a8121Smrg tuple(const _Elements&... __elements) 735fb8a8121Smrg noexcept(__nothrow_constructible<const _Elements&...>()) 736f9a78e0eSmrg : _Inherited(__elements...) { } 737f9a78e0eSmrg 738fb8a8121Smrg template<typename... _UElements, 739fb8a8121Smrg bool _Valid = __valid_args<_UElements...>(), 740fb8a8121Smrg _ImplicitCtor<_Valid, _UElements...> = true> 741fb8a8121Smrg constexpr 742fb8a8121Smrg tuple(_UElements&&... __elements) 743fb8a8121Smrg noexcept(__nothrow_constructible<_UElements...>()) 7444fee23f9Smrg : _Inherited(std::forward<_UElements>(__elements)...) { } 7454fee23f9Smrg 746fb8a8121Smrg template<typename... _UElements, 747fb8a8121Smrg bool _Valid = __valid_args<_UElements...>(), 748fb8a8121Smrg _ExplicitCtor<_Valid, _UElements...> = false> 749fb8a8121Smrg explicit constexpr 750fb8a8121Smrg tuple(_UElements&&... __elements) 751fb8a8121Smrg noexcept(__nothrow_constructible<_UElements...>()) 752f9a78e0eSmrg : _Inherited(std::forward<_UElements>(__elements)...) { } 753f9a78e0eSmrg 75448fb7bfaSmrg constexpr tuple(const tuple&) = default; 7554fee23f9Smrg 75648fb7bfaSmrg constexpr tuple(tuple&&) = default; 7574fee23f9Smrg 758fb8a8121Smrg template<typename... _UElements, 759fb8a8121Smrg bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 760fb8a8121Smrg && !__use_other_ctor<const tuple<_UElements...>&>(), 761fb8a8121Smrg _ImplicitCtor<_Valid, const _UElements&...> = true> 762fb8a8121Smrg constexpr 763fb8a8121Smrg tuple(const tuple<_UElements...>& __in) 764fb8a8121Smrg noexcept(__nothrow_constructible<const _UElements&...>()) 7654fee23f9Smrg : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 7664fee23f9Smrg { } 7674fee23f9Smrg 768fb8a8121Smrg template<typename... _UElements, 769fb8a8121Smrg bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 770fb8a8121Smrg && !__use_other_ctor<const tuple<_UElements...>&>(), 771fb8a8121Smrg _ExplicitCtor<_Valid, const _UElements&...> = false> 772fb8a8121Smrg explicit constexpr 773fb8a8121Smrg tuple(const tuple<_UElements...>& __in) 774fb8a8121Smrg noexcept(__nothrow_constructible<const _UElements&...>()) 775f9a78e0eSmrg : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 776f9a78e0eSmrg { } 777f9a78e0eSmrg 778fb8a8121Smrg template<typename... _UElements, 779fb8a8121Smrg bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 780fb8a8121Smrg && !__use_other_ctor<tuple<_UElements...>&&>(), 781fb8a8121Smrg _ImplicitCtor<_Valid, _UElements...> = true> 782fb8a8121Smrg constexpr 783fb8a8121Smrg tuple(tuple<_UElements...>&& __in) 784fb8a8121Smrg noexcept(__nothrow_constructible<_UElements...>()) 7854fee23f9Smrg : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 7864fee23f9Smrg 787fb8a8121Smrg template<typename... _UElements, 788fb8a8121Smrg bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 789fb8a8121Smrg && !__use_other_ctor<tuple<_UElements...>&&>(), 790fb8a8121Smrg _ExplicitCtor<_Valid, _UElements...> = false> 791fb8a8121Smrg explicit constexpr 792fb8a8121Smrg tuple(tuple<_UElements...>&& __in) 793fb8a8121Smrg noexcept(__nothrow_constructible<_UElements...>()) 794f9a78e0eSmrg : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 795f9a78e0eSmrg 79648fb7bfaSmrg // Allocator-extended constructors. 79748fb7bfaSmrg 798fb8a8121Smrg template<typename _Alloc, 799fb8a8121Smrg _ImplicitDefaultCtor<is_object<_Alloc>::value> = true> 800fb8a8121Smrg _GLIBCXX20_CONSTEXPR 80148fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a) 80248fb7bfaSmrg : _Inherited(__tag, __a) { } 80348fb7bfaSmrg 804*0a307195Smrg template<typename _Alloc, 805*0a307195Smrg _ExplicitDefaultCtor<is_object<_Alloc>::value> = false> 806*0a307195Smrg _GLIBCXX20_CONSTEXPR 807*0a307195Smrg explicit 808*0a307195Smrg tuple(allocator_arg_t __tag, const _Alloc& __a) 809*0a307195Smrg : _Inherited(__tag, __a) { } 810*0a307195Smrg 811fb8a8121Smrg template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1), 812fb8a8121Smrg _ImplicitCtor<_NotEmpty, const _Elements&...> = true> 813fb8a8121Smrg _GLIBCXX20_CONSTEXPR 81448fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, 81548fb7bfaSmrg const _Elements&... __elements) 81648fb7bfaSmrg : _Inherited(__tag, __a, __elements...) { } 81748fb7bfaSmrg 818fb8a8121Smrg template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1), 819fb8a8121Smrg _ExplicitCtor<_NotEmpty, const _Elements&...> = false> 820fb8a8121Smrg _GLIBCXX20_CONSTEXPR 821fb8a8121Smrg explicit 822fb8a8121Smrg tuple(allocator_arg_t __tag, const _Alloc& __a, 823f9a78e0eSmrg const _Elements&... __elements) 824f9a78e0eSmrg : _Inherited(__tag, __a, __elements...) { } 825f9a78e0eSmrg 826fb8a8121Smrg template<typename _Alloc, typename... _UElements, 827fb8a8121Smrg bool _Valid = __valid_args<_UElements...>(), 828fb8a8121Smrg _ImplicitCtor<_Valid, _UElements...> = true> 829fb8a8121Smrg _GLIBCXX20_CONSTEXPR 83048fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, 83148fb7bfaSmrg _UElements&&... __elements) 83248fb7bfaSmrg : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 83348fb7bfaSmrg { } 83448fb7bfaSmrg 835fb8a8121Smrg template<typename _Alloc, typename... _UElements, 836fb8a8121Smrg bool _Valid = __valid_args<_UElements...>(), 837fb8a8121Smrg _ExplicitCtor<_Valid, _UElements...> = false> 838fb8a8121Smrg _GLIBCXX20_CONSTEXPR 839fb8a8121Smrg explicit 840fb8a8121Smrg tuple(allocator_arg_t __tag, const _Alloc& __a, 841f9a78e0eSmrg _UElements&&... __elements) 842f9a78e0eSmrg : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 843f9a78e0eSmrg { } 844f9a78e0eSmrg 84548fb7bfaSmrg template<typename _Alloc> 846fb8a8121Smrg _GLIBCXX20_CONSTEXPR 84748fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 84848fb7bfaSmrg : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 84948fb7bfaSmrg 85048fb7bfaSmrg template<typename _Alloc> 851fb8a8121Smrg _GLIBCXX20_CONSTEXPR 85248fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 85348fb7bfaSmrg : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 85448fb7bfaSmrg 855fb8a8121Smrg template<typename _Alloc, typename... _UElements, 856fb8a8121Smrg bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 857fb8a8121Smrg && !__use_other_ctor<const tuple<_UElements...>&>(), 858fb8a8121Smrg _ImplicitCtor<_Valid, const _UElements&...> = true> 859fb8a8121Smrg _GLIBCXX20_CONSTEXPR 86048fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, 86148fb7bfaSmrg const tuple<_UElements...>& __in) 86248fb7bfaSmrg : _Inherited(__tag, __a, 86348fb7bfaSmrg static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 86448fb7bfaSmrg { } 86548fb7bfaSmrg 866fb8a8121Smrg template<typename _Alloc, typename... _UElements, 867fb8a8121Smrg bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 868fb8a8121Smrg && !__use_other_ctor<const tuple<_UElements...>&>(), 869fb8a8121Smrg _ExplicitCtor<_Valid, const _UElements&...> = false> 870fb8a8121Smrg _GLIBCXX20_CONSTEXPR 871fb8a8121Smrg explicit 872fb8a8121Smrg tuple(allocator_arg_t __tag, const _Alloc& __a, 873f9a78e0eSmrg const tuple<_UElements...>& __in) 874f9a78e0eSmrg : _Inherited(__tag, __a, 875f9a78e0eSmrg static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 876f9a78e0eSmrg { } 877f9a78e0eSmrg 878fb8a8121Smrg template<typename _Alloc, typename... _UElements, 879fb8a8121Smrg bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 880fb8a8121Smrg && !__use_other_ctor<tuple<_UElements...>&&>(), 881fb8a8121Smrg _ImplicitCtor<_Valid, _UElements...> = true> 882fb8a8121Smrg _GLIBCXX20_CONSTEXPR 88348fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, 88448fb7bfaSmrg tuple<_UElements...>&& __in) 88548fb7bfaSmrg : _Inherited(__tag, __a, 88648fb7bfaSmrg static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 8874fee23f9Smrg { } 8884fee23f9Smrg 889fb8a8121Smrg template<typename _Alloc, typename... _UElements, 890fb8a8121Smrg bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 891fb8a8121Smrg && !__use_other_ctor<tuple<_UElements...>&&>(), 892fb8a8121Smrg _ExplicitCtor<_Valid, _UElements...> = false> 893fb8a8121Smrg _GLIBCXX20_CONSTEXPR 894fb8a8121Smrg explicit 895fb8a8121Smrg tuple(allocator_arg_t __tag, const _Alloc& __a, 896f9a78e0eSmrg tuple<_UElements...>&& __in) 897f9a78e0eSmrg : _Inherited(__tag, __a, 898f9a78e0eSmrg static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 899f9a78e0eSmrg { } 900f9a78e0eSmrg 901181254a7Smrg // tuple assignment 902181254a7Smrg 903fb8a8121Smrg _GLIBCXX20_CONSTEXPR 9044fee23f9Smrg tuple& 905b1e83836Smrg operator=(__conditional_t<__assignable<const _Elements&...>(), 906181254a7Smrg const tuple&, 907b1e83836Smrg const __nonesuch&> __in) 908181254a7Smrg noexcept(__nothrow_assignable<const _Elements&...>()) 9094fee23f9Smrg { 910181254a7Smrg this->_M_assign(__in); 9114fee23f9Smrg return *this; 9124fee23f9Smrg } 9134fee23f9Smrg 914fb8a8121Smrg _GLIBCXX20_CONSTEXPR 9154fee23f9Smrg tuple& 916b1e83836Smrg operator=(__conditional_t<__assignable<_Elements...>(), 917181254a7Smrg tuple&&, 918b1e83836Smrg __nonesuch&&> __in) 919181254a7Smrg noexcept(__nothrow_assignable<_Elements...>()) 9204fee23f9Smrg { 921181254a7Smrg this->_M_assign(std::move(__in)); 9224fee23f9Smrg return *this; 9234fee23f9Smrg } 9244fee23f9Smrg 925b17d1066Smrg template<typename... _UElements> 926fb8a8121Smrg _GLIBCXX20_CONSTEXPR 927181254a7Smrg __enable_if_t<__assignable<const _UElements&...>(), tuple&> 9284fee23f9Smrg operator=(const tuple<_UElements...>& __in) 929181254a7Smrg noexcept(__nothrow_assignable<const _UElements&...>()) 9304fee23f9Smrg { 931181254a7Smrg this->_M_assign(__in); 9324fee23f9Smrg return *this; 9334fee23f9Smrg } 9344fee23f9Smrg 935b17d1066Smrg template<typename... _UElements> 936fb8a8121Smrg _GLIBCXX20_CONSTEXPR 937181254a7Smrg __enable_if_t<__assignable<_UElements...>(), tuple&> 9384fee23f9Smrg operator=(tuple<_UElements...>&& __in) 939181254a7Smrg noexcept(__nothrow_assignable<_UElements...>()) 9404fee23f9Smrg { 941181254a7Smrg this->_M_assign(std::move(__in)); 9424fee23f9Smrg return *this; 9434fee23f9Smrg } 9444fee23f9Smrg 945181254a7Smrg // tuple swap 946fb8a8121Smrg _GLIBCXX20_CONSTEXPR 9474fee23f9Smrg void 9484fee23f9Smrg swap(tuple& __in) 949181254a7Smrg noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value) 95048fb7bfaSmrg { _Inherited::_M_swap(__in); } 9514fee23f9Smrg }; 9524fee23f9Smrg 953b17d1066Smrg#if __cpp_deduction_guides >= 201606 954b17d1066Smrg template<typename... _UTypes> 955b17d1066Smrg tuple(_UTypes...) -> tuple<_UTypes...>; 956b17d1066Smrg template<typename _T1, typename _T2> 957b17d1066Smrg tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>; 958b17d1066Smrg template<typename _Alloc, typename... _UTypes> 959b17d1066Smrg tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>; 960b17d1066Smrg template<typename _Alloc, typename _T1, typename _T2> 961b17d1066Smrg tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>; 962b17d1066Smrg template<typename _Alloc, typename... _UTypes> 963b17d1066Smrg tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>; 964b17d1066Smrg#endif 965b17d1066Smrg 96648fb7bfaSmrg // Explicit specialization, zero-element tuple. 9674fee23f9Smrg template<> 9684fee23f9Smrg class tuple<> 9694fee23f9Smrg { 9704fee23f9Smrg public: 971a448f87cSmrg _GLIBCXX20_CONSTEXPR 97248fb7bfaSmrg void swap(tuple&) noexcept { /* no-op */ } 973b17d1066Smrg // We need the default since we're going to define no-op 974b17d1066Smrg // allocator constructors. 975b17d1066Smrg tuple() = default; 976b17d1066Smrg // No-op allocator constructors. 977b17d1066Smrg template<typename _Alloc> 978fb8a8121Smrg _GLIBCXX20_CONSTEXPR 979fb8a8121Smrg tuple(allocator_arg_t, const _Alloc&) noexcept { } 980b17d1066Smrg template<typename _Alloc> 981fb8a8121Smrg _GLIBCXX20_CONSTEXPR 982fb8a8121Smrg tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { } 9834fee23f9Smrg }; 9844fee23f9Smrg 98548fb7bfaSmrg /// Partial specialization, 2-element tuple. 98648fb7bfaSmrg /// Includes construction and assignment from a pair. 9874fee23f9Smrg template<typename _T1, typename _T2> 9884fee23f9Smrg class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 9894fee23f9Smrg { 9904fee23f9Smrg typedef _Tuple_impl<0, _T1, _T2> _Inherited; 9914fee23f9Smrg 992fb8a8121Smrg // Constraint for non-explicit default constructor 993fb8a8121Smrg template<bool _Dummy, typename _U1, typename _U2> 994fb8a8121Smrg using _ImplicitDefaultCtor = __enable_if_t< 995fb8a8121Smrg _TupleConstraints<_Dummy, _U1, _U2>:: 996fb8a8121Smrg __is_implicitly_default_constructible(), 997fb8a8121Smrg bool>; 998fb8a8121Smrg 999fb8a8121Smrg // Constraint for explicit default constructor 1000fb8a8121Smrg template<bool _Dummy, typename _U1, typename _U2> 1001fb8a8121Smrg using _ExplicitDefaultCtor = __enable_if_t< 1002fb8a8121Smrg _TupleConstraints<_Dummy, _U1, _U2>:: 1003fb8a8121Smrg __is_explicitly_default_constructible(), 1004fb8a8121Smrg bool>; 1005fb8a8121Smrg 1006fb8a8121Smrg template<bool _Dummy> 1007fb8a8121Smrg using _TCC = _TupleConstraints<_Dummy, _T1, _T2>; 1008fb8a8121Smrg 1009fb8a8121Smrg // Constraint for non-explicit constructors 1010fb8a8121Smrg template<bool _Cond, typename _U1, typename _U2> 1011fb8a8121Smrg using _ImplicitCtor = __enable_if_t< 1012fb8a8121Smrg _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(), 1013fb8a8121Smrg bool>; 1014fb8a8121Smrg 1015fb8a8121Smrg // Constraint for non-explicit constructors 1016fb8a8121Smrg template<bool _Cond, typename _U1, typename _U2> 1017fb8a8121Smrg using _ExplicitCtor = __enable_if_t< 1018fb8a8121Smrg _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(), 1019fb8a8121Smrg bool>; 1020fb8a8121Smrg 1021181254a7Smrg template<typename _U1, typename _U2> 1022181254a7Smrg static constexpr bool __assignable() 1023181254a7Smrg { 1024181254a7Smrg return __and_<is_assignable<_T1&, _U1>, 1025181254a7Smrg is_assignable<_T2&, _U2>>::value; 1026181254a7Smrg } 1027181254a7Smrg 1028181254a7Smrg template<typename _U1, typename _U2> 1029181254a7Smrg static constexpr bool __nothrow_assignable() 1030181254a7Smrg { 1031181254a7Smrg return __and_<is_nothrow_assignable<_T1&, _U1>, 1032181254a7Smrg is_nothrow_assignable<_T2&, _U2>>::value; 1033181254a7Smrg } 1034181254a7Smrg 1035fb8a8121Smrg template<typename _U1, typename _U2> 1036fb8a8121Smrg static constexpr bool __nothrow_constructible() 1037fb8a8121Smrg { 1038fb8a8121Smrg return __and_<is_nothrow_constructible<_T1, _U1>, 1039fb8a8121Smrg is_nothrow_constructible<_T2, _U2>>::value; 1040fb8a8121Smrg } 1041fb8a8121Smrg 1042fb8a8121Smrg static constexpr bool __nothrow_default_constructible() 1043fb8a8121Smrg { 1044fb8a8121Smrg return __and_<is_nothrow_default_constructible<_T1>, 1045fb8a8121Smrg is_nothrow_default_constructible<_T2>>::value; 1046fb8a8121Smrg } 1047fb8a8121Smrg 1048fb8a8121Smrg template<typename _U1> 1049fb8a8121Smrg static constexpr bool __is_alloc_arg() 1050fb8a8121Smrg { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; } 1051fb8a8121Smrg 10524fee23f9Smrg public: 1053fb8a8121Smrg template<bool _Dummy = true, 1054fb8a8121Smrg _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true> 1055fb8a8121Smrg constexpr 1056fb8a8121Smrg tuple() 1057fb8a8121Smrg noexcept(__nothrow_default_constructible()) 10584fee23f9Smrg : _Inherited() { } 10594fee23f9Smrg 1060fb8a8121Smrg template<bool _Dummy = true, 1061fb8a8121Smrg _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false> 1062fb8a8121Smrg explicit constexpr 1063fb8a8121Smrg tuple() 1064fb8a8121Smrg noexcept(__nothrow_default_constructible()) 1065f9a78e0eSmrg : _Inherited() { } 1066f9a78e0eSmrg 1067fb8a8121Smrg template<bool _Dummy = true, 1068fb8a8121Smrg _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true> 1069fb8a8121Smrg constexpr 1070fb8a8121Smrg tuple(const _T1& __a1, const _T2& __a2) 1071fb8a8121Smrg noexcept(__nothrow_constructible<const _T1&, const _T2&>()) 10724fee23f9Smrg : _Inherited(__a1, __a2) { } 10734fee23f9Smrg 1074fb8a8121Smrg template<bool _Dummy = true, 1075fb8a8121Smrg _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false> 1076fb8a8121Smrg explicit constexpr 1077fb8a8121Smrg tuple(const _T1& __a1, const _T2& __a2) 1078fb8a8121Smrg noexcept(__nothrow_constructible<const _T1&, const _T2&>()) 1079f9a78e0eSmrg : _Inherited(__a1, __a2) { } 1080f9a78e0eSmrg 1081fb8a8121Smrg template<typename _U1, typename _U2, 1082fb8a8121Smrg _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true> 1083fb8a8121Smrg constexpr 1084fb8a8121Smrg tuple(_U1&& __a1, _U2&& __a2) 1085fb8a8121Smrg noexcept(__nothrow_constructible<_U1, _U2>()) 10864fee23f9Smrg : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 10874fee23f9Smrg 1088fb8a8121Smrg template<typename _U1, typename _U2, 1089fb8a8121Smrg _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false> 1090fb8a8121Smrg explicit constexpr 1091fb8a8121Smrg tuple(_U1&& __a1, _U2&& __a2) 1092fb8a8121Smrg noexcept(__nothrow_constructible<_U1, _U2>()) 1093f9a78e0eSmrg : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 1094f9a78e0eSmrg 109548fb7bfaSmrg constexpr tuple(const tuple&) = default; 10964fee23f9Smrg 109748fb7bfaSmrg constexpr tuple(tuple&&) = default; 10984fee23f9Smrg 1099fb8a8121Smrg template<typename _U1, typename _U2, 1100fb8a8121Smrg _ImplicitCtor<true, const _U1&, const _U2&> = true> 1101fb8a8121Smrg constexpr 1102fb8a8121Smrg tuple(const tuple<_U1, _U2>& __in) 1103fb8a8121Smrg noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 11044fee23f9Smrg : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 11054fee23f9Smrg 1106fb8a8121Smrg template<typename _U1, typename _U2, 1107fb8a8121Smrg _ExplicitCtor<true, const _U1&, const _U2&> = false> 1108fb8a8121Smrg explicit constexpr 1109fb8a8121Smrg tuple(const tuple<_U1, _U2>& __in) 1110fb8a8121Smrg noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1111f9a78e0eSmrg : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 1112f9a78e0eSmrg 1113fb8a8121Smrg template<typename _U1, typename _U2, 1114fb8a8121Smrg _ImplicitCtor<true, _U1, _U2> = true> 1115fb8a8121Smrg constexpr 1116fb8a8121Smrg tuple(tuple<_U1, _U2>&& __in) 1117fb8a8121Smrg noexcept(__nothrow_constructible<_U1, _U2>()) 11184fee23f9Smrg : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 11194fee23f9Smrg 1120fb8a8121Smrg template<typename _U1, typename _U2, 1121fb8a8121Smrg _ExplicitCtor<true, _U1, _U2> = false> 1122fb8a8121Smrg explicit constexpr 1123fb8a8121Smrg tuple(tuple<_U1, _U2>&& __in) 1124fb8a8121Smrg noexcept(__nothrow_constructible<_U1, _U2>()) 1125f9a78e0eSmrg : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 1126f9a78e0eSmrg 1127fb8a8121Smrg template<typename _U1, typename _U2, 1128fb8a8121Smrg _ImplicitCtor<true, const _U1&, const _U2&> = true> 1129fb8a8121Smrg constexpr 1130fb8a8121Smrg tuple(const pair<_U1, _U2>& __in) 1131fb8a8121Smrg noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 11324fee23f9Smrg : _Inherited(__in.first, __in.second) { } 11334fee23f9Smrg 1134fb8a8121Smrg template<typename _U1, typename _U2, 1135fb8a8121Smrg _ExplicitCtor<true, const _U1&, const _U2&> = false> 1136fb8a8121Smrg explicit constexpr 1137fb8a8121Smrg tuple(const pair<_U1, _U2>& __in) 1138fb8a8121Smrg noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1139f9a78e0eSmrg : _Inherited(__in.first, __in.second) { } 1140f9a78e0eSmrg 1141fb8a8121Smrg template<typename _U1, typename _U2, 1142fb8a8121Smrg _ImplicitCtor<true, _U1, _U2> = true> 1143fb8a8121Smrg constexpr 1144fb8a8121Smrg tuple(pair<_U1, _U2>&& __in) 1145fb8a8121Smrg noexcept(__nothrow_constructible<_U1, _U2>()) 11464fee23f9Smrg : _Inherited(std::forward<_U1>(__in.first), 11474fee23f9Smrg std::forward<_U2>(__in.second)) { } 11484fee23f9Smrg 1149fb8a8121Smrg template<typename _U1, typename _U2, 1150fb8a8121Smrg _ExplicitCtor<true, _U1, _U2> = false> 1151fb8a8121Smrg explicit constexpr 1152fb8a8121Smrg tuple(pair<_U1, _U2>&& __in) 1153fb8a8121Smrg noexcept(__nothrow_constructible<_U1, _U2>()) 1154f9a78e0eSmrg : _Inherited(std::forward<_U1>(__in.first), 1155f9a78e0eSmrg std::forward<_U2>(__in.second)) { } 1156f9a78e0eSmrg 115748fb7bfaSmrg // Allocator-extended constructors. 115848fb7bfaSmrg 1159fb8a8121Smrg template<typename _Alloc, 1160fb8a8121Smrg _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true> 1161fb8a8121Smrg _GLIBCXX20_CONSTEXPR 116248fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a) 116348fb7bfaSmrg : _Inherited(__tag, __a) { } 116448fb7bfaSmrg 1165*0a307195Smrg template<typename _Alloc, 1166*0a307195Smrg _ExplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = false> 1167*0a307195Smrg _GLIBCXX20_CONSTEXPR 1168*0a307195Smrg explicit 1169*0a307195Smrg tuple(allocator_arg_t __tag, const _Alloc& __a) 1170*0a307195Smrg : _Inherited(__tag, __a) { } 1171*0a307195Smrg 1172fb8a8121Smrg template<typename _Alloc, bool _Dummy = true, 1173fb8a8121Smrg _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true> 1174fb8a8121Smrg _GLIBCXX20_CONSTEXPR 117548fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, 117648fb7bfaSmrg const _T1& __a1, const _T2& __a2) 117748fb7bfaSmrg : _Inherited(__tag, __a, __a1, __a2) { } 117848fb7bfaSmrg 1179fb8a8121Smrg template<typename _Alloc, bool _Dummy = true, 1180fb8a8121Smrg _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false> 1181fb8a8121Smrg explicit 1182fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1183fb8a8121Smrg tuple(allocator_arg_t __tag, const _Alloc& __a, 1184f9a78e0eSmrg const _T1& __a1, const _T2& __a2) 1185f9a78e0eSmrg : _Inherited(__tag, __a, __a1, __a2) { } 1186f9a78e0eSmrg 1187fb8a8121Smrg template<typename _Alloc, typename _U1, typename _U2, 1188fb8a8121Smrg _ImplicitCtor<true, _U1, _U2> = true> 1189fb8a8121Smrg _GLIBCXX20_CONSTEXPR 119048fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 119148fb7bfaSmrg : _Inherited(__tag, __a, std::forward<_U1>(__a1), 119248fb7bfaSmrg std::forward<_U2>(__a2)) { } 119348fb7bfaSmrg 1194fb8a8121Smrg template<typename _Alloc, typename _U1, typename _U2, 1195fb8a8121Smrg _ExplicitCtor<true, _U1, _U2> = false> 1196fb8a8121Smrg explicit 1197fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1198fb8a8121Smrg tuple(allocator_arg_t __tag, const _Alloc& __a, 1199f9a78e0eSmrg _U1&& __a1, _U2&& __a2) 1200f9a78e0eSmrg : _Inherited(__tag, __a, std::forward<_U1>(__a1), 1201f9a78e0eSmrg std::forward<_U2>(__a2)) { } 1202f9a78e0eSmrg 120348fb7bfaSmrg template<typename _Alloc> 1204fb8a8121Smrg _GLIBCXX20_CONSTEXPR 120548fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 120648fb7bfaSmrg : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 120748fb7bfaSmrg 120848fb7bfaSmrg template<typename _Alloc> 1209fb8a8121Smrg _GLIBCXX20_CONSTEXPR 121048fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 121148fb7bfaSmrg : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 121248fb7bfaSmrg 1213fb8a8121Smrg template<typename _Alloc, typename _U1, typename _U2, 1214fb8a8121Smrg _ImplicitCtor<true, const _U1&, const _U2&> = true> 1215fb8a8121Smrg _GLIBCXX20_CONSTEXPR 121648fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, 121748fb7bfaSmrg const tuple<_U1, _U2>& __in) 121848fb7bfaSmrg : _Inherited(__tag, __a, 121948fb7bfaSmrg static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 122048fb7bfaSmrg { } 122148fb7bfaSmrg 1222fb8a8121Smrg template<typename _Alloc, typename _U1, typename _U2, 1223fb8a8121Smrg _ExplicitCtor<true, const _U1&, const _U2&> = false> 1224fb8a8121Smrg explicit 1225fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1226fb8a8121Smrg tuple(allocator_arg_t __tag, const _Alloc& __a, 1227f9a78e0eSmrg const tuple<_U1, _U2>& __in) 1228f9a78e0eSmrg : _Inherited(__tag, __a, 1229f9a78e0eSmrg static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 1230f9a78e0eSmrg { } 1231f9a78e0eSmrg 1232fb8a8121Smrg template<typename _Alloc, typename _U1, typename _U2, 1233fb8a8121Smrg _ImplicitCtor<true, _U1, _U2> = true> 1234fb8a8121Smrg _GLIBCXX20_CONSTEXPR 123548fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 123648fb7bfaSmrg : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 123748fb7bfaSmrg { } 123848fb7bfaSmrg 1239fb8a8121Smrg template<typename _Alloc, typename _U1, typename _U2, 1240fb8a8121Smrg _ExplicitCtor<true, _U1, _U2> = false> 1241fb8a8121Smrg explicit 1242fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1243fb8a8121Smrg tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 1244f9a78e0eSmrg : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 1245f9a78e0eSmrg { } 1246f9a78e0eSmrg 1247fb8a8121Smrg template<typename _Alloc, typename _U1, typename _U2, 1248fb8a8121Smrg _ImplicitCtor<true, const _U1&, const _U2&> = true> 1249fb8a8121Smrg _GLIBCXX20_CONSTEXPR 125048fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, 125148fb7bfaSmrg const pair<_U1, _U2>& __in) 125248fb7bfaSmrg : _Inherited(__tag, __a, __in.first, __in.second) { } 125348fb7bfaSmrg 1254fb8a8121Smrg template<typename _Alloc, typename _U1, typename _U2, 1255fb8a8121Smrg _ExplicitCtor<true, const _U1&, const _U2&> = false> 1256fb8a8121Smrg explicit 1257fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1258fb8a8121Smrg tuple(allocator_arg_t __tag, const _Alloc& __a, 1259f9a78e0eSmrg const pair<_U1, _U2>& __in) 1260f9a78e0eSmrg : _Inherited(__tag, __a, __in.first, __in.second) { } 1261f9a78e0eSmrg 1262fb8a8121Smrg template<typename _Alloc, typename _U1, typename _U2, 1263fb8a8121Smrg _ImplicitCtor<true, _U1, _U2> = true> 1264fb8a8121Smrg _GLIBCXX20_CONSTEXPR 126548fb7bfaSmrg tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 126648fb7bfaSmrg : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 126748fb7bfaSmrg std::forward<_U2>(__in.second)) { } 126848fb7bfaSmrg 1269fb8a8121Smrg template<typename _Alloc, typename _U1, typename _U2, 1270fb8a8121Smrg _ExplicitCtor<true, _U1, _U2> = false> 1271fb8a8121Smrg explicit 1272fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1273fb8a8121Smrg tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 1274f9a78e0eSmrg : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 1275f9a78e0eSmrg std::forward<_U2>(__in.second)) { } 1276f9a78e0eSmrg 1277fb8a8121Smrg // Tuple assignment. 1278fb8a8121Smrg 1279fb8a8121Smrg _GLIBCXX20_CONSTEXPR 12804fee23f9Smrg tuple& 1281b1e83836Smrg operator=(__conditional_t<__assignable<const _T1&, const _T2&>(), 1282181254a7Smrg const tuple&, 1283b1e83836Smrg const __nonesuch&> __in) 1284181254a7Smrg noexcept(__nothrow_assignable<const _T1&, const _T2&>()) 12854fee23f9Smrg { 1286181254a7Smrg this->_M_assign(__in); 12874fee23f9Smrg return *this; 12884fee23f9Smrg } 12894fee23f9Smrg 1290fb8a8121Smrg _GLIBCXX20_CONSTEXPR 12914fee23f9Smrg tuple& 1292b1e83836Smrg operator=(__conditional_t<__assignable<_T1, _T2>(), 1293181254a7Smrg tuple&&, 1294b1e83836Smrg __nonesuch&&> __in) 1295181254a7Smrg noexcept(__nothrow_assignable<_T1, _T2>()) 12964fee23f9Smrg { 1297181254a7Smrg this->_M_assign(std::move(__in)); 12984fee23f9Smrg return *this; 12994fee23f9Smrg } 13004fee23f9Smrg 13014fee23f9Smrg template<typename _U1, typename _U2> 1302fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1303181254a7Smrg __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&> 13044fee23f9Smrg operator=(const tuple<_U1, _U2>& __in) 1305181254a7Smrg noexcept(__nothrow_assignable<const _U1&, const _U2&>()) 13064fee23f9Smrg { 1307181254a7Smrg this->_M_assign(__in); 13084fee23f9Smrg return *this; 13094fee23f9Smrg } 13104fee23f9Smrg 13114fee23f9Smrg template<typename _U1, typename _U2> 1312fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1313181254a7Smrg __enable_if_t<__assignable<_U1, _U2>(), tuple&> 13144fee23f9Smrg operator=(tuple<_U1, _U2>&& __in) 1315181254a7Smrg noexcept(__nothrow_assignable<_U1, _U2>()) 13164fee23f9Smrg { 1317181254a7Smrg this->_M_assign(std::move(__in)); 13184fee23f9Smrg return *this; 13194fee23f9Smrg } 13204fee23f9Smrg 13214fee23f9Smrg template<typename _U1, typename _U2> 1322fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1323181254a7Smrg __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&> 13244fee23f9Smrg operator=(const pair<_U1, _U2>& __in) 1325181254a7Smrg noexcept(__nothrow_assignable<const _U1&, const _U2&>()) 13264fee23f9Smrg { 132748fb7bfaSmrg this->_M_head(*this) = __in.first; 132848fb7bfaSmrg this->_M_tail(*this)._M_head(*this) = __in.second; 13294fee23f9Smrg return *this; 13304fee23f9Smrg } 13314fee23f9Smrg 13324fee23f9Smrg template<typename _U1, typename _U2> 1333fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1334181254a7Smrg __enable_if_t<__assignable<_U1, _U2>(), tuple&> 13354fee23f9Smrg operator=(pair<_U1, _U2>&& __in) 1336181254a7Smrg noexcept(__nothrow_assignable<_U1, _U2>()) 13374fee23f9Smrg { 133848fb7bfaSmrg this->_M_head(*this) = std::forward<_U1>(__in.first); 133948fb7bfaSmrg this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 13404fee23f9Smrg return *this; 13414fee23f9Smrg } 13424fee23f9Smrg 1343fb8a8121Smrg _GLIBCXX20_CONSTEXPR 13444fee23f9Smrg void 13454fee23f9Smrg swap(tuple& __in) 1346181254a7Smrg noexcept(__and_<__is_nothrow_swappable<_T1>, 1347181254a7Smrg __is_nothrow_swappable<_T2>>::value) 134848fb7bfaSmrg { _Inherited::_M_swap(__in); } 13494fee23f9Smrg }; 13504fee23f9Smrg 13514fee23f9Smrg 1352b17d1066Smrg /// class tuple_size 1353b17d1066Smrg template<typename... _Elements> 1354b17d1066Smrg struct tuple_size<tuple<_Elements...>> 1355b1e83836Smrg : public integral_constant<size_t, sizeof...(_Elements)> { }; 1356b17d1066Smrg 1357b1e83836Smrg#if __cplusplus >= 201703L 1358b1e83836Smrg template<typename... _Types> 1359b1e83836Smrg inline constexpr size_t tuple_size_v<tuple<_Types...>> 1360b1e83836Smrg = sizeof...(_Types); 1361b1e83836Smrg 1362b1e83836Smrg template<typename... _Types> 1363b1e83836Smrg inline constexpr size_t tuple_size_v<const tuple<_Types...>> 1364b1e83836Smrg = sizeof...(_Types); 1365b17d1066Smrg#endif 1366b17d1066Smrg 1367b1e83836Smrg /// Trait to get the Ith element type from a tuple. 1368b1e83836Smrg template<size_t __i, typename... _Types> 1369b1e83836Smrg struct tuple_element<__i, tuple<_Types...>> 13704fee23f9Smrg { 1371b1e83836Smrg static_assert(__i < sizeof...(_Types), "tuple index must be in range"); 1372b1e83836Smrg 1373b1e83836Smrg using type = typename _Nth_type<__i, _Types...>::type; 13744fee23f9Smrg }; 13754fee23f9Smrg 1376b1e83836Smrg template<size_t __i, typename _Head, typename... _Tail> 13774d5abbe8Smrg constexpr _Head& 137848fb7bfaSmrg __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 137948fb7bfaSmrg { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 13804fee23f9Smrg 1381b1e83836Smrg template<size_t __i, typename _Head, typename... _Tail> 13824d5abbe8Smrg constexpr const _Head& 138348fb7bfaSmrg __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 138448fb7bfaSmrg { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 13854fee23f9Smrg 1386b1e83836Smrg // Deleted overload to improve diagnostics for invalid indices 1387b1e83836Smrg template<size_t __i, typename... _Types> 1388b1e83836Smrg __enable_if_t<(__i >= sizeof...(_Types))> 1389b1e83836Smrg __get_helper(const tuple<_Types...>&) = delete; 1390b1e83836Smrg 13914d5abbe8Smrg /// Return a reference to the ith element of a tuple. 1392b1e83836Smrg template<size_t __i, typename... _Elements> 13934d5abbe8Smrg constexpr __tuple_element_t<__i, tuple<_Elements...>>& 139448fb7bfaSmrg get(tuple<_Elements...>& __t) noexcept 13955f4cdc7dSskrll { return std::__get_helper<__i>(__t); } 13964fee23f9Smrg 13974d5abbe8Smrg /// Return a const reference to the ith element of a const tuple. 1398b1e83836Smrg template<size_t __i, typename... _Elements> 13994d5abbe8Smrg constexpr const __tuple_element_t<__i, tuple<_Elements...>>& 140048fb7bfaSmrg get(const tuple<_Elements...>& __t) noexcept 14015f4cdc7dSskrll { return std::__get_helper<__i>(__t); } 14024fee23f9Smrg 14034d5abbe8Smrg /// Return an rvalue reference to the ith element of a tuple rvalue. 1404b1e83836Smrg template<size_t __i, typename... _Elements> 14054d5abbe8Smrg constexpr __tuple_element_t<__i, tuple<_Elements...>>&& 140648fb7bfaSmrg get(tuple<_Elements...>&& __t) noexcept 14074d5abbe8Smrg { 14084d5abbe8Smrg typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 1409b1e83836Smrg return std::forward<__element_type>(std::__get_helper<__i>(__t)); 14104d5abbe8Smrg } 141148fb7bfaSmrg 1412a3e9eb18Smrg /// Return a const rvalue reference to the ith element of a const tuple rvalue. 1413b1e83836Smrg template<size_t __i, typename... _Elements> 1414a3e9eb18Smrg constexpr const __tuple_element_t<__i, tuple<_Elements...>>&& 1415a3e9eb18Smrg get(const tuple<_Elements...>&& __t) noexcept 1416a3e9eb18Smrg { 1417a3e9eb18Smrg typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 1418b1e83836Smrg return std::forward<const __element_type>(std::__get_helper<__i>(__t)); 1419a3e9eb18Smrg } 1420a3e9eb18Smrg 1421b1e83836Smrg /// @cond undocumented 1422b1e83836Smrg // Deleted overload chosen for invalid indices. 1423b1e83836Smrg template<size_t __i, typename... _Elements> 1424b1e83836Smrg constexpr __enable_if_t<(__i >= sizeof...(_Elements))> 1425b1e83836Smrg get(const tuple<_Elements...>&) = delete; 1426b1e83836Smrg /// @endcond 1427b1e83836Smrg 1428181254a7Smrg#if __cplusplus >= 201402L 14294fee23f9Smrg 1430b1e83836Smrg#define __cpp_lib_tuples_by_type 201304L 14314d5abbe8Smrg 14324d5abbe8Smrg /// Return a reference to the unique element of type _Tp of a tuple. 14334d5abbe8Smrg template <typename _Tp, typename... _Types> 14344d5abbe8Smrg constexpr _Tp& 14354d5abbe8Smrg get(tuple<_Types...>& __t) noexcept 1436b1e83836Smrg { 1437b1e83836Smrg constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1438b1e83836Smrg static_assert(__idx < sizeof...(_Types), 1439b1e83836Smrg "the type T in std::get<T> must occur exactly once in the tuple"); 1440b1e83836Smrg return std::__get_helper<__idx>(__t); 1441b1e83836Smrg } 14424d5abbe8Smrg 14434d5abbe8Smrg /// Return a reference to the unique element of type _Tp of a tuple rvalue. 14444d5abbe8Smrg template <typename _Tp, typename... _Types> 14454d5abbe8Smrg constexpr _Tp&& 14464d5abbe8Smrg get(tuple<_Types...>&& __t) noexcept 1447b1e83836Smrg { 1448b1e83836Smrg constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1449b1e83836Smrg static_assert(__idx < sizeof...(_Types), 1450b1e83836Smrg "the type T in std::get<T> must occur exactly once in the tuple"); 1451b1e83836Smrg return std::forward<_Tp>(std::__get_helper<__idx>(__t)); 1452b1e83836Smrg } 14534d5abbe8Smrg 14544d5abbe8Smrg /// Return a const reference to the unique element of type _Tp of a tuple. 14554d5abbe8Smrg template <typename _Tp, typename... _Types> 14564d5abbe8Smrg constexpr const _Tp& 14574d5abbe8Smrg get(const tuple<_Types...>& __t) noexcept 1458b1e83836Smrg { 1459b1e83836Smrg constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1460b1e83836Smrg static_assert(__idx < sizeof...(_Types), 1461b1e83836Smrg "the type T in std::get<T> must occur exactly once in the tuple"); 1462b1e83836Smrg return std::__get_helper<__idx>(__t); 1463b1e83836Smrg } 1464a3e9eb18Smrg 1465a3e9eb18Smrg /// Return a const reference to the unique element of type _Tp of 1466a3e9eb18Smrg /// a const tuple rvalue. 1467a3e9eb18Smrg template <typename _Tp, typename... _Types> 1468a3e9eb18Smrg constexpr const _Tp&& 1469a3e9eb18Smrg get(const tuple<_Types...>&& __t) noexcept 1470b1e83836Smrg { 1471b1e83836Smrg constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1472b1e83836Smrg static_assert(__idx < sizeof...(_Types), 1473b1e83836Smrg "the type T in std::get<T> must occur exactly once in the tuple"); 1474b1e83836Smrg return std::forward<const _Tp>(std::__get_helper<__idx>(__t)); 1475b1e83836Smrg } 14764d5abbe8Smrg#endif 14774d5abbe8Smrg 14784d5abbe8Smrg // This class performs the comparison operations on tuples 14794d5abbe8Smrg template<typename _Tp, typename _Up, size_t __i, size_t __size> 14804d5abbe8Smrg struct __tuple_compare 14814fee23f9Smrg { 148248fb7bfaSmrg static constexpr bool 148348fb7bfaSmrg __eq(const _Tp& __t, const _Up& __u) 14844fee23f9Smrg { 14854d5abbe8Smrg return bool(std::get<__i>(__t) == std::get<__i>(__u)) 14864d5abbe8Smrg && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); 14874fee23f9Smrg } 14884fee23f9Smrg 148948fb7bfaSmrg static constexpr bool 149048fb7bfaSmrg __less(const _Tp& __t, const _Up& __u) 14914fee23f9Smrg { 14924d5abbe8Smrg return bool(std::get<__i>(__t) < std::get<__i>(__u)) 14934d5abbe8Smrg || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) 14944d5abbe8Smrg && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); 14954fee23f9Smrg } 14964fee23f9Smrg }; 14974fee23f9Smrg 14984d5abbe8Smrg template<typename _Tp, typename _Up, size_t __size> 14994d5abbe8Smrg struct __tuple_compare<_Tp, _Up, __size, __size> 15004fee23f9Smrg { 150148fb7bfaSmrg static constexpr bool 150248fb7bfaSmrg __eq(const _Tp&, const _Up&) { return true; } 15034fee23f9Smrg 150448fb7bfaSmrg static constexpr bool 150548fb7bfaSmrg __less(const _Tp&, const _Up&) { return false; } 15064fee23f9Smrg }; 15074fee23f9Smrg 15084fee23f9Smrg template<typename... _TElements, typename... _UElements> 150948fb7bfaSmrg constexpr bool 15104fee23f9Smrg operator==(const tuple<_TElements...>& __t, 15114fee23f9Smrg const tuple<_UElements...>& __u) 15124fee23f9Smrg { 15134d5abbe8Smrg static_assert(sizeof...(_TElements) == sizeof...(_UElements), 15144d5abbe8Smrg "tuple objects can only be compared if they have equal sizes."); 15154d5abbe8Smrg using __compare = __tuple_compare<tuple<_TElements...>, 15164d5abbe8Smrg tuple<_UElements...>, 15174d5abbe8Smrg 0, sizeof...(_TElements)>; 15184d5abbe8Smrg return __compare::__eq(__t, __u); 15194fee23f9Smrg } 15204fee23f9Smrg 1521fb8a8121Smrg#if __cpp_lib_three_way_comparison 1522fb8a8121Smrg template<typename _Cat, typename _Tp, typename _Up> 1523fb8a8121Smrg constexpr _Cat 1524fb8a8121Smrg __tuple_cmp(const _Tp&, const _Up&, index_sequence<>) 1525fb8a8121Smrg { return _Cat::equivalent; } 1526fb8a8121Smrg 1527fb8a8121Smrg template<typename _Cat, typename _Tp, typename _Up, 1528fb8a8121Smrg size_t _Idx0, size_t... _Idxs> 1529fb8a8121Smrg constexpr _Cat 1530fb8a8121Smrg __tuple_cmp(const _Tp& __t, const _Up& __u, 1531fb8a8121Smrg index_sequence<_Idx0, _Idxs...>) 1532fb8a8121Smrg { 1533fb8a8121Smrg auto __c 1534fb8a8121Smrg = __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u)); 1535fb8a8121Smrg if (__c != 0) 1536fb8a8121Smrg return __c; 1537fb8a8121Smrg return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>()); 1538fb8a8121Smrg } 1539fb8a8121Smrg 1540fb8a8121Smrg template<typename... _Tps, typename... _Ups> 1541fb8a8121Smrg constexpr 1542fb8a8121Smrg common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...> 1543fb8a8121Smrg operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u) 1544fb8a8121Smrg { 1545fb8a8121Smrg using _Cat 1546fb8a8121Smrg = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>; 1547fb8a8121Smrg return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>()); 1548fb8a8121Smrg } 1549fb8a8121Smrg#else 15504fee23f9Smrg template<typename... _TElements, typename... _UElements> 155148fb7bfaSmrg constexpr bool 15524fee23f9Smrg operator<(const tuple<_TElements...>& __t, 15534fee23f9Smrg const tuple<_UElements...>& __u) 15544fee23f9Smrg { 15554d5abbe8Smrg static_assert(sizeof...(_TElements) == sizeof...(_UElements), 15564d5abbe8Smrg "tuple objects can only be compared if they have equal sizes."); 15574d5abbe8Smrg using __compare = __tuple_compare<tuple<_TElements...>, 15584d5abbe8Smrg tuple<_UElements...>, 15594d5abbe8Smrg 0, sizeof...(_TElements)>; 15604d5abbe8Smrg return __compare::__less(__t, __u); 15614fee23f9Smrg } 15624fee23f9Smrg 15634fee23f9Smrg template<typename... _TElements, typename... _UElements> 15644d5abbe8Smrg constexpr bool 15654fee23f9Smrg operator!=(const tuple<_TElements...>& __t, 15664fee23f9Smrg const tuple<_UElements...>& __u) 15674fee23f9Smrg { return !(__t == __u); } 15684fee23f9Smrg 15694fee23f9Smrg template<typename... _TElements, typename... _UElements> 15704d5abbe8Smrg constexpr bool 15714fee23f9Smrg operator>(const tuple<_TElements...>& __t, 15724fee23f9Smrg const tuple<_UElements...>& __u) 15734fee23f9Smrg { return __u < __t; } 15744fee23f9Smrg 15754fee23f9Smrg template<typename... _TElements, typename... _UElements> 15764d5abbe8Smrg constexpr bool 15774fee23f9Smrg operator<=(const tuple<_TElements...>& __t, 15784fee23f9Smrg const tuple<_UElements...>& __u) 15794fee23f9Smrg { return !(__u < __t); } 15804fee23f9Smrg 15814fee23f9Smrg template<typename... _TElements, typename... _UElements> 15824d5abbe8Smrg constexpr bool 15834fee23f9Smrg operator>=(const tuple<_TElements...>& __t, 15844fee23f9Smrg const tuple<_UElements...>& __u) 15854fee23f9Smrg { return !(__t < __u); } 1586fb8a8121Smrg#endif // three_way_comparison 15874fee23f9Smrg 15884fee23f9Smrg // NB: DR 705. 1589*0a307195Smrg /// Create a tuple containing copies of the arguments 15904fee23f9Smrg template<typename... _Elements> 159148fb7bfaSmrg constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 15924fee23f9Smrg make_tuple(_Elements&&... __args) 15934fee23f9Smrg { 15944fee23f9Smrg typedef tuple<typename __decay_and_strip<_Elements>::__type...> 15954fee23f9Smrg __result_type; 15964fee23f9Smrg return __result_type(std::forward<_Elements>(__args)...); 15974fee23f9Smrg } 15984fee23f9Smrg 1599f9a78e0eSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 1600f9a78e0eSmrg // 2275. Why is forward_as_tuple not constexpr? 1601*0a307195Smrg /// Create a tuple of lvalue or rvalue references to the arguments 160248fb7bfaSmrg template<typename... _Elements> 1603f9a78e0eSmrg constexpr tuple<_Elements&&...> 160448fb7bfaSmrg forward_as_tuple(_Elements&&... __args) noexcept 160548fb7bfaSmrg { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 16064fee23f9Smrg 1607b1e83836Smrg // Declarations of std::array and its std::get overloads, so that 1608b1e83836Smrg // std::tuple_cat can use them if <tuple> is included before <array>. 1609b1e83836Smrg 1610b1e83836Smrg template<typename _Tp, size_t _Nm> struct array; 1611b1e83836Smrg 1612b1e83836Smrg template<size_t _Int, typename _Tp, size_t _Nm> 1613b1e83836Smrg constexpr _Tp& 1614b1e83836Smrg get(array<_Tp, _Nm>&) noexcept; 1615b1e83836Smrg 1616b1e83836Smrg template<size_t _Int, typename _Tp, size_t _Nm> 1617b1e83836Smrg constexpr _Tp&& 1618b1e83836Smrg get(array<_Tp, _Nm>&&) noexcept; 1619b1e83836Smrg 1620b1e83836Smrg template<size_t _Int, typename _Tp, size_t _Nm> 1621b1e83836Smrg constexpr const _Tp& 1622b1e83836Smrg get(const array<_Tp, _Nm>&) noexcept; 1623b1e83836Smrg 1624b1e83836Smrg template<size_t _Int, typename _Tp, size_t _Nm> 1625b1e83836Smrg constexpr const _Tp&& 1626b1e83836Smrg get(const array<_Tp, _Nm>&&) noexcept; 1627b1e83836Smrg 1628*0a307195Smrg /// @cond undocumented 16294d5abbe8Smrg template<size_t, typename, typename, size_t> 163048fb7bfaSmrg struct __make_tuple_impl; 163148fb7bfaSmrg 16324d5abbe8Smrg template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> 163348fb7bfaSmrg struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 16344d5abbe8Smrg : __make_tuple_impl<_Idx + 1, 16354d5abbe8Smrg tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, 16364d5abbe8Smrg _Tuple, _Nm> 16374d5abbe8Smrg { }; 163848fb7bfaSmrg 1639b1e83836Smrg template<size_t _Nm, typename _Tuple, typename... _Tp> 164048fb7bfaSmrg struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 164148fb7bfaSmrg { 164248fb7bfaSmrg typedef tuple<_Tp...> __type; 164348fb7bfaSmrg }; 164448fb7bfaSmrg 164548fb7bfaSmrg template<typename _Tuple> 164648fb7bfaSmrg struct __do_make_tuple 1647b1e83836Smrg : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value> 164848fb7bfaSmrg { }; 164948fb7bfaSmrg 165048fb7bfaSmrg // Returns the std::tuple equivalent of a tuple-like type. 165148fb7bfaSmrg template<typename _Tuple> 165248fb7bfaSmrg struct __make_tuple 1653181254a7Smrg : public __do_make_tuple<__remove_cvref_t<_Tuple>> 165448fb7bfaSmrg { }; 165548fb7bfaSmrg 165648fb7bfaSmrg // Combines several std::tuple's into a single one. 165748fb7bfaSmrg template<typename...> 165848fb7bfaSmrg struct __combine_tuples; 165948fb7bfaSmrg 166048fb7bfaSmrg template<> 166148fb7bfaSmrg struct __combine_tuples<> 166248fb7bfaSmrg { 166348fb7bfaSmrg typedef tuple<> __type; 166448fb7bfaSmrg }; 166548fb7bfaSmrg 166648fb7bfaSmrg template<typename... _Ts> 166748fb7bfaSmrg struct __combine_tuples<tuple<_Ts...>> 166848fb7bfaSmrg { 166948fb7bfaSmrg typedef tuple<_Ts...> __type; 167048fb7bfaSmrg }; 167148fb7bfaSmrg 167248fb7bfaSmrg template<typename... _T1s, typename... _T2s, typename... _Rem> 167348fb7bfaSmrg struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 167448fb7bfaSmrg { 167548fb7bfaSmrg typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 167648fb7bfaSmrg _Rem...>::__type __type; 167748fb7bfaSmrg }; 167848fb7bfaSmrg 167948fb7bfaSmrg // Computes the result type of tuple_cat given a set of tuple-like types. 168048fb7bfaSmrg template<typename... _Tpls> 168148fb7bfaSmrg struct __tuple_cat_result 168248fb7bfaSmrg { 168348fb7bfaSmrg typedef typename __combine_tuples 168448fb7bfaSmrg <typename __make_tuple<_Tpls>::__type...>::__type __type; 168548fb7bfaSmrg }; 168648fb7bfaSmrg 168748fb7bfaSmrg // Helper to determine the index set for the first tuple-like 168848fb7bfaSmrg // type of a given set. 168948fb7bfaSmrg template<typename...> 169048fb7bfaSmrg struct __make_1st_indices; 169148fb7bfaSmrg 169248fb7bfaSmrg template<> 169348fb7bfaSmrg struct __make_1st_indices<> 169448fb7bfaSmrg { 1695b1e83836Smrg typedef _Index_tuple<> __type; 169648fb7bfaSmrg }; 169748fb7bfaSmrg 169848fb7bfaSmrg template<typename _Tp, typename... _Tpls> 169948fb7bfaSmrg struct __make_1st_indices<_Tp, _Tpls...> 170048fb7bfaSmrg { 1701b1e83836Smrg typedef typename _Build_index_tuple<tuple_size< 1702b1e83836Smrg typename remove_reference<_Tp>::type>::value>::__type __type; 170348fb7bfaSmrg }; 170448fb7bfaSmrg 170548fb7bfaSmrg // Performs the actual concatenation by step-wise expanding tuple-like 170648fb7bfaSmrg // objects into the elements, which are finally forwarded into the 170748fb7bfaSmrg // result tuple. 170848fb7bfaSmrg template<typename _Ret, typename _Indices, typename... _Tpls> 170948fb7bfaSmrg struct __tuple_concater; 171048fb7bfaSmrg 1711b1e83836Smrg template<typename _Ret, size_t... _Is, typename _Tp, typename... _Tpls> 1712b1e83836Smrg struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...> 171348fb7bfaSmrg { 171448fb7bfaSmrg template<typename... _Us> 171548fb7bfaSmrg static constexpr _Ret 171648fb7bfaSmrg _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 171748fb7bfaSmrg { 171848fb7bfaSmrg typedef typename __make_1st_indices<_Tpls...>::__type __idx; 171948fb7bfaSmrg typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 172048fb7bfaSmrg return __next::_S_do(std::forward<_Tpls>(__tps)..., 172148fb7bfaSmrg std::forward<_Us>(__us)..., 172248fb7bfaSmrg std::get<_Is>(std::forward<_Tp>(__tp))...); 172348fb7bfaSmrg } 172448fb7bfaSmrg }; 172548fb7bfaSmrg 172648fb7bfaSmrg template<typename _Ret> 1727b1e83836Smrg struct __tuple_concater<_Ret, _Index_tuple<>> 172848fb7bfaSmrg { 172948fb7bfaSmrg template<typename... _Us> 173048fb7bfaSmrg static constexpr _Ret 173148fb7bfaSmrg _S_do(_Us&&... __us) 173248fb7bfaSmrg { 173348fb7bfaSmrg return _Ret(std::forward<_Us>(__us)...); 173448fb7bfaSmrg } 173548fb7bfaSmrg }; 173648fb7bfaSmrg 1737b1e83836Smrg template<typename... _Tps> 1738b1e83836Smrg struct __is_tuple_like_impl<tuple<_Tps...>> : true_type 1739b1e83836Smrg { }; 1740*0a307195Smrg /// @endcond 1741b1e83836Smrg 1742*0a307195Smrg /// Create a `tuple` containing all elements from multiple tuple-like objects 174348fb7bfaSmrg template<typename... _Tpls, typename = typename 174448fb7bfaSmrg enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 174548fb7bfaSmrg constexpr auto 174648fb7bfaSmrg tuple_cat(_Tpls&&... __tpls) 174748fb7bfaSmrg -> typename __tuple_cat_result<_Tpls...>::__type 174848fb7bfaSmrg { 174948fb7bfaSmrg typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 175048fb7bfaSmrg typedef typename __make_1st_indices<_Tpls...>::__type __idx; 175148fb7bfaSmrg typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 175248fb7bfaSmrg return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 17534fee23f9Smrg } 17544fee23f9Smrg 1755f9a78e0eSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 1756f9a78e0eSmrg // 2301. Why is tie not constexpr? 1757*0a307195Smrg /// Return a tuple of lvalue references bound to the arguments 17584fee23f9Smrg template<typename... _Elements> 1759f9a78e0eSmrg constexpr tuple<_Elements&...> 176048fb7bfaSmrg tie(_Elements&... __args) noexcept 17614fee23f9Smrg { return tuple<_Elements&...>(__args...); } 17624fee23f9Smrg 1763*0a307195Smrg /// Exchange the values of two tuples 17644fee23f9Smrg template<typename... _Elements> 1765fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1766b17d1066Smrg inline 1767b17d1066Smrg#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 1768b17d1066Smrg // Constrained free swap overload, see p0185r1 1769b17d1066Smrg typename enable_if<__and_<__is_swappable<_Elements>...>::value 1770b17d1066Smrg >::type 1771b17d1066Smrg#else 1772b17d1066Smrg void 1773b17d1066Smrg#endif 17744fee23f9Smrg swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 177548fb7bfaSmrg noexcept(noexcept(__x.swap(__y))) 17764fee23f9Smrg { __x.swap(__y); } 17774fee23f9Smrg 1778b17d1066Smrg#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 1779*0a307195Smrg /// Exchange the values of two const tuples (if const elements can be swapped) 1780b17d1066Smrg template<typename... _Elements> 1781fb8a8121Smrg _GLIBCXX20_CONSTEXPR 1782b17d1066Smrg typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type 1783b17d1066Smrg swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete; 1784b17d1066Smrg#endif 1785b17d1066Smrg 17864fee23f9Smrg // A class (and instance) which can be used in 'tie' when an element 1787b17d1066Smrg // of a tuple is not required. 1788b17d1066Smrg // _GLIBCXX14_CONSTEXPR 1789b17d1066Smrg // 2933. PR for LWG 2773 could be clearer 17904fee23f9Smrg struct _Swallow_assign 17914fee23f9Smrg { 17924fee23f9Smrg template<class _Tp> 1793b17d1066Smrg _GLIBCXX14_CONSTEXPR const _Swallow_assign& 179448fb7bfaSmrg operator=(const _Tp&) const 17954fee23f9Smrg { return *this; } 17964fee23f9Smrg }; 17974fee23f9Smrg 1798b17d1066Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 1799b17d1066Smrg // 2773. Making std::ignore constexpr 1800*0a307195Smrg /** Used with `std::tie` to ignore an element of a tuple 1801*0a307195Smrg * 1802*0a307195Smrg * When using `std::tie` to assign the elements of a tuple to variables, 1803*0a307195Smrg * unwanted elements can be ignored by using `std::ignore`. For example: 1804*0a307195Smrg * 1805*0a307195Smrg * ``` 1806*0a307195Smrg * int x, y; 1807*0a307195Smrg * std::tie(x, std::ignore, y) = std::make_tuple(1, 2, 3); 1808*0a307195Smrg * ``` 1809*0a307195Smrg * 1810*0a307195Smrg * This assignment will perform `x=1; std::ignore=2; y=3;` which results 1811*0a307195Smrg * in the second element being ignored. 1812*0a307195Smrg * 1813*0a307195Smrg * @since C++11 1814*0a307195Smrg */ 1815b17d1066Smrg _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{}; 18164fee23f9Smrg 181748fb7bfaSmrg /// Partial specialization for tuples 181848fb7bfaSmrg template<typename... _Types, typename _Alloc> 181948fb7bfaSmrg struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 182048fb7bfaSmrg 182148fb7bfaSmrg // See stl_pair.h... 1822fb8a8121Smrg /** "piecewise construction" using a tuple of arguments for each member. 1823fb8a8121Smrg * 1824fb8a8121Smrg * @param __first Arguments for the first member of the pair. 1825fb8a8121Smrg * @param __second Arguments for the second member of the pair. 1826fb8a8121Smrg * 1827fb8a8121Smrg * The elements of each tuple will be used as the constructor arguments 1828fb8a8121Smrg * for the data members of the pair. 1829fb8a8121Smrg */ 183048fb7bfaSmrg template<class _T1, class _T2> 183148fb7bfaSmrg template<typename... _Args1, typename... _Args2> 1832fb8a8121Smrg _GLIBCXX20_CONSTEXPR 183348fb7bfaSmrg inline 183448fb7bfaSmrg pair<_T1, _T2>:: 183548fb7bfaSmrg pair(piecewise_construct_t, 183648fb7bfaSmrg tuple<_Args1...> __first, tuple<_Args2...> __second) 183748fb7bfaSmrg : pair(__first, __second, 183848fb7bfaSmrg typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 183948fb7bfaSmrg typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 184048fb7bfaSmrg { } 184148fb7bfaSmrg 184248fb7bfaSmrg template<class _T1, class _T2> 1843b1e83836Smrg template<typename... _Args1, size_t... _Indexes1, 1844b1e83836Smrg typename... _Args2, size_t... _Indexes2> 1845fb8a8121Smrg _GLIBCXX20_CONSTEXPR inline 184648fb7bfaSmrg pair<_T1, _T2>:: 184748fb7bfaSmrg pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 184848fb7bfaSmrg _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 184948fb7bfaSmrg : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 185048fb7bfaSmrg second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 185148fb7bfaSmrg { } 185248fb7bfaSmrg 1853181254a7Smrg#if __cplusplus >= 201703L 1854fb8a8121Smrg 1855fb8a8121Smrg // Unpack a std::tuple into a type trait and use its value. 1856fb8a8121Smrg // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value. 1857fb8a8121Smrg // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value. 1858fb8a8121Smrg // Otherwise the result is false (because we don't know if std::get throws). 1859fb8a8121Smrg template<template<typename...> class _Trait, typename _Tp, typename _Tuple> 1860fb8a8121Smrg inline constexpr bool __unpack_std_tuple = false; 1861fb8a8121Smrg 1862fb8a8121Smrg template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1863fb8a8121Smrg inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>> 1864fb8a8121Smrg = _Trait<_Tp, _Up...>::value; 1865fb8a8121Smrg 1866fb8a8121Smrg template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1867fb8a8121Smrg inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&> 1868fb8a8121Smrg = _Trait<_Tp, _Up&...>::value; 1869fb8a8121Smrg 1870fb8a8121Smrg template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1871fb8a8121Smrg inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>> 1872fb8a8121Smrg = _Trait<_Tp, const _Up...>::value; 1873fb8a8121Smrg 1874fb8a8121Smrg template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1875fb8a8121Smrg inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&> 1876fb8a8121Smrg = _Trait<_Tp, const _Up&...>::value; 1877fb8a8121Smrg 1878b1e83836Smrg# define __cpp_lib_apply 201603L 1879b17d1066Smrg 1880b17d1066Smrg template <typename _Fn, typename _Tuple, size_t... _Idx> 1881b17d1066Smrg constexpr decltype(auto) 1882b17d1066Smrg __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>) 1883b17d1066Smrg { 1884b17d1066Smrg return std::__invoke(std::forward<_Fn>(__f), 1885b17d1066Smrg std::get<_Idx>(std::forward<_Tuple>(__t))...); 1886b17d1066Smrg } 1887b17d1066Smrg 1888b17d1066Smrg template <typename _Fn, typename _Tuple> 1889b17d1066Smrg constexpr decltype(auto) 1890b17d1066Smrg apply(_Fn&& __f, _Tuple&& __t) 1891fb8a8121Smrg noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>) 1892b17d1066Smrg { 1893181254a7Smrg using _Indices 1894181254a7Smrg = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>; 1895b17d1066Smrg return std::__apply_impl(std::forward<_Fn>(__f), 1896b17d1066Smrg std::forward<_Tuple>(__t), 1897b17d1066Smrg _Indices{}); 1898b17d1066Smrg } 1899b17d1066Smrg 1900b1e83836Smrg#define __cpp_lib_make_from_tuple 201606L 1901b17d1066Smrg 1902b17d1066Smrg template <typename _Tp, typename _Tuple, size_t... _Idx> 1903b17d1066Smrg constexpr _Tp 1904b17d1066Smrg __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>) 1905b17d1066Smrg { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); } 1906b17d1066Smrg 1907b17d1066Smrg template <typename _Tp, typename _Tuple> 1908b17d1066Smrg constexpr _Tp 1909b17d1066Smrg make_from_tuple(_Tuple&& __t) 1910fb8a8121Smrg noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>) 1911b17d1066Smrg { 1912b17d1066Smrg return __make_from_tuple_impl<_Tp>( 1913b17d1066Smrg std::forward<_Tuple>(__t), 1914181254a7Smrg make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>{}); 1915b17d1066Smrg } 1916b17d1066Smrg#endif // C++17 1917b17d1066Smrg 191848fb7bfaSmrg /// @} 191948fb7bfaSmrg 192048fb7bfaSmrg_GLIBCXX_END_NAMESPACE_VERSION 192148fb7bfaSmrg} // namespace std 192248fb7bfaSmrg 192348fb7bfaSmrg#endif // C++11 19244fee23f9Smrg 19254fee23f9Smrg#endif // _GLIBCXX_TUPLE 1926