]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/tuple
Move dg-error directives to relevant lines
[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
894d0b15 1246 /**
894d0b15
CF
1247 * Recursive case for tuple_element: strip off the first element in
1248 * the tuple and retrieve the (i-1)th element of the remaining tuple.
894d0b15 1249 */
740508be 1250 template<std::size_t __i, typename _Head, typename... _Tail>
894d0b15
CF
1251 struct tuple_element<__i, tuple<_Head, _Tail...> >
1252 : tuple_element<__i - 1, tuple<_Tail...> > { };
1253
1254 /**
894d0b15 1255 * Basis case for tuple_element: The first element is the one we're seeking.
894d0b15
CF
1256 */
1257 template<typename _Head, typename... _Tail>
1258 struct tuple_element<0, tuple<_Head, _Tail...> >
1259 {
1260 typedef _Head type;
1261 };
1262
664e12c1 1263 /// class tuple_size
894d0b15 1264 template<typename... _Elements>
664e12c1
PC
1265 struct tuple_size<tuple<_Elements...>>
1266 : public integral_constant<std::size_t, sizeof...(_Elements)> { };
894d0b15 1267
137422c8
VV
1268#if __cplusplus > 201402L
1269 template <typename _Tp>
1270 constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1271#endif
1272
740508be 1273 template<std::size_t __i, typename _Head, typename... _Tail>
af222e74 1274 constexpr _Head&
173f26ae 1275 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
9480716c 1276 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
894d0b15 1277
740508be 1278 template<std::size_t __i, typename _Head, typename... _Tail>
af222e74 1279 constexpr const _Head&
173f26ae 1280 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
9480716c 1281 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
894d0b15 1282
af222e74 1283 /// Return a reference to the ith element of a tuple.
740508be 1284 template<std::size_t __i, typename... _Elements>
af222e74 1285 constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1aa1114b 1286 get(tuple<_Elements...>& __t) noexcept
39e6a690 1287 { return std::__get_helper<__i>(__t); }
894d0b15 1288
af222e74 1289 /// Return a const reference to the ith element of a const tuple.
740508be 1290 template<std::size_t __i, typename... _Elements>
af222e74 1291 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1aa1114b 1292 get(const tuple<_Elements...>& __t) noexcept
39e6a690 1293 { return std::__get_helper<__i>(__t); }
894d0b15 1294
af222e74 1295 /// Return an rvalue reference to the ith element of a tuple rvalue.
1aa1114b 1296 template<std::size_t __i, typename... _Elements>
af222e74 1297 constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1aa1114b 1298 get(tuple<_Elements...>&& __t) noexcept
af222e74
JW
1299 {
1300 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1301 return std::forward<__element_type&&>(std::get<__i>(__t));
1302 }
1aa1114b 1303
b5a8fed6 1304#if __cplusplus > 201103L
a15f7cb8
ESR
1305
1306#define __cpp_lib_tuples_by_type 201304
1307
b5a8fed6 1308 template<typename _Head, size_t __i, typename... _Tail>
af222e74 1309 constexpr _Head&
b5a8fed6
JW
1310 __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1311 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1312
1313 template<typename _Head, size_t __i, typename... _Tail>
af222e74 1314 constexpr const _Head&
b5a8fed6
JW
1315 __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1316 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1317
af222e74 1318 /// Return a reference to the unique element of type _Tp of a tuple.
b5a8fed6
JW
1319 template <typename _Tp, typename... _Types>
1320 constexpr _Tp&
1321 get(tuple<_Types...>& __t) noexcept
39e6a690 1322 { return std::__get_helper2<_Tp>(__t); }
b5a8fed6 1323
af222e74 1324 /// Return a reference to the unique element of type _Tp of a tuple rvalue.
b5a8fed6
JW
1325 template <typename _Tp, typename... _Types>
1326 constexpr _Tp&&
1327 get(tuple<_Types...>&& __t) noexcept
af222e74 1328 { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
b5a8fed6 1329
af222e74 1330 /// Return a const reference to the unique element of type _Tp of a tuple.
b5a8fed6
JW
1331 template <typename _Tp, typename... _Types>
1332 constexpr const _Tp&
1333 get(const tuple<_Types...>& __t) noexcept
39e6a690 1334 { return std::__get_helper2<_Tp>(__t); }
b5a8fed6
JW
1335#endif
1336
af222e74
JW
1337 // This class performs the comparison operations on tuples
1338 template<typename _Tp, typename _Up, size_t __i, size_t __size>
1339 struct __tuple_compare
894d0b15 1340 {
af222e74 1341 static constexpr bool
a7d0c94e 1342 __eq(const _Tp& __t, const _Up& __u)
894d0b15 1343 {
75e75a08 1344 return bool(std::get<__i>(__t) == std::get<__i>(__u))
af222e74 1345 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
894d0b15 1346 }
33ac58d5 1347
af222e74 1348 static constexpr bool
a7d0c94e 1349 __less(const _Tp& __t, const _Up& __u)
894d0b15 1350 {
75e75a08 1351 return bool(std::get<__i>(__t) < std::get<__i>(__u))
af222e74
JW
1352 || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1353 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
894d0b15
CF
1354 }
1355 };
1356
af222e74
JW
1357 template<typename _Tp, typename _Up, size_t __size>
1358 struct __tuple_compare<_Tp, _Up, __size, __size>
894d0b15 1359 {
af222e74 1360 static constexpr bool
a7d0c94e 1361 __eq(const _Tp&, const _Up&) { return true; }
33ac58d5 1362
af222e74 1363 static constexpr bool
a7d0c94e 1364 __less(const _Tp&, const _Up&) { return false; }
894d0b15
CF
1365 };
1366
1367 template<typename... _TElements, typename... _UElements>
a9ba8ba5 1368 constexpr bool
894d0b15
CF
1369 operator==(const tuple<_TElements...>& __t,
1370 const tuple<_UElements...>& __u)
1371 {
af222e74
JW
1372 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1373 "tuple objects can only be compared if they have equal sizes.");
1374 using __compare = __tuple_compare<tuple<_TElements...>,
1375 tuple<_UElements...>,
1376 0, sizeof...(_TElements)>;
1377 return __compare::__eq(__t, __u);
894d0b15
CF
1378 }
1379
1380 template<typename... _TElements, typename... _UElements>
a9ba8ba5 1381 constexpr bool
894d0b15
CF
1382 operator<(const tuple<_TElements...>& __t,
1383 const tuple<_UElements...>& __u)
1384 {
af222e74
JW
1385 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1386 "tuple objects can only be compared if they have equal sizes.");
1387 using __compare = __tuple_compare<tuple<_TElements...>,
1388 tuple<_UElements...>,
1389 0, sizeof...(_TElements)>;
1390 return __compare::__less(__t, __u);
894d0b15
CF
1391 }
1392
1393 template<typename... _TElements, typename... _UElements>
fa409833 1394 constexpr bool
894d0b15
CF
1395 operator!=(const tuple<_TElements...>& __t,
1396 const tuple<_UElements...>& __u)
1397 { return !(__t == __u); }
1398
1399 template<typename... _TElements, typename... _UElements>
fa409833 1400 constexpr bool
894d0b15
CF
1401 operator>(const tuple<_TElements...>& __t,
1402 const tuple<_UElements...>& __u)
1403 { return __u < __t; }
1404
1405 template<typename... _TElements, typename... _UElements>
fa409833 1406 constexpr bool
894d0b15
CF
1407 operator<=(const tuple<_TElements...>& __t,
1408 const tuple<_UElements...>& __u)
1409 { return !(__u < __t); }
1410
1411 template<typename... _TElements, typename... _UElements>
fa409833 1412 constexpr bool
894d0b15
CF
1413 operator>=(const tuple<_TElements...>& __t,
1414 const tuple<_UElements...>& __u)
1415 { return !(__t < __u); }
1416
1417 // NB: DR 705.
1418 template<typename... _Elements>
fae3f459 1419 constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
894d0b15
CF
1420 make_tuple(_Elements&&... __args)
1421 {
1422 typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1423 __result_type;
1424 return __result_type(std::forward<_Elements>(__args)...);
1425 }
1426
cb2ef49e
JW
1427 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1428 // 2275. Why is forward_as_tuple not constexpr?
5e108459 1429 template<typename... _Elements>
cb2ef49e 1430 constexpr tuple<_Elements&&...>
1aa1114b 1431 forward_as_tuple(_Elements&&... __args) noexcept
00e9a944 1432 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
5e108459 1433
ac65b7d2
DK
1434 template<typename... _Tps>
1435 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
1436 { };
1437
ac65b7d2
DK
1438 // Internal type trait that allows us to sfinae-protect tuple_cat.
1439 template<typename _Tp>
1440 struct __is_tuple_like
1441 : public __is_tuple_like_impl<typename std::remove_cv
1442 <typename std::remove_reference<_Tp>::type>::type>::type
1443 { };
1444
af222e74 1445 template<size_t, typename, typename, size_t>
ac65b7d2
DK
1446 struct __make_tuple_impl;
1447
af222e74 1448 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
ac65b7d2 1449 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
af222e74
JW
1450 : __make_tuple_impl<_Idx + 1,
1451 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1452 _Tuple, _Nm>
1453 { };
894d0b15 1454
ac65b7d2
DK
1455 template<std::size_t _Nm, typename _Tuple, typename... _Tp>
1456 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
894d0b15 1457 {
ac65b7d2
DK
1458 typedef tuple<_Tp...> __type;
1459 };
894d0b15 1460
ac65b7d2
DK
1461 template<typename _Tuple>
1462 struct __do_make_tuple
af222e74 1463 : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
ac65b7d2
DK
1464 { };
1465
1466 // Returns the std::tuple equivalent of a tuple-like type.
1467 template<typename _Tuple>
1468 struct __make_tuple
1469 : public __do_make_tuple<typename std::remove_cv
1470 <typename std::remove_reference<_Tuple>::type>::type>
1471 { };
1472
1473 // Combines several std::tuple's into a single one.
1474 template<typename...>
1475 struct __combine_tuples;
1476
1477 template<>
1478 struct __combine_tuples<>
1479 {
1480 typedef tuple<> __type;
1481 };
1482
1483 template<typename... _Ts>
1484 struct __combine_tuples<tuple<_Ts...>>
894d0b15 1485 {
ac65b7d2
DK
1486 typedef tuple<_Ts...> __type;
1487 };
1488
1489 template<typename... _T1s, typename... _T2s, typename... _Rem>
1490 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1491 {
1492 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1493 _Rem...>::__type __type;
1494 };
1495
1496 // Computes the result type of tuple_cat given a set of tuple-like types.
1497 template<typename... _Tpls>
1498 struct __tuple_cat_result
1499 {
1500 typedef typename __combine_tuples
1501 <typename __make_tuple<_Tpls>::__type...>::__type __type;
1502 };
1503
1504 // Helper to determine the index set for the first tuple-like
1505 // type of a given set.
1506 template<typename...>
1507 struct __make_1st_indices;
1508
1509 template<>
1510 struct __make_1st_indices<>
1511 {
1512 typedef std::_Index_tuple<> __type;
1513 };
1514
1515 template<typename _Tp, typename... _Tpls>
1516 struct __make_1st_indices<_Tp, _Tpls...>
1517 {
1518 typedef typename std::_Build_index_tuple<std::tuple_size<
1519 typename std::remove_reference<_Tp>::type>::value>::__type __type;
1520 };
1521
1522 // Performs the actual concatenation by step-wise expanding tuple-like
1523 // objects into the elements, which are finally forwarded into the
1524 // result tuple.
1525 template<typename _Ret, typename _Indices, typename... _Tpls>
1526 struct __tuple_concater;
1527
1528 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
1529 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1530 {
1531 template<typename... _Us>
9480716c 1532 static constexpr _Ret
ac65b7d2
DK
1533 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1534 {
1535 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1536 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1537 return __next::_S_do(std::forward<_Tpls>(__tps)...,
1538 std::forward<_Us>(__us)...,
1539 std::get<_Is>(std::forward<_Tp>(__tp))...);
1540 }
1541 };
1542
1543 template<typename _Ret>
1544 struct __tuple_concater<_Ret, std::_Index_tuple<>>
1545 {
1546 template<typename... _Us>
9480716c 1547 static constexpr _Ret
ac65b7d2
DK
1548 _S_do(_Us&&... __us)
1549 {
1550 return _Ret(std::forward<_Us>(__us)...);
1551 }
1552 };
1553
c0ffa2ba 1554 /// tuple_cat
9480716c
DK
1555 template<typename... _Tpls, typename = typename
1556 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1557 constexpr auto
ac65b7d2 1558 tuple_cat(_Tpls&&... __tpls)
9480716c 1559 -> typename __tuple_cat_result<_Tpls...>::__type
ac65b7d2
DK
1560 {
1561 typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1562 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1563 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1564 return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
894d0b15
CF
1565 }
1566
cb2ef49e
JW
1567 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1568 // 2301. Why is tie not constexpr?
c0ffa2ba 1569 /// tie
894d0b15 1570 template<typename... _Elements>
cb2ef49e 1571 constexpr tuple<_Elements&...>
1aa1114b 1572 tie(_Elements&... __args) noexcept
894d0b15
CF
1573 { return tuple<_Elements&...>(__args...); }
1574
c0ffa2ba 1575 /// swap
3e93b275 1576 template<typename... _Elements>
6b9539e2
DK
1577 inline
1578#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1579 // Constrained free swap overload, see p0185r1
1580 typename enable_if<__and_<__is_swappable<_Elements>...>::value
1581 >::type
1582#else
1583 void
1584#endif
3e93b275 1585 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1aa1114b 1586 noexcept(noexcept(__x.swap(__y)))
3e93b275
CF
1587 { __x.swap(__y); }
1588
894d0b15
CF
1589 // A class (and instance) which can be used in 'tie' when an element
1590 // of a tuple is not required
1591 struct _Swallow_assign
1592 {
1593 template<class _Tp>
cff90044
JW
1594 const _Swallow_assign&
1595 operator=(const _Tp&) const
894d0b15
CF
1596 { return *this; }
1597 };
1598
cff90044 1599 const _Swallow_assign ignore{};
5e108459 1600
b8214660
JW
1601 /// Partial specialization for tuples
1602 template<typename... _Types, typename _Alloc>
1603 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1604
5e108459
PC
1605 // See stl_pair.h...
1606 template<class _T1, class _T2>
62b547b5
JW
1607 template<typename... _Args1, typename... _Args2>
1608 inline
1609 pair<_T1, _T2>::
1610 pair(piecewise_construct_t,
1611 tuple<_Args1...> __first, tuple<_Args2...> __second)
1612 : pair(__first, __second,
1613 typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1614 typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1615 { }
5e108459
PC
1616
1617 template<class _T1, class _T2>
62b547b5
JW
1618 template<typename... _Args1, std::size_t... _Indexes1,
1619 typename... _Args2, std::size_t... _Indexes2>
1620 inline
1621 pair<_T1, _T2>::
1622 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1623 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1624 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1625 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1626 { }
53dc5044 1627
c0ffa2ba
BK
1628 /// @}
1629
12ffa228 1630_GLIBCXX_END_NAMESPACE_VERSION
c0ffa2ba 1631} // namespace std
af13a7a6 1632
734f5023 1633#endif // C++11
57317d2a 1634
4514bed6 1635#endif // _GLIBCXX_TUPLE