1 | // -*- C++ -*- |
2 | //===----------------------------------------------------------------------===// |
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 | |
29 | template<class... UTypes> |
30 | constexpr explicit(see-below) tuple(tuple<UTypes...>&); // C++23 |
31 | template <class... U> |
32 | explicit(see-below) tuple(const tuple<U...>&); // constexpr in C++14 |
33 | template <class... U> |
34 | explicit(see-below) tuple(tuple<U...>&&); // constexpr in C++14 |
35 | template<class... UTypes> |
36 | constexpr explicit(see-below) tuple(const tuple<UTypes...>&&); // C++23 |
37 | |
38 | template<class U1, class U2> |
39 | constexpr explicit(see-below) tuple(pair<U1, U2>&); // iff sizeof...(Types) == 2 // C++23 |
40 | template <class U1, class U2> |
41 | explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14 |
42 | template <class U1, class U2> |
43 | explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++14 |
44 | template<class U1, class U2> |
45 | constexpr explicit(see-below) tuple(const pair<U1, U2>&&); // iff sizeof...(Types) == 2 // C++23 |
46 | |
47 | // allocator-extended constructors |
48 | template <class Alloc> |
49 | tuple(allocator_arg_t, const Alloc& a); |
50 | template <class Alloc> |
51 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...); // constexpr in C++20 |
52 | template <class Alloc, class... U> |
53 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...); // constexpr in C++20 |
54 | template <class Alloc> |
55 | tuple(allocator_arg_t, const Alloc& a, const tuple&); // constexpr in C++20 |
56 | template <class Alloc> |
57 | tuple(allocator_arg_t, const Alloc& a, tuple&&); // constexpr in C++20 |
58 | template<class Alloc, class... UTypes> |
59 | constexpr explicit(see-below) |
60 | tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&); // C++23 |
61 | template <class Alloc, class... U> |
62 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&); // constexpr in C++20 |
63 | template <class Alloc, class... U> |
64 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&); // constexpr in C++20 |
65 | template<class Alloc, class... UTypes> |
66 | constexpr explicit(see-below) |
67 | tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&&); // C++23 |
68 | template<class Alloc, class U1, class U2> |
69 | constexpr explicit(see-below) |
70 | tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&); // C++23 |
71 | template <class Alloc, class U1, class U2> |
72 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); // constexpr in C++20 |
73 | template <class Alloc, class U1, class U2> |
74 | explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); // constexpr in C++20 |
75 | template<class Alloc, class U1, class U2> |
76 | constexpr explicit(see-below) |
77 | tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&&); // C++23 |
78 | |
79 | tuple& operator=(const tuple&); // constexpr in C++20 |
80 | constexpr const tuple& operator=(const tuple&) const; // C++23 |
81 | tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...); // constexpr in C++20 |
82 | constexpr const tuple& operator=(tuple&&) const; // C++23 |
83 | template <class... U> |
84 | tuple& operator=(const tuple<U...>&); // constexpr in C++20 |
85 | template<class... UTypes> |
86 | constexpr const tuple& operator=(const tuple<UTypes...>&) const; // C++23 |
87 | template <class... U> |
88 | tuple& operator=(tuple<U...>&&); // constexpr in C++20 |
89 | template<class... UTypes> |
90 | constexpr const tuple& operator=(tuple<UTypes...>&&) const; // C++23 |
91 | template <class U1, class U2> |
92 | tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++20 |
93 | template<class U1, class U2> |
94 | constexpr const tuple& operator=(const pair<U1, U2>&) const; // iff sizeof...(Types) == 2 // C++23 |
95 | template <class U1, class U2> |
96 | tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++20 |
97 | template<class U1, class U2> |
98 | constexpr const tuple& operator=(pair<U1, U2>&&) const; // iff sizeof...(Types) == 2 // C++23 |
99 | |
100 | template<class U, size_t N> |
101 | tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION |
102 | template<class U, size_t N> |
103 | tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION |
104 | |
105 | void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); // constexpr in C++20 |
106 | constexpr void swap(const tuple&) const noexcept(see-below); // C++23 |
107 | }; |
108 | |
109 | |
110 | template<class... TTypes, class... UTypes, template<class> class TQual, template<class> class UQual> // since C++23 |
111 | requires requires { typename tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>; } |
112 | struct basic_common_reference<tuple<TTypes...>, tuple<UTypes...>, TQual, UQual> { |
113 | using type = tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>; |
114 | }; |
115 | |
116 | template<class... TTypes, class... UTypes> // since C++23 |
117 | requires requires { typename tuple<common_type_t<TTypes, UTypes>...>; } |
118 | struct common_type<tuple<TTypes...>, tuple<UTypes...>> { |
119 | using type = tuple<common_type_t<TTypes, UTypes>...>; |
120 | }; |
121 | |
122 | template <class ...T> |
123 | tuple(T...) -> tuple<T...>; // since C++17 |
124 | template <class T1, class T2> |
125 | tuple(pair<T1, T2>) -> tuple<T1, T2>; // since C++17 |
126 | template <class Alloc, class ...T> |
127 | tuple(allocator_arg_t, Alloc, T...) -> tuple<T...>; // since C++17 |
128 | template <class Alloc, class T1, class T2> |
129 | tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>; // since C++17 |
130 | template <class Alloc, class ...T> |
131 | tuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>; // since C++17 |
132 | |
133 | inline constexpr unspecified ignore; |
134 | |
135 | template <class... T> tuple<V...> make_tuple(T&&...); // constexpr in C++14 |
136 | template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14 |
137 | template <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14 |
138 | template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14 |
139 | |
140 | // [tuple.apply], calling a function with a tuple of arguments: |
141 | template <class F, class Tuple> |
142 | constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17 |
143 | template <class T, class Tuple> |
144 | constexpr T make_from_tuple(Tuple&& t); // C++17 |
145 | |
146 | // 20.4.1.4, tuple helper classes: |
147 | template <class T> struct tuple_size; // undefined |
148 | template <class... T> struct tuple_size<tuple<T...>>; |
149 | template <class T> |
150 | inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17 |
151 | template <size_t I, class T> struct tuple_element; // undefined |
152 | template <size_t I, class... T> struct tuple_element<I, tuple<T...>>; |
153 | template <size_t I, class T> |
154 | using tuple_element_t = typename tuple_element <I, T>::type; // C++14 |
155 | |
156 | // 20.4.1.5, element access: |
157 | template <size_t I, class... T> |
158 | typename tuple_element<I, tuple<T...>>::type& |
159 | get(tuple<T...>&) noexcept; // constexpr in C++14 |
160 | template <size_t I, class... T> |
161 | const typename tuple_element<I, tuple<T...>>::type& |
162 | get(const tuple<T...>&) noexcept; // constexpr in C++14 |
163 | template <size_t I, class... T> |
164 | typename tuple_element<I, tuple<T...>>::type&& |
165 | get(tuple<T...>&&) noexcept; // constexpr in C++14 |
166 | template <size_t I, class... T> |
167 | const typename tuple_element<I, tuple<T...>>::type&& |
168 | get(const tuple<T...>&&) noexcept; // constexpr in C++14 |
169 | |
170 | template <class T1, class... T> |
171 | constexpr T1& get(tuple<T...>&) noexcept; // C++14 |
172 | template <class T1, class... T> |
173 | constexpr const T1& get(const tuple<T...>&) noexcept; // C++14 |
174 | template <class T1, class... T> |
175 | constexpr T1&& get(tuple<T...>&&) noexcept; // C++14 |
176 | template <class T1, class... T> |
177 | constexpr const T1&& get(const tuple<T...>&&) noexcept; // C++14 |
178 | |
179 | // 20.4.1.6, relational operators: |
180 | template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14 |
181 | template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20 |
182 | template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20 |
183 | template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20 |
184 | template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20 |
185 | template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20 |
186 | template<class... T, class... U> |
187 | constexpr common_comparison_category_t<synth-three-way-result<T, U>...> |
188 | operator<=>(const tuple<T...>&, const tuple<U...>&); // since C++20 |
189 | |
190 | template <class... Types, class Alloc> |
191 | struct uses_allocator<tuple<Types...>, Alloc>; |
192 | |
193 | template <class... Types> |
194 | void |
195 | swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y))); |
196 | |
197 | template <class... Types> |
198 | constexpr void swap(const tuple<Types...>& x, const tuple<Types...>& y) noexcept(see-below); // C++23 |
199 | |
200 | } // std |
201 | |
202 | */ |
203 | |
204 | #include <__assert> // all public C++ headers provide the assertion handler |
205 | #include <__compare/common_comparison_category.h> |
206 | #include <__compare/synth_three_way.h> |
207 | #include <__config> |
208 | #include <__functional/unwrap_ref.h> |
209 | #include <__memory/allocator_arg_t.h> |
210 | #include <__memory/uses_allocator.h> |
211 | #include <__tuple> |
212 | #include <__utility/forward.h> |
213 | #include <__utility/integer_sequence.h> |
214 | #include <__utility/move.h> |
215 | #include <__utility/pair.h> |
216 | #include <__utility/piecewise_construct.h> |
217 | #include <__utility/swap.h> |
218 | #include <cstddef> |
219 | #include <type_traits> |
220 | #include <version> |
221 | |
222 | #ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES |
223 | # include <exception> |
224 | # include <iosfwd> |
225 | # include <new> |
226 | # include <typeinfo> |
227 | # include <utility> |
228 | #endif |
229 | |
230 | // standard-mandated includes |
231 | #include <compare> |
232 | |
233 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
234 | # pragma GCC system_header |
235 | #endif |
236 | |
237 | _LIBCPP_BEGIN_NAMESPACE_STD |
238 | |
239 | #ifndef _LIBCPP_CXX03_LANG |
240 | |
241 | |
242 | // __tuple_leaf |
243 | |
244 | template <size_t _Ip, class _Hp, |
245 | bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value |
246 | > |
247 | class __tuple_leaf; |
248 | |
249 | template <size_t _Ip, class _Hp, bool _Ep> |
250 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
251 | void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y) |
252 | _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value) |
253 | { |
254 | swap(__x.get(), __y.get()); |
255 | } |
256 | |
257 | template <size_t _Ip, class _Hp, bool _Ep> |
258 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 |
259 | void swap(const __tuple_leaf<_Ip, _Hp, _Ep>& __x, const __tuple_leaf<_Ip, _Hp, _Ep>& __y) |
260 | _NOEXCEPT_(__is_nothrow_swappable<const _Hp>::value) { |
261 | swap(__x.get(), __y.get()); |
262 | } |
263 | |
264 | template <size_t _Ip, class _Hp, bool> |
265 | class __tuple_leaf |
266 | { |
267 | _Hp __value_; |
268 | |
269 | template <class _Tp> |
270 | static constexpr bool __can_bind_reference() { |
271 | #if __has_keyword(__reference_binds_to_temporary) |
272 | return !__reference_binds_to_temporary(_Hp, _Tp); |
273 | #else |
274 | return true; |
275 | #endif |
276 | } |
277 | |
278 | _LIBCPP_CONSTEXPR_AFTER_CXX11 |
279 | __tuple_leaf& operator=(const __tuple_leaf&); |
280 | public: |
281 | _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf() |
282 | _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_() |
283 | {static_assert(!is_reference<_Hp>::value, |
284 | "Attempted to default construct a reference element in a tuple" );} |
285 | |
286 | template <class _Alloc> |
287 | _LIBCPP_INLINE_VISIBILITY constexpr |
288 | __tuple_leaf(integral_constant<int, 0>, const _Alloc&) |
289 | : __value_() |
290 | {static_assert(!is_reference<_Hp>::value, |
291 | "Attempted to default construct a reference element in a tuple" );} |
292 | |
293 | template <class _Alloc> |
294 | _LIBCPP_INLINE_VISIBILITY constexpr |
295 | __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) |
296 | : __value_(allocator_arg_t(), __a) |
297 | {static_assert(!is_reference<_Hp>::value, |
298 | "Attempted to default construct a reference element in a tuple" );} |
299 | |
300 | template <class _Alloc> |
301 | _LIBCPP_INLINE_VISIBILITY constexpr |
302 | __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) |
303 | : __value_(__a) |
304 | {static_assert(!is_reference<_Hp>::value, |
305 | "Attempted to default construct a reference element in a tuple" );} |
306 | |
307 | template <class _Tp, |
308 | class = __enable_if_t< |
309 | _And< |
310 | _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>, |
311 | is_constructible<_Hp, _Tp> |
312 | >::value |
313 | > |
314 | > |
315 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
316 | explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value)) |
317 | : __value_(_VSTD::forward<_Tp>(__t)) |
318 | {static_assert(__can_bind_reference<_Tp&&>(), |
319 | "Attempted construction of reference element binds to a temporary whose lifetime has ended" );} |
320 | |
321 | template <class _Tp, class _Alloc> |
322 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
323 | explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) |
324 | : __value_(_VSTD::forward<_Tp>(__t)) |
325 | {static_assert(__can_bind_reference<_Tp&&>(), |
326 | "Attempted construction of reference element binds to a temporary whose lifetime has ended" );} |
327 | |
328 | template <class _Tp, class _Alloc> |
329 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
330 | explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) |
331 | : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) |
332 | {static_assert(!is_reference<_Hp>::value, |
333 | "Attempted to uses-allocator construct a reference element in a tuple" );} |
334 | |
335 | template <class _Tp, class _Alloc> |
336 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
337 | explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) |
338 | : __value_(_VSTD::forward<_Tp>(__t), __a) |
339 | {static_assert(!is_reference<_Hp>::value, |
340 | "Attempted to uses-allocator construct a reference element in a tuple" );} |
341 | |
342 | __tuple_leaf(const __tuple_leaf& __t) = default; |
343 | __tuple_leaf(__tuple_leaf&& __t) = default; |
344 | |
345 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
346 | int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) |
347 | { |
348 | _VSTD::swap(*this, __t); |
349 | return 0; |
350 | } |
351 | |
352 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
353 | int swap(const __tuple_leaf& __t) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) { |
354 | _VSTD::swap(*this, __t); |
355 | return 0; |
356 | } |
357 | |
358 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return __value_;} |
359 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;} |
360 | }; |
361 | |
362 | template <size_t _Ip, class _Hp> |
363 | class __tuple_leaf<_Ip, _Hp, true> |
364 | : private _Hp |
365 | { |
366 | _LIBCPP_CONSTEXPR_AFTER_CXX11 |
367 | __tuple_leaf& operator=(const __tuple_leaf&); |
368 | public: |
369 | _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf() |
370 | _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {} |
371 | |
372 | template <class _Alloc> |
373 | _LIBCPP_INLINE_VISIBILITY constexpr |
374 | __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {} |
375 | |
376 | template <class _Alloc> |
377 | _LIBCPP_INLINE_VISIBILITY constexpr |
378 | __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) |
379 | : _Hp(allocator_arg_t(), __a) {} |
380 | |
381 | template <class _Alloc> |
382 | _LIBCPP_INLINE_VISIBILITY constexpr |
383 | __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) |
384 | : _Hp(__a) {} |
385 | |
386 | template <class _Tp, |
387 | class = __enable_if_t< |
388 | _And< |
389 | _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>, |
390 | is_constructible<_Hp, _Tp> |
391 | >::value |
392 | > |
393 | > |
394 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
395 | explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value)) |
396 | : _Hp(_VSTD::forward<_Tp>(__t)) {} |
397 | |
398 | template <class _Tp, class _Alloc> |
399 | _LIBCPP_INLINE_VISIBILITY constexpr |
400 | explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) |
401 | : _Hp(_VSTD::forward<_Tp>(__t)) {} |
402 | |
403 | template <class _Tp, class _Alloc> |
404 | _LIBCPP_INLINE_VISIBILITY constexpr |
405 | explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) |
406 | : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {} |
407 | |
408 | template <class _Tp, class _Alloc> |
409 | _LIBCPP_INLINE_VISIBILITY constexpr |
410 | explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) |
411 | : _Hp(_VSTD::forward<_Tp>(__t), __a) {} |
412 | |
413 | __tuple_leaf(__tuple_leaf const &) = default; |
414 | __tuple_leaf(__tuple_leaf &&) = default; |
415 | |
416 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
417 | int |
418 | swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) |
419 | { |
420 | _VSTD::swap(*this, __t); |
421 | return 0; |
422 | } |
423 | |
424 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
425 | int swap(const __tuple_leaf& __rhs) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) { |
426 | _VSTD::swap(*this, __rhs); |
427 | return 0; |
428 | } |
429 | |
430 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Hp& get() _NOEXCEPT {return static_cast<_Hp&>(*this);} |
431 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);} |
432 | }; |
433 | |
434 | template <class ..._Tp> |
435 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
436 | void __swallow(_Tp&&...) _NOEXCEPT {} |
437 | |
438 | template <class _Tp> |
439 | struct __all_default_constructible; |
440 | |
441 | template <class ..._Tp> |
442 | struct __all_default_constructible<__tuple_types<_Tp...>> |
443 | : __all<is_default_constructible<_Tp>::value...> |
444 | { }; |
445 | |
446 | // __tuple_impl |
447 | |
448 | template<class _Indx, class ..._Tp> struct __tuple_impl; |
449 | |
450 | template<size_t ..._Indx, class ..._Tp> |
451 | struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...> |
452 | : public __tuple_leaf<_Indx, _Tp>... |
453 | { |
454 | _LIBCPP_INLINE_VISIBILITY |
455 | constexpr __tuple_impl() |
456 | _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} |
457 | |
458 | template <size_t ..._Uf, class ..._Tf, |
459 | size_t ..._Ul, class ..._Tl, class ..._Up> |
460 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
461 | explicit |
462 | __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>, |
463 | __tuple_indices<_Ul...>, __tuple_types<_Tl...>, |
464 | _Up&&... __u) |
465 | _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value && |
466 | __all<is_nothrow_default_constructible<_Tl>::value...>::value)) : |
467 | __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))..., |
468 | __tuple_leaf<_Ul, _Tl>()... |
469 | {} |
470 | |
471 | template <class _Alloc, size_t ..._Uf, class ..._Tf, |
472 | size_t ..._Ul, class ..._Tl, class ..._Up> |
473 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
474 | explicit |
475 | __tuple_impl(allocator_arg_t, const _Alloc& __a, |
476 | __tuple_indices<_Uf...>, __tuple_types<_Tf...>, |
477 | __tuple_indices<_Ul...>, __tuple_types<_Tl...>, |
478 | _Up&&... __u) : |
479 | __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a, |
480 | _VSTD::forward<_Up>(__u))..., |
481 | __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)... |
482 | {} |
483 | |
484 | template <class _Tuple, |
485 | class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value> |
486 | > |
487 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
488 | __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx, |
489 | typename __make_tuple_types<_Tuple>::type>::type>::value...>::value)) |
490 | : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx, |
491 | typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))... |
492 | {} |
493 | |
494 | template <class _Alloc, class _Tuple, |
495 | class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value> |
496 | > |
497 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
498 | __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) |
499 | : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx, |
500 | typename __make_tuple_types<_Tuple>::type>::type>(), __a, |
501 | _VSTD::forward<typename tuple_element<_Indx, |
502 | typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))... |
503 | {} |
504 | |
505 | __tuple_impl(const __tuple_impl&) = default; |
506 | __tuple_impl(__tuple_impl&&) = default; |
507 | |
508 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
509 | void swap(__tuple_impl& __t) |
510 | _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) |
511 | { |
512 | _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...); |
513 | } |
514 | |
515 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
516 | void swap(const __tuple_impl& __t) const |
517 | _NOEXCEPT_(__all<__is_nothrow_swappable<const _Tp>::value...>::value) |
518 | { |
519 | _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t))...); |
520 | } |
521 | }; |
522 | |
523 | template<class _Dest, class _Source, size_t ..._Np> |
524 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
525 | void __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) { |
526 | _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...); |
527 | } |
528 | |
529 | template<class _Dest, class _Source, class ..._Up, size_t ..._Np> |
530 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
531 | void __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) { |
532 | _VSTD::__swallow((( |
533 | _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source)) |
534 | ), void(), 0)...); |
535 | } |
536 | |
537 | template <class ..._Tp> |
538 | class _LIBCPP_TEMPLATE_VIS tuple |
539 | { |
540 | typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT; |
541 | |
542 | _BaseT __base_; |
543 | |
544 | template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 |
545 | typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT; |
546 | template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 |
547 | const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT; |
548 | template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 |
549 | typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT; |
550 | template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 |
551 | const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT; |
552 | public: |
553 | // [tuple.cnstr] |
554 | |
555 | // tuple() constructors (including allocator_arg_t variants) |
556 | template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t< |
557 | _And< |
558 | _IsImpDefault<_Tp>... // explicit check |
559 | >::value |
560 | , int> = 0> |
561 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
562 | tuple() |
563 | _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value) |
564 | { } |
565 | |
566 | template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, |
567 | template<class...> class _IsDefault = is_default_constructible, __enable_if_t< |
568 | _And< |
569 | _IsDefault<_Tp>..., |
570 | _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check |
571 | >::value |
572 | , int> = 0> |
573 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
574 | explicit tuple() |
575 | _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value) |
576 | { } |
577 | |
578 | template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, __enable_if_t< |
579 | _And< |
580 | _IsImpDefault<_Tp>... // explicit check |
581 | >::value |
582 | , int> = 0> |
583 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
584 | tuple(allocator_arg_t, _Alloc const& __a) |
585 | : __base_(allocator_arg_t(), __a, |
586 | __tuple_indices<>(), __tuple_types<>(), |
587 | typename __make_tuple_indices<sizeof...(_Tp), 0>::type(), |
588 | __tuple_types<_Tp...>()) {} |
589 | |
590 | template <class _Alloc, |
591 | template<class...> class _IsImpDefault = __is_implicitly_default_constructible, |
592 | template<class...> class _IsDefault = is_default_constructible, __enable_if_t< |
593 | _And< |
594 | _IsDefault<_Tp>..., |
595 | _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check |
596 | >::value |
597 | , int> = 0> |
598 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
599 | explicit tuple(allocator_arg_t, _Alloc const& __a) |
600 | : __base_(allocator_arg_t(), __a, |
601 | __tuple_indices<>(), __tuple_types<>(), |
602 | typename __make_tuple_indices<sizeof...(_Tp), 0>::type(), |
603 | __tuple_types<_Tp...>()) {} |
604 | |
605 | // tuple(const T&...) constructors (including allocator_arg_t variants) |
606 | template <template<class...> class _And = _And, __enable_if_t< |
607 | _And< |
608 | _BoolConstant<sizeof...(_Tp) >= 1>, |
609 | is_copy_constructible<_Tp>..., |
610 | is_convertible<const _Tp&, _Tp>... // explicit check |
611 | >::value |
612 | , int> = 0> |
613 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
614 | tuple(const _Tp& ... __t) |
615 | _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value) |
616 | : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), |
617 | typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), |
618 | typename __make_tuple_indices<0>::type(), |
619 | typename __make_tuple_types<tuple, 0>::type(), |
620 | __t... |
621 | ) {} |
622 | |
623 | template <template<class...> class _And = _And, __enable_if_t< |
624 | _And< |
625 | _BoolConstant<sizeof...(_Tp) >= 1>, |
626 | is_copy_constructible<_Tp>..., |
627 | _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check |
628 | >::value |
629 | , int> = 0> |
630 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
631 | explicit tuple(const _Tp& ... __t) |
632 | _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value) |
633 | : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), |
634 | typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), |
635 | typename __make_tuple_indices<0>::type(), |
636 | typename __make_tuple_types<tuple, 0>::type(), |
637 | __t... |
638 | ) {} |
639 | |
640 | template <class _Alloc, template<class...> class _And = _And, __enable_if_t< |
641 | _And< |
642 | _BoolConstant<sizeof...(_Tp) >= 1>, |
643 | is_copy_constructible<_Tp>..., |
644 | is_convertible<const _Tp&, _Tp>... // explicit check |
645 | >::value |
646 | , int> = 0> |
647 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
648 | tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) |
649 | : __base_(allocator_arg_t(), __a, |
650 | typename __make_tuple_indices<sizeof...(_Tp)>::type(), |
651 | typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), |
652 | typename __make_tuple_indices<0>::type(), |
653 | typename __make_tuple_types<tuple, 0>::type(), |
654 | __t... |
655 | ) {} |
656 | |
657 | template <class _Alloc, template<class...> class _And = _And, __enable_if_t< |
658 | _And< |
659 | _BoolConstant<sizeof...(_Tp) >= 1>, |
660 | is_copy_constructible<_Tp>..., |
661 | _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check |
662 | >::value |
663 | , int> = 0> |
664 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
665 | explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) |
666 | : __base_(allocator_arg_t(), __a, |
667 | typename __make_tuple_indices<sizeof...(_Tp)>::type(), |
668 | typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), |
669 | typename __make_tuple_indices<0>::type(), |
670 | typename __make_tuple_types<tuple, 0>::type(), |
671 | __t... |
672 | ) {} |
673 | |
674 | // tuple(U&& ...) constructors (including allocator_arg_t variants) |
675 | template <class ..._Up> struct _IsThisTuple : false_type { }; |
676 | template <class _Up> struct _IsThisTuple<_Up> : is_same<__uncvref_t<_Up>, tuple> { }; |
677 | |
678 | template <class ..._Up> |
679 | struct _EnableUTypesCtor : _And< |
680 | _BoolConstant<sizeof...(_Tp) >= 1>, |
681 | _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors |
682 | is_constructible<_Tp, _Up>... |
683 | > { }; |
684 | |
685 | template <class ..._Up, __enable_if_t< |
686 | _And< |
687 | _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>, |
688 | _EnableUTypesCtor<_Up...>, |
689 | is_convertible<_Up, _Tp>... // explicit check |
690 | >::value |
691 | , int> = 0> |
692 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
693 | tuple(_Up&&... __u) |
694 | _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value)) |
695 | : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(), |
696 | typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), |
697 | typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), |
698 | typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), |
699 | _VSTD::forward<_Up>(__u)...) {} |
700 | |
701 | template <class ..._Up, __enable_if_t< |
702 | _And< |
703 | _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>, |
704 | _EnableUTypesCtor<_Up...>, |
705 | _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check |
706 | >::value |
707 | , int> = 0> |
708 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
709 | explicit tuple(_Up&&... __u) |
710 | _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value)) |
711 | : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(), |
712 | typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), |
713 | typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), |
714 | typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), |
715 | _VSTD::forward<_Up>(__u)...) {} |
716 | |
717 | template <class _Alloc, class ..._Up, __enable_if_t< |
718 | _And< |
719 | _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>, |
720 | _EnableUTypesCtor<_Up...>, |
721 | is_convertible<_Up, _Tp>... // explicit check |
722 | >::value |
723 | , int> = 0> |
724 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
725 | tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) |
726 | : __base_(allocator_arg_t(), __a, |
727 | typename __make_tuple_indices<sizeof...(_Up)>::type(), |
728 | typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), |
729 | typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), |
730 | typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), |
731 | _VSTD::forward<_Up>(__u)...) {} |
732 | |
733 | template <class _Alloc, class ..._Up, __enable_if_t< |
734 | _And< |
735 | _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>, |
736 | _EnableUTypesCtor<_Up...>, |
737 | _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check |
738 | >::value |
739 | , int> = 0> |
740 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
741 | explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) |
742 | : __base_(allocator_arg_t(), __a, |
743 | typename __make_tuple_indices<sizeof...(_Up)>::type(), |
744 | typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), |
745 | typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), |
746 | typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), |
747 | _VSTD::forward<_Up>(__u)...) {} |
748 | |
749 | // Copy and move constructors (including the allocator_arg_t variants) |
750 | tuple(const tuple&) = default; |
751 | tuple(tuple&&) = default; |
752 | |
753 | template <class _Alloc, template<class...> class _And = _And, __enable_if_t< |
754 | _And<is_copy_constructible<_Tp>...>::value |
755 | , int> = 0> |
756 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
757 | tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t) |
758 | : __base_(allocator_arg_t(), __alloc, __t) |
759 | { } |
760 | |
761 | template <class _Alloc, template<class...> class _And = _And, __enable_if_t< |
762 | _And<is_move_constructible<_Tp>...>::value |
763 | , int> = 0> |
764 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
765 | tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t) |
766 | : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t)) |
767 | { } |
768 | |
769 | // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants) |
770 | |
771 | template <class _OtherTuple, class _DecayedOtherTuple = __uncvref_t<_OtherTuple>, class = void> |
772 | struct _EnableCtorFromUTypesTuple : false_type {}; |
773 | |
774 | template <class _OtherTuple, class... _Up> |
775 | struct _EnableCtorFromUTypesTuple<_OtherTuple, tuple<_Up...>, |
776 | // the length of the packs needs to checked first otherwise the 2 packs cannot be expanded simultaneously below |
777 | __enable_if_t<sizeof...(_Up) == sizeof...(_Tp)>> : _And< |
778 | // the two conditions below are not in spec. The purpose is to disable the UTypes Ctor when copy/move Ctor can work. |
779 | // Otherwise, is_constructible can trigger hard error in those cases https://godbolt.org/z/M94cGdKcE |
780 | _Not<is_same<_OtherTuple, const tuple&> >, |
781 | _Not<is_same<_OtherTuple, tuple&&> >, |
782 | is_constructible<_Tp, __copy_cvref_t<_OtherTuple, _Up> >..., |
783 | _Lazy<_Or, _BoolConstant<sizeof...(_Tp) != 1>, |
784 | // _Tp and _Up are 1-element packs - the pack expansions look |
785 | // weird to avoid tripping up the type traits in degenerate cases |
786 | _Lazy<_And, |
787 | _Not<is_same<_Tp, _Up> >..., |
788 | _Not<is_convertible<_OtherTuple, _Tp> >..., |
789 | _Not<is_constructible<_Tp, _OtherTuple> >... |
790 | > |
791 | > |
792 | > {}; |
793 | |
794 | template <class ..._Up, __enable_if_t< |
795 | _And< |
796 | _EnableCtorFromUTypesTuple<const tuple<_Up...>&>, |
797 | is_convertible<const _Up&, _Tp>... // explicit check |
798 | >::value |
799 | , int> = 0> |
800 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
801 | tuple(const tuple<_Up...>& __t) |
802 | _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value)) |
803 | : __base_(__t) |
804 | { } |
805 | |
806 | template <class ..._Up, __enable_if_t< |
807 | _And< |
808 | _EnableCtorFromUTypesTuple<const tuple<_Up...>&>, |
809 | _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check |
810 | >::value |
811 | , int> = 0> |
812 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
813 | explicit tuple(const tuple<_Up...>& __t) |
814 | _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value)) |
815 | : __base_(__t) |
816 | { } |
817 | |
818 | template <class ..._Up, class _Alloc, __enable_if_t< |
819 | _And< |
820 | _EnableCtorFromUTypesTuple<const tuple<_Up...>&>, |
821 | is_convertible<const _Up&, _Tp>... // explicit check |
822 | >::value |
823 | , int> = 0> |
824 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
825 | tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t) |
826 | : __base_(allocator_arg_t(), __a, __t) |
827 | { } |
828 | |
829 | template <class ..._Up, class _Alloc, __enable_if_t< |
830 | _And< |
831 | _EnableCtorFromUTypesTuple<const tuple<_Up...>&>, |
832 | _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check |
833 | >::value |
834 | , int> = 0> |
835 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
836 | explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t) |
837 | : __base_(allocator_arg_t(), __a, __t) |
838 | { } |
839 | |
840 | #if _LIBCPP_STD_VER > 20 |
841 | // tuple(tuple<U...>&) constructors (including allocator_arg_t variants) |
842 | |
843 | template <class... _Up, enable_if_t< |
844 | _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr> |
845 | _LIBCPP_HIDE_FROM_ABI constexpr |
846 | explicit(!(is_convertible_v<_Up&, _Tp> && ...)) |
847 | tuple(tuple<_Up...>& __t) : __base_(__t) {} |
848 | |
849 | template <class _Alloc, class... _Up, enable_if_t< |
850 | _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr> |
851 | _LIBCPP_HIDE_FROM_ABI constexpr |
852 | explicit(!(is_convertible_v<_Up&, _Tp> && ...)) |
853 | tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t) : __base_(allocator_arg_t(), __alloc, __t) {} |
854 | #endif // _LIBCPP_STD_VER > 20 |
855 | |
856 | // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants) |
857 | |
858 | template <class ..._Up, __enable_if_t< |
859 | _And< |
860 | _EnableCtorFromUTypesTuple<tuple<_Up...>&&>, |
861 | is_convertible<_Up, _Tp>... // explicit check |
862 | >::value |
863 | , int> = 0> |
864 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
865 | tuple(tuple<_Up...>&& __t) |
866 | _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value)) |
867 | : __base_(_VSTD::move(__t)) |
868 | { } |
869 | |
870 | template <class ..._Up, __enable_if_t< |
871 | _And< |
872 | _EnableCtorFromUTypesTuple<tuple<_Up...>&&>, |
873 | _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check |
874 | >::value |
875 | , int> = 0> |
876 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
877 | explicit tuple(tuple<_Up...>&& __t) |
878 | _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value)) |
879 | : __base_(_VSTD::move(__t)) |
880 | { } |
881 | |
882 | template <class _Alloc, class ..._Up, __enable_if_t< |
883 | _And< |
884 | _EnableCtorFromUTypesTuple<tuple<_Up...>&&>, |
885 | is_convertible<_Up, _Tp>... // explicit check |
886 | >::value |
887 | , int> = 0> |
888 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
889 | tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t) |
890 | : __base_(allocator_arg_t(), __a, _VSTD::move(__t)) |
891 | { } |
892 | |
893 | template <class _Alloc, class ..._Up, __enable_if_t< |
894 | _And< |
895 | _EnableCtorFromUTypesTuple<tuple<_Up...>&&>, |
896 | _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check |
897 | >::value |
898 | , int> = 0> |
899 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
900 | explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t) |
901 | : __base_(allocator_arg_t(), __a, _VSTD::move(__t)) |
902 | { } |
903 | |
904 | #if _LIBCPP_STD_VER > 20 |
905 | // tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants) |
906 | |
907 | template <class... _Up, enable_if_t< |
908 | _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr> |
909 | _LIBCPP_HIDE_FROM_ABI constexpr |
910 | explicit(!(is_convertible_v<const _Up&&, _Tp> && ...)) |
911 | tuple(const tuple<_Up...>&& __t) : __base_(std::move(__t)) {} |
912 | |
913 | template <class _Alloc, class... _Up, enable_if_t< |
914 | _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr> |
915 | _LIBCPP_HIDE_FROM_ABI constexpr |
916 | explicit(!(is_convertible_v<const _Up&&, _Tp> && ...)) |
917 | tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t) |
918 | : __base_(allocator_arg_t(), __alloc, std::move(__t)) {} |
919 | #endif // _LIBCPP_STD_VER > 20 |
920 | |
921 | // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants) |
922 | |
923 | template <template <class...> class Pred, class _Pair, class _DecayedPair = __uncvref_t<_Pair>, class _Tuple = tuple> |
924 | struct _CtorPredicateFromPair : false_type{}; |
925 | |
926 | template <template <class...> class Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2> |
927 | struct _CtorPredicateFromPair<Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And< |
928 | Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >, |
929 | Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> > |
930 | > {}; |
931 | |
932 | template <class _Pair> |
933 | struct _EnableCtorFromPair : _CtorPredicateFromPair<is_constructible, _Pair>{}; |
934 | |
935 | template <class _Pair> |
936 | struct _NothrowConstructibleFromPair : _CtorPredicateFromPair<is_nothrow_constructible, _Pair>{}; |
937 | |
938 | template <class _Pair, class _DecayedPair = __uncvref_t<_Pair>, class _Tuple = tuple> |
939 | struct _BothImplicitlyConvertible : false_type{}; |
940 | |
941 | template <class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2> |
942 | struct _BothImplicitlyConvertible<_Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And< |
943 | is_convertible<__copy_cvref_t<_Pair, _Up1>, _Tp1>, |
944 | is_convertible<__copy_cvref_t<_Pair, _Up2>, _Tp2> |
945 | > {}; |
946 | |
947 | template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t< |
948 | _And< |
949 | _EnableCtorFromPair<const pair<_Up1, _Up2>&>, |
950 | _BothImplicitlyConvertible<const pair<_Up1, _Up2>&> // explicit check |
951 | >::value |
952 | , int> = 0> |
953 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
954 | tuple(const pair<_Up1, _Up2>& __p) |
955 | _NOEXCEPT_((_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value)) |
956 | : __base_(__p) |
957 | { } |
958 | |
959 | template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t< |
960 | _And< |
961 | _EnableCtorFromPair<const pair<_Up1, _Up2>&>, |
962 | _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> > // explicit check |
963 | >::value |
964 | , int> = 0> |
965 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
966 | explicit tuple(const pair<_Up1, _Up2>& __p) |
967 | _NOEXCEPT_((_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value)) |
968 | : __base_(__p) |
969 | { } |
970 | |
971 | template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t< |
972 | _And< |
973 | _EnableCtorFromPair<const pair<_Up1, _Up2>&>, |
974 | _BothImplicitlyConvertible<const pair<_Up1, _Up2>&> // explicit check |
975 | >::value |
976 | , int> = 0> |
977 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
978 | tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p) |
979 | : __base_(allocator_arg_t(), __a, __p) |
980 | { } |
981 | |
982 | template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t< |
983 | _And< |
984 | _EnableCtorFromPair<const pair<_Up1, _Up2>&>, |
985 | _Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> > // explicit check |
986 | >::value |
987 | , int> = 0> |
988 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
989 | explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p) |
990 | : __base_(allocator_arg_t(), __a, __p) |
991 | { } |
992 | |
993 | #if _LIBCPP_STD_VER > 20 |
994 | // tuple(pair<U1, U2>&) constructors (including allocator_arg_t variants) |
995 | |
996 | template <class _U1, class _U2, enable_if_t< |
997 | _EnableCtorFromPair<pair<_U1, _U2>&>::value>* = nullptr> |
998 | _LIBCPP_HIDE_FROM_ABI constexpr |
999 | explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value) |
1000 | tuple(pair<_U1, _U2>& __p) : __base_(__p) {} |
1001 | |
1002 | template <class _Alloc, class _U1, class _U2, enable_if_t< |
1003 | _EnableCtorFromPair<std::pair<_U1, _U2>&>::value>* = nullptr> |
1004 | _LIBCPP_HIDE_FROM_ABI constexpr |
1005 | explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value) |
1006 | tuple(allocator_arg_t, const _Alloc& __alloc, pair<_U1, _U2>& __p) : __base_(allocator_arg_t(), __alloc, __p) {} |
1007 | #endif |
1008 | |
1009 | // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants) |
1010 | |
1011 | template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t< |
1012 | _And< |
1013 | _EnableCtorFromPair<pair<_Up1, _Up2>&&>, |
1014 | _BothImplicitlyConvertible<pair<_Up1, _Up2>&&> // explicit check |
1015 | >::value |
1016 | , int> = 0> |
1017 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1018 | tuple(pair<_Up1, _Up2>&& __p) |
1019 | _NOEXCEPT_((_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value)) |
1020 | : __base_(_VSTD::move(__p)) |
1021 | { } |
1022 | |
1023 | template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t< |
1024 | _And< |
1025 | _EnableCtorFromPair<pair<_Up1, _Up2>&&>, |
1026 | _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> > // explicit check |
1027 | >::value |
1028 | , int> = 0> |
1029 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1030 | explicit tuple(pair<_Up1, _Up2>&& __p) |
1031 | _NOEXCEPT_((_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value)) |
1032 | : __base_(_VSTD::move(__p)) |
1033 | { } |
1034 | |
1035 | template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t< |
1036 | _And< |
1037 | _EnableCtorFromPair<pair<_Up1, _Up2>&&>, |
1038 | _BothImplicitlyConvertible<pair<_Up1, _Up2>&&> // explicit check |
1039 | >::value |
1040 | , int> = 0> |
1041 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1042 | tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p) |
1043 | : __base_(allocator_arg_t(), __a, _VSTD::move(__p)) |
1044 | { } |
1045 | |
1046 | template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t< |
1047 | _And< |
1048 | _EnableCtorFromPair<pair<_Up1, _Up2>&&>, |
1049 | _Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> > // explicit check |
1050 | >::value |
1051 | , int> = 0> |
1052 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1053 | explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p) |
1054 | : __base_(allocator_arg_t(), __a, _VSTD::move(__p)) |
1055 | { } |
1056 | |
1057 | #if _LIBCPP_STD_VER > 20 |
1058 | // tuple(const pair<U1, U2>&&) constructors (including allocator_arg_t variants) |
1059 | |
1060 | template <class _U1, class _U2, enable_if_t< |
1061 | _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr> |
1062 | _LIBCPP_HIDE_FROM_ABI constexpr |
1063 | explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value) |
1064 | tuple(const pair<_U1, _U2>&& __p) : __base_(std::move(__p)) {} |
1065 | |
1066 | template <class _Alloc, class _U1, class _U2, enable_if_t< |
1067 | _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr> |
1068 | _LIBCPP_HIDE_FROM_ABI constexpr |
1069 | explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value) |
1070 | tuple(allocator_arg_t, const _Alloc& __alloc, const pair<_U1, _U2>&& __p) |
1071 | : __base_(allocator_arg_t(), __alloc, std::move(__p)) {} |
1072 | #endif // _LIBCPP_STD_VER > 20 |
1073 | |
1074 | // [tuple.assign] |
1075 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1076 | tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple) |
1077 | _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value)) |
1078 | { |
1079 | _VSTD::__memberwise_copy_assign(*this, __tuple, |
1080 | typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
1081 | return *this; |
1082 | } |
1083 | |
1084 | #if _LIBCPP_STD_VER > 20 |
1085 | _LIBCPP_HIDE_FROM_ABI constexpr |
1086 | const tuple& operator=(tuple const& __tuple) const |
1087 | requires (_And<is_copy_assignable<const _Tp>...>::value) { |
1088 | std::__memberwise_copy_assign(*this, __tuple, typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
1089 | return *this; |
1090 | } |
1091 | |
1092 | _LIBCPP_HIDE_FROM_ABI constexpr |
1093 | const tuple& operator=(tuple&& __tuple) const |
1094 | requires (_And<is_assignable<const _Tp&, _Tp>...>::value) { |
1095 | std::__memberwise_forward_assign(*this, |
1096 | std::move(__tuple), |
1097 | __tuple_types<_Tp...>(), |
1098 | typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
1099 | return *this; |
1100 | } |
1101 | #endif // _LIBCPP_STD_VER > 20 |
1102 | |
1103 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1104 | tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple) |
1105 | _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value)) |
1106 | { |
1107 | _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple), |
1108 | __tuple_types<_Tp...>(), |
1109 | typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
1110 | return *this; |
1111 | } |
1112 | |
1113 | template<class... _Up, __enable_if_t< |
1114 | _And< |
1115 | _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>, |
1116 | is_assignable<_Tp&, _Up const&>... |
1117 | >::value |
1118 | ,int> = 0> |
1119 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1120 | tuple& operator=(tuple<_Up...> const& __tuple) |
1121 | _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value)) |
1122 | { |
1123 | _VSTD::__memberwise_copy_assign(*this, __tuple, |
1124 | typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
1125 | return *this; |
1126 | } |
1127 | |
1128 | template<class... _Up, __enable_if_t< |
1129 | _And< |
1130 | _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>, |
1131 | is_assignable<_Tp&, _Up>... |
1132 | >::value |
1133 | ,int> = 0> |
1134 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1135 | tuple& operator=(tuple<_Up...>&& __tuple) |
1136 | _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value)) |
1137 | { |
1138 | _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple), |
1139 | __tuple_types<_Up...>(), |
1140 | typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
1141 | return *this; |
1142 | } |
1143 | |
1144 | |
1145 | #if _LIBCPP_STD_VER > 20 |
1146 | template <class... _UTypes, enable_if_t< |
1147 | _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>, |
1148 | is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr> |
1149 | _LIBCPP_HIDE_FROM_ABI constexpr |
1150 | const tuple& operator=(const tuple<_UTypes...>& __u) const { |
1151 | std::__memberwise_copy_assign(*this, |
1152 | __u, |
1153 | typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
1154 | return *this; |
1155 | } |
1156 | |
1157 | template <class... _UTypes, enable_if_t< |
1158 | _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>, |
1159 | is_assignable<const _Tp&, _UTypes>...>::value>* = nullptr> |
1160 | _LIBCPP_HIDE_FROM_ABI constexpr |
1161 | const tuple& operator=(tuple<_UTypes...>&& __u) const { |
1162 | std::__memberwise_forward_assign(*this, |
1163 | __u, |
1164 | __tuple_types<_UTypes...>(), |
1165 | typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
1166 | return *this; |
1167 | } |
1168 | #endif // _LIBCPP_STD_VER > 20 |
1169 | |
1170 | template <template<class...> class Pred, bool _Const, |
1171 | class _Pair, class _DecayedPair = __uncvref_t<_Pair>, class _Tuple = tuple> |
1172 | struct _AssignPredicateFromPair : false_type {}; |
1173 | |
1174 | template <template<class...> class Pred, bool _Const, |
1175 | class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2> |
1176 | struct _AssignPredicateFromPair<Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : |
1177 | _And<Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >, |
1178 | Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> > |
1179 | > {}; |
1180 | |
1181 | template <bool _Const, class _Pair> |
1182 | struct _EnableAssignFromPair : _AssignPredicateFromPair<is_assignable, _Const, _Pair> {}; |
1183 | |
1184 | template <bool _Const, class _Pair> |
1185 | struct _NothrowAssignFromPair : _AssignPredicateFromPair<is_nothrow_assignable, _Const, _Pair> {}; |
1186 | |
1187 | #if _LIBCPP_STD_VER > 20 |
1188 | template <class _U1, class _U2, enable_if_t< |
1189 | _EnableAssignFromPair<true, const pair<_U1, _U2>&>::value>* = nullptr> |
1190 | _LIBCPP_HIDE_FROM_ABI constexpr |
1191 | const tuple& operator=(const pair<_U1, _U2>& __pair) const |
1192 | noexcept(_NothrowAssignFromPair<true, const pair<_U1, _U2>&>::value) { |
1193 | std::get<0>(*this) = __pair.first; |
1194 | std::get<1>(*this) = __pair.second; |
1195 | return *this; |
1196 | } |
1197 | |
1198 | template <class _U1, class _U2, enable_if_t< |
1199 | _EnableAssignFromPair<true, pair<_U1, _U2>&&>::value>* = nullptr> |
1200 | _LIBCPP_HIDE_FROM_ABI constexpr |
1201 | const tuple& operator=(pair<_U1, _U2>&& __pair) const |
1202 | noexcept(_NothrowAssignFromPair<true, pair<_U1, _U2>&&>::value) { |
1203 | std::get<0>(*this) = std::move(__pair.first); |
1204 | std::get<1>(*this) = std::move(__pair.second); |
1205 | return *this; |
1206 | } |
1207 | #endif // _LIBCPP_STD_VER > 20 |
1208 | |
1209 | template<class _Up1, class _Up2, __enable_if_t< |
1210 | _EnableAssignFromPair<false, pair<_Up1, _Up2> const&>::value |
1211 | ,int> = 0> |
1212 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1213 | tuple& operator=(pair<_Up1, _Up2> const& __pair) |
1214 | _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2> const&>::value)) |
1215 | { |
1216 | _VSTD::get<0>(*this) = __pair.first; |
1217 | _VSTD::get<1>(*this) = __pair.second; |
1218 | return *this; |
1219 | } |
1220 | |
1221 | template<class _Up1, class _Up2, __enable_if_t< |
1222 | _EnableAssignFromPair<false, pair<_Up1, _Up2>&&>::value |
1223 | ,int> = 0> |
1224 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1225 | tuple& operator=(pair<_Up1, _Up2>&& __pair) |
1226 | _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2>&&>::value)) |
1227 | { |
1228 | _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first); |
1229 | _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second); |
1230 | return *this; |
1231 | } |
1232 | |
1233 | // EXTENSION |
1234 | template<class _Up, size_t _Np, class = __enable_if_t< |
1235 | _And< |
1236 | _BoolConstant<_Np == sizeof...(_Tp)>, |
1237 | is_assignable<_Tp&, _Up const&>... |
1238 | >::value |
1239 | > > |
1240 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1241 | tuple& operator=(array<_Up, _Np> const& __array) |
1242 | _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value)) |
1243 | { |
1244 | _VSTD::__memberwise_copy_assign(*this, __array, |
1245 | typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
1246 | return *this; |
1247 | } |
1248 | |
1249 | // EXTENSION |
1250 | template<class _Up, size_t _Np, class = void, class = __enable_if_t< |
1251 | _And< |
1252 | _BoolConstant<_Np == sizeof...(_Tp)>, |
1253 | is_assignable<_Tp&, _Up>... |
1254 | >::value |
1255 | > > |
1256 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1257 | tuple& operator=(array<_Up, _Np>&& __array) |
1258 | _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value)) |
1259 | { |
1260 | _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array), |
1261 | __tuple_types<_If<true, _Up, _Tp>...>(), |
1262 | typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
1263 | return *this; |
1264 | } |
1265 | |
1266 | // [tuple.swap] |
1267 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1268 | void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) |
1269 | {__base_.swap(__t.__base_);} |
1270 | |
1271 | #if _LIBCPP_STD_VER > 20 |
1272 | _LIBCPP_HIDE_FROM_ABI constexpr |
1273 | void swap(const tuple& __t) const noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) { |
1274 | __base_.swap(__t.__base_); |
1275 | } |
1276 | #endif // _LIBCPP_STD_VER > 20 |
1277 | }; |
1278 | |
1279 | template <> |
1280 | class _LIBCPP_TEMPLATE_VIS tuple<> |
1281 | { |
1282 | public: |
1283 | _LIBCPP_INLINE_VISIBILITY constexpr |
1284 | tuple() _NOEXCEPT = default; |
1285 | template <class _Alloc> |
1286 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1287 | tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {} |
1288 | template <class _Alloc> |
1289 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1290 | tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {} |
1291 | template <class _Up> |
1292 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1293 | tuple(array<_Up, 0>) _NOEXCEPT {} |
1294 | template <class _Alloc, class _Up> |
1295 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1296 | tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {} |
1297 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1298 | void swap(tuple&) _NOEXCEPT {} |
1299 | #if _LIBCPP_STD_VER > 20 |
1300 | _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {} |
1301 | #endif |
1302 | }; |
1303 | |
1304 | #if _LIBCPP_STD_VER > 20 |
1305 | template <class... _TTypes, class... _UTypes, template<class> class _TQual, template<class> class _UQual> |
1306 | requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; } |
1307 | struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> { |
1308 | using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; |
1309 | }; |
1310 | |
1311 | template <class... _TTypes, class... _UTypes> |
1312 | requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; } |
1313 | struct common_type<tuple<_TTypes...>, tuple<_UTypes...>> { |
1314 | using type = tuple<common_type_t<_TTypes, _UTypes>...>; |
1315 | }; |
1316 | #endif // _LIBCPP_STD_VER > 20 |
1317 | |
1318 | #if _LIBCPP_STD_VER > 14 |
1319 | template <class ..._Tp> |
1320 | tuple(_Tp...) -> tuple<_Tp...>; |
1321 | template <class _Tp1, class _Tp2> |
1322 | tuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>; |
1323 | template <class _Alloc, class ..._Tp> |
1324 | tuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>; |
1325 | template <class _Alloc, class _Tp1, class _Tp2> |
1326 | tuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>; |
1327 | template <class _Alloc, class ..._Tp> |
1328 | tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>; |
1329 | #endif |
1330 | |
1331 | template <class ..._Tp> |
1332 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1333 | __enable_if_t<__all<__is_swappable<_Tp>::value...>::value, void> |
1334 | swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u) |
1335 | _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) |
1336 | {__t.swap(__u);} |
1337 | |
1338 | #if _LIBCPP_STD_VER > 20 |
1339 | template <class... _Tp> |
1340 | _LIBCPP_HIDE_FROM_ABI constexpr |
1341 | enable_if_t<__all<is_swappable_v<const _Tp>...>::value, void> |
1342 | swap(const tuple<_Tp...>& __lhs, const tuple<_Tp...>& __rhs) |
1343 | noexcept(__all<is_nothrow_swappable_v<const _Tp>...>::value) { |
1344 | __lhs.swap(__rhs); |
1345 | } |
1346 | #endif |
1347 | |
1348 | // get |
1349 | |
1350 | template <size_t _Ip, class ..._Tp> |
1351 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1352 | typename tuple_element<_Ip, tuple<_Tp...> >::type& |
1353 | get(tuple<_Tp...>& __t) _NOEXCEPT |
1354 | { |
1355 | typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type; |
1356 | return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get(); |
1357 | } |
1358 | |
1359 | template <size_t _Ip, class ..._Tp> |
1360 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1361 | const typename tuple_element<_Ip, tuple<_Tp...> >::type& |
1362 | get(const tuple<_Tp...>& __t) _NOEXCEPT |
1363 | { |
1364 | typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type; |
1365 | return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get(); |
1366 | } |
1367 | |
1368 | template <size_t _Ip, class ..._Tp> |
1369 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1370 | typename tuple_element<_Ip, tuple<_Tp...> >::type&& |
1371 | get(tuple<_Tp...>&& __t) _NOEXCEPT |
1372 | { |
1373 | typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type; |
1374 | return static_cast<type&&>( |
1375 | static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get()); |
1376 | } |
1377 | |
1378 | template <size_t _Ip, class ..._Tp> |
1379 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1380 | const typename tuple_element<_Ip, tuple<_Tp...> >::type&& |
1381 | get(const tuple<_Tp...>&& __t) _NOEXCEPT |
1382 | { |
1383 | typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type; |
1384 | return static_cast<const type&&>( |
1385 | static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get()); |
1386 | } |
1387 | |
1388 | #if _LIBCPP_STD_VER > 11 |
1389 | |
1390 | namespace __find_detail { |
1391 | |
1392 | static constexpr size_t __not_found = static_cast<size_t>(-1); |
1393 | static constexpr size_t __ambiguous = __not_found - 1; |
1394 | |
1395 | inline _LIBCPP_INLINE_VISIBILITY |
1396 | constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) { |
1397 | return !__matches ? __res : |
1398 | (__res == __not_found ? __curr_i : __ambiguous); |
1399 | } |
1400 | |
1401 | template <size_t _Nx> |
1402 | inline _LIBCPP_INLINE_VISIBILITY |
1403 | constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) { |
1404 | return __i == _Nx ? __not_found : |
1405 | __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]); |
1406 | } |
1407 | |
1408 | template <class _T1, class ..._Args> |
1409 | struct __find_exactly_one_checked { |
1410 | static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...}; |
1411 | static constexpr size_t value = __find_detail::__find_idx(0, __matches); |
1412 | static_assert(value != __not_found, "type not found in type list" ); |
1413 | static_assert(value != __ambiguous, "type occurs more than once in type list" ); |
1414 | }; |
1415 | |
1416 | template <class _T1> |
1417 | struct __find_exactly_one_checked<_T1> { |
1418 | static_assert(!is_same<_T1, _T1>::value, "type not in empty type list" ); |
1419 | }; |
1420 | |
1421 | } // namespace __find_detail |
1422 | |
1423 | template <typename _T1, typename... _Args> |
1424 | struct __find_exactly_one_t |
1425 | : public __find_detail::__find_exactly_one_checked<_T1, _Args...> { |
1426 | }; |
1427 | |
1428 | template <class _T1, class... _Args> |
1429 | inline _LIBCPP_INLINE_VISIBILITY |
1430 | constexpr _T1& get(tuple<_Args...>& __tup) noexcept |
1431 | { |
1432 | return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup); |
1433 | } |
1434 | |
1435 | template <class _T1, class... _Args> |
1436 | inline _LIBCPP_INLINE_VISIBILITY |
1437 | constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept |
1438 | { |
1439 | return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup); |
1440 | } |
1441 | |
1442 | template <class _T1, class... _Args> |
1443 | inline _LIBCPP_INLINE_VISIBILITY |
1444 | constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept |
1445 | { |
1446 | return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup)); |
1447 | } |
1448 | |
1449 | template <class _T1, class... _Args> |
1450 | inline _LIBCPP_INLINE_VISIBILITY |
1451 | constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept |
1452 | { |
1453 | return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup)); |
1454 | } |
1455 | |
1456 | #endif |
1457 | |
1458 | // tie |
1459 | |
1460 | template <class ..._Tp> |
1461 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1462 | tuple<_Tp&...> |
1463 | tie(_Tp&... __t) _NOEXCEPT |
1464 | { |
1465 | return tuple<_Tp&...>(__t...); |
1466 | } |
1467 | |
1468 | template <class _Up> |
1469 | struct __ignore_t |
1470 | { |
1471 | template <class _Tp> |
1472 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1473 | const __ignore_t& operator=(_Tp&&) const {return *this;} |
1474 | }; |
1475 | |
1476 | namespace { |
1477 | constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); |
1478 | } // namespace |
1479 | |
1480 | template <class... _Tp> |
1481 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1482 | tuple<typename __unwrap_ref_decay<_Tp>::type...> |
1483 | make_tuple(_Tp&&... __t) |
1484 | { |
1485 | return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...); |
1486 | } |
1487 | |
1488 | template <class... _Tp> |
1489 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1490 | tuple<_Tp&&...> |
1491 | forward_as_tuple(_Tp&&... __t) _NOEXCEPT |
1492 | { |
1493 | return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...); |
1494 | } |
1495 | |
1496 | template <size_t _Ip> |
1497 | struct __tuple_equal |
1498 | { |
1499 | template <class _Tp, class _Up> |
1500 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1501 | bool operator()(const _Tp& __x, const _Up& __y) |
1502 | { |
1503 | return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y); |
1504 | } |
1505 | }; |
1506 | |
1507 | template <> |
1508 | struct __tuple_equal<0> |
1509 | { |
1510 | template <class _Tp, class _Up> |
1511 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1512 | bool operator()(const _Tp&, const _Up&) |
1513 | { |
1514 | return true; |
1515 | } |
1516 | }; |
1517 | |
1518 | template <class ..._Tp, class ..._Up> |
1519 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1520 | bool |
1521 | operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1522 | { |
1523 | static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes" ); |
1524 | return __tuple_equal<sizeof...(_Tp)>()(__x, __y); |
1525 | } |
1526 | |
1527 | #if _LIBCPP_STD_VER > 17 |
1528 | |
1529 | // operator<=> |
1530 | |
1531 | template <class ..._Tp, class ..._Up, size_t ..._Is> |
1532 | _LIBCPP_HIDE_FROM_ABI constexpr |
1533 | auto |
1534 | __tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) { |
1535 | common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal; |
1536 | static_cast<void>(((__result = _VSTD::__synth_three_way(_VSTD::get<_Is>(__x), _VSTD::get<_Is>(__y)), __result != 0) || ...)); |
1537 | return __result; |
1538 | } |
1539 | |
1540 | template <class ..._Tp, class ..._Up> |
1541 | requires (sizeof...(_Tp) == sizeof...(_Up)) |
1542 | _LIBCPP_HIDE_FROM_ABI constexpr |
1543 | common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> |
1544 | operator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1545 | { |
1546 | return _VSTD::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{}); |
1547 | } |
1548 | |
1549 | #else // _LIBCPP_STD_VER > 17 |
1550 | |
1551 | template <class ..._Tp, class ..._Up> |
1552 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1553 | bool |
1554 | operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1555 | { |
1556 | return !(__x == __y); |
1557 | } |
1558 | |
1559 | template <size_t _Ip> |
1560 | struct __tuple_less |
1561 | { |
1562 | template <class _Tp, class _Up> |
1563 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1564 | bool operator()(const _Tp& __x, const _Up& __y) |
1565 | { |
1566 | const size_t __idx = tuple_size<_Tp>::value - _Ip; |
1567 | if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y)) |
1568 | return true; |
1569 | if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x)) |
1570 | return false; |
1571 | return __tuple_less<_Ip-1>()(__x, __y); |
1572 | } |
1573 | }; |
1574 | |
1575 | template <> |
1576 | struct __tuple_less<0> |
1577 | { |
1578 | template <class _Tp, class _Up> |
1579 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1580 | bool operator()(const _Tp&, const _Up&) |
1581 | { |
1582 | return false; |
1583 | } |
1584 | }; |
1585 | |
1586 | template <class ..._Tp, class ..._Up> |
1587 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1588 | bool |
1589 | operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1590 | { |
1591 | static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes" ); |
1592 | return __tuple_less<sizeof...(_Tp)>()(__x, __y); |
1593 | } |
1594 | |
1595 | template <class ..._Tp, class ..._Up> |
1596 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1597 | bool |
1598 | operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1599 | { |
1600 | return __y < __x; |
1601 | } |
1602 | |
1603 | template <class ..._Tp, class ..._Up> |
1604 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1605 | bool |
1606 | operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1607 | { |
1608 | return !(__x < __y); |
1609 | } |
1610 | |
1611 | template <class ..._Tp, class ..._Up> |
1612 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1613 | bool |
1614 | operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
1615 | { |
1616 | return !(__y < __x); |
1617 | } |
1618 | |
1619 | #endif // _LIBCPP_STD_VER > 17 |
1620 | |
1621 | // tuple_cat |
1622 | |
1623 | template <class _Tp, class _Up> struct __tuple_cat_type; |
1624 | |
1625 | template <class ..._Ttypes, class ..._Utypes> |
1626 | struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> > |
1627 | { |
1628 | typedef _LIBCPP_NODEBUG tuple<_Ttypes..., _Utypes...> type; |
1629 | }; |
1630 | |
1631 | template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples> |
1632 | struct __tuple_cat_return_1 |
1633 | { |
1634 | }; |
1635 | |
1636 | template <class ..._Types, class _Tuple0> |
1637 | struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0> |
1638 | { |
1639 | using type _LIBCPP_NODEBUG = typename __tuple_cat_type< |
1640 | tuple<_Types...>, |
1641 | typename __make_tuple_types<__uncvref_t<_Tuple0> >::type |
1642 | >::type; |
1643 | }; |
1644 | |
1645 | template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples> |
1646 | struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...> |
1647 | : public __tuple_cat_return_1< |
1648 | typename __tuple_cat_type< |
1649 | tuple<_Types...>, |
1650 | typename __make_tuple_types<__uncvref_t<_Tuple0> >::type |
1651 | >::type, |
1652 | __tuple_like<typename remove_reference<_Tuple1>::type>::value, |
1653 | _Tuple1, _Tuples...> |
1654 | { |
1655 | }; |
1656 | |
1657 | template <class ..._Tuples> struct __tuple_cat_return; |
1658 | |
1659 | template <class _Tuple0, class ..._Tuples> |
1660 | struct __tuple_cat_return<_Tuple0, _Tuples...> |
1661 | : public __tuple_cat_return_1<tuple<>, |
1662 | __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0, |
1663 | _Tuples...> |
1664 | { |
1665 | }; |
1666 | |
1667 | template <> |
1668 | struct __tuple_cat_return<> |
1669 | { |
1670 | typedef _LIBCPP_NODEBUG tuple<> type; |
1671 | }; |
1672 | |
1673 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1674 | tuple<> |
1675 | tuple_cat() |
1676 | { |
1677 | return tuple<>(); |
1678 | } |
1679 | |
1680 | template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples> |
1681 | struct __tuple_cat_return_ref_imp; |
1682 | |
1683 | template <class ..._Types, size_t ..._I0, class _Tuple0> |
1684 | struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0> |
1685 | { |
1686 | typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0; |
1687 | typedef tuple<_Types..., typename __apply_cv<_Tuple0, |
1688 | typename tuple_element<_I0, _T0>::type>::type&&...> type; |
1689 | }; |
1690 | |
1691 | template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples> |
1692 | struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, |
1693 | _Tuple0, _Tuple1, _Tuples...> |
1694 | : public __tuple_cat_return_ref_imp< |
1695 | tuple<_Types..., typename __apply_cv<_Tuple0, |
1696 | typename tuple_element<_I0, |
1697 | typename remove_reference<_Tuple0>::type>::type>::type&&...>, |
1698 | typename __make_tuple_indices<tuple_size<typename |
1699 | remove_reference<_Tuple1>::type>::value>::type, |
1700 | _Tuple1, _Tuples...> |
1701 | { |
1702 | }; |
1703 | |
1704 | template <class _Tuple0, class ..._Tuples> |
1705 | struct __tuple_cat_return_ref |
1706 | : public __tuple_cat_return_ref_imp<tuple<>, |
1707 | typename __make_tuple_indices< |
1708 | tuple_size<typename remove_reference<_Tuple0>::type>::value |
1709 | >::type, _Tuple0, _Tuples...> |
1710 | { |
1711 | }; |
1712 | |
1713 | template <class _Types, class _I0, class _J0> |
1714 | struct __tuple_cat; |
1715 | |
1716 | template <class ..._Types, size_t ..._I0, size_t ..._J0> |
1717 | struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> > |
1718 | { |
1719 | template <class _Tuple0> |
1720 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1721 | typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type |
1722 | operator()(tuple<_Types...> __t, _Tuple0&& __t0) |
1723 | { |
1724 | (void)__t; // avoid unused parameter warning on GCC when _I0 is empty |
1725 | return _VSTD::forward_as_tuple( |
1726 | _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))..., |
1727 | _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...); |
1728 | } |
1729 | |
1730 | template <class _Tuple0, class _Tuple1, class ..._Tuples> |
1731 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1732 | typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type |
1733 | operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls) |
1734 | { |
1735 | (void)__t; // avoid unused parameter warning on GCC when _I0 is empty |
1736 | typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0; |
1737 | typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple1>::type _T1; |
1738 | return __tuple_cat< |
1739 | tuple<_Types..., |
1740 | typename __apply_cv<_Tuple0, typename tuple_element< |
1741 | _J0, _T0>::type>::type&&...>, |
1742 | typename __make_tuple_indices<sizeof...(_Types) + |
1743 | tuple_size<_T0>::value>::type, |
1744 | typename __make_tuple_indices<tuple_size<_T1>::value>::type>()( |
1745 | _VSTD::forward_as_tuple( |
1746 | _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))..., |
1747 | _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...), |
1748 | _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...); |
1749 | } |
1750 | }; |
1751 | |
1752 | template <class _Tuple0, class... _Tuples> |
1753 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
1754 | typename __tuple_cat_return<_Tuple0, _Tuples...>::type |
1755 | tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls) |
1756 | { |
1757 | typedef _LIBCPP_NODEBUG typename remove_reference<_Tuple0>::type _T0; |
1758 | return __tuple_cat<tuple<>, __tuple_indices<>, |
1759 | typename __make_tuple_indices<tuple_size<_T0>::value>::type>() |
1760 | (tuple<>(), _VSTD::forward<_Tuple0>(__t0), |
1761 | _VSTD::forward<_Tuples>(__tpls)...); |
1762 | } |
1763 | |
1764 | template <class ..._Tp, class _Alloc> |
1765 | struct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc> |
1766 | : true_type {}; |
1767 | |
1768 | template <class _T1, class _T2> |
1769 | template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2> |
1770 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 |
1771 | pair<_T1, _T2>::pair(piecewise_construct_t, |
1772 | tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, |
1773 | __tuple_indices<_I1...>, __tuple_indices<_I2...>) |
1774 | : first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...), |
1775 | second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...) |
1776 | { |
1777 | } |
1778 | |
1779 | #if _LIBCPP_STD_VER > 14 |
1780 | template <class _Tp> |
1781 | inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; |
1782 | |
1783 | #define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; } |
1784 | |
1785 | template <class _Fn, class _Tuple, size_t ..._Id> |
1786 | inline _LIBCPP_INLINE_VISIBILITY |
1787 | constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, |
1788 | __tuple_indices<_Id...>) |
1789 | _LIBCPP_NOEXCEPT_RETURN( |
1790 | _VSTD::__invoke( |
1791 | _VSTD::forward<_Fn>(__f), |
1792 | _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...) |
1793 | ) |
1794 | |
1795 | template <class _Fn, class _Tuple> |
1796 | inline _LIBCPP_INLINE_VISIBILITY |
1797 | constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t) |
1798 | _LIBCPP_NOEXCEPT_RETURN( |
1799 | _VSTD::__apply_tuple_impl( |
1800 | _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t), |
1801 | typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{}) |
1802 | ) |
1803 | |
1804 | template <class _Tp, class _Tuple, size_t... _Idx> |
1805 | inline _LIBCPP_INLINE_VISIBILITY |
1806 | constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>) |
1807 | _LIBCPP_NOEXCEPT_RETURN( |
1808 | _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...) |
1809 | ) |
1810 | |
1811 | template <class _Tp, class _Tuple> |
1812 | inline _LIBCPP_INLINE_VISIBILITY |
1813 | constexpr _Tp make_from_tuple(_Tuple&& __t) |
1814 | _LIBCPP_NOEXCEPT_RETURN( |
1815 | _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t), |
1816 | typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{}) |
1817 | ) |
1818 | |
1819 | #undef _LIBCPP_NOEXCEPT_RETURN |
1820 | |
1821 | #endif // _LIBCPP_STD_VER > 14 |
1822 | |
1823 | #endif // !defined(_LIBCPP_CXX03_LANG) |
1824 | |
1825 | _LIBCPP_END_NAMESPACE_STD |
1826 | |
1827 | #endif // _LIBCPP_TUPLE |
1828 | |