1 | // -*- C++ -*- |
2 | //===--------------------------- tuple ------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef _LIBCPP_TUPLE |
11 | #define _LIBCPP_TUPLE |
12 | |
13 | /* |
14 | tuple synopsis |
15 | |
16 | namespace std |
17 | { |
18 | |
19 | template <class... T> |
20 | class tuple { |
21 | public: |
22 | explicit(see-below) constexpr tuple(); |
23 | explicit(see-below) tuple(const T&...); // constexpr in C++14 |
24 | template <class... U> |
25 | explicit(see-below) tuple(U&&...); // constexpr in C++14 |
26 | tuple(const tuple&) = default; |
27 | tuple(tuple&&) = default; |
28 | template <class... U> |
29 | explicit(see-below) tuple(const tuple<U...>&); // constexpr in C++14 |
30 | template <class... U> |
31 | explicit(see-below) tuple(tuple<U...>&&); // constexpr in C++14 |
32 | template <class U1, class U2> |
33 | explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14 |
34 | template <class U1, class U2> |
35 | explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++14 |
36 | |
37 | // allocator-extended constructors |
38 | template <class Alloc> |
39 | tuple(allocator_arg_t, const Alloc& a); |
40 | template <class Alloc> |
41 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...); |
42 | template <class Alloc, class... U> |
43 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...); |
44 | template <class Alloc> |
45 | tuple(allocator_arg_t, const Alloc& a, const tuple&); |
46 | template <class Alloc> |
47 | tuple(allocator_arg_t, const Alloc& a, tuple&&); |
48 | template <class Alloc, class... U> |
49 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&); |
50 | template <class Alloc, class... U> |
51 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&); |
52 | template <class Alloc, class U1, class U2> |
53 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); |
54 | template <class Alloc, class U1, class U2> |
55 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); |
56 | |
57 | tuple& operator=(const tuple&); |
58 | tuple& |
59 | operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...)); |
60 | template <class... U> |
61 | tuple& operator=(const tuple<U...>&); |
62 | template <class... U> |
63 | tuple& operator=(tuple<U...>&&); |
64 | template <class U1, class U2> |
65 | tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2 |
66 | template <class U1, class U2> |
67 | tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2 |
68 | |
69 | void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); |
70 | }; |
71 | |
72 | template <class ...T> |
73 | tuple(T...) -> tuple<T...>; // since C++17 |
74 | template <class T1, class T2> |
75 | tuple(pair<T1, T2>) -> tuple<T1, T2>; // since C++17 |
76 | template <class Alloc, class ...T> |
77 | tuple(allocator_arg_t, Alloc, T...) -> tuple<T...>; // since C++17 |
78 | template <class Alloc, class T1, class T2> |
79 | tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>; // since C++17 |
80 | template <class Alloc, class ...T> |
81 | tuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>; // since C++17 |
82 | |
83 | inline constexpr unspecified ignore; |
84 | |
85 | template <class... T> tuple<V...> make_tuple(T&&...); // constexpr in C++14 |
86 | template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14 |
87 | template <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14 |
88 | template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14 |
89 | |
90 | // [tuple.apply], calling a function with a tuple of arguments: |
91 | template <class F, class Tuple> |
92 | constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17 |
93 | template <class T, class Tuple> |
94 | constexpr T make_from_tuple(Tuple&& t); // C++17 |
95 | |
96 | // 20.4.1.4, tuple helper classes: |
97 | template <class T> struct tuple_size; // undefined |
98 | template <class... T> struct tuple_size<tuple<T...>>; |
99 | template <class T> |
100 | inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17 |
101 | template <size_t I, class T> struct tuple_element; // undefined |
102 | template <size_t I, class... T> struct tuple_element<I, tuple<T...>>; |
103 | template <size_t I, class T> |
104 | using tuple_element_t = typename tuple_element <I, T>::type; // C++14 |
105 | |
106 | // 20.4.1.5, element access: |
107 | template <size_t I, class... T> |
108 | typename tuple_element<I, tuple<T...>>::type& |
109 | get(tuple<T...>&) noexcept; // constexpr in C++14 |
110 | template <size_t I, class... T> |
111 | const typename tuple_element<I, tuple<T...>>::type& |
112 | get(const tuple<T...>&) noexcept; // constexpr in C++14 |
113 | template <size_t I, class... T> |
114 | typename tuple_element<I, tuple<T...>>::type&& |
115 | get(tuple<T...>&&) noexcept; // constexpr in C++14 |
116 | template <size_t I, class... T> |
117 | const typename tuple_element<I, tuple<T...>>::type&& |
118 | get(const tuple<T...>&&) noexcept; // constexpr in C++14 |
119 | |
120 | template <class T1, class... T> |
121 | constexpr T1& get(tuple<T...>&) noexcept; // C++14 |
122 | template <class T1, class... T> |
123 | constexpr const T1& get(const tuple<T...>&) noexcept; // C++14 |
124 | template <class T1, class... T> |
125 | constexpr T1&& get(tuple<T...>&&) noexcept; // C++14 |
126 | template <class T1, class... T> |
127 | constexpr const T1&& get(const tuple<T...>&&) noexcept; // C++14 |
128 | |
129 | // 20.4.1.6, relational operators: |
130 | template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14 |
131 | template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14 |
132 | template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14 |
133 | template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14 |
134 | template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14 |
135 | template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14 |
136 | |
137 | template <class... Types, class Alloc> |
138 | struct uses_allocator<tuple<Types...>, Alloc>; |
139 | |
140 | template <class... Types> |
141 | void |
142 | swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y))); |
143 | |
144 | } // std |
145 | |
146 | */ |
147 | |
148 | #include <__config> |
149 | #include <__tuple> |
150 | #include <cstddef> |
151 | #include <type_traits> |
152 | #include <__functional_base> |
153 | #include <utility> |
154 | #include <version> |
155 | |
156 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
157 | #pragma GCC system_header |
158 | #endif |
159 | |
160 | _LIBCPP_BEGIN_NAMESPACE_STD |
161 | |
162 | #ifndef _LIBCPP_CXX03_LANG |
163 | |
164 | |
165 | // __tuple_leaf |
166 | |
167 | template <size_t _Ip, class _Hp, |
168 | bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value |
169 | > |
170 | class __tuple_leaf; |
171 | |
172 | template <size_t _Ip, class _Hp, bool _Ep> |
173 | inline _LIBCPP_INLINE_VISIBILITY |
174 | void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y) |
175 | _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value) |
176 | { |
177 | swap(__x.get(), __y.get()); |
178 | } |
179 | |
180 | template <size_t _Ip, class _Hp, bool> |
181 | class __tuple_leaf |
182 | { |
183 | _Hp __value_; |
184 | |
185 | template <class _Tp> |
186 | static constexpr bool __can_bind_reference() { |
187 | #if __has_keyword(__reference_binds_to_temporary) |
188 | return !__reference_binds_to_temporary(_Hp, _Tp); |
189 | #else |
190 | return true; |
191 | #endif |
192 | } |
193 | |
194 | __tuple_leaf& operator=(const __tuple_leaf&); |
195 | public: |
196 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf() |
197 | _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_() |
198 | {static_assert(!is_reference<_Hp>::value, |
199 | "Attempted to default construct a reference element in a tuple" );} |
200 | |
201 | template <class _Alloc> |
202 | _LIBCPP_INLINE_VISIBILITY |
203 | __tuple_leaf(integral_constant<int, 0>, const _Alloc&) |
204 | : __value_() |
205 | {static_assert(!is_reference<_Hp>::value, |
206 | "Attempted to default construct a reference element in a tuple" );} |
207 | |
208 | template <class _Alloc> |
209 | _LIBCPP_INLINE_VISIBILITY |
210 | __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) |
211 | : __value_(allocator_arg_t(), __a) |
212 | {static_assert(!is_reference<_Hp>::value, |
213 | "Attempted to default construct a reference element in a tuple" );} |
214 | |
215 | template <class _Alloc> |
216 | _LIBCPP_INLINE_VISIBILITY |
217 | __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) |
218 | : __value_(__a) |
219 | {static_assert(!is_reference<_Hp>::value, |
220 | "Attempted to default construct a reference element in a tuple" );} |
221 | |
222 | template <class _Tp, |
223 | class = _EnableIf< |
224 | _And< |
225 | _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>, |
226 | is_constructible<_Hp, _Tp> |
227 | >::value |
228 | > |
229 | > |
230 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
231 | explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value)) |
232 | : __value_(_VSTD::forward<_Tp>(__t)) |
233 | {static_assert(__can_bind_reference<_Tp&&>(), |
234 | "Attempted construction of reference element binds to a temporary whose lifetime has ended" );} |
235 | |
236 | template <class _Tp, class _Alloc> |
237 | _LIBCPP_INLINE_VISIBILITY |
238 | explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) |
239 | : __value_(_VSTD::forward<_Tp>(__t)) |
240 | {static_assert(__can_bind_reference<_Tp&&>(), |
241 | "Attempted construction of reference element binds to a temporary whose lifetime has ended" );} |
242 | |
243 | template <class _Tp, class _Alloc> |
244 | _LIBCPP_INLINE_VISIBILITY |
245 | explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) |
246 | : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) |
247 | {static_assert(!is_reference<_Hp>::value, |
248 | "Attempted to uses-allocator construct a reference element in a tuple" );} |
249 | |
250 | template <class _Tp, class _Alloc> |
251 | _LIBCPP_INLINE_VISIBILITY |
252 | explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) |
253 | : __value_(_VSTD::forward<_Tp>(__t), __a) |
254 | {static_assert(!is_reference<_Hp>::value, |
255 | "Attempted to uses-allocator construct a reference element in a tuple" );} |
256 | |
257 | __tuple_leaf(const __tuple_leaf& __t) = default; |
258 | __tuple_leaf(__tuple_leaf&& __t) = default; |
259 | |
260 | template <class _Tp> |
261 | _LIBCPP_INLINE_VISIBILITY |
262 | __tuple_leaf& |
263 | operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value)) |
264 | { |
265 | __value_ = _VSTD::forward<_Tp>(__t); |
266 | return *this; |
267 | } |
268 | |
269 | _LIBCPP_INLINE_VISIBILITY |
270 | int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) |
271 | { |
272 | _VSTD::swap(*this, __t); |
273 | return 0; |
274 | } |
275 | |
276 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return __value_;} |
277 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;} |
278 | }; |
279 | |
280 | template <size_t _Ip, class _Hp> |
281 | class __tuple_leaf<_Ip, _Hp, true> |
282 | : private _Hp |
283 | { |
284 | |
285 | __tuple_leaf& operator=(const __tuple_leaf&); |
286 | public: |
287 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf() |
288 | _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {} |
289 | |
290 | template <class _Alloc> |
291 | _LIBCPP_INLINE_VISIBILITY |
292 | __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {} |
293 | |
294 | template <class _Alloc> |
295 | _LIBCPP_INLINE_VISIBILITY |
296 | __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) |
297 | : _Hp(allocator_arg_t(), __a) {} |
298 | |
299 | template <class _Alloc> |
300 | _LIBCPP_INLINE_VISIBILITY |
301 | __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) |
302 | : _Hp(__a) {} |
303 | |
304 | template <class _Tp, |
305 | class = _EnableIf< |
306 | _And< |
307 | _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>, |
308 | is_constructible<_Hp, _Tp> |
309 | >::value |
310 | > |
311 | > |
312 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
313 | explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value)) |
314 | : _Hp(_VSTD::forward<_Tp>(__t)) {} |
315 | |
316 | template <class _Tp, class _Alloc> |
317 | _LIBCPP_INLINE_VISIBILITY |
318 | explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) |
319 | : _Hp(_VSTD::forward<_Tp>(__t)) {} |
320 | |
321 | template <class _Tp, class _Alloc> |
322 | _LIBCPP_INLINE_VISIBILITY |
323 | explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) |
324 | : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {} |
325 | |
326 | template <class _Tp, class _Alloc> |
327 | _LIBCPP_INLINE_VISIBILITY |
328 | explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) |
329 | : _Hp(_VSTD::forward<_Tp>(__t), __a) {} |
330 | |
331 | __tuple_leaf(__tuple_leaf const &) = default; |
332 | __tuple_leaf(__tuple_leaf &&) = default; |
333 | |
334 | template <class _Tp> |
335 | _LIBCPP_INLINE_VISIBILITY |
336 | __tuple_leaf& |
337 | operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value)) |
338 | { |
339 | _Hp::operator=(_VSTD::forward<_Tp>(__t)); |
340 | return *this; |
341 | } |
342 | |
343 | _LIBCPP_INLINE_VISIBILITY |
344 | int |
345 | swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) |
346 | { |
347 | _VSTD::swap(*this, __t); |
348 | return 0; |
349 | } |
350 | |
351 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return static_cast<_Hp&>(*this);} |
352 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);} |
353 | }; |
354 | |
355 | template <class ..._Tp> |
356 | _LIBCPP_INLINE_VISIBILITY |
357 | void __swallow(_Tp&&...) _NOEXCEPT {} |
358 | |
359 | template <class _Tp> |
360 | struct __all_default_constructible; |
361 | |
362 | template <class ..._Tp> |
363 | struct __all_default_constructible<__tuple_types<_Tp...>> |
364 | : __all<is_default_constructible<_Tp>::value...> |
365 | { }; |
366 | |
367 | // __tuple_impl |
368 | |
369 | template<class _Indx, class ..._Tp> struct __tuple_impl; |
370 | |
371 | template<size_t ..._Indx, class ..._Tp> |
372 | struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...> |
373 | : public __tuple_leaf<_Indx, _Tp>... |
374 | { |
375 | _LIBCPP_INLINE_VISIBILITY |
376 | _LIBCPP_CONSTEXPR __tuple_impl() |
377 | _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} |
378 | |
379 | template <size_t ..._Uf, class ..._Tf, |
380 | size_t ..._Ul, class ..._Tl, class ..._Up> |
381 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
382 | explicit |
383 | __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>, |
384 | __tuple_indices<_Ul...>, __tuple_types<_Tl...>, |
385 | _Up&&... __u) |
386 | _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value && |
387 | __all<is_nothrow_default_constructible<_Tl>::value...>::value)) : |
388 | __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))..., |
389 | __tuple_leaf<_Ul, _Tl>()... |
390 | {} |
391 | |
392 | template <class _Alloc, size_t ..._Uf, class ..._Tf, |
393 | size_t ..._Ul, class ..._Tl, class ..._Up> |
394 | _LIBCPP_INLINE_VISIBILITY |
395 | explicit |
396 | __tuple_impl(allocator_arg_t, const _Alloc& __a, |
397 | __tuple_indices<_Uf...>, __tuple_types<_Tf...>, |
398 | __tuple_indices<_Ul...>, __tuple_types<_Tl...>, |
399 | _Up&&... __u) : |
400 | __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a, |
401 | _VSTD::forward<_Up>(__u))..., |
402 | __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)... |
403 | {} |
404 | |
405 | template <class _Tuple, |
406 | class = typename enable_if |
407 | < |
408 | __tuple_constructible<_Tuple, tuple<_Tp...> >::value |
409 | >::type |
410 | > |
411 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
412 | __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx, |
413 | typename __make_tuple_types<_Tuple>::type>::type>::value...>::value)) |
414 | : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx, |
415 | typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))... |
416 | {} |
417 | |
418 | template <class _Alloc, class _Tuple, |
419 | class = typename enable_if |
420 | < |
421 | __tuple_constructible<_Tuple, tuple<_Tp...> >::value |
422 | >::type |
423 | > |
424 | _LIBCPP_INLINE_VISIBILITY |
425 | __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) |
426 | : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx, |
427 | typename __make_tuple_types<_Tuple>::type>::type>(), __a, |
428 | _VSTD::forward<typename tuple_element<_Indx, |
429 | typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))... |
430 | {} |
431 | |
432 | template <class _Tuple> |
433 | _LIBCPP_INLINE_VISIBILITY |
434 | typename enable_if |
435 | < |
436 | __tuple_assignable<_Tuple, tuple<_Tp...> >::value, |
437 | __tuple_impl& |
438 | >::type |
439 | operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx, |
440 | typename __make_tuple_types<_Tuple>::type>::type>::value...>::value)) |
441 | { |
442 | __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx, |
443 | typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...); |
444 | return *this; |
445 | } |
446 | |
447 | __tuple_impl(const __tuple_impl&) = default; |
448 | __tuple_impl(__tuple_impl&&) = default; |
449 | |
450 | _LIBCPP_INLINE_VISIBILITY |
451 | __tuple_impl& |
452 | operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value)) |
453 | { |
454 | __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...); |
455 | return *this; |
456 | } |
457 | |
458 | _LIBCPP_INLINE_VISIBILITY |
459 | __tuple_impl& |
460 | operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value)) |
461 | { |
462 | __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...); |
463 | return *this; |
464 | } |
465 | |
466 | _LIBCPP_INLINE_VISIBILITY |
467 | void swap(__tuple_impl& __t) |
468 | _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) |
469 | { |
470 | __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...); |
471 | } |
472 | }; |
473 | |
474 | |
475 | |
476 | template <class ..._Tp> |
477 | class _LIBCPP_TEMPLATE_VIS tuple |
478 | { |
479 | typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT; |
480 | |
481 | _BaseT __base_; |
482 | |
483 | #if defined(_LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION) |
484 | static constexpr bool _EnableImplicitReducedArityExtension = true; |
485 | #else |
486 | static constexpr bool _EnableImplicitReducedArityExtension = false; |
487 | #endif |
488 | |
489 | template <class ..._Args> |
490 | struct _PackExpandsToThisTuple : false_type {}; |
491 | |
492 | template <class _Arg> |
493 | struct _PackExpandsToThisTuple<_Arg> |
494 | : is_same<typename __uncvref<_Arg>::type, tuple> {}; |
495 | |
496 | template <bool _MaybeEnable, class _Dummy = void> |
497 | struct _CheckArgsConstructor : __check_tuple_constructor_fail {}; |
498 | |
499 | template <class _Dummy> |
500 | struct _CheckArgsConstructor<true, _Dummy> |
501 | { |
502 | template <int&...> |
503 | static constexpr bool __enable_implicit_default() { |
504 | return __all<__is_implicitly_default_constructible<_Tp>::value... >::value; |
505 | } |
506 | |
507 | template <int&...> |
508 | static constexpr bool __enable_explicit_default() { |
509 | return |
510 | __all<is_default_constructible<_Tp>::value...>::value && |
511 | !__enable_implicit_default< >(); |
512 | } |
513 | |
514 | |
515 | template <class ..._Args> |
516 | static constexpr bool __enable_explicit() { |
517 | return |
518 | __tuple_constructible< |
519 | tuple<_Args...>, |
520 | typename __make_tuple_types<tuple, |
521 | sizeof...(_Args) < sizeof...(_Tp) ? |
522 | sizeof...(_Args) : |
523 | sizeof...(_Tp)>::type |
524 | >::value && |
525 | !__tuple_convertible< |
526 | tuple<_Args...>, |
527 | typename __make_tuple_types<tuple, |
528 | sizeof...(_Args) < sizeof...(_Tp) ? |
529 | sizeof...(_Args) : |
530 | sizeof...(_Tp)>::type |
531 | >::value && |
532 | __all_default_constructible< |
533 | typename __make_tuple_types<tuple, sizeof...(_Tp), |
534 | sizeof...(_Args) < sizeof...(_Tp) ? |
535 | sizeof...(_Args) : |
536 | sizeof...(_Tp)>::type |
537 | >::value; |
538 | } |
539 | |
540 | template <class ..._Args> |
541 | static constexpr bool __enable_implicit() { |
542 | return |
543 | __tuple_constructible< |
544 | tuple<_Args...>, |
545 | typename __make_tuple_types<tuple, |
546 | sizeof...(_Args) < sizeof...(_Tp) ? |
547 | sizeof...(_Args) : |
548 | sizeof...(_Tp)>::type |
549 | >::value && |
550 | __tuple_convertible< |
551 | tuple<_Args...>, |
552 | typename __make_tuple_types<tuple, |
553 | sizeof...(_Args) < sizeof...(_Tp) ? |
554 | sizeof...(_Args) : |
555 | sizeof...(_Tp)>::type |
556 | >::value && |
557 | __all_default_constructible< |
558 | typename __make_tuple_types<tuple, sizeof...(_Tp), |
559 | sizeof...(_Args) < sizeof...(_Tp) ? |
560 | sizeof...(_Args) : |
561 | sizeof...(_Tp)>::type |
562 | >::value; |
563 | } |
564 | }; |
565 | |
566 | template <bool _MaybeEnable, |
567 | bool = sizeof...(_Tp) == 1, |
568 | class _Dummy = void> |
569 | struct _CheckTupleLikeConstructor : __check_tuple_constructor_fail {}; |
570 | |
571 | template <class _Dummy> |
572 | struct _CheckTupleLikeConstructor<true, false, _Dummy> |
573 | { |
574 | template <class _Tuple> |
575 | static constexpr bool __enable_implicit() { |
576 | return __tuple_constructible<_Tuple, tuple>::value |
577 | && __tuple_convertible<_Tuple, tuple>::value; |
578 | } |
579 | |
580 | template <class _Tuple> |
581 | static constexpr bool __enable_explicit() { |
582 | return __tuple_constructible<_Tuple, tuple>::value |
583 | && !__tuple_convertible<_Tuple, tuple>::value; |
584 | } |
585 | }; |
586 | |
587 | template <class _Dummy> |
588 | struct _CheckTupleLikeConstructor<true, true, _Dummy> |
589 | { |
590 | // This trait is used to disable the tuple-like constructor when |
591 | // the UTypes... constructor should be selected instead. |
592 | // See LWG issue #2549. |
593 | template <class _Tuple> |
594 | using _PreferTupleLikeConstructor = _Or< |
595 | // Don't attempt the two checks below if the tuple we are given |
596 | // has the same type as this tuple. |
597 | _IsSame<__uncvref_t<_Tuple>, tuple>, |
598 | _Lazy<_And, |
599 | _Not<is_constructible<_Tp..., _Tuple>>, |
600 | _Not<is_convertible<_Tuple, _Tp...>> |
601 | > |
602 | >; |
603 | |
604 | template <class _Tuple> |
605 | static constexpr bool __enable_implicit() { |
606 | return _And< |
607 | __tuple_constructible<_Tuple, tuple>, |
608 | __tuple_convertible<_Tuple, tuple>, |
609 | _PreferTupleLikeConstructor<_Tuple> |
610 | >::value; |
611 | } |
612 | |
613 | template <class _Tuple> |
614 | static constexpr bool __enable_explicit() { |
615 | return _And< |
616 | __tuple_constructible<_Tuple, tuple>, |
617 | _PreferTupleLikeConstructor<_Tuple>, |
618 | _Not<__tuple_convertible<_Tuple, tuple>> |
619 | >::value; |
620 | } |
621 | }; |
622 | |
623 | template <class _Tuple, bool _DisableIfLValue> |
624 | using _EnableImplicitTupleLikeConstructor = _EnableIf< |
625 | _CheckTupleLikeConstructor< |
626 | __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value |
627 | && !_PackExpandsToThisTuple<_Tuple>::value |
628 | && (!is_lvalue_reference<_Tuple>::value || !_DisableIfLValue) |
629 | >::template __enable_implicit<_Tuple>(), |
630 | bool |
631 | >; |
632 | |
633 | template <class _Tuple, bool _DisableIfLValue> |
634 | using _EnableExplicitTupleLikeConstructor = _EnableIf< |
635 | _CheckTupleLikeConstructor< |
636 | __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value |
637 | && !_PackExpandsToThisTuple<_Tuple>::value |
638 | && (!is_lvalue_reference<_Tuple>::value || !_DisableIfLValue) |
639 | >::template __enable_explicit<_Tuple>(), |
640 | bool |
641 | >; |
642 | template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 |
643 | typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT; |
644 | template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 |
645 | const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT; |
646 | template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 |
647 | typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT; |
648 | template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 |
649 | const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT; |
650 | public: |
651 | |
652 | template <bool _Dummy = true, _EnableIf< |
653 | _CheckArgsConstructor<_Dummy>::__enable_implicit_default() |
654 | , void*> = nullptr> |
655 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
656 | tuple() |
657 | _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} |
658 | |
659 | template <bool _Dummy = true, _EnableIf< |
660 | _CheckArgsConstructor<_Dummy>::__enable_explicit_default() |
661 | , void*> = nullptr> |
662 | explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
663 | tuple() |
664 | _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} |
665 | |
666 | tuple(tuple const&) = default; |
667 | tuple(tuple&&) = default; |
668 | |
669 | template <class _AllocArgT, class _Alloc, _EnableIf< |
670 | _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value >::__enable_implicit_default() |
671 | , void*> = nullptr |
672 | > |
673 | _LIBCPP_INLINE_VISIBILITY |
674 | tuple(_AllocArgT, _Alloc const& __a) |
675 | : __base_(allocator_arg_t(), __a, |
676 | __tuple_indices<>(), __tuple_types<>(), |
677 | typename __make_tuple_indices<sizeof...(_Tp), 0>::type(), |
678 | __tuple_types<_Tp...>()) {} |
679 | |
680 | template <class _AllocArgT, class _Alloc, _EnableIf< |
681 | _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value>::__enable_explicit_default() |
682 | , void*> = nullptr |
683 | > |
684 | explicit _LIBCPP_INLINE_VISIBILITY |
685 | tuple(_AllocArgT, _Alloc const& __a) |
686 | : __base_(allocator_arg_t(), __a, |
687 | __tuple_indices<>(), __tuple_types<>(), |
688 | typename __make_tuple_indices<sizeof...(_Tp), 0>::type(), |
689 | __tuple_types<_Tp...>()) {} |
690 | |
691 | template <bool _Dummy = true, |
692 | typename enable_if |
693 | < |
694 | _CheckArgsConstructor< |
695 | _Dummy |
696 | >::template __enable_implicit<_Tp const&...>(), |
697 | bool |
698 | >::type = false |
699 | > |
700 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
701 | tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) |
702 | : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), |
703 | typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), |
704 | typename __make_tuple_indices<0>::type(), |
705 | typename __make_tuple_types<tuple, 0>::type(), |
706 | __t... |
707 | ) {} |
708 | |
709 | template <bool _Dummy = true, |
710 | typename enable_if |
711 | < |
712 | _CheckArgsConstructor< |
713 | _Dummy |
714 | >::template __enable_explicit<_Tp const&...>(), |
715 | bool |
716 | >::type = false |
717 | > |
718 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
719 | explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) |
720 | : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), |
721 | typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), |
722 | typename __make_tuple_indices<0>::type(), |
723 | typename __make_tuple_types<tuple, 0>::type(), |
724 | __t... |
725 | ) {} |
726 | |
727 | template <class _Alloc, bool _Dummy = true, |
728 | typename enable_if |
729 | < |
730 | _CheckArgsConstructor< |
731 | _Dummy |
732 | >::template __enable_implicit<_Tp const&...>(), |
733 | bool |
734 | >::type = false |
735 | > |
736 | _LIBCPP_INLINE_VISIBILITY |
737 | tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) |
738 | : __base_(allocator_arg_t(), __a, |
739 | typename __make_tuple_indices<sizeof...(_Tp)>::type(), |
740 | typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), |
741 | typename __make_tuple_indices<0>::type(), |
742 | typename __make_tuple_types<tuple, 0>::type(), |
743 | __t... |
744 | ) {} |
745 | |
746 | template <class _Alloc, bool _Dummy = true, |
747 | typename enable_if |
748 | < |
749 | _CheckArgsConstructor< |
750 | _Dummy |
751 | >::template __enable_explicit<_Tp const&...>(), |
752 | bool |
753 | >::type = false |
754 | > |
755 | _LIBCPP_INLINE_VISIBILITY |
756 | explicit |
757 | tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) |
758 | : __base_(allocator_arg_t(), __a, |
759 | typename __make_tuple_indices<sizeof...(_Tp)>::type(), |
760 | typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), |
761 | typename __make_tuple_indices<0>::type(), |
762 | typename __make_tuple_types<tuple, 0>::type(), |
763 | __t... |
764 | ) {} |
765 | |
766 | template <class ..._Up, |
767 | bool _PackIsTuple = _PackExpandsToThisTuple<_Up...>::value, |
768 | typename enable_if |
769 | < |
770 | _CheckArgsConstructor< |
771 | sizeof...(_Up) == sizeof...(_Tp) |
772 | && !_PackIsTuple |
773 | >::template __enable_implicit<_Up...>() || |
774 | _CheckArgsConstructor< |
775 | _EnableImplicitReducedArityExtension |
776 | && sizeof...(_Up) < sizeof...(_Tp) |
777 | && !_PackIsTuple |
778 | >::template __enable_implicit<_Up...>(), |
779 | bool |
780 | >::type = false |
781 | > |
782 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
783 | tuple(_Up&&... __u) |
784 | _NOEXCEPT_(( |
785 | is_nothrow_constructible<_BaseT, |
786 | typename __make_tuple_indices<sizeof...(_Up)>::type, |
787 | typename __make_tuple_types<tuple, sizeof...(_Up)>::type, |
788 | typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type, |
789 | typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type, |
790 | _Up... |
791 | >::value |
792 | )) |
793 | : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(), |
794 | typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), |
795 | typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), |
796 | typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), |
797 | _VSTD::forward<_Up>(__u)...) {} |
798 | |
799 | template <class ..._Up, |
800 | typename enable_if |
801 | < |
802 | _CheckArgsConstructor< |
803 | sizeof...(_Up) <= sizeof...(_Tp) |
804 | && !_PackExpandsToThisTuple<_Up...>::value |
805 | >::template __enable_explicit<_Up...>() || |
806 | _CheckArgsConstructor< |
807 | !_EnableImplicitReducedArityExtension |
808 | && sizeof...(_Up) < sizeof...(_Tp) |
809 | && !_PackExpandsToThisTuple<_Up...>::value |
810 | >::template __enable_implicit<_Up...>(), |
811 | bool |
812 | >::type = false |
813 | > |
814 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
815 | explicit |
816 | tuple(_Up&&... __u) |
817 | _NOEXCEPT_(( |
818 | is_nothrow_constructible<_BaseT, |
819 | typename __make_tuple_indices<sizeof...(_Up)>::type, |
820 | typename __make_tuple_types<tuple, sizeof...(_Up)>::type, |
821 | typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type, |
822 | typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type, |
823 | _Up... |
824 | >::value |
825 | )) |
826 | : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(), |
827 | typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), |
828 | typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), |
829 | typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), |
830 | _VSTD::forward<_Up>(__u)...) {} |
831 | |
832 | template <class _Alloc, class ..._Up, |
833 | typename enable_if |
834 | < |
835 | _CheckArgsConstructor< |
836 | sizeof...(_Up) == sizeof...(_Tp) && |
837 | !_PackExpandsToThisTuple<_Up...>::value |
838 | >::template __enable_implicit<_Up...>(), |
839 | bool |
840 | >::type = false |
841 | > |
842 | _LIBCPP_INLINE_VISIBILITY |
843 | tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) |
844 | : __base_(allocator_arg_t(), __a, |
845 | typename __make_tuple_indices<sizeof...(_Up)>::type(), |
846 | typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), |
847 | typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), |
848 | typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), |
849 | _VSTD::forward<_Up>(__u)...) {} |
850 | |
851 | template <class _Alloc, class ..._Up, |
852 | typename enable_if |
853 | < |
854 | _CheckArgsConstructor< |
855 | sizeof...(_Up) == sizeof...(_Tp) && |
856 | !_PackExpandsToThisTuple<_Up...>::value |
857 | >::template __enable_explicit<_Up...>(), |
858 | bool |
859 | >::type = false |
860 | > |
861 | _LIBCPP_INLINE_VISIBILITY |
862 | explicit |
863 | tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) |
864 | : __base_(allocator_arg_t(), __a, |
865 | typename __make_tuple_indices<sizeof...(_Up)>::type(), |
866 | typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), |
867 | typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), |
868 | typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), |
869 | _VSTD::forward<_Up>(__u)...) {} |
870 | |
871 | template <class _Tuple, _EnableImplicitTupleLikeConstructor<_Tuple, true> = false> |
872 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
873 | tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value)) |
874 | : __base_(_VSTD::forward<_Tuple>(__t)) {} |
875 | |
876 | template <class _Tuple, _EnableImplicitTupleLikeConstructor<const _Tuple&, false> = false> |
877 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
878 | tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, const _Tuple&>::value)) |
879 | : __base_(__t) {} |
880 | template <class _Tuple, _EnableExplicitTupleLikeConstructor<_Tuple, true> = false> |
881 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
882 | explicit |
883 | tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value)) |
884 | : __base_(_VSTD::forward<_Tuple>(__t)) {} |
885 | |
886 | template <class _Tuple, _EnableExplicitTupleLikeConstructor<const _Tuple&, false> = false> |
887 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
888 | explicit |
889 | tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, const _Tuple&>::value)) |
890 | : __base_(__t) {} |
891 | |
892 | template <class _Alloc, class _Tuple, |
893 | typename enable_if |
894 | < |
895 | _CheckTupleLikeConstructor< |
896 | __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value |
897 | >::template __enable_implicit<_Tuple>(), |
898 | bool |
899 | >::type = false |
900 | > |
901 | _LIBCPP_INLINE_VISIBILITY |
902 | tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) |
903 | : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} |
904 | |
905 | template <class _Alloc, class _Tuple, |
906 | typename enable_if |
907 | < |
908 | _CheckTupleLikeConstructor< |
909 | __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value |
910 | >::template __enable_explicit<_Tuple>(), |
911 | bool |
912 | >::type = false |
913 | > |
914 | _LIBCPP_INLINE_VISIBILITY |
915 | explicit |
916 | tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) |
917 | : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} |
918 | |
919 | using _CanCopyAssign = __all<is_copy_assignable<_Tp>::value...>; |
920 | using _CanMoveAssign = __all<is_move_assignable<_Tp>::value...>; |
921 | |
922 | _LIBCPP_INLINE_VISIBILITY |
923 | tuple& operator=(typename conditional<_CanCopyAssign::value, tuple, __nat>::type const& __t) |
924 | _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value)) |
925 | { |
926 | __base_.operator=(__t.__base_); |
927 | return *this; |
928 | } |
929 | |
930 | _LIBCPP_INLINE_VISIBILITY |
931 | tuple& operator=(typename conditional<_CanMoveAssign::value, tuple, __nat>::type&& __t) |
932 | _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value)) |
933 | { |
934 | __base_.operator=(static_cast<_BaseT&&>(__t.__base_)); |
935 | return *this; |
936 | } |
937 | |
938 | template <class _Tuple, |
939 | class = typename enable_if |
940 | < |
941 | __tuple_assignable<_Tuple, tuple>::value |
942 | >::type |
943 | > |
944 | _LIBCPP_INLINE_VISIBILITY |
945 | tuple& |
946 | operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<_BaseT&, _Tuple>::value)) |
947 | { |
948 | __base_.operator=(_VSTD::forward<_Tuple>(__t)); |
949 | return *this; |
950 | } |
951 | |
952 | _LIBCPP_INLINE_VISIBILITY |
953 | void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) |
954 | {__base_.swap(__t.__base_);} |
955 | }; |
956 | |
957 | template <> |
958 | class _LIBCPP_TEMPLATE_VIS tuple<> |
959 | { |
960 | public: |
961 | _LIBCPP_INLINE_VISIBILITY |
962 | _LIBCPP_CONSTEXPR tuple() _NOEXCEPT = default; |
963 | template <class _Alloc> |
964 | _LIBCPP_INLINE_VISIBILITY |
965 | tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {} |
966 | template <class _Alloc> |
967 | _LIBCPP_INLINE_VISIBILITY |
968 | tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {} |
969 | template <class _Up> |
970 | _LIBCPP_INLINE_VISIBILITY |
971 | tuple(array<_Up, 0>) _NOEXCEPT {} |
972 | template <class _Alloc, class _Up> |
973 | _LIBCPP_INLINE_VISIBILITY |
974 | tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {} |
975 | _LIBCPP_INLINE_VISIBILITY |
976 | void swap(tuple&) _NOEXCEPT {} |
977 | }; |
978 | |
979 | #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES |
980 | template <class ..._Tp> |
981 | tuple(_Tp...) -> tuple<_Tp...>; |
982 | template <class _Tp1, class _Tp2> |
983 | tuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>; |
984 | template <class _Alloc, class ..._Tp> |
985 | tuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>; |
986 | template <class _Alloc, class _Tp1, class _Tp2> |
987 | tuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>; |
988 | template <class _Alloc, class ..._Tp> |
989 | tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>; |
990 | #endif |
991 | |
992 | template <class ..._Tp> |
993 | inline _LIBCPP_INLINE_VISIBILITY |
994 | typename enable_if |
995 | < |
996 | __all<__is_swappable<_Tp>::value...>::value, |
997 | void |
998 | >::type |
999 | swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u) |
1000 | _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) |
1001 | {__t.swap(__u);} |
1002 | |
1003 | // get |
1004 | |
1005 | template <size_t _Ip, class ..._Tp> |
1006 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1007 | typename tuple_element<_Ip, tuple<_Tp...> >::type& |
1008 | get(tuple<_Tp...>& __t) _NOEXCEPT |
1009 | { |
1010 | typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type; |
1011 | return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get(); |
1012 | } |
1013 | |
1014 | template <size_t _Ip, class ..._Tp> |
1015 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1016 | const typename tuple_element<_Ip, tuple<_Tp...> >::type& |
1017 | get(const tuple<_Tp...>& __t) _NOEXCEPT |
1018 | { |
1019 | typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type; |
1020 | return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get(); |
1021 | } |
1022 | |
1023 | template <size_t _Ip, class ..._Tp> |
1024 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1025 | typename tuple_element<_Ip, tuple<_Tp...> >::type&& |
1026 | get(tuple<_Tp...>&& __t) _NOEXCEPT |
1027 | { |
1028 | typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type; |
1029 | return static_cast<type&&>( |
1030 | static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get()); |
1031 | } |
1032 | |
1033 | template <size_t _Ip, class ..._Tp> |
1034 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1035 | const typename tuple_element<_Ip, tuple<_Tp...> >::type&& |
1036 | get(const tuple<_Tp...>&& __t) _NOEXCEPT |
1037 | { |
1038 | typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type; |
1039 | return static_cast<const type&&>( |
1040 | static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get()); |
1041 | } |
1042 | |
1043 | #if _LIBCPP_STD_VER > 11 |
1044 | |
1045 | namespace __find_detail { |
1046 | |
1047 | static constexpr size_t __not_found = -1; |
1048 | static constexpr size_t __ambiguous = __not_found - 1; |
1049 | |
1050 | inline _LIBCPP_INLINE_VISIBILITY |
1051 | constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) { |
1052 | return !__matches ? __res : |
1053 | (__res == __not_found ? __curr_i : __ambiguous); |
1054 | } |
1055 | |
1056 | template <size_t _Nx> |
1057 | inline _LIBCPP_INLINE_VISIBILITY |
1058 | constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) { |
1059 | return __i == _Nx ? __not_found : |
1060 | __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]); |
1061 | } |
1062 | |
1063 | template <class _T1, class ..._Args> |
1064 | struct __find_exactly_one_checked { |
1065 | static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...}; |
1066 | static constexpr size_t value = __find_detail::__find_idx(0, __matches); |
1067 | static_assert(value != __not_found, "type not found in type list" ); |
1068 | static_assert(value != __ambiguous, "type occurs more than once in type list" ); |
1069 | }; |
1070 | |
1071 | template <class _T1> |
1072 | struct __find_exactly_one_checked<_T1> { |
1073 | static_assert(!is_same<_T1, _T1>::value, "type not in empty type list" ); |
1074 | }; |
1075 | |
1076 | } // namespace __find_detail; |
1077 | |
1078 | template <typename _T1, typename... _Args> |
1079 | struct __find_exactly_one_t |
1080 | : public __find_detail::__find_exactly_one_checked<_T1, _Args...> { |
1081 | }; |
1082 | |
1083 | template <class _T1, class... _Args> |
1084 | inline _LIBCPP_INLINE_VISIBILITY |
1085 | constexpr _T1& get(tuple<_Args...>& __tup) noexcept |
1086 | { |
1087 | return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup); |
1088 | } |
1089 | |
1090 | template <class _T1, class... _Args> |
1091 | inline _LIBCPP_INLINE_VISIBILITY |
1092 | constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept |
1093 | { |
1094 | return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup); |
1095 | } |
1096 | |
1097 | template <class _T1, class... _Args> |
1098 | inline _LIBCPP_INLINE_VISIBILITY |
1099 | constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept |
1100 | { |
1101 | return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup)); |
1102 | } |
1103 | |
1104 | template <class _T1, class... _Args> |
1105 | inline _LIBCPP_INLINE_VISIBILITY |
1106 | constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept |
1107 | { |
1108 | return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup)); |
1109 | } |
1110 | |
1111 | #endif |
1112 | |
1113 | // tie |
1114 | |
1115 | template <class ..._Tp> |
1116 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1117 | tuple<_Tp&...> |
1118 | tie(_Tp&... __t) _NOEXCEPT |
1119 | { |
1120 | return tuple<_Tp&...>(__t...); |
1121 | } |
1122 | |
1123 | template <class _Up> |
1124 | struct __ignore_t |
1125 | { |
1126 | template <class _Tp> |
1127 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1128 | const __ignore_t& operator=(_Tp&&) const {return *this;} |
1129 | }; |
1130 | |
1131 | namespace { |
1132 | _LIBCPP_INLINE_VAR constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); |
1133 | } |
1134 | |
1135 | template <class... _Tp> |
1136 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1137 | tuple<typename __unwrap_ref_decay<_Tp>::type...> |
1138 | make_tuple(_Tp&&... __t) |
1139 | { |
1140 | return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...); |
1141 | } |
1142 | |
1143 | template <class... _Tp> |
1144 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1145 | tuple<_Tp&&...> |
1146 | forward_as_tuple(_Tp&&... __t) _NOEXCEPT |
1147 | { |
1148 | return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...); |
1149 | } |
1150 | |
1151 | template <size_t _Ip> |
1152 | struct __tuple_equal |
1153 | { |
1154 | template <class _Tp, class _Up> |
1155 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1156 | bool operator()(const _Tp& __x, const _Up& __y) |
1157 | { |
1158 | return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y); |
1159 | } |
1160 | }; |
1161 | |
1162 | template <> |
1163 | struct __tuple_equal<0> |
1164 | { |
1165 | template <class _Tp, class _Up> |
1166 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1167 | bool operator()(const _Tp&, const _Up&) |
1168 | { |
1169 | return true; |
1170 | } |
1171 | }; |
1172 | |
1173 | template <class ..._Tp, class ..._Up> |
1174 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1175 | bool |
1176 | operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1177 | { |
1178 | static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes" ); |
1179 | return __tuple_equal<sizeof...(_Tp)>()(__x, __y); |
1180 | } |
1181 | |
1182 | template <class ..._Tp, class ..._Up> |
1183 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1184 | bool |
1185 | operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1186 | { |
1187 | return !(__x == __y); |
1188 | } |
1189 | |
1190 | template <size_t _Ip> |
1191 | struct __tuple_less |
1192 | { |
1193 | template <class _Tp, class _Up> |
1194 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1195 | bool operator()(const _Tp& __x, const _Up& __y) |
1196 | { |
1197 | const size_t __idx = tuple_size<_Tp>::value - _Ip; |
1198 | if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y)) |
1199 | return true; |
1200 | if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x)) |
1201 | return false; |
1202 | return __tuple_less<_Ip-1>()(__x, __y); |
1203 | } |
1204 | }; |
1205 | |
1206 | template <> |
1207 | struct __tuple_less<0> |
1208 | { |
1209 | template <class _Tp, class _Up> |
1210 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1211 | bool operator()(const _Tp&, const _Up&) |
1212 | { |
1213 | return false; |
1214 | } |
1215 | }; |
1216 | |
1217 | template <class ..._Tp, class ..._Up> |
1218 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1219 | bool |
1220 | operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1221 | { |
1222 | static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes" ); |
1223 | return __tuple_less<sizeof...(_Tp)>()(__x, __y); |
1224 | } |
1225 | |
1226 | template <class ..._Tp, class ..._Up> |
1227 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1228 | bool |
1229 | operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1230 | { |
1231 | return __y < __x; |
1232 | } |
1233 | |
1234 | template <class ..._Tp, class ..._Up> |
1235 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1236 | bool |
1237 | operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1238 | { |
1239 | return !(__x < __y); |
1240 | } |
1241 | |
1242 | template <class ..._Tp, class ..._Up> |
1243 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1244 | bool |
1245 | operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1246 | { |
1247 | return !(__y < __x); |
1248 | } |
1249 | |
1250 | // tuple_cat |
1251 | |
1252 | template <class _Tp, class _Up> struct __tuple_cat_type; |
1253 | |
1254 | template <class ..._Ttypes, class ..._Utypes> |
1255 | struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> > |
1256 | { |
1257 | typedef _LIBCPP_NODEBUG_TYPE tuple<_Ttypes..., _Utypes...> type; |
1258 | }; |
1259 | |
1260 | template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples> |
1261 | struct __tuple_cat_return_1 |
1262 | { |
1263 | }; |
1264 | |
1265 | template <class ..._Types, class _Tuple0> |
1266 | struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0> |
1267 | { |
1268 | typedef _LIBCPP_NODEBUG_TYPE typename __tuple_cat_type<tuple<_Types...>, |
1269 | typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type>::type |
1270 | type; |
1271 | }; |
1272 | |
1273 | template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples> |
1274 | struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...> |
1275 | : public __tuple_cat_return_1< |
1276 | typename __tuple_cat_type< |
1277 | tuple<_Types...>, |
1278 | typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type |
1279 | >::type, |
1280 | __tuple_like<typename remove_reference<_Tuple1>::type>::value, |
1281 | _Tuple1, _Tuples...> |
1282 | { |
1283 | }; |
1284 | |
1285 | template <class ..._Tuples> struct __tuple_cat_return; |
1286 | |
1287 | template <class _Tuple0, class ..._Tuples> |
1288 | struct __tuple_cat_return<_Tuple0, _Tuples...> |
1289 | : public __tuple_cat_return_1<tuple<>, |
1290 | __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0, |
1291 | _Tuples...> |
1292 | { |
1293 | }; |
1294 | |
1295 | template <> |
1296 | struct __tuple_cat_return<> |
1297 | { |
1298 | typedef _LIBCPP_NODEBUG_TYPE tuple<> type; |
1299 | }; |
1300 | |
1301 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1302 | tuple<> |
1303 | tuple_cat() |
1304 | { |
1305 | return tuple<>(); |
1306 | } |
1307 | |
1308 | template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples> |
1309 | struct __tuple_cat_return_ref_imp; |
1310 | |
1311 | template <class ..._Types, size_t ..._I0, class _Tuple0> |
1312 | struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0> |
1313 | { |
1314 | typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0; |
1315 | typedef tuple<_Types..., typename __apply_cv<_Tuple0, |
1316 | typename tuple_element<_I0, _T0>::type>::type&&...> type; |
1317 | }; |
1318 | |
1319 | template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples> |
1320 | struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, |
1321 | _Tuple0, _Tuple1, _Tuples...> |
1322 | : public __tuple_cat_return_ref_imp< |
1323 | tuple<_Types..., typename __apply_cv<_Tuple0, |
1324 | typename tuple_element<_I0, |
1325 | typename remove_reference<_Tuple0>::type>::type>::type&&...>, |
1326 | typename __make_tuple_indices<tuple_size<typename |
1327 | remove_reference<_Tuple1>::type>::value>::type, |
1328 | _Tuple1, _Tuples...> |
1329 | { |
1330 | }; |
1331 | |
1332 | template <class _Tuple0, class ..._Tuples> |
1333 | struct __tuple_cat_return_ref |
1334 | : public __tuple_cat_return_ref_imp<tuple<>, |
1335 | typename __make_tuple_indices< |
1336 | tuple_size<typename remove_reference<_Tuple0>::type>::value |
1337 | >::type, _Tuple0, _Tuples...> |
1338 | { |
1339 | }; |
1340 | |
1341 | template <class _Types, class _I0, class _J0> |
1342 | struct __tuple_cat; |
1343 | |
1344 | template <class ..._Types, size_t ..._I0, size_t ..._J0> |
1345 | struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> > |
1346 | { |
1347 | template <class _Tuple0> |
1348 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1349 | typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type |
1350 | operator()(tuple<_Types...> __t, _Tuple0&& __t0) |
1351 | { |
1352 | return _VSTD::forward_as_tuple( |
1353 | _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))..., |
1354 | _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...); |
1355 | } |
1356 | |
1357 | template <class _Tuple0, class _Tuple1, class ..._Tuples> |
1358 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1359 | typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type |
1360 | operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls) |
1361 | { |
1362 | typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0; |
1363 | typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple1>::type _T1; |
1364 | return __tuple_cat< |
1365 | tuple<_Types..., |
1366 | typename __apply_cv<_Tuple0, typename tuple_element< |
1367 | _J0, _T0>::type>::type&&...>, |
1368 | typename __make_tuple_indices<sizeof...(_Types) + |
1369 | tuple_size<_T0>::value>::type, |
1370 | typename __make_tuple_indices<tuple_size<_T1>::value>::type>()( |
1371 | _VSTD::forward_as_tuple( |
1372 | _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))..., |
1373 | _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...), |
1374 | _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...); |
1375 | } |
1376 | }; |
1377 | |
1378 | template <class _Tuple0, class... _Tuples> |
1379 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1380 | typename __tuple_cat_return<_Tuple0, _Tuples...>::type |
1381 | tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls) |
1382 | { |
1383 | typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0; |
1384 | return __tuple_cat<tuple<>, __tuple_indices<>, |
1385 | typename __make_tuple_indices<tuple_size<_T0>::value>::type>() |
1386 | (tuple<>(), _VSTD::forward<_Tuple0>(__t0), |
1387 | _VSTD::forward<_Tuples>(__tpls)...); |
1388 | } |
1389 | |
1390 | template <class ..._Tp, class _Alloc> |
1391 | struct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc> |
1392 | : true_type {}; |
1393 | |
1394 | template <class _T1, class _T2> |
1395 | template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2> |
1396 | inline _LIBCPP_INLINE_VISIBILITY |
1397 | pair<_T1, _T2>::pair(piecewise_construct_t, |
1398 | tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, |
1399 | __tuple_indices<_I1...>, __tuple_indices<_I2...>) |
1400 | : first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...), |
1401 | second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...) |
1402 | { |
1403 | } |
1404 | |
1405 | #if _LIBCPP_STD_VER > 14 |
1406 | template <class _Tp> |
1407 | _LIBCPP_INLINE_VAR constexpr size_t tuple_size_v = tuple_size<_Tp>::value; |
1408 | |
1409 | #define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; } |
1410 | |
1411 | template <class _Fn, class _Tuple, size_t ..._Id> |
1412 | inline _LIBCPP_INLINE_VISIBILITY |
1413 | constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, |
1414 | __tuple_indices<_Id...>) |
1415 | _LIBCPP_NOEXCEPT_RETURN( |
1416 | _VSTD::__invoke_constexpr( |
1417 | _VSTD::forward<_Fn>(__f), |
1418 | _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...) |
1419 | ) |
1420 | |
1421 | template <class _Fn, class _Tuple> |
1422 | inline _LIBCPP_INLINE_VISIBILITY |
1423 | constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t) |
1424 | _LIBCPP_NOEXCEPT_RETURN( |
1425 | _VSTD::__apply_tuple_impl( |
1426 | _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t), |
1427 | typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{}) |
1428 | ) |
1429 | |
1430 | template <class _Tp, class _Tuple, size_t... _Idx> |
1431 | inline _LIBCPP_INLINE_VISIBILITY |
1432 | constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>) |
1433 | _LIBCPP_NOEXCEPT_RETURN( |
1434 | _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...) |
1435 | ) |
1436 | |
1437 | template <class _Tp, class _Tuple> |
1438 | inline _LIBCPP_INLINE_VISIBILITY |
1439 | constexpr _Tp make_from_tuple(_Tuple&& __t) |
1440 | _LIBCPP_NOEXCEPT_RETURN( |
1441 | _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t), |
1442 | typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{}) |
1443 | ) |
1444 | |
1445 | #undef _LIBCPP_NOEXCEPT_RETURN |
1446 | |
1447 | #endif // _LIBCPP_STD_VER > 14 |
1448 | |
1449 | #endif // !defined(_LIBCPP_CXX03_LANG) |
1450 | |
1451 | _LIBCPP_END_NAMESPACE_STD |
1452 | |
1453 | #endif // _LIBCPP_TUPLE |
1454 | |