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