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 | #include <__config> |
14 | #include <cstddef> |
15 | #include <type_traits> |
16 | |
17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
18 | #pragma GCC system_header |
19 | #endif |
20 | |
21 | |
22 | _LIBCPP_BEGIN_NAMESPACE_STD |
23 | |
24 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size; |
25 | |
26 | #if !defined(_LIBCPP_CXX03_LANG) |
27 | template <class _Tp, class...> |
28 | using __enable_if_tuple_size_imp = _Tp; |
29 | |
30 | template <class _Tp> |
31 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< |
32 | const _Tp, |
33 | typename enable_if<!is_volatile<_Tp>::value>::type, |
34 | integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> |
35 | : public integral_constant<size_t, tuple_size<_Tp>::value> {}; |
36 | |
37 | template <class _Tp> |
38 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< |
39 | volatile _Tp, |
40 | typename enable_if<!is_const<_Tp>::value>::type, |
41 | integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> |
42 | : public integral_constant<size_t, tuple_size<_Tp>::value> {}; |
43 | |
44 | template <class _Tp> |
45 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< |
46 | const volatile _Tp, |
47 | integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> |
48 | : public integral_constant<size_t, tuple_size<_Tp>::value> {}; |
49 | |
50 | #else |
51 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {}; |
52 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {}; |
53 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {}; |
54 | #endif |
55 | |
56 | template <size_t _Ip, class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_element; |
57 | |
58 | template <size_t _Ip, class _Tp> |
59 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp> |
60 | { |
61 | typedef _LIBCPP_NODEBUG_TYPE typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type; |
62 | }; |
63 | |
64 | template <size_t _Ip, class _Tp> |
65 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp> |
66 | { |
67 | typedef _LIBCPP_NODEBUG_TYPE typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type; |
68 | }; |
69 | |
70 | template <size_t _Ip, class _Tp> |
71 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp> |
72 | { |
73 | typedef _LIBCPP_NODEBUG_TYPE typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type; |
74 | }; |
75 | |
76 | template <class _Tp> struct __tuple_like : false_type {}; |
77 | |
78 | template <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {}; |
79 | template <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {}; |
80 | template <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {}; |
81 | |
82 | // tuple specializations |
83 | |
84 | #ifndef _LIBCPP_CXX03_LANG |
85 | |
86 | template <size_t...> struct __tuple_indices {}; |
87 | |
88 | template <class _IdxType, _IdxType... _Values> |
89 | struct __integer_sequence { |
90 | template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType> |
91 | using __convert = _ToIndexSeq<_ToIndexType, _Values...>; |
92 | |
93 | template <size_t _Sp> |
94 | using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>; |
95 | }; |
96 | |
97 | #if !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) |
98 | namespace __detail { |
99 | |
100 | template<typename _Tp, size_t ..._Extra> struct __repeat; |
101 | template<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> { |
102 | typedef _LIBCPP_NODEBUG_TYPE __integer_sequence<_Tp, |
103 | _Np..., |
104 | sizeof...(_Np) + _Np..., |
105 | 2 * sizeof...(_Np) + _Np..., |
106 | 3 * sizeof...(_Np) + _Np..., |
107 | 4 * sizeof...(_Np) + _Np..., |
108 | 5 * sizeof...(_Np) + _Np..., |
109 | 6 * sizeof...(_Np) + _Np..., |
110 | 7 * sizeof...(_Np) + _Np..., |
111 | _Extra...> type; |
112 | }; |
113 | |
114 | template<size_t _Np> struct __parity; |
115 | template<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {}; |
116 | |
117 | template<> struct __make<0> { typedef __integer_sequence<size_t> type; }; |
118 | template<> struct __make<1> { typedef __integer_sequence<size_t, 0> type; }; |
119 | template<> struct __make<2> { typedef __integer_sequence<size_t, 0, 1> type; }; |
120 | template<> struct __make<3> { typedef __integer_sequence<size_t, 0, 1, 2> type; }; |
121 | template<> struct __make<4> { typedef __integer_sequence<size_t, 0, 1, 2, 3> type; }; |
122 | template<> struct __make<5> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4> type; }; |
123 | template<> struct __make<6> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; }; |
124 | template<> struct __make<7> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; }; |
125 | |
126 | template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; }; |
127 | template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; }; |
128 | template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; }; |
129 | template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; }; |
130 | template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; |
131 | template<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; |
132 | template<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; |
133 | template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; |
134 | |
135 | } // namespace detail |
136 | |
137 | #endif // !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) |
138 | |
139 | #if __has_builtin(__make_integer_seq) |
140 | template <size_t _Ep, size_t _Sp> |
141 | using __make_indices_imp = |
142 | typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template |
143 | __to_tuple_indices<_Sp>; |
144 | #else |
145 | template <size_t _Ep, size_t _Sp> |
146 | using __make_indices_imp = |
147 | typename __detail::__make<_Ep - _Sp>::type::template __to_tuple_indices<_Sp>; |
148 | |
149 | #endif |
150 | |
151 | template <size_t _Ep, size_t _Sp = 0> |
152 | struct __make_tuple_indices |
153 | { |
154 | static_assert(_Sp <= _Ep, "__make_tuple_indices input error" ); |
155 | typedef __make_indices_imp<_Ep, _Sp> type; |
156 | }; |
157 | |
158 | |
159 | template <class ..._Tp> class _LIBCPP_TEMPLATE_VIS tuple; |
160 | |
161 | template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {}; |
162 | |
163 | template <class ..._Tp> |
164 | struct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> > |
165 | : public integral_constant<size_t, sizeof...(_Tp)> |
166 | { |
167 | }; |
168 | |
169 | template <size_t _Ip, class ..._Tp> |
170 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
171 | typename tuple_element<_Ip, tuple<_Tp...> >::type& |
172 | get(tuple<_Tp...>&) _NOEXCEPT; |
173 | |
174 | template <size_t _Ip, class ..._Tp> |
175 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
176 | const typename tuple_element<_Ip, tuple<_Tp...> >::type& |
177 | get(const tuple<_Tp...>&) _NOEXCEPT; |
178 | |
179 | template <size_t _Ip, class ..._Tp> |
180 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
181 | typename tuple_element<_Ip, tuple<_Tp...> >::type&& |
182 | get(tuple<_Tp...>&&) _NOEXCEPT; |
183 | |
184 | template <size_t _Ip, class ..._Tp> |
185 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
186 | const typename tuple_element<_Ip, tuple<_Tp...> >::type&& |
187 | get(const tuple<_Tp...>&&) _NOEXCEPT; |
188 | |
189 | #endif // !defined(_LIBCPP_CXX03_LANG) |
190 | |
191 | // pair specializations |
192 | |
193 | template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {}; |
194 | |
195 | template <size_t _Ip, class _T1, class _T2> |
196 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
197 | typename tuple_element<_Ip, pair<_T1, _T2> >::type& |
198 | get(pair<_T1, _T2>&) _NOEXCEPT; |
199 | |
200 | template <size_t _Ip, class _T1, class _T2> |
201 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
202 | const typename tuple_element<_Ip, pair<_T1, _T2> >::type& |
203 | get(const pair<_T1, _T2>&) _NOEXCEPT; |
204 | |
205 | #ifndef _LIBCPP_CXX03_LANG |
206 | template <size_t _Ip, class _T1, class _T2> |
207 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
208 | typename tuple_element<_Ip, pair<_T1, _T2> >::type&& |
209 | get(pair<_T1, _T2>&&) _NOEXCEPT; |
210 | |
211 | template <size_t _Ip, class _T1, class _T2> |
212 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
213 | const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& |
214 | get(const pair<_T1, _T2>&&) _NOEXCEPT; |
215 | #endif |
216 | |
217 | // array specializations |
218 | |
219 | template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array; |
220 | |
221 | template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {}; |
222 | |
223 | template <size_t _Ip, class _Tp, size_t _Size> |
224 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
225 | _Tp& |
226 | get(array<_Tp, _Size>&) _NOEXCEPT; |
227 | |
228 | template <size_t _Ip, class _Tp, size_t _Size> |
229 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
230 | const _Tp& |
231 | get(const array<_Tp, _Size>&) _NOEXCEPT; |
232 | |
233 | #ifndef _LIBCPP_CXX03_LANG |
234 | template <size_t _Ip, class _Tp, size_t _Size> |
235 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
236 | _Tp&& |
237 | get(array<_Tp, _Size>&&) _NOEXCEPT; |
238 | |
239 | template <size_t _Ip, class _Tp, size_t _Size> |
240 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
241 | const _Tp&& |
242 | get(const array<_Tp, _Size>&&) _NOEXCEPT; |
243 | #endif |
244 | |
245 | #ifndef _LIBCPP_CXX03_LANG |
246 | |
247 | // __tuple_types |
248 | |
249 | template <class ..._Tp> struct __tuple_types {}; |
250 | |
251 | #if !__has_builtin(__type_pack_element) |
252 | |
253 | namespace __indexer_detail { |
254 | |
255 | template <size_t _Idx, class _Tp> |
256 | struct __indexed { using type _LIBCPP_NODEBUG_TYPE = _Tp; }; |
257 | |
258 | template <class _Types, class _Indexes> struct __indexer; |
259 | |
260 | template <class ..._Types, size_t ..._Idx> |
261 | struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>> |
262 | : __indexed<_Idx, _Types>... |
263 | {}; |
264 | |
265 | template <size_t _Idx, class _Tp> |
266 | __indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&); |
267 | |
268 | } // namespace __indexer_detail |
269 | |
270 | template <size_t _Idx, class ..._Types> |
271 | using __type_pack_element _LIBCPP_NODEBUG_TYPE = typename decltype( |
272 | __indexer_detail::__at_index<_Idx>( |
273 | __indexer_detail::__indexer< |
274 | __tuple_types<_Types...>, |
275 | typename __make_tuple_indices<sizeof...(_Types)>::type |
276 | >{}) |
277 | )::type; |
278 | #endif |
279 | |
280 | template <size_t _Ip, class ..._Types> |
281 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...>> |
282 | { |
283 | static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range" ); |
284 | typedef _LIBCPP_NODEBUG_TYPE __type_pack_element<_Ip, _Types...> type; |
285 | }; |
286 | |
287 | |
288 | template <class ..._Tp> |
289 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> > |
290 | : public integral_constant<size_t, sizeof...(_Tp)> |
291 | { |
292 | }; |
293 | |
294 | template <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {}; |
295 | |
296 | template <bool _ApplyLV, bool _ApplyConst, bool _ApplyVolatile> |
297 | struct __apply_cv_mf; |
298 | template <> |
299 | struct __apply_cv_mf<false, false, false> { |
300 | template <class _Tp> using __apply = _Tp; |
301 | }; |
302 | template <> |
303 | struct __apply_cv_mf<false, true, false> { |
304 | template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE = const _Tp; |
305 | }; |
306 | template <> |
307 | struct __apply_cv_mf<false, false, true> { |
308 | template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE = volatile _Tp; |
309 | }; |
310 | template <> |
311 | struct __apply_cv_mf<false, true, true> { |
312 | template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE = const volatile _Tp; |
313 | }; |
314 | template <> |
315 | struct __apply_cv_mf<true, false, false> { |
316 | template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE = _Tp&; |
317 | }; |
318 | template <> |
319 | struct __apply_cv_mf<true, true, false> { |
320 | template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE = const _Tp&; |
321 | }; |
322 | template <> |
323 | struct __apply_cv_mf<true, false, true> { |
324 | template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE = volatile _Tp&; |
325 | }; |
326 | template <> |
327 | struct __apply_cv_mf<true, true, true> { |
328 | template <class _Tp> using __apply _LIBCPP_NODEBUG_TYPE = const volatile _Tp&; |
329 | }; |
330 | template <class _Tp, class _RawTp = typename remove_reference<_Tp>::type> |
331 | using __apply_cv_t _LIBCPP_NODEBUG_TYPE = __apply_cv_mf< |
332 | is_lvalue_reference<_Tp>::value, |
333 | is_const<_RawTp>::value, |
334 | is_volatile<_RawTp>::value>; |
335 | |
336 | // __make_tuple_types |
337 | |
338 | // __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a |
339 | // __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep). |
340 | // _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a |
341 | // lvalue_reference type, then __tuple_types<_Types&...> is the result. |
342 | |
343 | template <class _TupleTypes, class _TupleIndices> |
344 | struct __make_tuple_types_flat; |
345 | |
346 | template <template <class...> class _Tuple, class ..._Types, size_t ..._Idx> |
347 | struct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> { |
348 | // Specialization for pair, tuple, and __tuple_types |
349 | template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>> |
350 | using __apply_quals _LIBCPP_NODEBUG_TYPE = __tuple_types< |
351 | typename _ApplyFn::template __apply<__type_pack_element<_Idx, _Types...>>... |
352 | >; |
353 | }; |
354 | |
355 | template <class _Vt, size_t _Np, size_t ..._Idx> |
356 | struct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> { |
357 | template <size_t> |
358 | using __value_type = _Vt; |
359 | template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>> |
360 | using __apply_quals = __tuple_types< |
361 | typename _ApplyFn::template __apply<__value_type<_Idx>>... |
362 | >; |
363 | }; |
364 | |
365 | template <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, |
366 | size_t _Sp = 0, |
367 | bool _SameSize = (_Ep == tuple_size<typename remove_reference<_Tp>::type>::value)> |
368 | struct __make_tuple_types |
369 | { |
370 | static_assert(_Sp <= _Ep, "__make_tuple_types input error" ); |
371 | using _RawTp = typename remove_cv<typename remove_reference<_Tp>::type>::type; |
372 | using _Maker = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>; |
373 | using type = typename _Maker::template __apply_quals<_Tp>; |
374 | }; |
375 | |
376 | template <class ..._Types, size_t _Ep> |
377 | struct __make_tuple_types<tuple<_Types...>, _Ep, 0, true> { |
378 | typedef _LIBCPP_NODEBUG_TYPE __tuple_types<_Types...> type; |
379 | }; |
380 | |
381 | template <class ..._Types, size_t _Ep> |
382 | struct __make_tuple_types<__tuple_types<_Types...>, _Ep, 0, true> { |
383 | typedef _LIBCPP_NODEBUG_TYPE __tuple_types<_Types...> type; |
384 | }; |
385 | |
386 | template <bool ..._Preds> |
387 | struct __all_dummy; |
388 | |
389 | template <bool ..._Pred> |
390 | using __all = _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>>; |
391 | |
392 | struct __tuple_sfinae_base { |
393 | template <template <class, class...> class _Trait, |
394 | class ..._LArgs, class ..._RArgs> |
395 | static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>) |
396 | -> __all<typename enable_if<_Trait<_LArgs, _RArgs>::value, bool>::type{true}...>; |
397 | template <template <class...> class> |
398 | static auto __do_test(...) -> false_type; |
399 | |
400 | template <class _FromArgs, class _ToArgs> |
401 | using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{})); |
402 | template <class _FromArgs, class _ToArgs> |
403 | using __convertible = decltype(__do_test<is_convertible>(_FromArgs{}, _ToArgs{})); |
404 | template <class _FromArgs, class _ToArgs> |
405 | using __assignable = decltype(__do_test<is_assignable>(_ToArgs{}, _FromArgs{})); |
406 | }; |
407 | |
408 | // __tuple_convertible |
409 | |
410 | template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, |
411 | bool = __tuple_like<_Up>::value> |
412 | struct __tuple_convertible |
413 | : public false_type {}; |
414 | |
415 | template <class _Tp, class _Up> |
416 | struct __tuple_convertible<_Tp, _Up, true, true> |
417 | : public __tuple_sfinae_base::__convertible< |
418 | typename __make_tuple_types<_Tp>::type |
419 | , typename __make_tuple_types<_Up>::type |
420 | > |
421 | {}; |
422 | |
423 | // __tuple_constructible |
424 | |
425 | template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, |
426 | bool = __tuple_like<_Up>::value> |
427 | struct __tuple_constructible |
428 | : public false_type {}; |
429 | |
430 | template <class _Tp, class _Up> |
431 | struct __tuple_constructible<_Tp, _Up, true, true> |
432 | : public __tuple_sfinae_base::__constructible< |
433 | typename __make_tuple_types<_Tp>::type |
434 | , typename __make_tuple_types<_Up>::type |
435 | > |
436 | {}; |
437 | |
438 | // __tuple_assignable |
439 | |
440 | template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, |
441 | bool = __tuple_like<_Up>::value> |
442 | struct __tuple_assignable |
443 | : public false_type {}; |
444 | |
445 | template <class _Tp, class _Up> |
446 | struct __tuple_assignable<_Tp, _Up, true, true> |
447 | : public __tuple_sfinae_base::__assignable< |
448 | typename __make_tuple_types<_Tp>::type |
449 | , typename __make_tuple_types<_Up&>::type |
450 | > |
451 | {}; |
452 | |
453 | |
454 | template <size_t _Ip, class ..._Tp> |
455 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> > |
456 | { |
457 | typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type; |
458 | }; |
459 | |
460 | #if _LIBCPP_STD_VER > 11 |
461 | template <size_t _Ip, class ..._Tp> |
462 | using tuple_element_t _LIBCPP_NODEBUG_TYPE = typename tuple_element <_Ip, _Tp...>::type; |
463 | #endif |
464 | |
465 | template <bool _IsTuple, class _SizeTrait, size_t _Expected> |
466 | struct __tuple_like_with_size_imp : false_type {}; |
467 | |
468 | template <class _SizeTrait, size_t _Expected> |
469 | struct __tuple_like_with_size_imp<true, _SizeTrait, _Expected> |
470 | : integral_constant<bool, _SizeTrait::value == _Expected> {}; |
471 | |
472 | template <class _Tuple, size_t _ExpectedSize, |
473 | class _RawTuple = typename __uncvref<_Tuple>::type> |
474 | using __tuple_like_with_size _LIBCPP_NODEBUG_TYPE = __tuple_like_with_size_imp< |
475 | __tuple_like<_RawTuple>::value, |
476 | tuple_size<_RawTuple>, _ExpectedSize |
477 | >; |
478 | |
479 | struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail { |
480 | |
481 | static constexpr bool __enable_explicit_default() { return false; } |
482 | static constexpr bool __enable_implicit_default() { return false; } |
483 | template <class ...> |
484 | static constexpr bool __enable_explicit() { return false; } |
485 | template <class ...> |
486 | static constexpr bool __enable_implicit() { return false; } |
487 | template <class ...> |
488 | static constexpr bool __enable_assign() { return false; } |
489 | }; |
490 | #endif // !defined(_LIBCPP_CXX03_LANG) |
491 | |
492 | #if _LIBCPP_STD_VER > 14 |
493 | |
494 | template <bool _CanCopy, bool _CanMove> |
495 | struct __sfinae_ctor_base {}; |
496 | template <> |
497 | struct __sfinae_ctor_base<false, false> { |
498 | __sfinae_ctor_base() = default; |
499 | __sfinae_ctor_base(__sfinae_ctor_base const&) = delete; |
500 | __sfinae_ctor_base(__sfinae_ctor_base &&) = delete; |
501 | __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; |
502 | __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; |
503 | }; |
504 | template <> |
505 | struct __sfinae_ctor_base<true, false> { |
506 | __sfinae_ctor_base() = default; |
507 | __sfinae_ctor_base(__sfinae_ctor_base const&) = default; |
508 | __sfinae_ctor_base(__sfinae_ctor_base &&) = delete; |
509 | __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; |
510 | __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; |
511 | }; |
512 | template <> |
513 | struct __sfinae_ctor_base<false, true> { |
514 | __sfinae_ctor_base() = default; |
515 | __sfinae_ctor_base(__sfinae_ctor_base const&) = delete; |
516 | __sfinae_ctor_base(__sfinae_ctor_base &&) = default; |
517 | __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; |
518 | __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; |
519 | }; |
520 | |
521 | template <bool _CanCopy, bool _CanMove> |
522 | struct __sfinae_assign_base {}; |
523 | template <> |
524 | struct __sfinae_assign_base<false, false> { |
525 | __sfinae_assign_base() = default; |
526 | __sfinae_assign_base(__sfinae_assign_base const&) = default; |
527 | __sfinae_assign_base(__sfinae_assign_base &&) = default; |
528 | __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete; |
529 | __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete; |
530 | }; |
531 | template <> |
532 | struct __sfinae_assign_base<true, false> { |
533 | __sfinae_assign_base() = default; |
534 | __sfinae_assign_base(__sfinae_assign_base const&) = default; |
535 | __sfinae_assign_base(__sfinae_assign_base &&) = default; |
536 | __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default; |
537 | __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete; |
538 | }; |
539 | template <> |
540 | struct __sfinae_assign_base<false, true> { |
541 | __sfinae_assign_base() = default; |
542 | __sfinae_assign_base(__sfinae_assign_base const&) = default; |
543 | __sfinae_assign_base(__sfinae_assign_base &&) = default; |
544 | __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete; |
545 | __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default; |
546 | }; |
547 | #endif // _LIBCPP_STD_VER > 14 |
548 | |
549 | _LIBCPP_END_NAMESPACE_STD |
550 | |
551 | #endif // _LIBCPP___TUPLE |
552 | |