Branch data Line data Source code
1 : : // <tuple> -*- C++ -*-
2 : :
3 : : // Copyright (C) 2007-2015 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 : : constexpr _Head_base()
59 : : : _Head() { }
60 : :
61 : : constexpr _Head_base(const _Head& __h)
62 : : : _Head(__h) { }
63 : :
64 : : constexpr _Head_base(const _Head_base&) = default;
65 : : constexpr _Head_base(_Head_base&&) = default;
66 : :
67 : : template<typename _UHead>
68 : : constexpr _Head_base(_UHead&& __h)
69 : : : _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 : : _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 : : struct _Head_base<_Idx, _Head, false>
103 : : {
104 : : constexpr _Head_base()
105 : 0 : : _M_head_impl() { }
106 : :
107 : : constexpr _Head_base(const _Head& __h)
108 : : : _M_head_impl(__h) { }
109 : :
110 : : constexpr _Head_base(const _Head_base&) = default;
111 : : constexpr _Head_base(_Head_base&&) = default;
112 : :
113 : : template<typename _UHead>
114 : : constexpr _Head_base(_UHead&& __h)
115 : 4 : : _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 : : _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
143 : :
144 : : static constexpr const _Head&
145 : : _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 : : 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 : : _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
191 : :
192 : : static constexpr const _Head&
193 : : _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
194 : :
195 : : static constexpr _Inherited&
196 : : _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 : : constexpr _Tuple_impl()
202 : : : _Inherited(), _Base() { }
203 : :
204 : : explicit
205 : : constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
206 : : : _Inherited(__tail...), _Base(__head) { }
207 : :
208 : : template<typename _UHead, typename... _UTail, typename = typename
209 : : enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
210 : : explicit
211 : : constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
212 : : : _Inherited(std::forward<_UTail>(__tail)...),
213 : : _Base(std::forward<_UHead>(__head)) { }
214 : :
215 : : constexpr _Tuple_impl(const _Tuple_impl&) = default;
216 : :
217 : : constexpr
218 : : _Tuple_impl(_Tuple_impl&& __in)
219 : : noexcept(__and_<is_nothrow_move_constructible<_Head>,
220 : : is_nothrow_move_constructible<_Inherited>>::value)
221 : : : _Inherited(std::move(_M_tail(__in))),
222 : : _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 : : constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
231 : : : _Inherited(std::move
232 : : (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
233 : : _Base(std::forward<_UHead>
234 : : (_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 : : operator=(_Tuple_impl&& __in)
296 : : noexcept(__and_<is_nothrow_move_assignable<_Head>,
297 : : is_nothrow_move_assignable<_Inherited>>::value)
298 : : {
299 : : _M_head(*this) = std::forward<_Head>(_M_head(__in));
300 : : _M_tail(*this) = std::move(_M_tail(__in));
301 : : 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(noexcept(swap(std::declval<_Head&>(),
328 : : std::declval<_Head&>()))
329 : : && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
330 : : {
331 : : using std::swap;
332 : : swap(_M_head(*this), _M_head(__in));
333 : : _Inherited::_M_swap(_M_tail(__in));
334 : : }
335 : : };
336 : :
337 : : // Basis case of inheritance recursion.
338 : : template<std::size_t _Idx, typename _Head>
339 : : struct _Tuple_impl<_Idx, _Head>
340 : : : private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value>
341 : : {
342 : : template<std::size_t, typename...> friend class _Tuple_impl;
343 : :
344 : : typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base;
345 : :
346 : : static constexpr _Head&
347 : : _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
348 : :
349 : : static constexpr const _Head&
350 : : _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
351 : :
352 : : constexpr _Tuple_impl()
353 : : : _Base() { }
354 : :
355 : : explicit
356 : : constexpr _Tuple_impl(const _Head& __head)
357 : : : _Base(__head) { }
358 : :
359 : : template<typename _UHead>
360 : : explicit
361 : : constexpr _Tuple_impl(_UHead&& __head)
362 : : : _Base(std::forward<_UHead>(__head)) { }
363 : :
364 : : constexpr _Tuple_impl(const _Tuple_impl&) = default;
365 : :
366 : : constexpr
367 : : _Tuple_impl(_Tuple_impl&& __in)
368 : : noexcept(is_nothrow_move_constructible<_Head>::value)
369 : : : _Base(std::forward<_Head>(_M_head(__in))) { }
370 : :
371 : : template<typename _UHead>
372 : : constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
373 : : : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
374 : :
375 : : template<typename _UHead>
376 : : constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
377 : : : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
378 : : { }
379 : :
380 : : template<typename _Alloc>
381 : : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
382 : : : _Base(__tag, __use_alloc<_Head>(__a)) { }
383 : :
384 : : template<typename _Alloc>
385 : : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
386 : : const _Head& __head)
387 : : : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
388 : :
389 : : template<typename _Alloc, typename _UHead>
390 : : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
391 : : _UHead&& __head)
392 : : : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
393 : : std::forward<_UHead>(__head)) { }
394 : :
395 : : template<typename _Alloc>
396 : : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
397 : : const _Tuple_impl& __in)
398 : : : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
399 : :
400 : : template<typename _Alloc>
401 : : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
402 : : _Tuple_impl&& __in)
403 : : : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
404 : : std::forward<_Head>(_M_head(__in))) { }
405 : :
406 : : template<typename _Alloc, typename _UHead>
407 : : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
408 : : const _Tuple_impl<_Idx, _UHead>& __in)
409 : : : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
410 : : _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
411 : :
412 : : template<typename _Alloc, typename _UHead>
413 : : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
414 : : _Tuple_impl<_Idx, _UHead>&& __in)
415 : : : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
416 : : std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
417 : : { }
418 : :
419 : : _Tuple_impl&
420 : : operator=(const _Tuple_impl& __in)
421 : : {
422 : : _M_head(*this) = _M_head(__in);
423 : : return *this;
424 : : }
425 : :
426 : : _Tuple_impl&
427 : : operator=(_Tuple_impl&& __in)
428 : : noexcept(is_nothrow_move_assignable<_Head>::value)
429 : : {
430 : : _M_head(*this) = std::forward<_Head>(_M_head(__in));
431 : : return *this;
432 : : }
433 : :
434 : : template<typename _UHead>
435 : : _Tuple_impl&
436 : : operator=(const _Tuple_impl<_Idx, _UHead>& __in)
437 : : {
438 : : _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
439 : : return *this;
440 : : }
441 : :
442 : : template<typename _UHead>
443 : : _Tuple_impl&
444 : : operator=(_Tuple_impl<_Idx, _UHead>&& __in)
445 : : {
446 : : _M_head(*this)
447 : : = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
448 : : return *this;
449 : : }
450 : :
451 : : protected:
452 : : void
453 : : _M_swap(_Tuple_impl& __in)
454 : : noexcept(noexcept(swap(std::declval<_Head&>(), std::declval<_Head&>())))
455 : : {
456 : : using std::swap;
457 : : swap(_M_head(*this), _M_head(__in));
458 : : }
459 : : };
460 : :
461 : : /// Primary class template, tuple
462 : : template<typename... _Elements>
463 : : class tuple : public _Tuple_impl<0, _Elements...>
464 : : {
465 : : typedef _Tuple_impl<0, _Elements...> _Inherited;
466 : :
467 : : public:
468 : : constexpr tuple()
469 : : : _Inherited() { }
470 : :
471 : : explicit
472 : : constexpr tuple(const _Elements&... __elements)
473 : : : _Inherited(__elements...) { }
474 : :
475 : : template<typename... _UElements, typename = typename
476 : : enable_if<__and_<is_convertible<_UElements,
477 : : _Elements>...>::value>::type>
478 : : explicit
479 : : constexpr tuple(_UElements&&... __elements)
480 : : : _Inherited(std::forward<_UElements>(__elements)...) { }
481 : :
482 : : constexpr tuple(const tuple&) = default;
483 : :
484 : : constexpr tuple(tuple&&) = default;
485 : :
486 : : template<typename... _UElements, typename = typename
487 : : enable_if<__and_<is_convertible<const _UElements&,
488 : : _Elements>...>::value>::type>
489 : : constexpr tuple(const tuple<_UElements...>& __in)
490 : : : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
491 : : { }
492 : :
493 : : template<typename... _UElements, typename = typename
494 : : enable_if<__and_<is_convertible<_UElements,
495 : : _Elements>...>::value>::type>
496 : : constexpr tuple(tuple<_UElements...>&& __in)
497 : : : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
498 : :
499 : : // Allocator-extended constructors.
500 : :
501 : : template<typename _Alloc>
502 : : tuple(allocator_arg_t __tag, const _Alloc& __a)
503 : : : _Inherited(__tag, __a) { }
504 : :
505 : : template<typename _Alloc>
506 : : tuple(allocator_arg_t __tag, const _Alloc& __a,
507 : : const _Elements&... __elements)
508 : : : _Inherited(__tag, __a, __elements...) { }
509 : :
510 : : template<typename _Alloc, typename... _UElements, typename = typename
511 : : enable_if<sizeof...(_UElements)
512 : : == sizeof...(_Elements)>::type>
513 : : tuple(allocator_arg_t __tag, const _Alloc& __a,
514 : : _UElements&&... __elements)
515 : : : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
516 : : { }
517 : :
518 : : template<typename _Alloc>
519 : : tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
520 : : : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
521 : :
522 : : template<typename _Alloc>
523 : : tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
524 : : : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
525 : :
526 : : template<typename _Alloc, typename... _UElements, typename = typename
527 : : enable_if<sizeof...(_UElements)
528 : : == sizeof...(_Elements)>::type>
529 : : tuple(allocator_arg_t __tag, const _Alloc& __a,
530 : : const tuple<_UElements...>& __in)
531 : : : _Inherited(__tag, __a,
532 : : static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
533 : : { }
534 : :
535 : : template<typename _Alloc, typename... _UElements, typename = typename
536 : : enable_if<sizeof...(_UElements)
537 : : == sizeof...(_Elements)>::type>
538 : : tuple(allocator_arg_t __tag, const _Alloc& __a,
539 : : tuple<_UElements...>&& __in)
540 : : : _Inherited(__tag, __a,
541 : : static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
542 : : { }
543 : :
544 : : tuple&
545 : : operator=(const tuple& __in)
546 : : {
547 : : static_cast<_Inherited&>(*this) = __in;
548 : : return *this;
549 : : }
550 : :
551 : : tuple&
552 : : operator=(tuple&& __in)
553 : : noexcept(is_nothrow_move_assignable<_Inherited>::value)
554 : : {
555 : : static_cast<_Inherited&>(*this) = std::move(__in);
556 : : return *this;
557 : : }
558 : :
559 : : template<typename... _UElements, typename = typename
560 : : enable_if<sizeof...(_UElements)
561 : : == sizeof...(_Elements)>::type>
562 : : tuple&
563 : : operator=(const tuple<_UElements...>& __in)
564 : : {
565 : : static_cast<_Inherited&>(*this) = __in;
566 : : return *this;
567 : : }
568 : :
569 : : template<typename... _UElements, typename = typename
570 : : enable_if<sizeof...(_UElements)
571 : : == sizeof...(_Elements)>::type>
572 : : tuple&
573 : : operator=(tuple<_UElements...>&& __in)
574 : : {
575 : : static_cast<_Inherited&>(*this) = std::move(__in);
576 : : return *this;
577 : : }
578 : :
579 : : void
580 : : swap(tuple& __in)
581 : : noexcept(noexcept(__in._M_swap(__in)))
582 : : { _Inherited::_M_swap(__in); }
583 : : };
584 : :
585 : : // Explicit specialization, zero-element tuple.
586 : : template<>
587 : : class tuple<>
588 : : {
589 : : public:
590 : : void swap(tuple&) noexcept { /* no-op */ }
591 : : };
592 : :
593 : : /// Partial specialization, 2-element tuple.
594 : : /// Includes construction and assignment from a pair.
595 : : template<typename _T1, typename _T2>
596 : : class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
597 : : {
598 : : typedef _Tuple_impl<0, _T1, _T2> _Inherited;
599 : :
600 : : public:
601 : : constexpr tuple()
602 : : : _Inherited() { }
603 : :
604 : : explicit
605 : : constexpr tuple(const _T1& __a1, const _T2& __a2)
606 : : : _Inherited(__a1, __a2) { }
607 : :
608 : : template<typename _U1, typename _U2, typename = typename
609 : : enable_if<__and_<is_convertible<_U1, _T1>,
610 : : is_convertible<_U2, _T2>>::value>::type>
611 : : explicit
612 : : constexpr tuple(_U1&& __a1, _U2&& __a2)
613 : : : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
614 : :
615 : : constexpr tuple(const tuple&) = default;
616 : :
617 : : constexpr tuple(tuple&&) = default;
618 : :
619 : : template<typename _U1, typename _U2, typename = typename
620 : : enable_if<__and_<is_convertible<const _U1&, _T1>,
621 : : is_convertible<const _U2&, _T2>>::value>::type>
622 : : constexpr tuple(const tuple<_U1, _U2>& __in)
623 : : : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
624 : :
625 : : template<typename _U1, typename _U2, typename = typename
626 : : enable_if<__and_<is_convertible<_U1, _T1>,
627 : : is_convertible<_U2, _T2>>::value>::type>
628 : : constexpr tuple(tuple<_U1, _U2>&& __in)
629 : : : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
630 : :
631 : : template<typename _U1, typename _U2, typename = typename
632 : : enable_if<__and_<is_convertible<const _U1&, _T1>,
633 : : is_convertible<const _U2&, _T2>>::value>::type>
634 : : constexpr tuple(const pair<_U1, _U2>& __in)
635 : : : _Inherited(__in.first, __in.second) { }
636 : :
637 : : template<typename _U1, typename _U2, typename = typename
638 : : enable_if<__and_<is_convertible<_U1, _T1>,
639 : : is_convertible<_U2, _T2>>::value>::type>
640 : : constexpr tuple(pair<_U1, _U2>&& __in)
641 : : : _Inherited(std::forward<_U1>(__in.first),
642 : : std::forward<_U2>(__in.second)) { }
643 : :
644 : : // Allocator-extended constructors.
645 : :
646 : : template<typename _Alloc>
647 : : tuple(allocator_arg_t __tag, const _Alloc& __a)
648 : : : _Inherited(__tag, __a) { }
649 : :
650 : : template<typename _Alloc>
651 : : tuple(allocator_arg_t __tag, const _Alloc& __a,
652 : : const _T1& __a1, const _T2& __a2)
653 : : : _Inherited(__tag, __a, __a1, __a2) { }
654 : :
655 : : template<typename _Alloc, typename _U1, typename _U2>
656 : : tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
657 : : : _Inherited(__tag, __a, std::forward<_U1>(__a1),
658 : : std::forward<_U2>(__a2)) { }
659 : :
660 : : template<typename _Alloc>
661 : : tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
662 : : : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
663 : :
664 : : template<typename _Alloc>
665 : : tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
666 : : : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
667 : :
668 : : template<typename _Alloc, typename _U1, typename _U2>
669 : : tuple(allocator_arg_t __tag, const _Alloc& __a,
670 : : const tuple<_U1, _U2>& __in)
671 : : : _Inherited(__tag, __a,
672 : : static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
673 : : { }
674 : :
675 : : template<typename _Alloc, typename _U1, typename _U2>
676 : : tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
677 : : : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
678 : : { }
679 : :
680 : : template<typename _Alloc, typename _U1, typename _U2>
681 : : tuple(allocator_arg_t __tag, const _Alloc& __a,
682 : : const pair<_U1, _U2>& __in)
683 : : : _Inherited(__tag, __a, __in.first, __in.second) { }
684 : :
685 : : template<typename _Alloc, typename _U1, typename _U2>
686 : : tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
687 : : : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
688 : : std::forward<_U2>(__in.second)) { }
689 : :
690 : : tuple&
691 : : operator=(const tuple& __in)
692 : : {
693 : : static_cast<_Inherited&>(*this) = __in;
694 : : return *this;
695 : : }
696 : :
697 : : tuple&
698 : : operator=(tuple&& __in)
699 : : noexcept(is_nothrow_move_assignable<_Inherited>::value)
700 : : {
701 : : static_cast<_Inherited&>(*this) = std::move(__in);
702 : : return *this;
703 : : }
704 : :
705 : : template<typename _U1, typename _U2>
706 : : tuple&
707 : : operator=(const tuple<_U1, _U2>& __in)
708 : : {
709 : : static_cast<_Inherited&>(*this) = __in;
710 : : return *this;
711 : : }
712 : :
713 : : template<typename _U1, typename _U2>
714 : : tuple&
715 : : operator=(tuple<_U1, _U2>&& __in)
716 : : {
717 : : static_cast<_Inherited&>(*this) = std::move(__in);
718 : : return *this;
719 : : }
720 : :
721 : : template<typename _U1, typename _U2>
722 : : tuple&
723 : : operator=(const pair<_U1, _U2>& __in)
724 : : {
725 : : this->_M_head(*this) = __in.first;
726 : : this->_M_tail(*this)._M_head(*this) = __in.second;
727 : : return *this;
728 : : }
729 : :
730 : : template<typename _U1, typename _U2>
731 : : tuple&
732 : : operator=(pair<_U1, _U2>&& __in)
733 : : {
734 : : this->_M_head(*this) = std::forward<_U1>(__in.first);
735 : : this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
736 : : return *this;
737 : : }
738 : :
739 : : void
740 : : swap(tuple& __in)
741 : : noexcept(noexcept(__in._M_swap(__in)))
742 : : { _Inherited::_M_swap(__in); }
743 : : };
744 : :
745 : :
746 : : /// Gives the type of the ith element of a given tuple type.
747 : : template<std::size_t __i, typename _Tp>
748 : : struct tuple_element;
749 : :
750 : : /**
751 : : * Recursive case for tuple_element: strip off the first element in
752 : : * the tuple and retrieve the (i-1)th element of the remaining tuple.
753 : : */
754 : : template<std::size_t __i, typename _Head, typename... _Tail>
755 : : struct tuple_element<__i, tuple<_Head, _Tail...> >
756 : : : tuple_element<__i - 1, tuple<_Tail...> > { };
757 : :
758 : : /**
759 : : * Basis case for tuple_element: The first element is the one we're seeking.
760 : : */
761 : : template<typename _Head, typename... _Tail>
762 : : struct tuple_element<0, tuple<_Head, _Tail...> >
763 : : {
764 : : typedef _Head type;
765 : : };
766 : :
767 : : // Duplicate of C++14's tuple_element_t for internal use in C++11 mode
768 : : template<std::size_t __i, typename _Tp>
769 : : using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
770 : :
771 : : template<std::size_t __i, typename _Tp>
772 : : struct tuple_element<__i, const _Tp>
773 : : {
774 : : typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
775 : : };
776 : :
777 : : template<std::size_t __i, typename _Tp>
778 : : struct tuple_element<__i, volatile _Tp>
779 : : {
780 : : typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
781 : : };
782 : :
783 : : template<std::size_t __i, typename _Tp>
784 : : struct tuple_element<__i, const volatile _Tp>
785 : : {
786 : : typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type;
787 : : };
788 : :
789 : : #if __cplusplus > 201103L
790 : : #define __cpp_lib_tuple_element_t 201402
791 : :
792 : : template<std::size_t __i, typename _Tp>
793 : : using tuple_element_t = typename tuple_element<__i, _Tp>::type;
794 : : #endif
795 : :
796 : : /// Finds the size of a given tuple type.
797 : : template<typename _Tp>
798 : : struct tuple_size;
799 : :
800 : : // _GLIBCXX_RESOLVE_LIB_DEFECTS
801 : : // 2313. tuple_size should always derive from integral_constant<size_t, N>
802 : : template<typename _Tp>
803 : : struct tuple_size<const _Tp>
804 : : : integral_constant<size_t, tuple_size<_Tp>::value> { };
805 : :
806 : : template<typename _Tp>
807 : : struct tuple_size<volatile _Tp>
808 : : : integral_constant<size_t, tuple_size<_Tp>::value> { };
809 : :
810 : : template<typename _Tp>
811 : : struct tuple_size<const volatile _Tp>
812 : : : integral_constant<size_t, tuple_size<_Tp>::value> { };
813 : :
814 : : /// class tuple_size
815 : : template<typename... _Elements>
816 : : struct tuple_size<tuple<_Elements...>>
817 : : : public integral_constant<std::size_t, sizeof...(_Elements)> { };
818 : :
819 : : template<std::size_t __i, typename _Head, typename... _Tail>
820 : : constexpr _Head&
821 : : __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
822 : : { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
823 : :
824 : : template<std::size_t __i, typename _Head, typename... _Tail>
825 : : constexpr const _Head&
826 : : __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
827 : : { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
828 : :
829 : : /// Return a reference to the ith element of a tuple.
830 : : template<std::size_t __i, typename... _Elements>
831 : : constexpr __tuple_element_t<__i, tuple<_Elements...>>&
832 : : get(tuple<_Elements...>& __t) noexcept
833 : : { return std::__get_helper<__i>(__t); }
834 : :
835 : : /// Return a const reference to the ith element of a const tuple.
836 : : template<std::size_t __i, typename... _Elements>
837 : : constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
838 : : get(const tuple<_Elements...>& __t) noexcept
839 : : { return std::__get_helper<__i>(__t); }
840 : :
841 : : /// Return an rvalue reference to the ith element of a tuple rvalue.
842 : : template<std::size_t __i, typename... _Elements>
843 : : constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
844 : : get(tuple<_Elements...>&& __t) noexcept
845 : : {
846 : : typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
847 : : return std::forward<__element_type&&>(std::get<__i>(__t));
848 : : }
849 : :
850 : : #if __cplusplus > 201103L
851 : :
852 : : #define __cpp_lib_tuples_by_type 201304
853 : :
854 : : template<typename _Head, size_t __i, typename... _Tail>
855 : : constexpr _Head&
856 : : __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
857 : : { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
858 : :
859 : : template<typename _Head, size_t __i, typename... _Tail>
860 : : constexpr const _Head&
861 : : __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
862 : : { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
863 : :
864 : : /// Return a reference to the unique element of type _Tp of a tuple.
865 : : template <typename _Tp, typename... _Types>
866 : : constexpr _Tp&
867 : : get(tuple<_Types...>& __t) noexcept
868 : : { return std::__get_helper2<_Tp>(__t); }
869 : :
870 : : /// Return a reference to the unique element of type _Tp of a tuple rvalue.
871 : : template <typename _Tp, typename... _Types>
872 : : constexpr _Tp&&
873 : : get(tuple<_Types...>&& __t) noexcept
874 : : { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
875 : :
876 : : /// Return a const reference to the unique element of type _Tp of a tuple.
877 : : template <typename _Tp, typename... _Types>
878 : : constexpr const _Tp&
879 : : get(const tuple<_Types...>& __t) noexcept
880 : : { return std::__get_helper2<_Tp>(__t); }
881 : : #endif
882 : :
883 : : // This class performs the comparison operations on tuples
884 : : template<typename _Tp, typename _Up, size_t __i, size_t __size>
885 : : struct __tuple_compare
886 : : {
887 : : static constexpr bool
888 : : __eq(const _Tp& __t, const _Up& __u)
889 : : {
890 : : return bool(std::get<__i>(__t) == std::get<__i>(__u))
891 : : && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
892 : : }
893 : :
894 : : static constexpr bool
895 : : __less(const _Tp& __t, const _Up& __u)
896 : : {
897 : : return bool(std::get<__i>(__t) < std::get<__i>(__u))
898 : : || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
899 : : && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
900 : : }
901 : : };
902 : :
903 : : template<typename _Tp, typename _Up, size_t __size>
904 : : struct __tuple_compare<_Tp, _Up, __size, __size>
905 : : {
906 : : static constexpr bool
907 : : __eq(const _Tp&, const _Up&) { return true; }
908 : :
909 : : static constexpr bool
910 : : __less(const _Tp&, const _Up&) { return false; }
911 : : };
912 : :
913 : : template<typename... _TElements, typename... _UElements>
914 : : constexpr bool
915 : : operator==(const tuple<_TElements...>& __t,
916 : : const tuple<_UElements...>& __u)
917 : : {
918 : : static_assert(sizeof...(_TElements) == sizeof...(_UElements),
919 : : "tuple objects can only be compared if they have equal sizes.");
920 : : using __compare = __tuple_compare<tuple<_TElements...>,
921 : : tuple<_UElements...>,
922 : : 0, sizeof...(_TElements)>;
923 : : return __compare::__eq(__t, __u);
924 : : }
925 : :
926 : : template<typename... _TElements, typename... _UElements>
927 : : constexpr bool
928 : : operator<(const tuple<_TElements...>& __t,
929 : : const tuple<_UElements...>& __u)
930 : : {
931 : : static_assert(sizeof...(_TElements) == sizeof...(_UElements),
932 : : "tuple objects can only be compared if they have equal sizes.");
933 : : using __compare = __tuple_compare<tuple<_TElements...>,
934 : : tuple<_UElements...>,
935 : : 0, sizeof...(_TElements)>;
936 : : return __compare::__less(__t, __u);
937 : : }
938 : :
939 : : template<typename... _TElements, typename... _UElements>
940 : : constexpr bool
941 : : operator!=(const tuple<_TElements...>& __t,
942 : : const tuple<_UElements...>& __u)
943 : : { return !(__t == __u); }
944 : :
945 : : template<typename... _TElements, typename... _UElements>
946 : : constexpr bool
947 : : operator>(const tuple<_TElements...>& __t,
948 : : const tuple<_UElements...>& __u)
949 : : { return __u < __t; }
950 : :
951 : : template<typename... _TElements, typename... _UElements>
952 : : constexpr bool
953 : : operator<=(const tuple<_TElements...>& __t,
954 : : const tuple<_UElements...>& __u)
955 : : { return !(__u < __t); }
956 : :
957 : : template<typename... _TElements, typename... _UElements>
958 : : constexpr bool
959 : : operator>=(const tuple<_TElements...>& __t,
960 : : const tuple<_UElements...>& __u)
961 : : { return !(__t < __u); }
962 : :
963 : : // NB: DR 705.
964 : : template<typename... _Elements>
965 : : constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
966 : : make_tuple(_Elements&&... __args)
967 : : {
968 : : typedef tuple<typename __decay_and_strip<_Elements>::__type...>
969 : : __result_type;
970 : : return __result_type(std::forward<_Elements>(__args)...);
971 : : }
972 : :
973 : : template<typename... _Elements>
974 : : tuple<_Elements&&...>
975 : : forward_as_tuple(_Elements&&... __args) noexcept
976 : : { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
977 : :
978 : : template<typename>
979 : : struct __is_tuple_like_impl : false_type
980 : : { };
981 : :
982 : : template<typename... _Tps>
983 : : struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
984 : : { };
985 : :
986 : : template<typename _T1, typename _T2>
987 : : struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
988 : : { };
989 : :
990 : : template<typename _Tp, std::size_t _Nm>
991 : : struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
992 : : { };
993 : :
994 : : // Internal type trait that allows us to sfinae-protect tuple_cat.
995 : : template<typename _Tp>
996 : : struct __is_tuple_like
997 : : : public __is_tuple_like_impl<typename std::remove_cv
998 : : <typename std::remove_reference<_Tp>::type>::type>::type
999 : : { };
1000 : :
1001 : : template<size_t, typename, typename, size_t>
1002 : : struct __make_tuple_impl;
1003 : :
1004 : : template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1005 : : struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1006 : : : __make_tuple_impl<_Idx + 1,
1007 : : tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1008 : : _Tuple, _Nm>
1009 : : { };
1010 : :
1011 : : template<std::size_t _Nm, typename _Tuple, typename... _Tp>
1012 : : struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1013 : : {
1014 : : typedef tuple<_Tp...> __type;
1015 : : };
1016 : :
1017 : : template<typename _Tuple>
1018 : : struct __do_make_tuple
1019 : : : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
1020 : : { };
1021 : :
1022 : : // Returns the std::tuple equivalent of a tuple-like type.
1023 : : template<typename _Tuple>
1024 : : struct __make_tuple
1025 : : : public __do_make_tuple<typename std::remove_cv
1026 : : <typename std::remove_reference<_Tuple>::type>::type>
1027 : : { };
1028 : :
1029 : : // Combines several std::tuple's into a single one.
1030 : : template<typename...>
1031 : : struct __combine_tuples;
1032 : :
1033 : : template<>
1034 : : struct __combine_tuples<>
1035 : : {
1036 : : typedef tuple<> __type;
1037 : : };
1038 : :
1039 : : template<typename... _Ts>
1040 : : struct __combine_tuples<tuple<_Ts...>>
1041 : : {
1042 : : typedef tuple<_Ts...> __type;
1043 : : };
1044 : :
1045 : : template<typename... _T1s, typename... _T2s, typename... _Rem>
1046 : : struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1047 : : {
1048 : : typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1049 : : _Rem...>::__type __type;
1050 : : };
1051 : :
1052 : : // Computes the result type of tuple_cat given a set of tuple-like types.
1053 : : template<typename... _Tpls>
1054 : : struct __tuple_cat_result
1055 : : {
1056 : : typedef typename __combine_tuples
1057 : : <typename __make_tuple<_Tpls>::__type...>::__type __type;
1058 : : };
1059 : :
1060 : : // Helper to determine the index set for the first tuple-like
1061 : : // type of a given set.
1062 : : template<typename...>
1063 : : struct __make_1st_indices;
1064 : :
1065 : : template<>
1066 : : struct __make_1st_indices<>
1067 : : {
1068 : : typedef std::_Index_tuple<> __type;
1069 : : };
1070 : :
1071 : : template<typename _Tp, typename... _Tpls>
1072 : : struct __make_1st_indices<_Tp, _Tpls...>
1073 : : {
1074 : : typedef typename std::_Build_index_tuple<std::tuple_size<
1075 : : typename std::remove_reference<_Tp>::type>::value>::__type __type;
1076 : : };
1077 : :
1078 : : // Performs the actual concatenation by step-wise expanding tuple-like
1079 : : // objects into the elements, which are finally forwarded into the
1080 : : // result tuple.
1081 : : template<typename _Ret, typename _Indices, typename... _Tpls>
1082 : : struct __tuple_concater;
1083 : :
1084 : : template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
1085 : : struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1086 : : {
1087 : : template<typename... _Us>
1088 : : static constexpr _Ret
1089 : : _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1090 : : {
1091 : : typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1092 : : typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1093 : : return __next::_S_do(std::forward<_Tpls>(__tps)...,
1094 : : std::forward<_Us>(__us)...,
1095 : : std::get<_Is>(std::forward<_Tp>(__tp))...);
1096 : : }
1097 : : };
1098 : :
1099 : : template<typename _Ret>
1100 : : struct __tuple_concater<_Ret, std::_Index_tuple<>>
1101 : : {
1102 : : template<typename... _Us>
1103 : : static constexpr _Ret
1104 : : _S_do(_Us&&... __us)
1105 : : {
1106 : : return _Ret(std::forward<_Us>(__us)...);
1107 : : }
1108 : : };
1109 : :
1110 : : /// tuple_cat
1111 : : template<typename... _Tpls, typename = typename
1112 : : enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1113 : : constexpr auto
1114 : : tuple_cat(_Tpls&&... __tpls)
1115 : : -> typename __tuple_cat_result<_Tpls...>::__type
1116 : : {
1117 : : typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1118 : : typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1119 : : typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1120 : : return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1121 : : }
1122 : :
1123 : : /// tie
1124 : : template<typename... _Elements>
1125 : : inline tuple<_Elements&...>
1126 : : tie(_Elements&... __args) noexcept
1127 : : { return tuple<_Elements&...>(__args...); }
1128 : :
1129 : : /// swap
1130 : : template<typename... _Elements>
1131 : : inline void
1132 : : swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1133 : : noexcept(noexcept(__x.swap(__y)))
1134 : : { __x.swap(__y); }
1135 : :
1136 : : // A class (and instance) which can be used in 'tie' when an element
1137 : : // of a tuple is not required
1138 : : struct _Swallow_assign
1139 : : {
1140 : : template<class _Tp>
1141 : : const _Swallow_assign&
1142 : : operator=(const _Tp&) const
1143 : : { return *this; }
1144 : : };
1145 : :
1146 : : const _Swallow_assign ignore{};
1147 : :
1148 : : /// Partial specialization for tuples
1149 : : template<typename... _Types, typename _Alloc>
1150 : : struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1151 : :
1152 : : // See stl_pair.h...
1153 : : template<class _T1, class _T2>
1154 : : template<typename... _Args1, typename... _Args2>
1155 : : inline
1156 : : pair<_T1, _T2>::
1157 : : pair(piecewise_construct_t,
1158 : : tuple<_Args1...> __first, tuple<_Args2...> __second)
1159 : : : pair(__first, __second,
1160 : : typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1161 : : typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1162 : : { }
1163 : :
1164 : : template<class _T1, class _T2>
1165 : : template<typename... _Args1, std::size_t... _Indexes1,
1166 : : typename... _Args2, std::size_t... _Indexes2>
1167 : : inline
1168 : : pair<_T1, _T2>::
1169 : : pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1170 : : _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1171 : : : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1172 : : second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1173 : : { }
1174 : :
1175 : : /// @}
1176 : :
1177 : : _GLIBCXX_END_NAMESPACE_VERSION
1178 : : } // namespace std
1179 : :
1180 : : #endif // C++11
1181 : :
1182 : : #endif // _GLIBCXX_TUPLE
|