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