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