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