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 187 : constexpr _Head_base()
59 187 : : _Head() { }
60 :
61 10 : constexpr _Head_base(const _Head& __h)
62 10 : : _Head(__h) { }
63 :
64 : constexpr _Head_base(const _Head_base&) = default;
65 : constexpr _Head_base(_Head_base&&) = default;
66 :
67 : template<typename _UHead>
68 10 : constexpr _Head_base(_UHead&& __h)
69 10 : : _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 28 : _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 429 : struct _Head_base<_Idx, _Head, false>
103 : {
104 367 : constexpr _Head_base()
105 367 : : _M_head_impl() { }
106 :
107 121 : constexpr _Head_base(const _Head& __h)
108 121 : : _M_head_impl(__h) { }
109 :
110 40 : constexpr _Head_base(const _Head_base&) = default;
111 : constexpr _Head_base(_Head_base&&) = default;
112 :
113 : template<typename _UHead>
114 126 : constexpr _Head_base(_UHead&& __h)
115 126 : : _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 301 : _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
143 :
144 : static constexpr const _Head&
145 168 : _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 354 : 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 272 : _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
191 :
192 : static constexpr const _Head&
193 154 : _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
194 :
195 : static constexpr _Inherited&
196 53 : _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 321 : constexpr _Tuple_impl()
202 321 : : _Inherited(), _Base() { }
203 :
204 : explicit
205 5 : constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
206 5 : : _Inherited(__tail...), _Base(__head) { }
207 :
208 : template<typename _UHead, typename... _UTail, typename = typename
209 : enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
210 : explicit
211 159 : constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
212 0 : : _Inherited(std::forward<_UTail>(__tail)...),
213 159 : _Base(std::forward<_UHead>(__head)) { }
214 :
215 46 : constexpr _Tuple_impl(const _Tuple_impl&) = default;
216 :
217 : constexpr
218 19 : _Tuple_impl(_Tuple_impl&& __in)
219 : noexcept(__and_<is_nothrow_move_constructible<_Head>,
220 : is_nothrow_move_constructible<_Inherited>>::value)
221 19 : : _Inherited(std::move(_M_tail(__in))),
222 19 : _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 17 : operator=(_Tuple_impl&& __in)
296 : noexcept(__and_<is_nothrow_move_assignable<_Head>,
297 : is_nothrow_move_assignable<_Inherited>>::value)
298 : {
299 17 : _M_head(*this) = std::forward<_Head>(_M_head(__in));
300 17 : _M_tail(*this) = std::move(_M_tail(__in));
301 17 : 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 113 : 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 57 : _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
347 :
348 : static constexpr const _Head&
349 14 : _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
350 :
351 233 : constexpr _Tuple_impl()
352 233 : : _Base() { }
353 :
354 : explicit
355 9 : constexpr _Tuple_impl(const _Head& __head)
356 9 : : _Base(__head) { }
357 :
358 : template<typename _UHead>
359 : explicit
360 61 : constexpr _Tuple_impl(_UHead&& __head)
361 61 : : _Base(std::forward<_UHead>(__head)) { }
362 :
363 12 : constexpr _Tuple_impl(const _Tuple_impl&) = default;
364 :
365 : constexpr
366 14 : _Tuple_impl(_Tuple_impl&& __in)
367 : noexcept(is_nothrow_move_constructible<_Head>::value)
368 14 : : _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 7 : operator=(_Tuple_impl&& __in)
427 : noexcept(is_nothrow_move_assignable<_Head>::value)
428 : {
429 7 : _M_head(*this) = std::forward<_Head>(_M_head(__in));
430 7 : 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 125 : 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 46 : constexpr tuple()
580 46 : : _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 7 : constexpr tuple(const _Elements&... __elements)
607 7 : : _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 61 : constexpr tuple(_UElements&&... __elements)
637 61 : : _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 18 : constexpr tuple(const tuple&) = default;
653 :
654 12 : 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 7 : operator=(tuple&& __in)
823 : noexcept(is_nothrow_move_assignable<_Inherited>::value)
824 : {
825 7 : static_cast<_Inherited&>(*this) = std::move(__in);
826 7 : 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 8 : 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 187 : constexpr tuple()
879 187 : : _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 2 : constexpr tuple(const _T1& __a1, const _T2& __a2)
907 2 : : _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 : && !is_same<typename decay<_U1>::type,
928 : allocator_arg_t>::value,
929 : bool>::type = true>
930 0 : constexpr tuple(_U1&& __a1, _U2&& __a2)
931 0 : : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
932 :
933 : template<typename _U1, typename _U2, typename
934 : enable_if<_TMC::template
935 : _MoveConstructibleTuple<_U1, _U2>()
936 : && !_TMC::template
937 : _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
938 : && !is_same<typename decay<_U1>::type,
939 : allocator_arg_t>::value,
940 : bool>::type = false>
941 : explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
942 : : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
943 :
944 4 : constexpr tuple(const tuple&) = default;
945 :
946 2 : constexpr tuple(tuple&&) = default;
947 :
948 : template<typename _U1, typename _U2, typename
949 : enable_if<_TMC::template
950 : _ConstructibleTuple<_U1, _U2>()
951 : && _TMC::template
952 : _ImplicitlyConvertibleTuple<_U1, _U2>(),
953 : bool>::type = true>
954 : constexpr tuple(const tuple<_U1, _U2>& __in)
955 : : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
956 :
957 : template<typename _U1, typename _U2, typename
958 : enable_if<_TMC::template
959 : _ConstructibleTuple<_U1, _U2>()
960 : && !_TMC::template
961 : _ImplicitlyConvertibleTuple<_U1, _U2>(),
962 : bool>::type = false>
963 : explicit constexpr tuple(const tuple<_U1, _U2>& __in)
964 : : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
965 :
966 : template<typename _U1, typename _U2, typename
967 : enable_if<_TMC::template
968 : _MoveConstructibleTuple<_U1, _U2>()
969 : && _TMC::template
970 : _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
971 : bool>::type = true>
972 : constexpr tuple(tuple<_U1, _U2>&& __in)
973 : : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
974 :
975 : template<typename _U1, typename _U2, typename
976 : enable_if<_TMC::template
977 : _MoveConstructibleTuple<_U1, _U2>()
978 : && !_TMC::template
979 : _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
980 : bool>::type = false>
981 : explicit constexpr tuple(tuple<_U1, _U2>&& __in)
982 : : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
983 :
984 : template<typename _U1, typename _U2, typename
985 : enable_if<_TMC::template
986 : _ConstructibleTuple<_U1, _U2>()
987 : && _TMC::template
988 : _ImplicitlyConvertibleTuple<_U1, _U2>(),
989 : bool>::type = true>
990 : constexpr tuple(const pair<_U1, _U2>& __in)
991 : : _Inherited(__in.first, __in.second) { }
992 :
993 : template<typename _U1, typename _U2, typename
994 : enable_if<_TMC::template
995 : _ConstructibleTuple<_U1, _U2>()
996 : && !_TMC::template
997 : _ImplicitlyConvertibleTuple<_U1, _U2>(),
998 : bool>::type = false>
999 : explicit constexpr tuple(const pair<_U1, _U2>& __in)
1000 : : _Inherited(__in.first, __in.second) { }
1001 :
1002 : template<typename _U1, typename _U2, typename
1003 : enable_if<_TMC::template
1004 : _MoveConstructibleTuple<_U1, _U2>()
1005 : && _TMC::template
1006 : _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1007 : bool>::type = true>
1008 : constexpr tuple(pair<_U1, _U2>&& __in)
1009 : : _Inherited(std::forward<_U1>(__in.first),
1010 : std::forward<_U2>(__in.second)) { }
1011 :
1012 : template<typename _U1, typename _U2, typename
1013 : enable_if<_TMC::template
1014 : _MoveConstructibleTuple<_U1, _U2>()
1015 : && !_TMC::template
1016 : _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1017 : bool>::type = false>
1018 : explicit constexpr tuple(pair<_U1, _U2>&& __in)
1019 : : _Inherited(std::forward<_U1>(__in.first),
1020 : std::forward<_U2>(__in.second)) { }
1021 :
1022 : // Allocator-extended constructors.
1023 :
1024 : template<typename _Alloc>
1025 : tuple(allocator_arg_t __tag, const _Alloc& __a)
1026 : : _Inherited(__tag, __a) { }
1027 :
1028 : template<typename _Alloc, typename _Dummy = void,
1029 : typename enable_if<
1030 : _TCC<_Dummy>::template
1031 : _ConstructibleTuple<_T1, _T2>()
1032 : && _TCC<_Dummy>::template
1033 : _ImplicitlyConvertibleTuple<_T1, _T2>(),
1034 : bool>::type=true>
1035 :
1036 : tuple(allocator_arg_t __tag, const _Alloc& __a,
1037 : const _T1& __a1, const _T2& __a2)
1038 : : _Inherited(__tag, __a, __a1, __a2) { }
1039 :
1040 : template<typename _Alloc, typename _Dummy = void,
1041 : typename enable_if<
1042 : _TCC<_Dummy>::template
1043 : _ConstructibleTuple<_T1, _T2>()
1044 : && !_TCC<_Dummy>::template
1045 : _ImplicitlyConvertibleTuple<_T1, _T2>(),
1046 : bool>::type=false>
1047 :
1048 : explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1049 : const _T1& __a1, const _T2& __a2)
1050 : : _Inherited(__tag, __a, __a1, __a2) { }
1051 :
1052 : template<typename _Alloc, typename _U1, typename _U2, typename
1053 : enable_if<_TMC::template
1054 : _MoveConstructibleTuple<_U1, _U2>()
1055 : && _TMC::template
1056 : _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1057 : bool>::type = true>
1058 : tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1059 : : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1060 : std::forward<_U2>(__a2)) { }
1061 :
1062 : template<typename _Alloc, typename _U1, typename _U2, typename
1063 : enable_if<_TMC::template
1064 : _MoveConstructibleTuple<_U1, _U2>()
1065 : && !_TMC::template
1066 : _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1067 : bool>::type = false>
1068 : explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1069 : _U1&& __a1, _U2&& __a2)
1070 : : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1071 : std::forward<_U2>(__a2)) { }
1072 :
1073 : template<typename _Alloc>
1074 : tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1075 : : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1076 :
1077 : template<typename _Alloc>
1078 : tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1079 : : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1080 :
1081 : template<typename _Alloc, typename _U1, typename _U2, typename
1082 : enable_if<_TMC::template
1083 : _ConstructibleTuple<_U1, _U2>()
1084 : && _TMC::template
1085 : _ImplicitlyConvertibleTuple<_U1, _U2>(),
1086 : bool>::type = true>
1087 : tuple(allocator_arg_t __tag, const _Alloc& __a,
1088 : const tuple<_U1, _U2>& __in)
1089 : : _Inherited(__tag, __a,
1090 : static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1091 : { }
1092 :
1093 : template<typename _Alloc, typename _U1, typename _U2, typename
1094 : enable_if<_TMC::template
1095 : _ConstructibleTuple<_U1, _U2>()
1096 : && !_TMC::template
1097 : _ImplicitlyConvertibleTuple<_U1, _U2>(),
1098 : bool>::type = false>
1099 : explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1100 : const tuple<_U1, _U2>& __in)
1101 : : _Inherited(__tag, __a,
1102 : static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1103 : { }
1104 :
1105 : template<typename _Alloc, typename _U1, typename _U2, typename
1106 : enable_if<_TMC::template
1107 : _MoveConstructibleTuple<_U1, _U2>()
1108 : && _TMC::template
1109 : _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1110 : bool>::type = true>
1111 : tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1112 : : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1113 : { }
1114 :
1115 : template<typename _Alloc, typename _U1, typename _U2, typename
1116 : enable_if<_TMC::template
1117 : _MoveConstructibleTuple<_U1, _U2>()
1118 : && !_TMC::template
1119 : _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1120 : bool>::type = false>
1121 : explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1122 : tuple<_U1, _U2>&& __in)
1123 : : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1124 : { }
1125 :
1126 : template<typename _Alloc, typename _U1, typename _U2, typename
1127 : enable_if<_TMC::template
1128 : _ConstructibleTuple<_U1, _U2>()
1129 : && _TMC::template
1130 : _ImplicitlyConvertibleTuple<_U1, _U2>(),
1131 : bool>::type = true>
1132 : tuple(allocator_arg_t __tag, const _Alloc& __a,
1133 : const pair<_U1, _U2>& __in)
1134 : : _Inherited(__tag, __a, __in.first, __in.second) { }
1135 :
1136 : template<typename _Alloc, typename _U1, typename _U2, typename
1137 : enable_if<_TMC::template
1138 : _ConstructibleTuple<_U1, _U2>()
1139 : && !_TMC::template
1140 : _ImplicitlyConvertibleTuple<_U1, _U2>(),
1141 : bool>::type = false>
1142 : explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1143 : const pair<_U1, _U2>& __in)
1144 : : _Inherited(__tag, __a, __in.first, __in.second) { }
1145 :
1146 : template<typename _Alloc, typename _U1, typename _U2, typename
1147 : enable_if<_TMC::template
1148 : _MoveConstructibleTuple<_U1, _U2>()
1149 : && _TMC::template
1150 : _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1151 : bool>::type = true>
1152 : tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1153 : : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1154 : std::forward<_U2>(__in.second)) { }
1155 :
1156 : template<typename _Alloc, typename _U1, typename _U2, typename
1157 : enable_if<_TMC::template
1158 : _MoveConstructibleTuple<_U1, _U2>()
1159 : && !_TMC::template
1160 : _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1161 : bool>::type = false>
1162 : explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1163 : pair<_U1, _U2>&& __in)
1164 : : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1165 : std::forward<_U2>(__in.second)) { }
1166 :
1167 : tuple&
1168 : operator=(const tuple& __in)
1169 : {
1170 : static_cast<_Inherited&>(*this) = __in;
1171 : return *this;
1172 : }
1173 :
1174 : tuple&
1175 : operator=(tuple&& __in)
1176 : noexcept(is_nothrow_move_assignable<_Inherited>::value)
1177 : {
1178 : static_cast<_Inherited&>(*this) = std::move(__in);
1179 : return *this;
1180 : }
1181 :
1182 : template<typename _U1, typename _U2>
1183 : tuple&
1184 : operator=(const tuple<_U1, _U2>& __in)
1185 : {
1186 : static_cast<_Inherited&>(*this) = __in;
1187 : return *this;
1188 : }
1189 :
1190 : template<typename _U1, typename _U2>
1191 : tuple&
1192 : operator=(tuple<_U1, _U2>&& __in)
1193 : {
1194 : static_cast<_Inherited&>(*this) = std::move(__in);
1195 : return *this;
1196 : }
1197 :
1198 : template<typename _U1, typename _U2>
1199 : tuple&
1200 : operator=(const pair<_U1, _U2>& __in)
1201 : {
1202 : this->_M_head(*this) = __in.first;
1203 : this->_M_tail(*this)._M_head(*this) = __in.second;
1204 : return *this;
1205 : }
1206 :
1207 : template<typename _U1, typename _U2>
1208 : tuple&
1209 : operator=(pair<_U1, _U2>&& __in)
1210 : {
1211 : this->_M_head(*this) = std::forward<_U1>(__in.first);
1212 : this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1213 : return *this;
1214 : }
1215 :
1216 : void
1217 : swap(tuple& __in)
1218 : noexcept(noexcept(__in._M_swap(__in)))
1219 : { _Inherited::_M_swap(__in); }
1220 : };
1221 :
1222 :
1223 : /**
1224 : * Recursive case for tuple_element: strip off the first element in
1225 : * the tuple and retrieve the (i-1)th element of the remaining tuple.
1226 : */
1227 : template<std::size_t __i, typename _Head, typename... _Tail>
1228 : struct tuple_element<__i, tuple<_Head, _Tail...> >
1229 : : tuple_element<__i - 1, tuple<_Tail...> > { };
1230 :
1231 : /**
1232 : * Basis case for tuple_element: The first element is the one we're seeking.
1233 : */
1234 : template<typename _Head, typename... _Tail>
1235 : struct tuple_element<0, tuple<_Head, _Tail...> >
1236 : {
1237 : typedef _Head type;
1238 : };
1239 :
1240 : /// class tuple_size
1241 : template<typename... _Elements>
1242 : struct tuple_size<tuple<_Elements...>>
1243 : : public integral_constant<std::size_t, sizeof...(_Elements)> { };
1244 :
1245 : template<std::size_t __i, typename _Head, typename... _Tail>
1246 : constexpr _Head&
1247 248 : __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1248 248 : { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1249 :
1250 : template<std::size_t __i, typename _Head, typename... _Tail>
1251 : constexpr const _Head&
1252 168 : __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1253 168 : { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1254 :
1255 : /// Return a reference to the ith element of a tuple.
1256 : template<std::size_t __i, typename... _Elements>
1257 : constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1258 248 : get(tuple<_Elements...>& __t) noexcept
1259 248 : { return std::__get_helper<__i>(__t); }
1260 :
1261 : /// Return a const reference to the ith element of a const tuple.
1262 : template<std::size_t __i, typename... _Elements>
1263 : constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1264 168 : get(const tuple<_Elements...>& __t) noexcept
1265 168 : { return std::__get_helper<__i>(__t); }
1266 :
1267 : /// Return an rvalue reference to the ith element of a tuple rvalue.
1268 : template<std::size_t __i, typename... _Elements>
1269 : constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1270 2 : get(tuple<_Elements...>&& __t) noexcept
1271 : {
1272 : typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1273 2 : return std::forward<__element_type&&>(std::get<__i>(__t));
1274 : }
1275 :
1276 : #if __cplusplus > 201103L
1277 :
1278 : #define __cpp_lib_tuples_by_type 201304
1279 :
1280 : template<typename _Head, size_t __i, typename... _Tail>
1281 : constexpr _Head&
1282 : __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1283 : { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1284 :
1285 : template<typename _Head, size_t __i, typename... _Tail>
1286 : constexpr const _Head&
1287 : __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1288 : { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1289 :
1290 : /// Return a reference to the unique element of type _Tp of a tuple.
1291 : template <typename _Tp, typename... _Types>
1292 : constexpr _Tp&
1293 : get(tuple<_Types...>& __t) noexcept
1294 : { return std::__get_helper2<_Tp>(__t); }
1295 :
1296 : /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1297 : template <typename _Tp, typename... _Types>
1298 : constexpr _Tp&&
1299 : get(tuple<_Types...>&& __t) noexcept
1300 : { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
1301 :
1302 : /// Return a const reference to the unique element of type _Tp of a tuple.
1303 : template <typename _Tp, typename... _Types>
1304 : constexpr const _Tp&
1305 : get(const tuple<_Types...>& __t) noexcept
1306 : { return std::__get_helper2<_Tp>(__t); }
1307 : #endif
1308 :
1309 : // This class performs the comparison operations on tuples
1310 : template<typename _Tp, typename _Up, size_t __i, size_t __size>
1311 : struct __tuple_compare
1312 : {
1313 : static constexpr bool
1314 : __eq(const _Tp& __t, const _Up& __u)
1315 : {
1316 : return bool(std::get<__i>(__t) == std::get<__i>(__u))
1317 : && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1318 : }
1319 :
1320 : static constexpr bool
1321 0 : __less(const _Tp& __t, const _Up& __u)
1322 : {
1323 0 : return bool(std::get<__i>(__t) < std::get<__i>(__u))
1324 0 : || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1325 0 : && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1326 : }
1327 : };
1328 :
1329 : template<typename _Tp, typename _Up, size_t __size>
1330 : struct __tuple_compare<_Tp, _Up, __size, __size>
1331 : {
1332 : static constexpr bool
1333 : __eq(const _Tp&, const _Up&) { return true; }
1334 :
1335 : static constexpr bool
1336 0 : __less(const _Tp&, const _Up&) { return false; }
1337 : };
1338 :
1339 : template<typename... _TElements, typename... _UElements>
1340 : constexpr bool
1341 : operator==(const tuple<_TElements...>& __t,
1342 : const tuple<_UElements...>& __u)
1343 : {
1344 : static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1345 : "tuple objects can only be compared if they have equal sizes.");
1346 : using __compare = __tuple_compare<tuple<_TElements...>,
1347 : tuple<_UElements...>,
1348 : 0, sizeof...(_TElements)>;
1349 : return __compare::__eq(__t, __u);
1350 : }
1351 :
1352 : template<typename... _TElements, typename... _UElements>
1353 : constexpr bool
1354 0 : operator<(const tuple<_TElements...>& __t,
1355 : const tuple<_UElements...>& __u)
1356 : {
1357 : static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1358 : "tuple objects can only be compared if they have equal sizes.");
1359 : using __compare = __tuple_compare<tuple<_TElements...>,
1360 : tuple<_UElements...>,
1361 : 0, sizeof...(_TElements)>;
1362 0 : return __compare::__less(__t, __u);
1363 : }
1364 :
1365 : template<typename... _TElements, typename... _UElements>
1366 : constexpr bool
1367 : operator!=(const tuple<_TElements...>& __t,
1368 : const tuple<_UElements...>& __u)
1369 : { return !(__t == __u); }
1370 :
1371 : template<typename... _TElements, typename... _UElements>
1372 : constexpr bool
1373 : operator>(const tuple<_TElements...>& __t,
1374 : const tuple<_UElements...>& __u)
1375 : { return __u < __t; }
1376 :
1377 : template<typename... _TElements, typename... _UElements>
1378 : constexpr bool
1379 : operator<=(const tuple<_TElements...>& __t,
1380 : const tuple<_UElements...>& __u)
1381 : { return !(__u < __t); }
1382 :
1383 : template<typename... _TElements, typename... _UElements>
1384 : constexpr bool
1385 : operator>=(const tuple<_TElements...>& __t,
1386 : const tuple<_UElements...>& __u)
1387 : { return !(__t < __u); }
1388 :
1389 : // NB: DR 705.
1390 : template<typename... _Elements>
1391 : constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
1392 49 : make_tuple(_Elements&&... __args)
1393 : {
1394 : typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1395 : __result_type;
1396 49 : return __result_type(std::forward<_Elements>(__args)...);
1397 : }
1398 :
1399 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
1400 : // 2275. Why is forward_as_tuple not constexpr?
1401 : template<typename... _Elements>
1402 : constexpr tuple<_Elements&&...>
1403 14 : forward_as_tuple(_Elements&&... __args) noexcept
1404 14 : { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1405 :
1406 : template<typename... _Tps>
1407 : struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
1408 : { };
1409 :
1410 : // Internal type trait that allows us to sfinae-protect tuple_cat.
1411 : template<typename _Tp>
1412 : struct __is_tuple_like
1413 : : public __is_tuple_like_impl<typename std::remove_cv
1414 : <typename std::remove_reference<_Tp>::type>::type>::type
1415 : { };
1416 :
1417 : template<size_t, typename, typename, size_t>
1418 : struct __make_tuple_impl;
1419 :
1420 : template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1421 : struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1422 : : __make_tuple_impl<_Idx + 1,
1423 : tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1424 : _Tuple, _Nm>
1425 : { };
1426 :
1427 : template<std::size_t _Nm, typename _Tuple, typename... _Tp>
1428 : struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1429 : {
1430 : typedef tuple<_Tp...> __type;
1431 : };
1432 :
1433 : template<typename _Tuple>
1434 : struct __do_make_tuple
1435 : : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
1436 : { };
1437 :
1438 : // Returns the std::tuple equivalent of a tuple-like type.
1439 : template<typename _Tuple>
1440 : struct __make_tuple
1441 : : public __do_make_tuple<typename std::remove_cv
1442 : <typename std::remove_reference<_Tuple>::type>::type>
1443 : { };
1444 :
1445 : // Combines several std::tuple's into a single one.
1446 : template<typename...>
1447 : struct __combine_tuples;
1448 :
1449 : template<>
1450 : struct __combine_tuples<>
1451 : {
1452 : typedef tuple<> __type;
1453 : };
1454 :
1455 : template<typename... _Ts>
1456 : struct __combine_tuples<tuple<_Ts...>>
1457 : {
1458 : typedef tuple<_Ts...> __type;
1459 : };
1460 :
1461 : template<typename... _T1s, typename... _T2s, typename... _Rem>
1462 : struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1463 : {
1464 : typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1465 : _Rem...>::__type __type;
1466 : };
1467 :
1468 : // Computes the result type of tuple_cat given a set of tuple-like types.
1469 : template<typename... _Tpls>
1470 : struct __tuple_cat_result
1471 : {
1472 : typedef typename __combine_tuples
1473 : <typename __make_tuple<_Tpls>::__type...>::__type __type;
1474 : };
1475 :
1476 : // Helper to determine the index set for the first tuple-like
1477 : // type of a given set.
1478 : template<typename...>
1479 : struct __make_1st_indices;
1480 :
1481 : template<>
1482 : struct __make_1st_indices<>
1483 : {
1484 : typedef std::_Index_tuple<> __type;
1485 : };
1486 :
1487 : template<typename _Tp, typename... _Tpls>
1488 : struct __make_1st_indices<_Tp, _Tpls...>
1489 : {
1490 : typedef typename std::_Build_index_tuple<std::tuple_size<
1491 : typename std::remove_reference<_Tp>::type>::value>::__type __type;
1492 : };
1493 :
1494 : // Performs the actual concatenation by step-wise expanding tuple-like
1495 : // objects into the elements, which are finally forwarded into the
1496 : // result tuple.
1497 : template<typename _Ret, typename _Indices, typename... _Tpls>
1498 : struct __tuple_concater;
1499 :
1500 : template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
1501 : struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1502 : {
1503 : template<typename... _Us>
1504 : static constexpr _Ret
1505 : _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1506 : {
1507 : typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1508 : typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1509 : return __next::_S_do(std::forward<_Tpls>(__tps)...,
1510 : std::forward<_Us>(__us)...,
1511 : std::get<_Is>(std::forward<_Tp>(__tp))...);
1512 : }
1513 : };
1514 :
1515 : template<typename _Ret>
1516 : struct __tuple_concater<_Ret, std::_Index_tuple<>>
1517 : {
1518 : template<typename... _Us>
1519 : static constexpr _Ret
1520 : _S_do(_Us&&... __us)
1521 : {
1522 : return _Ret(std::forward<_Us>(__us)...);
1523 : }
1524 : };
1525 :
1526 : /// tuple_cat
1527 : template<typename... _Tpls, typename = typename
1528 : enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1529 : constexpr auto
1530 : tuple_cat(_Tpls&&... __tpls)
1531 : -> typename __tuple_cat_result<_Tpls...>::__type
1532 : {
1533 : typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1534 : typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1535 : typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1536 : return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1537 : }
1538 :
1539 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
1540 : // 2301. Why is tie not constexpr?
1541 : /// tie
1542 : template<typename... _Elements>
1543 : constexpr tuple<_Elements&...>
1544 : tie(_Elements&... __args) noexcept
1545 : { return tuple<_Elements&...>(__args...); }
1546 :
1547 : /// swap
1548 : template<typename... _Elements>
1549 : inline void
1550 : swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1551 : noexcept(noexcept(__x.swap(__y)))
1552 : { __x.swap(__y); }
1553 :
1554 : // A class (and instance) which can be used in 'tie' when an element
1555 : // of a tuple is not required
1556 : struct _Swallow_assign
1557 : {
1558 : template<class _Tp>
1559 : const _Swallow_assign&
1560 : operator=(const _Tp&) const
1561 : { return *this; }
1562 : };
1563 :
1564 : const _Swallow_assign ignore{};
1565 :
1566 : /// Partial specialization for tuples
1567 : template<typename... _Types, typename _Alloc>
1568 : struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1569 :
1570 : // See stl_pair.h...
1571 : template<class _T1, class _T2>
1572 : template<typename... _Args1, typename... _Args2>
1573 : inline
1574 0 : pair<_T1, _T2>::
1575 : pair(piecewise_construct_t,
1576 : tuple<_Args1...> __first, tuple<_Args2...> __second)
1577 : : pair(__first, __second,
1578 : typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1579 0 : typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1580 0 : { }
1581 :
1582 : template<class _T1, class _T2>
1583 : template<typename... _Args1, std::size_t... _Indexes1,
1584 : typename... _Args2, std::size_t... _Indexes2>
1585 : inline
1586 0 : pair<_T1, _T2>::
1587 : pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1588 : _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1589 0 : : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1590 0 : second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1591 0 : { }
1592 :
1593 : /// @}
1594 :
1595 : _GLIBCXX_END_NAMESPACE_VERSION
1596 : } // namespace std
1597 :
1598 : #endif // C++11
1599 :
1600 : #endif // _GLIBCXX_TUPLE
|