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