1 | // -*- C++ -*- |
2 | //===------------------------------ variant -------------------------------===// |
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_VARIANT |
11 | #define _LIBCPP_VARIANT |
12 | |
13 | /* |
14 | variant synopsis |
15 | |
16 | namespace std { |
17 | |
18 | // 20.7.2, class template variant |
19 | template <class... Types> |
20 | class variant { |
21 | public: |
22 | |
23 | // 20.7.2.1, constructors |
24 | constexpr variant() noexcept(see below); |
25 | variant(const variant&); // constexpr in C++20 |
26 | variant(variant&&) noexcept(see below); // constexpr in C++20 |
27 | |
28 | template <class T> constexpr variant(T&&) noexcept(see below); |
29 | |
30 | template <class T, class... Args> |
31 | constexpr explicit variant(in_place_type_t<T>, Args&&...); |
32 | |
33 | template <class T, class U, class... Args> |
34 | constexpr explicit variant( |
35 | in_place_type_t<T>, initializer_list<U>, Args&&...); |
36 | |
37 | template <size_t I, class... Args> |
38 | constexpr explicit variant(in_place_index_t<I>, Args&&...); |
39 | |
40 | template <size_t I, class U, class... Args> |
41 | constexpr explicit variant( |
42 | in_place_index_t<I>, initializer_list<U>, Args&&...); |
43 | |
44 | // 20.7.2.2, destructor |
45 | ~variant(); |
46 | |
47 | // 20.7.2.3, assignment |
48 | variant& operator=(const variant&); // constexpr in C++20 |
49 | variant& operator=(variant&&) noexcept(see below); // constexpr in C++20 |
50 | |
51 | template <class T> variant& operator=(T&&) noexcept(see below); |
52 | |
53 | // 20.7.2.4, modifiers |
54 | template <class T, class... Args> |
55 | T& emplace(Args&&...); |
56 | |
57 | template <class T, class U, class... Args> |
58 | T& emplace(initializer_list<U>, Args&&...); |
59 | |
60 | template <size_t I, class... Args> |
61 | variant_alternative_t<I, variant>& emplace(Args&&...); |
62 | |
63 | template <size_t I, class U, class... Args> |
64 | variant_alternative_t<I, variant>& emplace(initializer_list<U>, Args&&...); |
65 | |
66 | // 20.7.2.5, value status |
67 | constexpr bool valueless_by_exception() const noexcept; |
68 | constexpr size_t index() const noexcept; |
69 | |
70 | // 20.7.2.6, swap |
71 | void swap(variant&) noexcept(see below); |
72 | }; |
73 | |
74 | // 20.7.3, variant helper classes |
75 | template <class T> struct variant_size; // undefined |
76 | |
77 | template <class T> |
78 | inline constexpr size_t variant_size_v = variant_size<T>::value; |
79 | |
80 | template <class T> struct variant_size<const T>; |
81 | template <class T> struct variant_size<volatile T>; |
82 | template <class T> struct variant_size<const volatile T>; |
83 | |
84 | template <class... Types> |
85 | struct variant_size<variant<Types...>>; |
86 | |
87 | template <size_t I, class T> struct variant_alternative; // undefined |
88 | |
89 | template <size_t I, class T> |
90 | using variant_alternative_t = typename variant_alternative<I, T>::type; |
91 | |
92 | template <size_t I, class T> struct variant_alternative<I, const T>; |
93 | template <size_t I, class T> struct variant_alternative<I, volatile T>; |
94 | template <size_t I, class T> struct variant_alternative<I, const volatile T>; |
95 | |
96 | template <size_t I, class... Types> |
97 | struct variant_alternative<I, variant<Types...>>; |
98 | |
99 | inline constexpr size_t variant_npos = -1; |
100 | |
101 | // 20.7.4, value access |
102 | template <class T, class... Types> |
103 | constexpr bool holds_alternative(const variant<Types...>&) noexcept; |
104 | |
105 | template <size_t I, class... Types> |
106 | constexpr variant_alternative_t<I, variant<Types...>>& |
107 | get(variant<Types...>&); |
108 | |
109 | template <size_t I, class... Types> |
110 | constexpr variant_alternative_t<I, variant<Types...>>&& |
111 | get(variant<Types...>&&); |
112 | |
113 | template <size_t I, class... Types> |
114 | constexpr variant_alternative_t<I, variant<Types...>> const& |
115 | get(const variant<Types...>&); |
116 | |
117 | template <size_t I, class... Types> |
118 | constexpr variant_alternative_t<I, variant<Types...>> const&& |
119 | get(const variant<Types...>&&); |
120 | |
121 | template <class T, class... Types> |
122 | constexpr T& get(variant<Types...>&); |
123 | |
124 | template <class T, class... Types> |
125 | constexpr T&& get(variant<Types...>&&); |
126 | |
127 | template <class T, class... Types> |
128 | constexpr const T& get(const variant<Types...>&); |
129 | |
130 | template <class T, class... Types> |
131 | constexpr const T&& get(const variant<Types...>&&); |
132 | |
133 | template <size_t I, class... Types> |
134 | constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>> |
135 | get_if(variant<Types...>*) noexcept; |
136 | |
137 | template <size_t I, class... Types> |
138 | constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>> |
139 | get_if(const variant<Types...>*) noexcept; |
140 | |
141 | template <class T, class... Types> |
142 | constexpr add_pointer_t<T> |
143 | get_if(variant<Types...>*) noexcept; |
144 | |
145 | template <class T, class... Types> |
146 | constexpr add_pointer_t<const T> |
147 | get_if(const variant<Types...>*) noexcept; |
148 | |
149 | // 20.7.5, relational operators |
150 | template <class... Types> |
151 | constexpr bool operator==(const variant<Types...>&, const variant<Types...>&); |
152 | |
153 | template <class... Types> |
154 | constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&); |
155 | |
156 | template <class... Types> |
157 | constexpr bool operator<(const variant<Types...>&, const variant<Types...>&); |
158 | |
159 | template <class... Types> |
160 | constexpr bool operator>(const variant<Types...>&, const variant<Types...>&); |
161 | |
162 | template <class... Types> |
163 | constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&); |
164 | |
165 | template <class... Types> |
166 | constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&); |
167 | |
168 | // 20.7.6, visitation |
169 | template <class Visitor, class... Variants> |
170 | constexpr see below visit(Visitor&&, Variants&&...); |
171 | |
172 | // 20.7.7, class monostate |
173 | struct monostate; |
174 | |
175 | // 20.7.8, monostate relational operators |
176 | constexpr bool operator<(monostate, monostate) noexcept; |
177 | constexpr bool operator>(monostate, monostate) noexcept; |
178 | constexpr bool operator<=(monostate, monostate) noexcept; |
179 | constexpr bool operator>=(monostate, monostate) noexcept; |
180 | constexpr bool operator==(monostate, monostate) noexcept; |
181 | constexpr bool operator!=(monostate, monostate) noexcept; |
182 | |
183 | // 20.7.9, specialized algorithms |
184 | template <class... Types> |
185 | void swap(variant<Types...>&, variant<Types...>&) noexcept(see below); |
186 | |
187 | // 20.7.10, class bad_variant_access |
188 | class bad_variant_access; |
189 | |
190 | // 20.7.11, hash support |
191 | template <class T> struct hash; |
192 | template <class... Types> struct hash<variant<Types...>>; |
193 | template <> struct hash<monostate>; |
194 | |
195 | } // namespace std |
196 | |
197 | */ |
198 | |
199 | #include <__config> |
200 | #include <__tuple> |
201 | #include <array> |
202 | #include <exception> |
203 | #include <functional> |
204 | #include <initializer_list> |
205 | #include <new> |
206 | #include <tuple> |
207 | #include <type_traits> |
208 | #include <utility> |
209 | #include <limits> |
210 | #include <version> |
211 | |
212 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
213 | #pragma GCC system_header |
214 | #endif |
215 | |
216 | _LIBCPP_PUSH_MACROS |
217 | #include <__undef_macros> |
218 | |
219 | namespace std { // explicitly not using versioning namespace |
220 | |
221 | class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception { |
222 | public: |
223 | virtual const char* what() const _NOEXCEPT; |
224 | }; |
225 | |
226 | } // namespace std |
227 | |
228 | _LIBCPP_BEGIN_NAMESPACE_STD |
229 | |
230 | #if _LIBCPP_STD_VER > 14 |
231 | |
232 | _LIBCPP_NORETURN |
233 | inline _LIBCPP_INLINE_VISIBILITY |
234 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
235 | void __throw_bad_variant_access() { |
236 | #ifndef _LIBCPP_NO_EXCEPTIONS |
237 | throw bad_variant_access(); |
238 | #else |
239 | _VSTD::abort(); |
240 | #endif |
241 | } |
242 | |
243 | template <class... _Types> |
244 | class _LIBCPP_TEMPLATE_VIS variant; |
245 | |
246 | template <class _Tp> |
247 | struct _LIBCPP_TEMPLATE_VIS variant_size; |
248 | |
249 | template <class _Tp> |
250 | _LIBCPP_INLINE_VAR constexpr size_t variant_size_v = variant_size<_Tp>::value; |
251 | |
252 | template <class _Tp> |
253 | struct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {}; |
254 | |
255 | template <class _Tp> |
256 | struct _LIBCPP_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {}; |
257 | |
258 | template <class _Tp> |
259 | struct _LIBCPP_TEMPLATE_VIS variant_size<const volatile _Tp> |
260 | : variant_size<_Tp> {}; |
261 | |
262 | template <class... _Types> |
263 | struct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>> |
264 | : integral_constant<size_t, sizeof...(_Types)> {}; |
265 | |
266 | template <size_t _Ip, class _Tp> |
267 | struct _LIBCPP_TEMPLATE_VIS variant_alternative; |
268 | |
269 | template <size_t _Ip, class _Tp> |
270 | using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type; |
271 | |
272 | template <size_t _Ip, class _Tp> |
273 | struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp> |
274 | : add_const<variant_alternative_t<_Ip, _Tp>> {}; |
275 | |
276 | template <size_t _Ip, class _Tp> |
277 | struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp> |
278 | : add_volatile<variant_alternative_t<_Ip, _Tp>> {}; |
279 | |
280 | template <size_t _Ip, class _Tp> |
281 | struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp> |
282 | : add_cv<variant_alternative_t<_Ip, _Tp>> {}; |
283 | |
284 | template <size_t _Ip, class... _Types> |
285 | struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> { |
286 | static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>" ); |
287 | using type = __type_pack_element<_Ip, _Types...>; |
288 | }; |
289 | |
290 | _LIBCPP_INLINE_VAR constexpr size_t variant_npos = static_cast<size_t>(-1); |
291 | |
292 | constexpr int __choose_index_type(unsigned int __num_elem) { |
293 | if (__num_elem < std::numeric_limits<unsigned char>::max()) |
294 | return 0; |
295 | if (__num_elem < std::numeric_limits<unsigned short>::max()) |
296 | return 1; |
297 | return 2; |
298 | } |
299 | |
300 | template <size_t _NumAlts> |
301 | using __variant_index_t = |
302 | #ifndef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION |
303 | unsigned int; |
304 | #else |
305 | std::tuple_element_t< |
306 | __choose_index_type(_NumAlts), |
307 | std::tuple<unsigned char, unsigned short, unsigned int> |
308 | >; |
309 | #endif |
310 | |
311 | template <class _IndexType> |
312 | constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1); |
313 | |
314 | namespace __find_detail { |
315 | |
316 | template <class _Tp, class... _Types> |
317 | inline _LIBCPP_INLINE_VISIBILITY |
318 | constexpr size_t __find_index() { |
319 | constexpr bool __matches[] = {is_same_v<_Tp, _Types>...}; |
320 | size_t __result = __not_found; |
321 | for (size_t __i = 0; __i < sizeof...(_Types); ++__i) { |
322 | if (__matches[__i]) { |
323 | if (__result != __not_found) { |
324 | return __ambiguous; |
325 | } |
326 | __result = __i; |
327 | } |
328 | } |
329 | return __result; |
330 | } |
331 | |
332 | template <size_t _Index> |
333 | struct __find_unambiguous_index_sfinae_impl |
334 | : integral_constant<size_t, _Index> {}; |
335 | |
336 | template <> |
337 | struct __find_unambiguous_index_sfinae_impl<__not_found> {}; |
338 | |
339 | template <> |
340 | struct __find_unambiguous_index_sfinae_impl<__ambiguous> {}; |
341 | |
342 | template <class _Tp, class... _Types> |
343 | struct __find_unambiguous_index_sfinae |
344 | : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {}; |
345 | |
346 | } // namespace __find_detail |
347 | |
348 | namespace __variant_detail { |
349 | |
350 | struct __valueless_t {}; |
351 | |
352 | enum class _Trait { _TriviallyAvailable, _Available, _Unavailable }; |
353 | |
354 | template <typename _Tp, |
355 | template <typename> class _IsTriviallyAvailable, |
356 | template <typename> class _IsAvailable> |
357 | constexpr _Trait __trait = |
358 | _IsTriviallyAvailable<_Tp>::value |
359 | ? _Trait::_TriviallyAvailable |
360 | : _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable; |
361 | |
362 | inline _LIBCPP_INLINE_VISIBILITY |
363 | constexpr _Trait __common_trait(initializer_list<_Trait> __traits) { |
364 | _Trait __result = _Trait::_TriviallyAvailable; |
365 | for (_Trait __t : __traits) { |
366 | if (static_cast<int>(__t) > static_cast<int>(__result)) { |
367 | __result = __t; |
368 | } |
369 | } |
370 | return __result; |
371 | } |
372 | |
373 | template <typename... _Types> |
374 | struct __traits { |
375 | static constexpr _Trait __copy_constructible_trait = |
376 | __common_trait({__trait<_Types, |
377 | is_trivially_copy_constructible, |
378 | is_copy_constructible>...}); |
379 | |
380 | static constexpr _Trait __move_constructible_trait = |
381 | __common_trait({__trait<_Types, |
382 | is_trivially_move_constructible, |
383 | is_move_constructible>...}); |
384 | |
385 | static constexpr _Trait __copy_assignable_trait = __common_trait( |
386 | {__copy_constructible_trait, |
387 | __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...}); |
388 | |
389 | static constexpr _Trait __move_assignable_trait = __common_trait( |
390 | {__move_constructible_trait, |
391 | __trait<_Types, is_trivially_move_assignable, is_move_assignable>...}); |
392 | |
393 | static constexpr _Trait __destructible_trait = __common_trait( |
394 | {__trait<_Types, is_trivially_destructible, is_destructible>...}); |
395 | }; |
396 | |
397 | namespace __access { |
398 | |
399 | struct __union { |
400 | template <class _Vp> |
401 | inline _LIBCPP_INLINE_VISIBILITY |
402 | static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) { |
403 | return _VSTD::forward<_Vp>(__v).__head; |
404 | } |
405 | |
406 | template <class _Vp, size_t _Ip> |
407 | inline _LIBCPP_INLINE_VISIBILITY |
408 | static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) { |
409 | return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>); |
410 | } |
411 | }; |
412 | |
413 | struct __base { |
414 | template <size_t _Ip, class _Vp> |
415 | inline _LIBCPP_INLINE_VISIBILITY |
416 | static constexpr auto&& __get_alt(_Vp&& __v) { |
417 | return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data, |
418 | in_place_index<_Ip>); |
419 | } |
420 | }; |
421 | |
422 | struct __variant { |
423 | template <size_t _Ip, class _Vp> |
424 | inline _LIBCPP_INLINE_VISIBILITY |
425 | static constexpr auto&& __get_alt(_Vp&& __v) { |
426 | return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl); |
427 | } |
428 | }; |
429 | |
430 | } // namespace __access |
431 | |
432 | namespace __visitation { |
433 | |
434 | struct __base { |
435 | template <class _Visitor, class... _Vs> |
436 | inline _LIBCPP_INLINE_VISIBILITY |
437 | static constexpr decltype(auto) |
438 | __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { |
439 | constexpr auto __fdiagonal = |
440 | __make_fdiagonal<_Visitor&&, |
441 | decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>(); |
442 | return __fdiagonal[__index](_VSTD::forward<_Visitor>(__visitor), |
443 | _VSTD::forward<_Vs>(__vs).__as_base()...); |
444 | } |
445 | |
446 | template <class _Visitor, class... _Vs> |
447 | inline _LIBCPP_INLINE_VISIBILITY |
448 | static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, |
449 | _Vs&&... __vs) { |
450 | constexpr auto __fmatrix = |
451 | __make_fmatrix<_Visitor&&, |
452 | decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>(); |
453 | return __at(__fmatrix, __vs.index()...)( |
454 | _VSTD::forward<_Visitor>(__visitor), |
455 | _VSTD::forward<_Vs>(__vs).__as_base()...); |
456 | } |
457 | |
458 | private: |
459 | template <class _Tp> |
460 | inline _LIBCPP_INLINE_VISIBILITY |
461 | static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; } |
462 | |
463 | template <class _Tp, size_t _Np, typename... _Indices> |
464 | inline _LIBCPP_INLINE_VISIBILITY |
465 | static constexpr auto&& __at(const array<_Tp, _Np>& __elems, |
466 | size_t __index, _Indices... __indices) { |
467 | return __at(__elems[__index], __indices...); |
468 | } |
469 | |
470 | template <class _Fp, class... _Fs> |
471 | static constexpr void __std_visit_visitor_return_type_check() { |
472 | static_assert( |
473 | __all<is_same_v<_Fp, _Fs>...>::value, |
474 | "`std::visit` requires the visitor to have a single return type." ); |
475 | } |
476 | |
477 | template <class... _Fs> |
478 | inline _LIBCPP_INLINE_VISIBILITY |
479 | static constexpr auto __make_farray(_Fs&&... __fs) { |
480 | __std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>(); |
481 | using __result = array<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>; |
482 | return __result{{_VSTD::forward<_Fs>(__fs)...}}; |
483 | } |
484 | |
485 | template <std::size_t... _Is> |
486 | struct __dispatcher { |
487 | template <class _Fp, class... _Vs> |
488 | inline _LIBCPP_INLINE_VISIBILITY |
489 | static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) { |
490 | return __invoke_constexpr( |
491 | static_cast<_Fp>(__f), |
492 | __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...); |
493 | } |
494 | }; |
495 | |
496 | template <class _Fp, class... _Vs, size_t... _Is> |
497 | inline _LIBCPP_INLINE_VISIBILITY |
498 | static constexpr auto __make_dispatch(index_sequence<_Is...>) { |
499 | return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>; |
500 | } |
501 | |
502 | template <size_t _Ip, class _Fp, class... _Vs> |
503 | inline _LIBCPP_INLINE_VISIBILITY |
504 | static constexpr auto __make_fdiagonal_impl() { |
505 | return __make_dispatch<_Fp, _Vs...>( |
506 | index_sequence<(__identity<_Vs>{}, _Ip)...>{}); |
507 | } |
508 | |
509 | template <class _Fp, class... _Vs, size_t... _Is> |
510 | inline _LIBCPP_INLINE_VISIBILITY |
511 | static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) { |
512 | return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...); |
513 | } |
514 | |
515 | template <class _Fp, class _Vp, class... _Vs> |
516 | inline _LIBCPP_INLINE_VISIBILITY |
517 | static constexpr auto __make_fdiagonal() { |
518 | constexpr size_t _Np = __uncvref_t<_Vp>::__size(); |
519 | static_assert(__all<(_Np == __uncvref_t<_Vs>::__size())...>::value); |
520 | return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{}); |
521 | } |
522 | |
523 | template <class _Fp, class... _Vs, size_t... _Is> |
524 | inline _LIBCPP_INLINE_VISIBILITY |
525 | static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) { |
526 | return __make_dispatch<_Fp, _Vs...>(__is); |
527 | } |
528 | |
529 | template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls> |
530 | inline _LIBCPP_INLINE_VISIBILITY |
531 | static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>, |
532 | index_sequence<_Js...>, |
533 | _Ls... __ls) { |
534 | return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>( |
535 | index_sequence<_Is..., _Js>{}, __ls...)...); |
536 | } |
537 | |
538 | template <class _Fp, class... _Vs> |
539 | inline _LIBCPP_INLINE_VISIBILITY |
540 | static constexpr auto __make_fmatrix() { |
541 | return __make_fmatrix_impl<_Fp, _Vs...>( |
542 | index_sequence<>{}, make_index_sequence<__uncvref_t<_Vs>::__size()>{}...); |
543 | } |
544 | }; |
545 | |
546 | struct __variant { |
547 | template <class _Visitor, class... _Vs> |
548 | inline _LIBCPP_INLINE_VISIBILITY |
549 | static constexpr decltype(auto) |
550 | __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { |
551 | return __base::__visit_alt_at(__index, |
552 | _VSTD::forward<_Visitor>(__visitor), |
553 | _VSTD::forward<_Vs>(__vs).__impl...); |
554 | } |
555 | |
556 | template <class _Visitor, class... _Vs> |
557 | inline _LIBCPP_INLINE_VISIBILITY |
558 | static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, |
559 | _Vs&&... __vs) { |
560 | return __base::__visit_alt(_VSTD::forward<_Visitor>(__visitor), |
561 | _VSTD::forward<_Vs>(__vs).__impl...); |
562 | } |
563 | |
564 | template <class _Visitor, class... _Vs> |
565 | inline _LIBCPP_INLINE_VISIBILITY |
566 | static constexpr decltype(auto) |
567 | __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { |
568 | return __visit_alt_at( |
569 | __index, |
570 | __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)), |
571 | _VSTD::forward<_Vs>(__vs)...); |
572 | } |
573 | |
574 | template <class _Visitor, class... _Vs> |
575 | inline _LIBCPP_INLINE_VISIBILITY |
576 | static constexpr decltype(auto) __visit_value(_Visitor&& __visitor, |
577 | _Vs&&... __vs) { |
578 | return __visit_alt( |
579 | __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)), |
580 | _VSTD::forward<_Vs>(__vs)...); |
581 | } |
582 | |
583 | private: |
584 | template <class _Visitor, class... _Values> |
585 | static constexpr void __std_visit_exhaustive_visitor_check() { |
586 | static_assert(is_invocable_v<_Visitor, _Values...>, |
587 | "`std::visit` requires the visitor to be exhaustive." ); |
588 | } |
589 | |
590 | template <class _Visitor> |
591 | struct __value_visitor { |
592 | template <class... _Alts> |
593 | inline _LIBCPP_INLINE_VISIBILITY |
594 | constexpr decltype(auto) operator()(_Alts&&... __alts) const { |
595 | __std_visit_exhaustive_visitor_check< |
596 | _Visitor, |
597 | decltype((_VSTD::forward<_Alts>(__alts).__value))...>(); |
598 | return __invoke_constexpr(_VSTD::forward<_Visitor>(__visitor), |
599 | _VSTD::forward<_Alts>(__alts).__value...); |
600 | } |
601 | _Visitor&& __visitor; |
602 | }; |
603 | |
604 | template <class _Visitor> |
605 | inline _LIBCPP_INLINE_VISIBILITY |
606 | static constexpr auto __make_value_visitor(_Visitor&& __visitor) { |
607 | return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)}; |
608 | } |
609 | }; |
610 | |
611 | } // namespace __visitation |
612 | |
613 | template <size_t _Index, class _Tp> |
614 | struct _LIBCPP_TEMPLATE_VIS __alt { |
615 | using __value_type = _Tp; |
616 | |
617 | template <class... _Args> |
618 | inline _LIBCPP_INLINE_VISIBILITY |
619 | explicit constexpr __alt(in_place_t, _Args&&... __args) |
620 | : __value(_VSTD::forward<_Args>(__args)...) {} |
621 | |
622 | __value_type __value; |
623 | }; |
624 | |
625 | template <_Trait _DestructibleTrait, size_t _Index, class... _Types> |
626 | union _LIBCPP_TEMPLATE_VIS __union; |
627 | |
628 | template <_Trait _DestructibleTrait, size_t _Index> |
629 | union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {}; |
630 | |
631 | #define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \ |
632 | template <size_t _Index, class _Tp, class... _Types> \ |
633 | union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, \ |
634 | _Index, \ |
635 | _Tp, \ |
636 | _Types...> { \ |
637 | public: \ |
638 | inline _LIBCPP_INLINE_VISIBILITY \ |
639 | explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \ |
640 | \ |
641 | template <class... _Args> \ |
642 | inline _LIBCPP_INLINE_VISIBILITY \ |
643 | explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \ |
644 | : __head(in_place, _VSTD::forward<_Args>(__args)...) {} \ |
645 | \ |
646 | template <size_t _Ip, class... _Args> \ |
647 | inline _LIBCPP_INLINE_VISIBILITY \ |
648 | explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \ |
649 | : __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \ |
650 | \ |
651 | __union(const __union&) = default; \ |
652 | __union(__union&&) = default; \ |
653 | \ |
654 | destructor \ |
655 | \ |
656 | __union& operator=(const __union&) = default; \ |
657 | __union& operator=(__union&&) = default; \ |
658 | \ |
659 | private: \ |
660 | char __dummy; \ |
661 | __alt<_Index, _Tp> __head; \ |
662 | __union<destructible_trait, _Index + 1, _Types...> __tail; \ |
663 | \ |
664 | friend struct __access::__union; \ |
665 | } |
666 | |
667 | _LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;); |
668 | _LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union() {}); |
669 | _LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;); |
670 | |
671 | #undef _LIBCPP_VARIANT_UNION |
672 | |
673 | template <_Trait _DestructibleTrait, class... _Types> |
674 | class _LIBCPP_TEMPLATE_VIS __base { |
675 | public: |
676 | using __index_t = __variant_index_t<sizeof...(_Types)>; |
677 | |
678 | inline _LIBCPP_INLINE_VISIBILITY |
679 | explicit constexpr __base(__valueless_t tag) noexcept |
680 | : __data(tag), __index(__variant_npos<__index_t>) {} |
681 | |
682 | template <size_t _Ip, class... _Args> |
683 | inline _LIBCPP_INLINE_VISIBILITY |
684 | explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args) |
685 | : |
686 | __data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...), |
687 | __index(_Ip) {} |
688 | |
689 | inline _LIBCPP_INLINE_VISIBILITY |
690 | constexpr bool valueless_by_exception() const noexcept { |
691 | return index() == variant_npos; |
692 | } |
693 | |
694 | inline _LIBCPP_INLINE_VISIBILITY |
695 | constexpr size_t index() const noexcept { |
696 | return __index == __variant_npos<__index_t> ? variant_npos : __index; |
697 | } |
698 | |
699 | protected: |
700 | inline _LIBCPP_INLINE_VISIBILITY |
701 | constexpr auto&& __as_base() & { return *this; } |
702 | |
703 | inline _LIBCPP_INLINE_VISIBILITY |
704 | constexpr auto&& __as_base() && { return _VSTD::move(*this); } |
705 | |
706 | inline _LIBCPP_INLINE_VISIBILITY |
707 | constexpr auto&& __as_base() const & { return *this; } |
708 | |
709 | inline _LIBCPP_INLINE_VISIBILITY |
710 | constexpr auto&& __as_base() const && { return _VSTD::move(*this); } |
711 | |
712 | inline _LIBCPP_INLINE_VISIBILITY |
713 | static constexpr size_t __size() { return sizeof...(_Types); } |
714 | |
715 | __union<_DestructibleTrait, 0, _Types...> __data; |
716 | __index_t __index; |
717 | |
718 | friend struct __access::__base; |
719 | friend struct __visitation::__base; |
720 | }; |
721 | |
722 | template <class _Traits, _Trait = _Traits::__destructible_trait> |
723 | class _LIBCPP_TEMPLATE_VIS __destructor; |
724 | |
725 | #define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor, destroy) \ |
726 | template <class... _Types> \ |
727 | class _LIBCPP_TEMPLATE_VIS __destructor<__traits<_Types...>, \ |
728 | destructible_trait> \ |
729 | : public __base<destructible_trait, _Types...> { \ |
730 | using __base_type = __base<destructible_trait, _Types...>; \ |
731 | using __index_t = typename __base_type::__index_t; \ |
732 | \ |
733 | public: \ |
734 | using __base_type::__base_type; \ |
735 | using __base_type::operator=; \ |
736 | \ |
737 | __destructor(const __destructor&) = default; \ |
738 | __destructor(__destructor&&) = default; \ |
739 | destructor \ |
740 | __destructor& operator=(const __destructor&) = default; \ |
741 | __destructor& operator=(__destructor&&) = default; \ |
742 | \ |
743 | protected: \ |
744 | inline _LIBCPP_INLINE_VISIBILITY \ |
745 | destroy \ |
746 | } |
747 | |
748 | _LIBCPP_VARIANT_DESTRUCTOR( |
749 | _Trait::_TriviallyAvailable, |
750 | ~__destructor() = default;, |
751 | void __destroy() noexcept { this->__index = __variant_npos<__index_t>; }); |
752 | |
753 | _LIBCPP_VARIANT_DESTRUCTOR( |
754 | _Trait::_Available, |
755 | ~__destructor() { __destroy(); }, |
756 | void __destroy() noexcept { |
757 | if (!this->valueless_by_exception()) { |
758 | __visitation::__base::__visit_alt( |
759 | [](auto& __alt) noexcept { |
760 | using __alt_type = __uncvref_t<decltype(__alt)>; |
761 | __alt.~__alt_type(); |
762 | }, |
763 | *this); |
764 | } |
765 | this->__index = __variant_npos<__index_t>; |
766 | }); |
767 | |
768 | _LIBCPP_VARIANT_DESTRUCTOR( |
769 | _Trait::_Unavailable, |
770 | ~__destructor() = delete;, |
771 | void __destroy() noexcept = delete;); |
772 | |
773 | #undef _LIBCPP_VARIANT_DESTRUCTOR |
774 | |
775 | template <class _Traits> |
776 | class _LIBCPP_TEMPLATE_VIS __constructor : public __destructor<_Traits> { |
777 | using __base_type = __destructor<_Traits>; |
778 | |
779 | public: |
780 | using __base_type::__base_type; |
781 | using __base_type::operator=; |
782 | |
783 | protected: |
784 | template <size_t _Ip, class _Tp, class... _Args> |
785 | inline _LIBCPP_INLINE_VISIBILITY |
786 | static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) { |
787 | ::new ((void*)_VSTD::addressof(__a)) |
788 | __alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...); |
789 | return __a.__value; |
790 | } |
791 | |
792 | template <class _Rhs> |
793 | inline _LIBCPP_INLINE_VISIBILITY |
794 | static void __generic_construct(__constructor& __lhs, _Rhs&& __rhs) { |
795 | __lhs.__destroy(); |
796 | if (!__rhs.valueless_by_exception()) { |
797 | __visitation::__base::__visit_alt_at( |
798 | __rhs.index(), |
799 | [](auto& __lhs_alt, auto&& __rhs_alt) { |
800 | __construct_alt( |
801 | __lhs_alt, |
802 | _VSTD::forward<decltype(__rhs_alt)>(__rhs_alt).__value); |
803 | }, |
804 | __lhs, _VSTD::forward<_Rhs>(__rhs)); |
805 | __lhs.__index = __rhs.index(); |
806 | } |
807 | } |
808 | }; |
809 | |
810 | template <class _Traits, _Trait = _Traits::__move_constructible_trait> |
811 | class _LIBCPP_TEMPLATE_VIS __move_constructor; |
812 | |
813 | #define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, \ |
814 | move_constructor) \ |
815 | template <class... _Types> \ |
816 | class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, \ |
817 | move_constructible_trait> \ |
818 | : public __constructor<__traits<_Types...>> { \ |
819 | using __base_type = __constructor<__traits<_Types...>>; \ |
820 | \ |
821 | public: \ |
822 | using __base_type::__base_type; \ |
823 | using __base_type::operator=; \ |
824 | \ |
825 | __move_constructor(const __move_constructor&) = default; \ |
826 | move_constructor \ |
827 | ~__move_constructor() = default; \ |
828 | __move_constructor& operator=(const __move_constructor&) = default; \ |
829 | __move_constructor& operator=(__move_constructor&&) = default; \ |
830 | } |
831 | |
832 | _LIBCPP_VARIANT_MOVE_CONSTRUCTOR( |
833 | _Trait::_TriviallyAvailable, |
834 | __move_constructor(__move_constructor&& __that) = default;); |
835 | |
836 | _LIBCPP_VARIANT_MOVE_CONSTRUCTOR( |
837 | _Trait::_Available, |
838 | __move_constructor(__move_constructor&& __that) noexcept( |
839 | __all<is_nothrow_move_constructible_v<_Types>...>::value) |
840 | : __move_constructor(__valueless_t{}) { |
841 | this->__generic_construct(*this, _VSTD::move(__that)); |
842 | }); |
843 | |
844 | _LIBCPP_VARIANT_MOVE_CONSTRUCTOR( |
845 | _Trait::_Unavailable, |
846 | __move_constructor(__move_constructor&&) = delete;); |
847 | |
848 | #undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR |
849 | |
850 | template <class _Traits, _Trait = _Traits::__copy_constructible_trait> |
851 | class _LIBCPP_TEMPLATE_VIS __copy_constructor; |
852 | |
853 | #define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \ |
854 | copy_constructor) \ |
855 | template <class... _Types> \ |
856 | class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \ |
857 | copy_constructible_trait> \ |
858 | : public __move_constructor<__traits<_Types...>> { \ |
859 | using __base_type = __move_constructor<__traits<_Types...>>; \ |
860 | \ |
861 | public: \ |
862 | using __base_type::__base_type; \ |
863 | using __base_type::operator=; \ |
864 | \ |
865 | copy_constructor \ |
866 | __copy_constructor(__copy_constructor&&) = default; \ |
867 | ~__copy_constructor() = default; \ |
868 | __copy_constructor& operator=(const __copy_constructor&) = default; \ |
869 | __copy_constructor& operator=(__copy_constructor&&) = default; \ |
870 | } |
871 | |
872 | _LIBCPP_VARIANT_COPY_CONSTRUCTOR( |
873 | _Trait::_TriviallyAvailable, |
874 | __copy_constructor(const __copy_constructor& __that) = default;); |
875 | |
876 | _LIBCPP_VARIANT_COPY_CONSTRUCTOR( |
877 | _Trait::_Available, |
878 | __copy_constructor(const __copy_constructor& __that) |
879 | : __copy_constructor(__valueless_t{}) { |
880 | this->__generic_construct(*this, __that); |
881 | }); |
882 | |
883 | _LIBCPP_VARIANT_COPY_CONSTRUCTOR( |
884 | _Trait::_Unavailable, |
885 | __copy_constructor(const __copy_constructor&) = delete;); |
886 | |
887 | #undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR |
888 | |
889 | template <class _Traits> |
890 | class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> { |
891 | using __base_type = __copy_constructor<_Traits>; |
892 | |
893 | public: |
894 | using __base_type::__base_type; |
895 | using __base_type::operator=; |
896 | |
897 | template <size_t _Ip, class... _Args> |
898 | inline _LIBCPP_INLINE_VISIBILITY |
899 | auto& __emplace(_Args&&... __args) { |
900 | this->__destroy(); |
901 | auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this), |
902 | _VSTD::forward<_Args>(__args)...); |
903 | this->__index = _Ip; |
904 | return __res; |
905 | } |
906 | |
907 | protected: |
908 | template <size_t _Ip, class _Tp, class _Arg> |
909 | inline _LIBCPP_INLINE_VISIBILITY |
910 | void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) { |
911 | if (this->index() == _Ip) { |
912 | __a.__value = _VSTD::forward<_Arg>(__arg); |
913 | } else { |
914 | struct { |
915 | void operator()(true_type) const { |
916 | __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg)); |
917 | } |
918 | void operator()(false_type) const { |
919 | __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg))); |
920 | } |
921 | __assignment* __this; |
922 | _Arg&& __arg; |
923 | } __impl{this, _VSTD::forward<_Arg>(__arg)}; |
924 | __impl(bool_constant<is_nothrow_constructible_v<_Tp, _Arg> || |
925 | !is_nothrow_move_constructible_v<_Tp>>{}); |
926 | } |
927 | } |
928 | |
929 | template <class _That> |
930 | inline _LIBCPP_INLINE_VISIBILITY |
931 | void __generic_assign(_That&& __that) { |
932 | if (this->valueless_by_exception() && __that.valueless_by_exception()) { |
933 | // do nothing. |
934 | } else if (__that.valueless_by_exception()) { |
935 | this->__destroy(); |
936 | } else { |
937 | __visitation::__base::__visit_alt_at( |
938 | __that.index(), |
939 | [this](auto& __this_alt, auto&& __that_alt) { |
940 | this->__assign_alt( |
941 | __this_alt, |
942 | _VSTD::forward<decltype(__that_alt)>(__that_alt).__value); |
943 | }, |
944 | *this, _VSTD::forward<_That>(__that)); |
945 | } |
946 | } |
947 | }; |
948 | |
949 | template <class _Traits, _Trait = _Traits::__move_assignable_trait> |
950 | class _LIBCPP_TEMPLATE_VIS __move_assignment; |
951 | |
952 | #define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \ |
953 | move_assignment) \ |
954 | template <class... _Types> \ |
955 | class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \ |
956 | move_assignable_trait> \ |
957 | : public __assignment<__traits<_Types...>> { \ |
958 | using __base_type = __assignment<__traits<_Types...>>; \ |
959 | \ |
960 | public: \ |
961 | using __base_type::__base_type; \ |
962 | using __base_type::operator=; \ |
963 | \ |
964 | __move_assignment(const __move_assignment&) = default; \ |
965 | __move_assignment(__move_assignment&&) = default; \ |
966 | ~__move_assignment() = default; \ |
967 | __move_assignment& operator=(const __move_assignment&) = default; \ |
968 | move_assignment \ |
969 | } |
970 | |
971 | _LIBCPP_VARIANT_MOVE_ASSIGNMENT( |
972 | _Trait::_TriviallyAvailable, |
973 | __move_assignment& operator=(__move_assignment&& __that) = default;); |
974 | |
975 | _LIBCPP_VARIANT_MOVE_ASSIGNMENT( |
976 | _Trait::_Available, |
977 | __move_assignment& operator=(__move_assignment&& __that) noexcept( |
978 | __all<(is_nothrow_move_constructible_v<_Types> && |
979 | is_nothrow_move_assignable_v<_Types>)...>::value) { |
980 | this->__generic_assign(_VSTD::move(__that)); |
981 | return *this; |
982 | }); |
983 | |
984 | _LIBCPP_VARIANT_MOVE_ASSIGNMENT( |
985 | _Trait::_Unavailable, |
986 | __move_assignment& operator=(__move_assignment&&) = delete;); |
987 | |
988 | #undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT |
989 | |
990 | template <class _Traits, _Trait = _Traits::__copy_assignable_trait> |
991 | class _LIBCPP_TEMPLATE_VIS __copy_assignment; |
992 | |
993 | #define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \ |
994 | copy_assignment) \ |
995 | template <class... _Types> \ |
996 | class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \ |
997 | copy_assignable_trait> \ |
998 | : public __move_assignment<__traits<_Types...>> { \ |
999 | using __base_type = __move_assignment<__traits<_Types...>>; \ |
1000 | \ |
1001 | public: \ |
1002 | using __base_type::__base_type; \ |
1003 | using __base_type::operator=; \ |
1004 | \ |
1005 | __copy_assignment(const __copy_assignment&) = default; \ |
1006 | __copy_assignment(__copy_assignment&&) = default; \ |
1007 | ~__copy_assignment() = default; \ |
1008 | copy_assignment \ |
1009 | __copy_assignment& operator=(__copy_assignment&&) = default; \ |
1010 | } |
1011 | |
1012 | _LIBCPP_VARIANT_COPY_ASSIGNMENT( |
1013 | _Trait::_TriviallyAvailable, |
1014 | __copy_assignment& operator=(const __copy_assignment& __that) = default;); |
1015 | |
1016 | _LIBCPP_VARIANT_COPY_ASSIGNMENT( |
1017 | _Trait::_Available, |
1018 | __copy_assignment& operator=(const __copy_assignment& __that) { |
1019 | this->__generic_assign(__that); |
1020 | return *this; |
1021 | }); |
1022 | |
1023 | _LIBCPP_VARIANT_COPY_ASSIGNMENT( |
1024 | _Trait::_Unavailable, |
1025 | __copy_assignment& operator=(const __copy_assignment&) = delete;); |
1026 | |
1027 | #undef _LIBCPP_VARIANT_COPY_ASSIGNMENT |
1028 | |
1029 | template <class... _Types> |
1030 | class _LIBCPP_TEMPLATE_VIS __impl |
1031 | : public __copy_assignment<__traits<_Types...>> { |
1032 | using __base_type = __copy_assignment<__traits<_Types...>>; |
1033 | |
1034 | public: |
1035 | using __base_type::__base_type; |
1036 | using __base_type::operator=; |
1037 | |
1038 | template <size_t _Ip, class _Arg> |
1039 | inline _LIBCPP_INLINE_VISIBILITY |
1040 | void __assign(_Arg&& __arg) { |
1041 | this->__assign_alt(__access::__base::__get_alt<_Ip>(*this), |
1042 | _VSTD::forward<_Arg>(__arg)); |
1043 | } |
1044 | |
1045 | inline _LIBCPP_INLINE_VISIBILITY |
1046 | void __swap(__impl& __that) { |
1047 | if (this->valueless_by_exception() && __that.valueless_by_exception()) { |
1048 | // do nothing. |
1049 | } else if (this->index() == __that.index()) { |
1050 | __visitation::__base::__visit_alt_at( |
1051 | this->index(), |
1052 | [](auto& __this_alt, auto& __that_alt) { |
1053 | using _VSTD::swap; |
1054 | swap(__this_alt.__value, __that_alt.__value); |
1055 | }, |
1056 | *this, |
1057 | __that); |
1058 | } else { |
1059 | __impl* __lhs = this; |
1060 | __impl* __rhs = _VSTD::addressof(__that); |
1061 | if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) { |
1062 | _VSTD::swap(__lhs, __rhs); |
1063 | } |
1064 | __impl __tmp(_VSTD::move(*__rhs)); |
1065 | #ifndef _LIBCPP_NO_EXCEPTIONS |
1066 | // EXTENSION: When the move construction of `__lhs` into `__rhs` throws |
1067 | // and `__tmp` is nothrow move constructible then we move `__tmp` back |
1068 | // into `__rhs` and provide the strong exception safety guarantee. |
1069 | try { |
1070 | this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); |
1071 | } catch (...) { |
1072 | if (__tmp.__move_nothrow()) { |
1073 | this->__generic_construct(*__rhs, _VSTD::move(__tmp)); |
1074 | } |
1075 | throw; |
1076 | } |
1077 | #else |
1078 | this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); |
1079 | #endif |
1080 | this->__generic_construct(*__lhs, _VSTD::move(__tmp)); |
1081 | } |
1082 | } |
1083 | |
1084 | private: |
1085 | inline _LIBCPP_INLINE_VISIBILITY |
1086 | bool __move_nothrow() const { |
1087 | constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...}; |
1088 | return this->valueless_by_exception() || __results[this->index()]; |
1089 | } |
1090 | }; |
1091 | |
1092 | struct __no_narrowing_check { |
1093 | template <class _Dest, class _Source> |
1094 | using _Apply = __identity<_Dest>; |
1095 | }; |
1096 | |
1097 | struct __narrowing_check { |
1098 | template <class _Dest> |
1099 | static auto __test_impl(_Dest (&&)[1]) -> __identity<_Dest>; |
1100 | template <class _Dest, class _Source> |
1101 | using _Apply _LIBCPP_NODEBUG_TYPE = decltype(__test_impl<_Dest>({std::declval<_Source>()})); |
1102 | }; |
1103 | |
1104 | template <class _Dest, class _Source> |
1105 | using __check_for_narrowing _LIBCPP_NODEBUG_TYPE = |
1106 | typename _If< |
1107 | #ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT |
1108 | false && |
1109 | #endif |
1110 | is_arithmetic<_Dest>::value, |
1111 | __narrowing_check, |
1112 | __no_narrowing_check |
1113 | >::template _Apply<_Dest, _Source>; |
1114 | |
1115 | template <class _Tp, size_t _Idx> |
1116 | struct __overload { |
1117 | template <class _Up> |
1118 | auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>; |
1119 | }; |
1120 | |
1121 | template <class _Tp, size_t> |
1122 | struct __overload_bool { |
1123 | template <class _Up, class _Ap = __uncvref_t<_Up>> |
1124 | auto operator()(bool, _Up&&) const |
1125 | -> enable_if_t<is_same_v<_Ap, bool>, __identity<_Tp>>; |
1126 | }; |
1127 | |
1128 | template <size_t _Idx> |
1129 | struct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {}; |
1130 | template <size_t _Idx> |
1131 | struct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {}; |
1132 | template <size_t _Idx> |
1133 | struct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {}; |
1134 | template <size_t _Idx> |
1135 | struct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {}; |
1136 | |
1137 | template <class ..._Bases> |
1138 | struct __all_overloads : _Bases... { |
1139 | void operator()() const; |
1140 | using _Bases::operator()...; |
1141 | }; |
1142 | |
1143 | template <class IdxSeq> |
1144 | struct __make_overloads_imp; |
1145 | |
1146 | template <size_t ..._Idx> |
1147 | struct __make_overloads_imp<__tuple_indices<_Idx...> > { |
1148 | template <class ..._Types> |
1149 | using _Apply _LIBCPP_NODEBUG_TYPE = __all_overloads<__overload<_Types, _Idx>...>; |
1150 | }; |
1151 | |
1152 | template <class ..._Types> |
1153 | using _MakeOverloads _LIBCPP_NODEBUG_TYPE = typename __make_overloads_imp< |
1154 | __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>; |
1155 | |
1156 | template <class _Tp, class... _Types> |
1157 | using __best_match_t = |
1158 | typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type; |
1159 | |
1160 | } // __variant_detail |
1161 | |
1162 | template <class... _Types> |
1163 | class _LIBCPP_TEMPLATE_VIS variant |
1164 | : private __sfinae_ctor_base< |
1165 | __all<is_copy_constructible_v<_Types>...>::value, |
1166 | __all<is_move_constructible_v<_Types>...>::value>, |
1167 | private __sfinae_assign_base< |
1168 | __all<(is_copy_constructible_v<_Types> && |
1169 | is_copy_assignable_v<_Types>)...>::value, |
1170 | __all<(is_move_constructible_v<_Types> && |
1171 | is_move_assignable_v<_Types>)...>::value> { |
1172 | static_assert(0 < sizeof...(_Types), |
1173 | "variant must consist of at least one alternative." ); |
1174 | |
1175 | static_assert(__all<!is_array_v<_Types>...>::value, |
1176 | "variant can not have an array type as an alternative." ); |
1177 | |
1178 | static_assert(__all<!is_reference_v<_Types>...>::value, |
1179 | "variant can not have a reference type as an alternative." ); |
1180 | |
1181 | static_assert(__all<!is_void_v<_Types>...>::value, |
1182 | "variant can not have a void type as an alternative." ); |
1183 | |
1184 | using __first_type = variant_alternative_t<0, variant>; |
1185 | |
1186 | public: |
1187 | template <bool _Dummy = true, |
1188 | enable_if_t<__dependent_type<is_default_constructible<__first_type>, |
1189 | _Dummy>::value, |
1190 | int> = 0> |
1191 | inline _LIBCPP_INLINE_VISIBILITY |
1192 | constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>) |
1193 | : __impl(in_place_index<0>) {} |
1194 | |
1195 | variant(const variant&) = default; |
1196 | variant(variant&&) = default; |
1197 | |
1198 | template < |
1199 | class _Arg, |
1200 | enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0, |
1201 | enable_if_t<!__is_inplace_type<__uncvref_t<_Arg>>::value, int> = 0, |
1202 | enable_if_t<!__is_inplace_index<__uncvref_t<_Arg>>::value, int> = 0, |
1203 | class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, |
1204 | size_t _Ip = |
1205 | __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, |
1206 | enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0> |
1207 | inline _LIBCPP_INLINE_VISIBILITY |
1208 | constexpr variant(_Arg&& __arg) noexcept( |
1209 | is_nothrow_constructible_v<_Tp, _Arg>) |
1210 | : __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {} |
1211 | |
1212 | template <size_t _Ip, class... _Args, |
1213 | class = enable_if_t<(_Ip < sizeof...(_Types)), int>, |
1214 | class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, |
1215 | enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> |
1216 | inline _LIBCPP_INLINE_VISIBILITY |
1217 | explicit constexpr variant( |
1218 | in_place_index_t<_Ip>, |
1219 | _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>) |
1220 | : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {} |
1221 | |
1222 | template < |
1223 | size_t _Ip, |
1224 | class _Up, |
1225 | class... _Args, |
1226 | enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, |
1227 | class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, |
1228 | enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, |
1229 | int> = 0> |
1230 | inline _LIBCPP_INLINE_VISIBILITY |
1231 | explicit constexpr variant( |
1232 | in_place_index_t<_Ip>, |
1233 | initializer_list<_Up> __il, |
1234 | _Args&&... __args) noexcept( |
1235 | is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) |
1236 | : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {} |
1237 | |
1238 | template < |
1239 | class _Tp, |
1240 | class... _Args, |
1241 | size_t _Ip = |
1242 | __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, |
1243 | enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> |
1244 | inline _LIBCPP_INLINE_VISIBILITY |
1245 | explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept( |
1246 | is_nothrow_constructible_v<_Tp, _Args...>) |
1247 | : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {} |
1248 | |
1249 | template < |
1250 | class _Tp, |
1251 | class _Up, |
1252 | class... _Args, |
1253 | size_t _Ip = |
1254 | __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, |
1255 | enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, |
1256 | int> = 0> |
1257 | inline _LIBCPP_INLINE_VISIBILITY |
1258 | explicit constexpr variant( |
1259 | in_place_type_t<_Tp>, |
1260 | initializer_list<_Up> __il, |
1261 | _Args&&... __args) noexcept( |
1262 | is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>) |
1263 | : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {} |
1264 | |
1265 | ~variant() = default; |
1266 | |
1267 | variant& operator=(const variant&) = default; |
1268 | variant& operator=(variant&&) = default; |
1269 | |
1270 | template < |
1271 | class _Arg, |
1272 | enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0, |
1273 | class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, |
1274 | size_t _Ip = |
1275 | __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, |
1276 | enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>, |
1277 | int> = 0> |
1278 | inline _LIBCPP_INLINE_VISIBILITY |
1279 | variant& operator=(_Arg&& __arg) noexcept( |
1280 | is_nothrow_assignable_v<_Tp&, _Arg> && |
1281 | is_nothrow_constructible_v<_Tp, _Arg>) { |
1282 | __impl.template __assign<_Ip>(_VSTD::forward<_Arg>(__arg)); |
1283 | return *this; |
1284 | } |
1285 | |
1286 | template < |
1287 | size_t _Ip, |
1288 | class... _Args, |
1289 | enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, |
1290 | class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, |
1291 | enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> |
1292 | inline _LIBCPP_INLINE_VISIBILITY |
1293 | _Tp& emplace(_Args&&... __args) { |
1294 | return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...); |
1295 | } |
1296 | |
1297 | template < |
1298 | size_t _Ip, |
1299 | class _Up, |
1300 | class... _Args, |
1301 | enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, |
1302 | class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, |
1303 | enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, |
1304 | int> = 0> |
1305 | inline _LIBCPP_INLINE_VISIBILITY |
1306 | _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) { |
1307 | return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...); |
1308 | } |
1309 | |
1310 | template < |
1311 | class _Tp, |
1312 | class... _Args, |
1313 | size_t _Ip = |
1314 | __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, |
1315 | enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> |
1316 | inline _LIBCPP_INLINE_VISIBILITY |
1317 | _Tp& emplace(_Args&&... __args) { |
1318 | return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...); |
1319 | } |
1320 | |
1321 | template < |
1322 | class _Tp, |
1323 | class _Up, |
1324 | class... _Args, |
1325 | size_t _Ip = |
1326 | __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, |
1327 | enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, |
1328 | int> = 0> |
1329 | inline _LIBCPP_INLINE_VISIBILITY |
1330 | _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) { |
1331 | return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...); |
1332 | } |
1333 | |
1334 | inline _LIBCPP_INLINE_VISIBILITY |
1335 | constexpr bool valueless_by_exception() const noexcept { |
1336 | return __impl.valueless_by_exception(); |
1337 | } |
1338 | |
1339 | inline _LIBCPP_INLINE_VISIBILITY |
1340 | constexpr size_t index() const noexcept { return __impl.index(); } |
1341 | |
1342 | template < |
1343 | bool _Dummy = true, |
1344 | enable_if_t< |
1345 | __all<( |
1346 | __dependent_type<is_move_constructible<_Types>, _Dummy>::value && |
1347 | __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value, |
1348 | int> = 0> |
1349 | inline _LIBCPP_INLINE_VISIBILITY |
1350 | void swap(variant& __that) noexcept( |
1351 | __all<(is_nothrow_move_constructible_v<_Types> && |
1352 | is_nothrow_swappable_v<_Types>)...>::value) { |
1353 | __impl.__swap(__that.__impl); |
1354 | } |
1355 | |
1356 | private: |
1357 | __variant_detail::__impl<_Types...> __impl; |
1358 | |
1359 | friend struct __variant_detail::__access::__variant; |
1360 | friend struct __variant_detail::__visitation::__variant; |
1361 | }; |
1362 | |
1363 | template <size_t _Ip, class... _Types> |
1364 | inline _LIBCPP_INLINE_VISIBILITY |
1365 | constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept { |
1366 | return __v.index() == _Ip; |
1367 | } |
1368 | |
1369 | template <class _Tp, class... _Types> |
1370 | inline _LIBCPP_INLINE_VISIBILITY |
1371 | constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept { |
1372 | return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v); |
1373 | } |
1374 | |
1375 | template <size_t _Ip, class _Vp> |
1376 | inline _LIBCPP_INLINE_VISIBILITY |
1377 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
1378 | constexpr auto&& __generic_get(_Vp&& __v) { |
1379 | using __variant_detail::__access::__variant; |
1380 | if (!__holds_alternative<_Ip>(__v)) { |
1381 | __throw_bad_variant_access(); |
1382 | } |
1383 | return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value; |
1384 | } |
1385 | |
1386 | template <size_t _Ip, class... _Types> |
1387 | inline _LIBCPP_INLINE_VISIBILITY |
1388 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
1389 | constexpr variant_alternative_t<_Ip, variant<_Types...>>& get( |
1390 | variant<_Types...>& __v) { |
1391 | static_assert(_Ip < sizeof...(_Types)); |
1392 | static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); |
1393 | return __generic_get<_Ip>(__v); |
1394 | } |
1395 | |
1396 | template <size_t _Ip, class... _Types> |
1397 | inline _LIBCPP_INLINE_VISIBILITY |
1398 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
1399 | constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get( |
1400 | variant<_Types...>&& __v) { |
1401 | static_assert(_Ip < sizeof...(_Types)); |
1402 | static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); |
1403 | return __generic_get<_Ip>(_VSTD::move(__v)); |
1404 | } |
1405 | |
1406 | template <size_t _Ip, class... _Types> |
1407 | inline _LIBCPP_INLINE_VISIBILITY |
1408 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
1409 | constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get( |
1410 | const variant<_Types...>& __v) { |
1411 | static_assert(_Ip < sizeof...(_Types)); |
1412 | static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); |
1413 | return __generic_get<_Ip>(__v); |
1414 | } |
1415 | |
1416 | template <size_t _Ip, class... _Types> |
1417 | inline _LIBCPP_INLINE_VISIBILITY |
1418 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
1419 | constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get( |
1420 | const variant<_Types...>&& __v) { |
1421 | static_assert(_Ip < sizeof...(_Types)); |
1422 | static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); |
1423 | return __generic_get<_Ip>(_VSTD::move(__v)); |
1424 | } |
1425 | |
1426 | template <class _Tp, class... _Types> |
1427 | inline _LIBCPP_INLINE_VISIBILITY |
1428 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
1429 | constexpr _Tp& get(variant<_Types...>& __v) { |
1430 | static_assert(!is_void_v<_Tp>); |
1431 | return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); |
1432 | } |
1433 | |
1434 | template <class _Tp, class... _Types> |
1435 | inline _LIBCPP_INLINE_VISIBILITY |
1436 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
1437 | constexpr _Tp&& get(variant<_Types...>&& __v) { |
1438 | static_assert(!is_void_v<_Tp>); |
1439 | return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>( |
1440 | _VSTD::move(__v)); |
1441 | } |
1442 | |
1443 | template <class _Tp, class... _Types> |
1444 | inline _LIBCPP_INLINE_VISIBILITY |
1445 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
1446 | constexpr const _Tp& get(const variant<_Types...>& __v) { |
1447 | static_assert(!is_void_v<_Tp>); |
1448 | return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); |
1449 | } |
1450 | |
1451 | template <class _Tp, class... _Types> |
1452 | inline _LIBCPP_INLINE_VISIBILITY |
1453 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
1454 | constexpr const _Tp&& get(const variant<_Types...>&& __v) { |
1455 | static_assert(!is_void_v<_Tp>); |
1456 | return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>( |
1457 | _VSTD::move(__v)); |
1458 | } |
1459 | |
1460 | template <size_t _Ip, class _Vp> |
1461 | inline _LIBCPP_INLINE_VISIBILITY |
1462 | constexpr auto* __generic_get_if(_Vp* __v) noexcept { |
1463 | using __variant_detail::__access::__variant; |
1464 | return __v && __holds_alternative<_Ip>(*__v) |
1465 | ? _VSTD::addressof(__variant::__get_alt<_Ip>(*__v).__value) |
1466 | : nullptr; |
1467 | } |
1468 | |
1469 | template <size_t _Ip, class... _Types> |
1470 | inline _LIBCPP_INLINE_VISIBILITY |
1471 | constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>> |
1472 | get_if(variant<_Types...>* __v) noexcept { |
1473 | static_assert(_Ip < sizeof...(_Types)); |
1474 | static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); |
1475 | return __generic_get_if<_Ip>(__v); |
1476 | } |
1477 | |
1478 | template <size_t _Ip, class... _Types> |
1479 | inline _LIBCPP_INLINE_VISIBILITY |
1480 | constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>> |
1481 | get_if(const variant<_Types...>* __v) noexcept { |
1482 | static_assert(_Ip < sizeof...(_Types)); |
1483 | static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); |
1484 | return __generic_get_if<_Ip>(__v); |
1485 | } |
1486 | |
1487 | template <class _Tp, class... _Types> |
1488 | inline _LIBCPP_INLINE_VISIBILITY |
1489 | constexpr add_pointer_t<_Tp> |
1490 | get_if(variant<_Types...>* __v) noexcept { |
1491 | static_assert(!is_void_v<_Tp>); |
1492 | return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v); |
1493 | } |
1494 | |
1495 | template <class _Tp, class... _Types> |
1496 | inline _LIBCPP_INLINE_VISIBILITY |
1497 | constexpr add_pointer_t<const _Tp> |
1498 | get_if(const variant<_Types...>* __v) noexcept { |
1499 | static_assert(!is_void_v<_Tp>); |
1500 | return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v); |
1501 | } |
1502 | |
1503 | template <class _Operator> |
1504 | struct __convert_to_bool { |
1505 | template <class _T1, class _T2> |
1506 | _LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const { |
1507 | static_assert(std::is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value, |
1508 | "the relational operator does not return a type which is implicitly convertible to bool" ); |
1509 | return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2)); |
1510 | } |
1511 | }; |
1512 | |
1513 | template <class... _Types> |
1514 | inline _LIBCPP_INLINE_VISIBILITY |
1515 | constexpr bool operator==(const variant<_Types...>& __lhs, |
1516 | const variant<_Types...>& __rhs) { |
1517 | using __variant_detail::__visitation::__variant; |
1518 | if (__lhs.index() != __rhs.index()) return false; |
1519 | if (__lhs.valueless_by_exception()) return true; |
1520 | return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs); |
1521 | } |
1522 | |
1523 | template <class... _Types> |
1524 | inline _LIBCPP_INLINE_VISIBILITY |
1525 | constexpr bool operator!=(const variant<_Types...>& __lhs, |
1526 | const variant<_Types...>& __rhs) { |
1527 | using __variant_detail::__visitation::__variant; |
1528 | if (__lhs.index() != __rhs.index()) return true; |
1529 | if (__lhs.valueless_by_exception()) return false; |
1530 | return __variant::__visit_value_at( |
1531 | __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs); |
1532 | } |
1533 | |
1534 | template <class... _Types> |
1535 | inline _LIBCPP_INLINE_VISIBILITY |
1536 | constexpr bool operator<(const variant<_Types...>& __lhs, |
1537 | const variant<_Types...>& __rhs) { |
1538 | using __variant_detail::__visitation::__variant; |
1539 | if (__rhs.valueless_by_exception()) return false; |
1540 | if (__lhs.valueless_by_exception()) return true; |
1541 | if (__lhs.index() < __rhs.index()) return true; |
1542 | if (__lhs.index() > __rhs.index()) return false; |
1543 | return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs); |
1544 | } |
1545 | |
1546 | template <class... _Types> |
1547 | inline _LIBCPP_INLINE_VISIBILITY |
1548 | constexpr bool operator>(const variant<_Types...>& __lhs, |
1549 | const variant<_Types...>& __rhs) { |
1550 | using __variant_detail::__visitation::__variant; |
1551 | if (__lhs.valueless_by_exception()) return false; |
1552 | if (__rhs.valueless_by_exception()) return true; |
1553 | if (__lhs.index() > __rhs.index()) return true; |
1554 | if (__lhs.index() < __rhs.index()) return false; |
1555 | return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs); |
1556 | } |
1557 | |
1558 | template <class... _Types> |
1559 | inline _LIBCPP_INLINE_VISIBILITY |
1560 | constexpr bool operator<=(const variant<_Types...>& __lhs, |
1561 | const variant<_Types...>& __rhs) { |
1562 | using __variant_detail::__visitation::__variant; |
1563 | if (__lhs.valueless_by_exception()) return true; |
1564 | if (__rhs.valueless_by_exception()) return false; |
1565 | if (__lhs.index() < __rhs.index()) return true; |
1566 | if (__lhs.index() > __rhs.index()) return false; |
1567 | return __variant::__visit_value_at( |
1568 | __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs); |
1569 | } |
1570 | |
1571 | template <class... _Types> |
1572 | inline _LIBCPP_INLINE_VISIBILITY |
1573 | constexpr bool operator>=(const variant<_Types...>& __lhs, |
1574 | const variant<_Types...>& __rhs) { |
1575 | using __variant_detail::__visitation::__variant; |
1576 | if (__rhs.valueless_by_exception()) return true; |
1577 | if (__lhs.valueless_by_exception()) return false; |
1578 | if (__lhs.index() > __rhs.index()) return true; |
1579 | if (__lhs.index() < __rhs.index()) return false; |
1580 | return __variant::__visit_value_at( |
1581 | __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs); |
1582 | } |
1583 | |
1584 | template <class _Visitor, class... _Vs> |
1585 | inline _LIBCPP_INLINE_VISIBILITY |
1586 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
1587 | constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) { |
1588 | using __variant_detail::__visitation::__variant; |
1589 | bool __results[] = {__vs.valueless_by_exception()...}; |
1590 | for (bool __result : __results) { |
1591 | if (__result) { |
1592 | __throw_bad_variant_access(); |
1593 | } |
1594 | } |
1595 | return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor), |
1596 | _VSTD::forward<_Vs>(__vs)...); |
1597 | } |
1598 | |
1599 | struct _LIBCPP_TEMPLATE_VIS monostate {}; |
1600 | |
1601 | inline _LIBCPP_INLINE_VISIBILITY |
1602 | constexpr bool operator<(monostate, monostate) noexcept { return false; } |
1603 | |
1604 | inline _LIBCPP_INLINE_VISIBILITY |
1605 | constexpr bool operator>(monostate, monostate) noexcept { return false; } |
1606 | |
1607 | inline _LIBCPP_INLINE_VISIBILITY |
1608 | constexpr bool operator<=(monostate, monostate) noexcept { return true; } |
1609 | |
1610 | inline _LIBCPP_INLINE_VISIBILITY |
1611 | constexpr bool operator>=(monostate, monostate) noexcept { return true; } |
1612 | |
1613 | inline _LIBCPP_INLINE_VISIBILITY |
1614 | constexpr bool operator==(monostate, monostate) noexcept { return true; } |
1615 | |
1616 | inline _LIBCPP_INLINE_VISIBILITY |
1617 | constexpr bool operator!=(monostate, monostate) noexcept { return false; } |
1618 | |
1619 | template <class... _Types> |
1620 | inline _LIBCPP_INLINE_VISIBILITY |
1621 | auto swap(variant<_Types...>& __lhs, |
1622 | variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs))) |
1623 | -> decltype(__lhs.swap(__rhs)) { |
1624 | __lhs.swap(__rhs); |
1625 | } |
1626 | |
1627 | template <class... _Types> |
1628 | struct _LIBCPP_TEMPLATE_VIS hash< |
1629 | __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> { |
1630 | using argument_type = variant<_Types...>; |
1631 | using result_type = size_t; |
1632 | |
1633 | inline _LIBCPP_INLINE_VISIBILITY |
1634 | result_type operator()(const argument_type& __v) const { |
1635 | using __variant_detail::__visitation::__variant; |
1636 | size_t __res = |
1637 | __v.valueless_by_exception() |
1638 | ? 299792458 // Random value chosen by the universe upon creation |
1639 | : __variant::__visit_alt( |
1640 | [](const auto& __alt) { |
1641 | using __alt_type = __uncvref_t<decltype(__alt)>; |
1642 | using __value_type = remove_const_t< |
1643 | typename __alt_type::__value_type>; |
1644 | return hash<__value_type>{}(__alt.__value); |
1645 | }, |
1646 | __v); |
1647 | return __hash_combine(__res, hash<size_t>{}(__v.index())); |
1648 | } |
1649 | }; |
1650 | |
1651 | template <> |
1652 | struct _LIBCPP_TEMPLATE_VIS hash<monostate> { |
1653 | using argument_type = monostate; |
1654 | using result_type = size_t; |
1655 | |
1656 | inline _LIBCPP_INLINE_VISIBILITY |
1657 | result_type operator()(const argument_type&) const _NOEXCEPT { |
1658 | return 66740831; // return a fundamentally attractive random value. |
1659 | } |
1660 | }; |
1661 | |
1662 | #endif // _LIBCPP_STD_VER > 14 |
1663 | |
1664 | _LIBCPP_END_NAMESPACE_STD |
1665 | |
1666 | _LIBCPP_POP_MACROS |
1667 | |
1668 | #endif // _LIBCPP_VARIANT |
1669 | |