blob: 4e3db1f7afbc7b08c16afe45b39a496c55b5b9fc [file] [log] [blame]
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001// -*- C++ -*-
2//===------------------------------ variant -------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// 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
Eric Fiselier94cdacc2016-12-02 23:00:05 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_VARIANT
11#define _LIBCPP_VARIANT
12
13/*
14 variant synopsis
15
16namespace 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);
Louis Dionnecee59012019-01-10 20:06:11 +000025 variant(const variant&); // constexpr in C++20
26 variant(variant&&) noexcept(see below); // constexpr in C++20
Eric Fiselier94cdacc2016-12-02 23:00:05 +000027
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
Louis Dionnecee59012019-01-10 20:06:11 +000048 variant& operator=(const variant&); // constexpr in C++20
49 variant& operator=(variant&&) noexcept(see below); // constexpr in C++20
Eric Fiselier94cdacc2016-12-02 23:00:05 +000050
51 template <class T> variant& operator=(T&&) noexcept(see below);
52
53 // 20.7.2.4, modifiers
54 template <class T, class... Args>
Eric Fiselier62928442017-04-15 19:32:02 +000055 T& emplace(Args&&...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +000056
57 template <class T, class U, class... Args>
Eric Fiselier62928442017-04-15 19:32:02 +000058 T& emplace(initializer_list<U>, Args&&...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +000059
60 template <size_t I, class... Args>
Eric Fiselier62928442017-04-15 19:32:02 +000061 variant_alternative_t<I, variant>& emplace(Args&&...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +000062
63 template <size_t I, class U, class... Args>
Eric Fiselier62928442017-04-15 19:32:02 +000064 variant_alternative_t<I, variant>& emplace(initializer_list<U>, Args&&...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +000065
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>
Marshall Clowf1bf62f2018-01-02 17:17:01 +000078 inline constexpr size_t variant_size_v = variant_size<T>::value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +000079
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
Marshall Clowf1bf62f2018-01-02 17:17:01 +000099 inline constexpr size_t variant_npos = -1;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000100
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
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500172 template <class R, class Visitor, class... Variants>
173 constexpr R visit(Visitor&&, Variants&&...); // since C++20
174
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000175 // 20.7.7, class monostate
176 struct monostate;
177
178 // 20.7.8, monostate relational operators
179 constexpr bool operator<(monostate, monostate) noexcept;
180 constexpr bool operator>(monostate, monostate) noexcept;
181 constexpr bool operator<=(monostate, monostate) noexcept;
182 constexpr bool operator>=(monostate, monostate) noexcept;
183 constexpr bool operator==(monostate, monostate) noexcept;
184 constexpr bool operator!=(monostate, monostate) noexcept;
185
186 // 20.7.9, specialized algorithms
187 template <class... Types>
188 void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
189
190 // 20.7.10, class bad_variant_access
191 class bad_variant_access;
192
193 // 20.7.11, hash support
194 template <class T> struct hash;
195 template <class... Types> struct hash<variant<Types...>>;
196 template <> struct hash<monostate>;
197
198} // namespace std
199
200*/
201
202#include <__config>
Louis Dionne73912b22020-11-04 15:01:25 -0500203#include <__availability>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000204#include <__tuple>
205#include <array>
206#include <exception>
207#include <functional>
208#include <initializer_list>
209#include <new>
210#include <tuple>
211#include <type_traits>
212#include <utility>
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000213#include <limits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000214#include <version>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000215
216#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
217#pragma GCC system_header
218#endif
219
Eric Fiselier8625d332017-11-19 04:57:22 +0000220_LIBCPP_PUSH_MACROS
221#include <__undef_macros>
222
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000223namespace std { // explicitly not using versioning namespace
224
Louis Dionnecef92e62018-11-19 15:37:04 +0000225class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000226public:
Saleem Abdulrasool5ee83382016-12-31 17:34:26 +0000227 virtual const char* what() const _NOEXCEPT;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000228};
229
230} // namespace std
231
232_LIBCPP_BEGIN_NAMESPACE_STD
233
Louis Dionne7202cd62020-07-22 15:24:16 -0400234// TODO: GCC 5 lies about its support for C++17 (it says it supports it but it
235// really doesn't). That breaks variant, which uses some C++17 features.
236// Remove this once we drop support for GCC 5.
Louis Dionne129391d2020-07-22 15:59:09 -0400237#if _LIBCPP_STD_VER > 14 && !(defined(_LIBCPP_COMPILER_GCC) && _GNUC_VER_NEW < 6000)
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000238
Eric Fiselier10642ea2016-12-03 01:58:07 +0000239_LIBCPP_NORETURN
240inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +0000241_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier10642ea2016-12-03 01:58:07 +0000242void __throw_bad_variant_access() {
243#ifndef _LIBCPP_NO_EXCEPTIONS
244 throw bad_variant_access();
245#else
246 _VSTD::abort();
247#endif
248}
249
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000250template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000251class _LIBCPP_TEMPLATE_VIS variant;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000252
253template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000254struct _LIBCPP_TEMPLATE_VIS variant_size;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000255
256template <class _Tp>
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000257_LIBCPP_INLINE_VAR constexpr size_t variant_size_v = variant_size<_Tp>::value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000258
259template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000260struct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000261
262template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000263struct _LIBCPP_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000264
265template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000266struct _LIBCPP_TEMPLATE_VIS variant_size<const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000267 : variant_size<_Tp> {};
268
269template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000270struct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000271 : integral_constant<size_t, sizeof...(_Types)> {};
272
273template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000274struct _LIBCPP_TEMPLATE_VIS variant_alternative;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000275
276template <size_t _Ip, class _Tp>
277using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type;
278
279template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000280struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000281 : add_const<variant_alternative_t<_Ip, _Tp>> {};
282
283template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000284struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000285 : add_volatile<variant_alternative_t<_Ip, _Tp>> {};
286
287template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000288struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000289 : add_cv<variant_alternative_t<_Ip, _Tp>> {};
290
291template <size_t _Ip, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000292struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
Marshall Clow185577f2017-06-12 16:13:17 +0000293 static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000294 using type = __type_pack_element<_Ip, _Types...>;
295};
296
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000297_LIBCPP_INLINE_VAR constexpr size_t variant_npos = static_cast<size_t>(-1);
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000298
299constexpr int __choose_index_type(unsigned int __num_elem) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500300 if (__num_elem < numeric_limits<unsigned char>::max())
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000301 return 0;
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500302 if (__num_elem < numeric_limits<unsigned short>::max())
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000303 return 1;
304 return 2;
305}
306
307template <size_t _NumAlts>
308using __variant_index_t =
309#ifndef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
310 unsigned int;
311#else
312 std::tuple_element_t<
313 __choose_index_type(_NumAlts),
314 std::tuple<unsigned char, unsigned short, unsigned int>
315 >;
316#endif
317
318template <class _IndexType>
319constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000320
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100321template <class... _Types>
322class _LIBCPP_TEMPLATE_VIS variant;
323
324template <class... _Types>
325_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&
326__as_variant(variant<_Types...>& __vs) noexcept {
327 return __vs;
328}
329
330template <class... _Types>
331_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&
332__as_variant(const variant<_Types...>& __vs) noexcept {
333 return __vs;
334}
335
336template <class... _Types>
337_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&&
338__as_variant(variant<_Types...>&& __vs) noexcept {
339 return _VSTD::move(__vs);
340}
341
342template <class... _Types>
343_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&&
344__as_variant(const variant<_Types...>&& __vs) noexcept {
345 return _VSTD::move(__vs);
346}
347
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000348namespace __find_detail {
349
350template <class _Tp, class... _Types>
351inline _LIBCPP_INLINE_VISIBILITY
352constexpr size_t __find_index() {
353 constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};
354 size_t __result = __not_found;
355 for (size_t __i = 0; __i < sizeof...(_Types); ++__i) {
356 if (__matches[__i]) {
357 if (__result != __not_found) {
358 return __ambiguous;
359 }
360 __result = __i;
361 }
362 }
363 return __result;
364}
365
366template <size_t _Index>
367struct __find_unambiguous_index_sfinae_impl
368 : integral_constant<size_t, _Index> {};
369
370template <>
371struct __find_unambiguous_index_sfinae_impl<__not_found> {};
372
373template <>
374struct __find_unambiguous_index_sfinae_impl<__ambiguous> {};
375
376template <class _Tp, class... _Types>
377struct __find_unambiguous_index_sfinae
378 : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {};
379
380} // namespace __find_detail
381
382namespace __variant_detail {
383
384struct __valueless_t {};
385
386enum class _Trait { _TriviallyAvailable, _Available, _Unavailable };
387
Eric Fiselier87994112020-11-17 17:34:23 -0500388template <typename _Tp,
389 template <typename> class _IsTriviallyAvailable,
390 template <typename> class _IsAvailable>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000391constexpr _Trait __trait =
392 _IsTriviallyAvailable<_Tp>::value
393 ? _Trait::_TriviallyAvailable
394 : _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable;
395
396inline _LIBCPP_INLINE_VISIBILITY
397constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
398 _Trait __result = _Trait::_TriviallyAvailable;
399 for (_Trait __t : __traits) {
400 if (static_cast<int>(__t) > static_cast<int>(__result)) {
401 __result = __t;
402 }
403 }
404 return __result;
405}
406
Eric Fiselier87994112020-11-17 17:34:23 -0500407template <typename... _Types>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000408struct __traits {
409 static constexpr _Trait __copy_constructible_trait =
410 __common_trait({__trait<_Types,
411 is_trivially_copy_constructible,
412 is_copy_constructible>...});
413
414 static constexpr _Trait __move_constructible_trait =
415 __common_trait({__trait<_Types,
416 is_trivially_move_constructible,
417 is_move_constructible>...});
418
419 static constexpr _Trait __copy_assignable_trait = __common_trait(
420 {__copy_constructible_trait,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000421 __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});
422
423 static constexpr _Trait __move_assignable_trait = __common_trait(
424 {__move_constructible_trait,
425 __trait<_Types, is_trivially_move_assignable, is_move_assignable>...});
426
427 static constexpr _Trait __destructible_trait = __common_trait(
428 {__trait<_Types, is_trivially_destructible, is_destructible>...});
429};
430
431namespace __access {
432
433struct __union {
434 template <class _Vp>
435 inline _LIBCPP_INLINE_VISIBILITY
436 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {
437 return _VSTD::forward<_Vp>(__v).__head;
438 }
439
440 template <class _Vp, size_t _Ip>
441 inline _LIBCPP_INLINE_VISIBILITY
442 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {
443 return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);
444 }
445};
446
447struct __base {
448 template <size_t _Ip, class _Vp>
449 inline _LIBCPP_INLINE_VISIBILITY
450 static constexpr auto&& __get_alt(_Vp&& __v) {
451 return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data,
452 in_place_index<_Ip>);
453 }
454};
455
456struct __variant {
457 template <size_t _Ip, class _Vp>
458 inline _LIBCPP_INLINE_VISIBILITY
459 static constexpr auto&& __get_alt(_Vp&& __v) {
460 return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl);
461 }
462};
463
464} // namespace __access
465
466namespace __visitation {
467
468struct __base {
Eric Fiselier87994112020-11-17 17:34:23 -0500469 template <class _Visitor, class... _Vs>
470 inline _LIBCPP_INLINE_VISIBILITY
471 static constexpr decltype(auto)
472 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
473 constexpr auto __fdiagonal =
474 __make_fdiagonal<_Visitor&&,
475 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
476 return __fdiagonal[__index](_VSTD::forward<_Visitor>(__visitor),
477 _VSTD::forward<_Vs>(__vs).__as_base()...);
478 }
479
480 template <class _Visitor, class... _Vs>
481 inline _LIBCPP_INLINE_VISIBILITY
482 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
483 _Vs&&... __vs) {
484 constexpr auto __fmatrix =
485 __make_fmatrix<_Visitor&&,
486 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
487 return __at(__fmatrix, __vs.index()...)(
488 _VSTD::forward<_Visitor>(__visitor),
489 _VSTD::forward<_Vs>(__vs).__as_base()...);
490 }
491
492private:
493 template <class _Tp>
494 inline _LIBCPP_INLINE_VISIBILITY
495 static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; }
496
497 template <class _Tp, size_t _Np, typename... _Indices>
498 inline _LIBCPP_INLINE_VISIBILITY
499 static constexpr auto&& __at(const array<_Tp, _Np>& __elems,
500 size_t __index, _Indices... __indices) {
501 return __at(__elems[__index], __indices...);
502 }
503
504 template <class _Fp, class... _Fs>
505 static constexpr void __std_visit_visitor_return_type_check() {
506 static_assert(
507 __all<is_same_v<_Fp, _Fs>...>::value,
508 "`std::visit` requires the visitor to have a single return type.");
509 }
510
511 template <class... _Fs>
512 inline _LIBCPP_INLINE_VISIBILITY
513 static constexpr auto __make_farray(_Fs&&... __fs) {
514 __std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>();
515 using __result = array<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>;
516 return __result{{_VSTD::forward<_Fs>(__fs)...}};
517 }
518
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500519 template <size_t... _Is>
Eric Fiselier87994112020-11-17 17:34:23 -0500520 struct __dispatcher {
521 template <class _Fp, class... _Vs>
Michael Park32334da2020-08-30 12:42:35 -0400522 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500523 static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {
Arthur O'Dwyerf0bff152020-11-24 09:59:26 -0500524 return _VSTD::__invoke_constexpr(
Eric Fiselier87994112020-11-17 17:34:23 -0500525 static_cast<_Fp>(__f),
526 __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...);
Michael Park32334da2020-08-30 12:42:35 -0400527 }
528 };
529
Eric Fiselier87994112020-11-17 17:34:23 -0500530 template <class _Fp, class... _Vs, size_t... _Is>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000531 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500532 static constexpr auto __make_dispatch(index_sequence<_Is...>) {
533 return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000534 }
535
Eric Fiselier87994112020-11-17 17:34:23 -0500536 template <size_t _Ip, class _Fp, class... _Vs>
537 inline _LIBCPP_INLINE_VISIBILITY
538 static constexpr auto __make_fdiagonal_impl() {
539 return __make_dispatch<_Fp, _Vs...>(
540 index_sequence<(__identity<_Vs>{}, _Ip)...>{});
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000541 }
Eric Fiselier87994112020-11-17 17:34:23 -0500542
543 template <class _Fp, class... _Vs, size_t... _Is>
544 inline _LIBCPP_INLINE_VISIBILITY
545 static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) {
546 return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);
547 }
548
549 template <class _Fp, class _Vp, class... _Vs>
550 inline _LIBCPP_INLINE_VISIBILITY
551 static constexpr auto __make_fdiagonal() {
552 constexpr size_t _Np = __uncvref_t<_Vp>::__size();
553 static_assert(__all<(_Np == __uncvref_t<_Vs>::__size())...>::value);
554 return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{});
555 }
556
557 template <class _Fp, class... _Vs, size_t... _Is>
558 inline _LIBCPP_INLINE_VISIBILITY
559 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) {
560 return __make_dispatch<_Fp, _Vs...>(__is);
561 }
562
563 template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls>
564 inline _LIBCPP_INLINE_VISIBILITY
565 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>,
566 index_sequence<_Js...>,
567 _Ls... __ls) {
568 return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>(
569 index_sequence<_Is..., _Js>{}, __ls...)...);
570 }
571
572 template <class _Fp, class... _Vs>
573 inline _LIBCPP_INLINE_VISIBILITY
574 static constexpr auto __make_fmatrix() {
575 return __make_fmatrix_impl<_Fp, _Vs...>(
576 index_sequence<>{}, make_index_sequence<__uncvref_t<_Vs>::__size()>{}...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000577 }
578};
579
580struct __variant {
Eric Fiselier87994112020-11-17 17:34:23 -0500581 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000582 inline _LIBCPP_INLINE_VISIBILITY
583 static constexpr decltype(auto)
Eric Fiselier87994112020-11-17 17:34:23 -0500584 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000585 return __base::__visit_alt_at(__index,
Eric Fiselier87994112020-11-17 17:34:23 -0500586 _VSTD::forward<_Visitor>(__visitor),
587 _VSTD::forward<_Vs>(__vs).__impl...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000588 }
589
Eric Fiselier87994112020-11-17 17:34:23 -0500590 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000591 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500592 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
593 _Vs&&... __vs) {
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100594 return __base::__visit_alt(
595 _VSTD::forward<_Visitor>(__visitor),
596 _VSTD::__as_variant(_VSTD::forward<_Vs>(__vs)).__impl...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000597 }
598
Eric Fiselier87994112020-11-17 17:34:23 -0500599 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000600 inline _LIBCPP_INLINE_VISIBILITY
601 static constexpr decltype(auto)
Eric Fiselier87994112020-11-17 17:34:23 -0500602 __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
603 return __visit_alt_at(
604 __index,
605 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
606 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000607 }
608
Eric Fiselier87994112020-11-17 17:34:23 -0500609 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000610 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500611 static constexpr decltype(auto) __visit_value(_Visitor&& __visitor,
612 _Vs&&... __vs) {
613 return __visit_alt(
614 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
615 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000616 }
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100617
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500618#if _LIBCPP_STD_VER > 17
619 template <class _Rp, class _Visitor, class... _Vs>
620 inline _LIBCPP_INLINE_VISIBILITY
621 static constexpr _Rp __visit_value(_Visitor&& __visitor,
622 _Vs&&... __vs) {
623 return __visit_alt(
624 __make_value_visitor<_Rp>(_VSTD::forward<_Visitor>(__visitor)),
625 _VSTD::forward<_Vs>(__vs)...);
626 }
627#endif
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000628
629private:
Eric Fiselier87994112020-11-17 17:34:23 -0500630 template <class _Visitor, class... _Values>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000631 static constexpr void __std_visit_exhaustive_visitor_check() {
Eric Fiselier87994112020-11-17 17:34:23 -0500632 static_assert(is_invocable_v<_Visitor, _Values...>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000633 "`std::visit` requires the visitor to be exhaustive.");
634 }
635
Eric Fiselier87994112020-11-17 17:34:23 -0500636 template <class _Visitor>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000637 struct __value_visitor {
638 template <class... _Alts>
639 inline _LIBCPP_INLINE_VISIBILITY
640 constexpr decltype(auto) operator()(_Alts&&... __alts) const {
641 __std_visit_exhaustive_visitor_check<
Eric Fiselier87994112020-11-17 17:34:23 -0500642 _Visitor,
643 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
Arthur O'Dwyerf0bff152020-11-24 09:59:26 -0500644 return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000645 _VSTD::forward<_Alts>(__alts).__value...);
646 }
Eric Fiselier87994112020-11-17 17:34:23 -0500647 _Visitor&& __visitor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000648 };
649
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500650#if _LIBCPP_STD_VER > 17
651 template <class _Rp, class _Visitor>
652 struct __value_visitor_return_type {
653 template <class... _Alts>
654 inline _LIBCPP_INLINE_VISIBILITY
655 constexpr _Rp operator()(_Alts&&... __alts) const {
656 __std_visit_exhaustive_visitor_check<
657 _Visitor,
658 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
659 if constexpr (is_void_v<_Rp>) {
660 _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
661 _VSTD::forward<_Alts>(__alts).__value...);
662 }
663 else {
664 return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
665 _VSTD::forward<_Alts>(__alts).__value...);
666 }
667 }
668
669 _Visitor&& __visitor;
670 };
671#endif
672
Eric Fiselier87994112020-11-17 17:34:23 -0500673 template <class _Visitor>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000674 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500675 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
676 return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000677 }
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500678
679#if _LIBCPP_STD_VER > 17
680 template <class _Rp, class _Visitor>
681 inline _LIBCPP_INLINE_VISIBILITY
682 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
683 return __value_visitor_return_type<_Rp, _Visitor>{_VSTD::forward<_Visitor>(__visitor)};
684 }
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500685#endif
Nico Weber8aa36612021-01-25 15:10:41 -0500686};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000687
688} // namespace __visitation
689
690template <size_t _Index, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000691struct _LIBCPP_TEMPLATE_VIS __alt {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000692 using __value_type = _Tp;
693
694 template <class... _Args>
695 inline _LIBCPP_INLINE_VISIBILITY
696 explicit constexpr __alt(in_place_t, _Args&&... __args)
697 : __value(_VSTD::forward<_Args>(__args)...) {}
698
699 __value_type __value;
700};
701
702template <_Trait _DestructibleTrait, size_t _Index, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000703union _LIBCPP_TEMPLATE_VIS __union;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000704
705template <_Trait _DestructibleTrait, size_t _Index>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000706union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000707
708#define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \
709 template <size_t _Index, class _Tp, class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -0500710 union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000711 _Index, \
712 _Tp, \
713 _Types...> { \
714 public: \
715 inline _LIBCPP_INLINE_VISIBILITY \
716 explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \
717 \
718 template <class... _Args> \
719 inline _LIBCPP_INLINE_VISIBILITY \
720 explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \
721 : __head(in_place, _VSTD::forward<_Args>(__args)...) {} \
722 \
723 template <size_t _Ip, class... _Args> \
724 inline _LIBCPP_INLINE_VISIBILITY \
725 explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \
726 : __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \
727 \
728 __union(const __union&) = default; \
729 __union(__union&&) = default; \
730 \
731 destructor \
732 \
733 __union& operator=(const __union&) = default; \
734 __union& operator=(__union&&) = default; \
735 \
736 private: \
737 char __dummy; \
738 __alt<_Index, _Tp> __head; \
739 __union<destructible_trait, _Index + 1, _Types...> __tail; \
740 \
741 friend struct __access::__union; \
742 }
743
744_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;);
745_LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union() {});
746_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;);
747
748#undef _LIBCPP_VARIANT_UNION
749
750template <_Trait _DestructibleTrait, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000751class _LIBCPP_TEMPLATE_VIS __base {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000752public:
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000753 using __index_t = __variant_index_t<sizeof...(_Types)>;
754
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000755 inline _LIBCPP_INLINE_VISIBILITY
756 explicit constexpr __base(__valueless_t tag) noexcept
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000757 : __data(tag), __index(__variant_npos<__index_t>) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000758
759 template <size_t _Ip, class... _Args>
760 inline _LIBCPP_INLINE_VISIBILITY
761 explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)
Eric Fiselier2adf0872016-12-02 23:17:33 +0000762 :
763 __data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...),
764 __index(_Ip) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000765
766 inline _LIBCPP_INLINE_VISIBILITY
767 constexpr bool valueless_by_exception() const noexcept {
768 return index() == variant_npos;
769 }
770
771 inline _LIBCPP_INLINE_VISIBILITY
772 constexpr size_t index() const noexcept {
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000773 return __index == __variant_npos<__index_t> ? variant_npos : __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000774 }
775
776protected:
777 inline _LIBCPP_INLINE_VISIBILITY
778 constexpr auto&& __as_base() & { return *this; }
779
780 inline _LIBCPP_INLINE_VISIBILITY
781 constexpr auto&& __as_base() && { return _VSTD::move(*this); }
782
783 inline _LIBCPP_INLINE_VISIBILITY
784 constexpr auto&& __as_base() const & { return *this; }
785
786 inline _LIBCPP_INLINE_VISIBILITY
787 constexpr auto&& __as_base() const && { return _VSTD::move(*this); }
788
789 inline _LIBCPP_INLINE_VISIBILITY
790 static constexpr size_t __size() { return sizeof...(_Types); }
791
792 __union<_DestructibleTrait, 0, _Types...> __data;
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000793 __index_t __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000794
795 friend struct __access::__base;
796 friend struct __visitation::__base;
797};
798
799template <class _Traits, _Trait = _Traits::__destructible_trait>
Louis Dionneff05add2020-10-05 16:30:23 -0400800class _LIBCPP_TEMPLATE_VIS __dtor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000801
802#define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor, destroy) \
803 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400804 class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, \
805 destructible_trait> \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000806 : public __base<destructible_trait, _Types...> { \
807 using __base_type = __base<destructible_trait, _Types...>; \
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000808 using __index_t = typename __base_type::__index_t; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000809 \
810 public: \
811 using __base_type::__base_type; \
812 using __base_type::operator=; \
813 \
Louis Dionneff05add2020-10-05 16:30:23 -0400814 __dtor(const __dtor&) = default; \
815 __dtor(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000816 destructor \
Louis Dionneff05add2020-10-05 16:30:23 -0400817 __dtor& operator=(const __dtor&) = default; \
818 __dtor& operator=(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000819 \
820 protected: \
821 inline _LIBCPP_INLINE_VISIBILITY \
822 destroy \
823 }
824
825_LIBCPP_VARIANT_DESTRUCTOR(
826 _Trait::_TriviallyAvailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400827 ~__dtor() = default;,
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000828 void __destroy() noexcept { this->__index = __variant_npos<__index_t>; });
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000829
830_LIBCPP_VARIANT_DESTRUCTOR(
831 _Trait::_Available,
Louis Dionneff05add2020-10-05 16:30:23 -0400832 ~__dtor() { __destroy(); },
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000833 void __destroy() noexcept {
834 if (!this->valueless_by_exception()) {
835 __visitation::__base::__visit_alt(
836 [](auto& __alt) noexcept {
Marshall Clowe61ba952018-02-12 15:41:25 +0000837 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000838 __alt.~__alt_type();
839 },
840 *this);
841 }
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000842 this->__index = __variant_npos<__index_t>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000843 });
844
845_LIBCPP_VARIANT_DESTRUCTOR(
846 _Trait::_Unavailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400847 ~__dtor() = delete;,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000848 void __destroy() noexcept = delete;);
849
850#undef _LIBCPP_VARIANT_DESTRUCTOR
851
852template <class _Traits>
Louis Dionneff05add2020-10-05 16:30:23 -0400853class _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> {
854 using __base_type = __dtor<_Traits>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000855
856public:
857 using __base_type::__base_type;
858 using __base_type::operator=;
859
860protected:
861 template <size_t _Ip, class _Tp, class... _Args>
862 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000863 static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) {
Eric Fiselier87994112020-11-17 17:34:23 -0500864 ::new ((void*)_VSTD::addressof(__a))
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000865 __alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...);
Eric Fiselier87994112020-11-17 17:34:23 -0500866 return __a.__value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000867 }
868
869 template <class _Rhs>
870 inline _LIBCPP_INLINE_VISIBILITY
Louis Dionneff05add2020-10-05 16:30:23 -0400871 static void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000872 __lhs.__destroy();
873 if (!__rhs.valueless_by_exception()) {
874 __visitation::__base::__visit_alt_at(
875 __rhs.index(),
876 [](auto& __lhs_alt, auto&& __rhs_alt) {
877 __construct_alt(
878 __lhs_alt,
879 _VSTD::forward<decltype(__rhs_alt)>(__rhs_alt).__value);
880 },
881 __lhs, _VSTD::forward<_Rhs>(__rhs));
882 __lhs.__index = __rhs.index();
883 }
884 }
885};
886
887template <class _Traits, _Trait = _Traits::__move_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000888class _LIBCPP_TEMPLATE_VIS __move_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000889
890#define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, \
891 move_constructor) \
892 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400893 class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, \
894 move_constructible_trait> \
895 : public __ctor<__traits<_Types...>> { \
896 using __base_type = __ctor<__traits<_Types...>>; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000897 \
898 public: \
899 using __base_type::__base_type; \
900 using __base_type::operator=; \
901 \
902 __move_constructor(const __move_constructor&) = default; \
903 move_constructor \
904 ~__move_constructor() = default; \
905 __move_constructor& operator=(const __move_constructor&) = default; \
906 __move_constructor& operator=(__move_constructor&&) = default; \
907 }
908
909_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
910 _Trait::_TriviallyAvailable,
911 __move_constructor(__move_constructor&& __that) = default;);
912
913_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
914 _Trait::_Available,
915 __move_constructor(__move_constructor&& __that) noexcept(
916 __all<is_nothrow_move_constructible_v<_Types>...>::value)
917 : __move_constructor(__valueless_t{}) {
918 this->__generic_construct(*this, _VSTD::move(__that));
919 });
920
921_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
922 _Trait::_Unavailable,
923 __move_constructor(__move_constructor&&) = delete;);
924
925#undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR
926
927template <class _Traits, _Trait = _Traits::__copy_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000928class _LIBCPP_TEMPLATE_VIS __copy_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000929
930#define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \
931 copy_constructor) \
932 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -0500933 class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000934 copy_constructible_trait> \
935 : public __move_constructor<__traits<_Types...>> { \
936 using __base_type = __move_constructor<__traits<_Types...>>; \
937 \
938 public: \
939 using __base_type::__base_type; \
940 using __base_type::operator=; \
941 \
942 copy_constructor \
943 __copy_constructor(__copy_constructor&&) = default; \
944 ~__copy_constructor() = default; \
945 __copy_constructor& operator=(const __copy_constructor&) = default; \
946 __copy_constructor& operator=(__copy_constructor&&) = default; \
947 }
948
949_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
950 _Trait::_TriviallyAvailable,
951 __copy_constructor(const __copy_constructor& __that) = default;);
952
953_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
954 _Trait::_Available,
955 __copy_constructor(const __copy_constructor& __that)
956 : __copy_constructor(__valueless_t{}) {
957 this->__generic_construct(*this, __that);
958 });
959
960_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
961 _Trait::_Unavailable,
962 __copy_constructor(const __copy_constructor&) = delete;);
963
964#undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR
965
966template <class _Traits>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000967class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000968 using __base_type = __copy_constructor<_Traits>;
969
970public:
971 using __base_type::__base_type;
972 using __base_type::operator=;
973
974 template <size_t _Ip, class... _Args>
975 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000976 auto& __emplace(_Args&&... __args) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000977 this->__destroy();
Eric Fiselier62928442017-04-15 19:32:02 +0000978 auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this),
Eric Fiselier87994112020-11-17 17:34:23 -0500979 _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000980 this->__index = _Ip;
Eric Fiselier62928442017-04-15 19:32:02 +0000981 return __res;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000982 }
983
984protected:
Michael Park62118352017-06-07 10:22:43 +0000985 template <size_t _Ip, class _Tp, class _Arg>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000986 inline _LIBCPP_INLINE_VISIBILITY
Michael Park62118352017-06-07 10:22:43 +0000987 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000988 if (this->index() == _Ip) {
989 __a.__value = _VSTD::forward<_Arg>(__arg);
990 } else {
991 struct {
992 void operator()(true_type) const {
Michael Park62118352017-06-07 10:22:43 +0000993 __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000994 }
995 void operator()(false_type) const {
Michael Park62118352017-06-07 10:22:43 +0000996 __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg)));
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000997 }
998 __assignment* __this;
999 _Arg&& __arg;
1000 } __impl{this, _VSTD::forward<_Arg>(__arg)};
Michael Park62118352017-06-07 10:22:43 +00001001 __impl(bool_constant<is_nothrow_constructible_v<_Tp, _Arg> ||
1002 !is_nothrow_move_constructible_v<_Tp>>{});
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001003 }
1004 }
1005
1006 template <class _That>
1007 inline _LIBCPP_INLINE_VISIBILITY
1008 void __generic_assign(_That&& __that) {
1009 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1010 // do nothing.
1011 } else if (__that.valueless_by_exception()) {
1012 this->__destroy();
1013 } else {
1014 __visitation::__base::__visit_alt_at(
1015 __that.index(),
1016 [this](auto& __this_alt, auto&& __that_alt) {
1017 this->__assign_alt(
1018 __this_alt,
Michael Park62118352017-06-07 10:22:43 +00001019 _VSTD::forward<decltype(__that_alt)>(__that_alt).__value);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001020 },
1021 *this, _VSTD::forward<_That>(__that));
1022 }
1023 }
1024};
1025
1026template <class _Traits, _Trait = _Traits::__move_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001027class _LIBCPP_TEMPLATE_VIS __move_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001028
1029#define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \
1030 move_assignment) \
1031 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -05001032 class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001033 move_assignable_trait> \
1034 : public __assignment<__traits<_Types...>> { \
1035 using __base_type = __assignment<__traits<_Types...>>; \
1036 \
1037 public: \
1038 using __base_type::__base_type; \
1039 using __base_type::operator=; \
1040 \
1041 __move_assignment(const __move_assignment&) = default; \
1042 __move_assignment(__move_assignment&&) = default; \
1043 ~__move_assignment() = default; \
1044 __move_assignment& operator=(const __move_assignment&) = default; \
1045 move_assignment \
1046 }
1047
1048_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1049 _Trait::_TriviallyAvailable,
1050 __move_assignment& operator=(__move_assignment&& __that) = default;);
1051
1052_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1053 _Trait::_Available,
1054 __move_assignment& operator=(__move_assignment&& __that) noexcept(
1055 __all<(is_nothrow_move_constructible_v<_Types> &&
1056 is_nothrow_move_assignable_v<_Types>)...>::value) {
1057 this->__generic_assign(_VSTD::move(__that));
1058 return *this;
1059 });
1060
1061_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1062 _Trait::_Unavailable,
1063 __move_assignment& operator=(__move_assignment&&) = delete;);
1064
1065#undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT
1066
1067template <class _Traits, _Trait = _Traits::__copy_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001068class _LIBCPP_TEMPLATE_VIS __copy_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001069
1070#define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \
1071 copy_assignment) \
1072 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -05001073 class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001074 copy_assignable_trait> \
1075 : public __move_assignment<__traits<_Types...>> { \
1076 using __base_type = __move_assignment<__traits<_Types...>>; \
1077 \
1078 public: \
1079 using __base_type::__base_type; \
1080 using __base_type::operator=; \
1081 \
1082 __copy_assignment(const __copy_assignment&) = default; \
1083 __copy_assignment(__copy_assignment&&) = default; \
1084 ~__copy_assignment() = default; \
1085 copy_assignment \
1086 __copy_assignment& operator=(__copy_assignment&&) = default; \
1087 }
1088
1089_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1090 _Trait::_TriviallyAvailable,
1091 __copy_assignment& operator=(const __copy_assignment& __that) = default;);
1092
1093_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1094 _Trait::_Available,
1095 __copy_assignment& operator=(const __copy_assignment& __that) {
1096 this->__generic_assign(__that);
1097 return *this;
1098 });
1099
1100_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1101 _Trait::_Unavailable,
1102 __copy_assignment& operator=(const __copy_assignment&) = delete;);
1103
1104#undef _LIBCPP_VARIANT_COPY_ASSIGNMENT
1105
1106template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001107class _LIBCPP_TEMPLATE_VIS __impl
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001108 : public __copy_assignment<__traits<_Types...>> {
1109 using __base_type = __copy_assignment<__traits<_Types...>>;
1110
1111public:
1112 using __base_type::__base_type;
1113 using __base_type::operator=;
1114
1115 template <size_t _Ip, class _Arg>
1116 inline _LIBCPP_INLINE_VISIBILITY
1117 void __assign(_Arg&& __arg) {
1118 this->__assign_alt(__access::__base::__get_alt<_Ip>(*this),
Michael Park62118352017-06-07 10:22:43 +00001119 _VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001120 }
1121
1122 inline _LIBCPP_INLINE_VISIBILITY
1123 void __swap(__impl& __that) {
1124 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1125 // do nothing.
1126 } else if (this->index() == __that.index()) {
1127 __visitation::__base::__visit_alt_at(
1128 this->index(),
1129 [](auto& __this_alt, auto& __that_alt) {
1130 using _VSTD::swap;
1131 swap(__this_alt.__value, __that_alt.__value);
1132 },
1133 *this,
1134 __that);
1135 } else {
1136 __impl* __lhs = this;
1137 __impl* __rhs = _VSTD::addressof(__that);
1138 if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) {
1139 _VSTD::swap(__lhs, __rhs);
1140 }
1141 __impl __tmp(_VSTD::move(*__rhs));
Michael Park5dee7342020-06-16 15:15:10 -07001142#ifndef _LIBCPP_NO_EXCEPTIONS
Michael Park6a9ef642020-07-08 10:46:02 -07001143 if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
Michael Park31967aa2020-06-16 13:29:23 -07001144 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1145 } else {
1146 // EXTENSION: When the move construction of `__lhs` into `__rhs` throws
1147 // and `__tmp` is nothrow move constructible then we move `__tmp` back
1148 // into `__rhs` and provide the strong exception safety guarantee.
1149 try {
1150 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1151 } catch (...) {
1152 if (__tmp.__move_nothrow()) {
1153 this->__generic_construct(*__rhs, _VSTD::move(__tmp));
1154 }
1155 throw;
1156 }
1157 }
Michael Park5dee7342020-06-16 15:15:10 -07001158#else
1159 // this isn't consolidated with the `if constexpr` branch above due to
1160 // `throw` being ill-formed with exceptions disabled even when discarded.
1161 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1162#endif
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001163 this->__generic_construct(*__lhs, _VSTD::move(__tmp));
1164 }
1165 }
1166
1167private:
1168 inline _LIBCPP_INLINE_VISIBILITY
1169 bool __move_nothrow() const {
1170 constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};
1171 return this->valueless_by_exception() || __results[this->index()];
1172 }
1173};
1174
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001175struct __no_narrowing_check {
1176 template <class _Dest, class _Source>
1177 using _Apply = __identity<_Dest>;
1178};
1179
1180struct __narrowing_check {
1181 template <class _Dest>
1182 static auto __test_impl(_Dest (&&)[1]) -> __identity<_Dest>;
1183 template <class _Dest, class _Source>
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001184 using _Apply _LIBCPP_NODEBUG_TYPE = decltype(__test_impl<_Dest>({_VSTD::declval<_Source>()}));
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001185};
1186
1187template <class _Dest, class _Source>
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001188using __check_for_narrowing _LIBCPP_NODEBUG_TYPE =
1189 typename _If<
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001190#ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT
1191 false &&
1192#endif
1193 is_arithmetic<_Dest>::value,
1194 __narrowing_check,
1195 __no_narrowing_check
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001196 >::template _Apply<_Dest, _Source>;
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001197
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001198template <class _Tp, size_t _Idx>
1199struct __overload {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001200 template <class _Up>
Eric Fiselier80f5dfb2019-07-14 18:31:55 +00001201 auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001202};
1203
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001204template <class _Tp, size_t>
1205struct __overload_bool {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001206 template <class _Up, class _Ap = __uncvref_t<_Up>>
1207 auto operator()(bool, _Up&&) const
1208 -> enable_if_t<is_same_v<_Ap, bool>, __identity<_Tp>>;
1209};
1210
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001211template <size_t _Idx>
1212struct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {};
1213template <size_t _Idx>
1214struct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {};
1215template <size_t _Idx>
1216struct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {};
1217template <size_t _Idx>
1218struct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {};
1219
1220template <class ..._Bases>
1221struct __all_overloads : _Bases... {
1222 void operator()() const;
1223 using _Bases::operator()...;
1224};
1225
1226template <class IdxSeq>
1227struct __make_overloads_imp;
1228
1229template <size_t ..._Idx>
1230struct __make_overloads_imp<__tuple_indices<_Idx...> > {
1231 template <class ..._Types>
1232 using _Apply _LIBCPP_NODEBUG_TYPE = __all_overloads<__overload<_Types, _Idx>...>;
1233};
1234
1235template <class ..._Types>
1236using _MakeOverloads _LIBCPP_NODEBUG_TYPE = typename __make_overloads_imp<
1237 __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>;
Zhihao Yuan821efb82019-06-20 22:09:40 +00001238
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001239template <class _Tp, class... _Types>
Zhihao Yuan821efb82019-06-20 22:09:40 +00001240using __best_match_t =
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001241 typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001242
1243} // __variant_detail
1244
1245template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001246class _LIBCPP_TEMPLATE_VIS variant
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001247 : private __sfinae_ctor_base<
1248 __all<is_copy_constructible_v<_Types>...>::value,
1249 __all<is_move_constructible_v<_Types>...>::value>,
1250 private __sfinae_assign_base<
1251 __all<(is_copy_constructible_v<_Types> &&
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001252 is_copy_assignable_v<_Types>)...>::value,
1253 __all<(is_move_constructible_v<_Types> &&
1254 is_move_assignable_v<_Types>)...>::value> {
1255 static_assert(0 < sizeof...(_Types),
1256 "variant must consist of at least one alternative.");
1257
1258 static_assert(__all<!is_array_v<_Types>...>::value,
1259 "variant can not have an array type as an alternative.");
1260
1261 static_assert(__all<!is_reference_v<_Types>...>::value,
1262 "variant can not have a reference type as an alternative.");
1263
1264 static_assert(__all<!is_void_v<_Types>...>::value,
1265 "variant can not have a void type as an alternative.");
1266
1267 using __first_type = variant_alternative_t<0, variant>;
1268
1269public:
1270 template <bool _Dummy = true,
1271 enable_if_t<__dependent_type<is_default_constructible<__first_type>,
1272 _Dummy>::value,
1273 int> = 0>
1274 inline _LIBCPP_INLINE_VISIBILITY
1275 constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
1276 : __impl(in_place_index<0>) {}
1277
1278 variant(const variant&) = default;
1279 variant(variant&&) = default;
1280
1281 template <
1282 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001283 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
1284 enable_if_t<!__is_inplace_type<__uncvref_t<_Arg>>::value, int> = 0,
1285 enable_if_t<!__is_inplace_index<__uncvref_t<_Arg>>::value, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001286 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1287 size_t _Ip =
1288 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1289 enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
1290 inline _LIBCPP_INLINE_VISIBILITY
1291 constexpr variant(_Arg&& __arg) noexcept(
1292 is_nothrow_constructible_v<_Tp, _Arg>)
1293 : __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {}
1294
1295 template <size_t _Ip, class... _Args,
Eric Fiselier5d2df752018-03-23 23:42:30 +00001296 class = enable_if_t<(_Ip < sizeof...(_Types)), int>,
1297 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1298 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001299 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001300 explicit constexpr variant(
1301 in_place_index_t<_Ip>,
1302 _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001303 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1304
Eric Fiselier5d2df752018-03-23 23:42:30 +00001305 template <
1306 size_t _Ip,
1307 class _Up,
1308 class... _Args,
1309 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1310 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001311 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1312 int> = 0>
1313 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001314 explicit constexpr variant(
1315 in_place_index_t<_Ip>,
1316 initializer_list<_Up> __il,
1317 _Args&&... __args) noexcept(
1318 is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001319 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1320
1321 template <
1322 class _Tp,
1323 class... _Args,
1324 size_t _Ip =
1325 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1326 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1327 inline _LIBCPP_INLINE_VISIBILITY
1328 explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept(
1329 is_nothrow_constructible_v<_Tp, _Args...>)
1330 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1331
1332 template <
1333 class _Tp,
1334 class _Up,
1335 class... _Args,
1336 size_t _Ip =
1337 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1338 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1339 int> = 0>
1340 inline _LIBCPP_INLINE_VISIBILITY
1341 explicit constexpr variant(
1342 in_place_type_t<_Tp>,
1343 initializer_list<_Up> __il,
1344 _Args&&... __args) noexcept(
1345 is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>)
1346 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1347
1348 ~variant() = default;
1349
1350 variant& operator=(const variant&) = default;
1351 variant& operator=(variant&&) = default;
1352
1353 template <
1354 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001355 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001356 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1357 size_t _Ip =
1358 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1359 enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>,
1360 int> = 0>
1361 inline _LIBCPP_INLINE_VISIBILITY
1362 variant& operator=(_Arg&& __arg) noexcept(
1363 is_nothrow_assignable_v<_Tp&, _Arg> &&
1364 is_nothrow_constructible_v<_Tp, _Arg>) {
1365 __impl.template __assign<_Ip>(_VSTD::forward<_Arg>(__arg));
1366 return *this;
1367 }
1368
1369 template <
1370 size_t _Ip,
1371 class... _Args,
1372 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1373 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1374 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1375 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001376 _Tp& emplace(_Args&&... __args) {
1377 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001378 }
1379
1380 template <
1381 size_t _Ip,
1382 class _Up,
1383 class... _Args,
1384 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1385 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1386 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1387 int> = 0>
1388 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001389 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1390 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001391 }
1392
1393 template <
1394 class _Tp,
1395 class... _Args,
1396 size_t _Ip =
1397 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1398 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1399 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001400 _Tp& emplace(_Args&&... __args) {
1401 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001402 }
1403
1404 template <
1405 class _Tp,
1406 class _Up,
1407 class... _Args,
1408 size_t _Ip =
1409 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1410 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1411 int> = 0>
1412 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001413 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1414 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001415 }
1416
1417 inline _LIBCPP_INLINE_VISIBILITY
1418 constexpr bool valueless_by_exception() const noexcept {
1419 return __impl.valueless_by_exception();
1420 }
1421
1422 inline _LIBCPP_INLINE_VISIBILITY
1423 constexpr size_t index() const noexcept { return __impl.index(); }
1424
1425 template <
1426 bool _Dummy = true,
1427 enable_if_t<
1428 __all<(
1429 __dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
1430 __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value,
1431 int> = 0>
1432 inline _LIBCPP_INLINE_VISIBILITY
1433 void swap(variant& __that) noexcept(
1434 __all<(is_nothrow_move_constructible_v<_Types> &&
1435 is_nothrow_swappable_v<_Types>)...>::value) {
1436 __impl.__swap(__that.__impl);
1437 }
1438
1439private:
1440 __variant_detail::__impl<_Types...> __impl;
1441
1442 friend struct __variant_detail::__access::__variant;
1443 friend struct __variant_detail::__visitation::__variant;
1444};
1445
1446template <size_t _Ip, class... _Types>
1447inline _LIBCPP_INLINE_VISIBILITY
1448constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
1449 return __v.index() == _Ip;
1450}
1451
1452template <class _Tp, class... _Types>
1453inline _LIBCPP_INLINE_VISIBILITY
1454constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
1455 return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1456}
1457
1458template <size_t _Ip, class _Vp>
1459inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001460_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Richard Smith66d1c552018-08-27 21:41:50 +00001461constexpr auto&& __generic_get(_Vp&& __v) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001462 using __variant_detail::__access::__variant;
1463 if (!__holds_alternative<_Ip>(__v)) {
Eric Fiselier10642ea2016-12-03 01:58:07 +00001464 __throw_bad_variant_access();
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001465 }
1466 return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
1467}
1468
1469template <size_t _Ip, class... _Types>
1470inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001471_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001472constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
1473 variant<_Types...>& __v) {
1474 static_assert(_Ip < sizeof...(_Types));
1475 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1476 return __generic_get<_Ip>(__v);
1477}
1478
1479template <size_t _Ip, class... _Types>
1480inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001481_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001482constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
1483 variant<_Types...>&& __v) {
1484 static_assert(_Ip < sizeof...(_Types));
1485 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1486 return __generic_get<_Ip>(_VSTD::move(__v));
1487}
1488
1489template <size_t _Ip, class... _Types>
1490inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001491_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001492constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
1493 const variant<_Types...>& __v) {
1494 static_assert(_Ip < sizeof...(_Types));
1495 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1496 return __generic_get<_Ip>(__v);
1497}
1498
1499template <size_t _Ip, class... _Types>
1500inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001501_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001502constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
1503 const variant<_Types...>&& __v) {
1504 static_assert(_Ip < sizeof...(_Types));
1505 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1506 return __generic_get<_Ip>(_VSTD::move(__v));
1507}
1508
1509template <class _Tp, class... _Types>
1510inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001511_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001512constexpr _Tp& get(variant<_Types...>& __v) {
1513 static_assert(!is_void_v<_Tp>);
1514 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1515}
1516
1517template <class _Tp, class... _Types>
1518inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001519_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001520constexpr _Tp&& get(variant<_Types...>&& __v) {
1521 static_assert(!is_void_v<_Tp>);
1522 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1523 _VSTD::move(__v));
1524}
1525
1526template <class _Tp, class... _Types>
1527inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001528_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001529constexpr const _Tp& get(const variant<_Types...>& __v) {
1530 static_assert(!is_void_v<_Tp>);
1531 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1532}
1533
1534template <class _Tp, class... _Types>
1535inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001536_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001537constexpr const _Tp&& get(const variant<_Types...>&& __v) {
1538 static_assert(!is_void_v<_Tp>);
1539 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1540 _VSTD::move(__v));
1541}
1542
1543template <size_t _Ip, class _Vp>
1544inline _LIBCPP_INLINE_VISIBILITY
1545constexpr auto* __generic_get_if(_Vp* __v) noexcept {
1546 using __variant_detail::__access::__variant;
1547 return __v && __holds_alternative<_Ip>(*__v)
1548 ? _VSTD::addressof(__variant::__get_alt<_Ip>(*__v).__value)
1549 : nullptr;
1550}
1551
1552template <size_t _Ip, class... _Types>
1553inline _LIBCPP_INLINE_VISIBILITY
1554constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
1555get_if(variant<_Types...>* __v) noexcept {
1556 static_assert(_Ip < sizeof...(_Types));
1557 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1558 return __generic_get_if<_Ip>(__v);
1559}
1560
1561template <size_t _Ip, class... _Types>
1562inline _LIBCPP_INLINE_VISIBILITY
1563constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
1564get_if(const variant<_Types...>* __v) noexcept {
1565 static_assert(_Ip < sizeof...(_Types));
1566 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1567 return __generic_get_if<_Ip>(__v);
1568}
1569
1570template <class _Tp, class... _Types>
1571inline _LIBCPP_INLINE_VISIBILITY
1572constexpr add_pointer_t<_Tp>
1573get_if(variant<_Types...>* __v) noexcept {
1574 static_assert(!is_void_v<_Tp>);
1575 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1576}
1577
1578template <class _Tp, class... _Types>
1579inline _LIBCPP_INLINE_VISIBILITY
1580constexpr add_pointer_t<const _Tp>
1581get_if(const variant<_Types...>* __v) noexcept {
1582 static_assert(!is_void_v<_Tp>);
1583 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1584}
1585
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001586template <class _Operator>
1587struct __convert_to_bool {
1588 template <class _T1, class _T2>
1589 _LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001590 static_assert(is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value,
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001591 "the relational operator does not return a type which is implicitly convertible to bool");
1592 return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
1593 }
1594};
1595
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001596template <class... _Types>
1597inline _LIBCPP_INLINE_VISIBILITY
1598constexpr bool operator==(const variant<_Types...>& __lhs,
1599 const variant<_Types...>& __rhs) {
1600 using __variant_detail::__visitation::__variant;
1601 if (__lhs.index() != __rhs.index()) return false;
1602 if (__lhs.valueless_by_exception()) return true;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001603 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001604}
1605
1606template <class... _Types>
1607inline _LIBCPP_INLINE_VISIBILITY
1608constexpr bool operator!=(const variant<_Types...>& __lhs,
1609 const variant<_Types...>& __rhs) {
1610 using __variant_detail::__visitation::__variant;
1611 if (__lhs.index() != __rhs.index()) return true;
1612 if (__lhs.valueless_by_exception()) return false;
1613 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001614 __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001615}
1616
1617template <class... _Types>
1618inline _LIBCPP_INLINE_VISIBILITY
1619constexpr bool operator<(const variant<_Types...>& __lhs,
1620 const variant<_Types...>& __rhs) {
1621 using __variant_detail::__visitation::__variant;
1622 if (__rhs.valueless_by_exception()) return false;
1623 if (__lhs.valueless_by_exception()) return true;
1624 if (__lhs.index() < __rhs.index()) return true;
1625 if (__lhs.index() > __rhs.index()) return false;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001626 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001627}
1628
1629template <class... _Types>
1630inline _LIBCPP_INLINE_VISIBILITY
1631constexpr bool operator>(const variant<_Types...>& __lhs,
1632 const variant<_Types...>& __rhs) {
1633 using __variant_detail::__visitation::__variant;
1634 if (__lhs.valueless_by_exception()) return false;
1635 if (__rhs.valueless_by_exception()) return true;
1636 if (__lhs.index() > __rhs.index()) return true;
1637 if (__lhs.index() < __rhs.index()) return false;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001638 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001639}
1640
1641template <class... _Types>
1642inline _LIBCPP_INLINE_VISIBILITY
1643constexpr bool operator<=(const variant<_Types...>& __lhs,
1644 const variant<_Types...>& __rhs) {
1645 using __variant_detail::__visitation::__variant;
1646 if (__lhs.valueless_by_exception()) return true;
1647 if (__rhs.valueless_by_exception()) return false;
1648 if (__lhs.index() < __rhs.index()) return true;
1649 if (__lhs.index() > __rhs.index()) return false;
1650 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001651 __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001652}
1653
1654template <class... _Types>
1655inline _LIBCPP_INLINE_VISIBILITY
1656constexpr bool operator>=(const variant<_Types...>& __lhs,
1657 const variant<_Types...>& __rhs) {
1658 using __variant_detail::__visitation::__variant;
1659 if (__rhs.valueless_by_exception()) return true;
1660 if (__lhs.valueless_by_exception()) return false;
1661 if (__lhs.index() > __rhs.index()) return true;
1662 if (__lhs.index() < __rhs.index()) return false;
1663 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001664 __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001665}
1666
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001667template <class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001668inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001669 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr void
1670 __throw_if_valueless(_Vs&&... __vs) {
1671 const bool __valueless =
1672 (... || _VSTD::__as_variant(__vs).valueless_by_exception());
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001673 if (__valueless) {
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001674 __throw_bad_variant_access();
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001675 }
1676}
1677
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001678template <
1679 class _Visitor, class... _Vs,
1680 typename = void_t<decltype(_VSTD::__as_variant(_VSTD::declval<_Vs>()))...> >
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001681inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001682 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr
1683 decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001684 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001685 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Eric Fiselier87994112020-11-17 17:34:23 -05001686 return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001687 _VSTD::forward<_Vs>(__vs)...);
1688}
1689
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001690#if _LIBCPP_STD_VER > 17
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001691template <
1692 class _Rp, class _Visitor, class... _Vs,
1693 typename = void_t<decltype(_VSTD::__as_variant(_VSTD::declval<_Vs>()))...> >
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001694inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001695 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp
1696 visit(_Visitor&& __visitor, _Vs&&... __vs) {
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001697 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001698 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001699 return __variant::__visit_value<_Rp>(_VSTD::forward<_Visitor>(__visitor),
1700 _VSTD::forward<_Vs>(__vs)...);
1701}
1702#endif
1703
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001704struct _LIBCPP_TEMPLATE_VIS monostate {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001705
1706inline _LIBCPP_INLINE_VISIBILITY
1707constexpr bool operator<(monostate, monostate) noexcept { return false; }
1708
1709inline _LIBCPP_INLINE_VISIBILITY
1710constexpr bool operator>(monostate, monostate) noexcept { return false; }
1711
1712inline _LIBCPP_INLINE_VISIBILITY
1713constexpr bool operator<=(monostate, monostate) noexcept { return true; }
1714
1715inline _LIBCPP_INLINE_VISIBILITY
1716constexpr bool operator>=(monostate, monostate) noexcept { return true; }
1717
1718inline _LIBCPP_INLINE_VISIBILITY
1719constexpr bool operator==(monostate, monostate) noexcept { return true; }
1720
1721inline _LIBCPP_INLINE_VISIBILITY
1722constexpr bool operator!=(monostate, monostate) noexcept { return false; }
1723
1724template <class... _Types>
1725inline _LIBCPP_INLINE_VISIBILITY
1726auto swap(variant<_Types...>& __lhs,
1727 variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs)))
1728 -> decltype(__lhs.swap(__rhs)) {
1729 __lhs.swap(__rhs);
1730}
1731
1732template <class... _Types>
Eric Fiselier698a97b2017-01-21 00:02:12 +00001733struct _LIBCPP_TEMPLATE_VIS hash<
1734 __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001735 using argument_type = variant<_Types...>;
1736 using result_type = size_t;
1737
1738 inline _LIBCPP_INLINE_VISIBILITY
1739 result_type operator()(const argument_type& __v) const {
1740 using __variant_detail::__visitation::__variant;
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001741 size_t __res =
1742 __v.valueless_by_exception()
Eric Fiselier6b1683c2016-12-04 21:37:37 +00001743 ? 299792458 // Random value chosen by the universe upon creation
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001744 : __variant::__visit_alt(
1745 [](const auto& __alt) {
Marshall Clowe61ba952018-02-12 15:41:25 +00001746 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier698a97b2017-01-21 00:02:12 +00001747 using __value_type = remove_const_t<
1748 typename __alt_type::__value_type>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001749 return hash<__value_type>{}(__alt.__value);
1750 },
1751 __v);
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001752 return __hash_combine(__res, hash<size_t>{}(__v.index()));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001753 }
1754};
1755
1756template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001757struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001758 using argument_type = monostate;
1759 using result_type = size_t;
1760
1761 inline _LIBCPP_INLINE_VISIBILITY
Marshall Clow49036892017-03-23 02:40:28 +00001762 result_type operator()(const argument_type&) const _NOEXCEPT {
Eric Fiselier6b1683c2016-12-04 21:37:37 +00001763 return 66740831; // return a fundamentally attractive random value.
1764 }
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001765};
1766
1767#endif // _LIBCPP_STD_VER > 14
1768
1769_LIBCPP_END_NAMESPACE_STD
1770
Eric Fiselier8625d332017-11-19 04:57:22 +00001771_LIBCPP_POP_MACROS
1772
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001773#endif // _LIBCPP_VARIANT