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