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