10d3d8de0SEric Fiselier// -*- C++ -*- 2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===// 30d3d8de0SEric Fiselier// 457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70d3d8de0SEric Fiselier// 80d3d8de0SEric Fiselier//===----------------------------------------------------------------------===// 90d3d8de0SEric Fiselier 100d3d8de0SEric Fiselier#ifndef _LIBCPP_VARIANT 110d3d8de0SEric Fiselier#define _LIBCPP_VARIANT 120d3d8de0SEric Fiselier 130d3d8de0SEric Fiselier/* 140d3d8de0SEric Fiselier variant synopsis 150d3d8de0SEric Fiselier 160d3d8de0SEric Fiseliernamespace std { 170d3d8de0SEric Fiselier 180d3d8de0SEric Fiselier // 20.7.2, class template variant 190d3d8de0SEric Fiselier template <class... Types> 200d3d8de0SEric Fiselier class variant { 210d3d8de0SEric Fiselier public: 220d3d8de0SEric Fiselier 230d3d8de0SEric Fiselier // 20.7.2.1, constructors 240d3d8de0SEric Fiselier constexpr variant() noexcept(see below); 251d5f6a81SLouis Dionne variant(const variant&); // constexpr in C++20 261d5f6a81SLouis Dionne variant(variant&&) noexcept(see below); // constexpr in C++20 270d3d8de0SEric Fiselier 280d3d8de0SEric Fiselier template <class T> constexpr variant(T&&) noexcept(see below); 290d3d8de0SEric Fiselier 300d3d8de0SEric Fiselier template <class T, class... Args> 310d3d8de0SEric Fiselier constexpr explicit variant(in_place_type_t<T>, Args&&...); 320d3d8de0SEric Fiselier 330d3d8de0SEric Fiselier template <class T, class U, class... Args> 340d3d8de0SEric Fiselier constexpr explicit variant( 350d3d8de0SEric Fiselier in_place_type_t<T>, initializer_list<U>, Args&&...); 360d3d8de0SEric Fiselier 370d3d8de0SEric Fiselier template <size_t I, class... Args> 380d3d8de0SEric Fiselier constexpr explicit variant(in_place_index_t<I>, Args&&...); 390d3d8de0SEric Fiselier 400d3d8de0SEric Fiselier template <size_t I, class U, class... Args> 410d3d8de0SEric Fiselier constexpr explicit variant( 420d3d8de0SEric Fiselier in_place_index_t<I>, initializer_list<U>, Args&&...); 430d3d8de0SEric Fiselier 440d3d8de0SEric Fiselier // 20.7.2.2, destructor 450d3d8de0SEric Fiselier ~variant(); 460d3d8de0SEric Fiselier 470d3d8de0SEric Fiselier // 20.7.2.3, assignment 481d5f6a81SLouis Dionne variant& operator=(const variant&); // constexpr in C++20 491d5f6a81SLouis Dionne variant& operator=(variant&&) noexcept(see below); // constexpr in C++20 500d3d8de0SEric Fiselier 510d3d8de0SEric Fiselier template <class T> variant& operator=(T&&) noexcept(see below); 520d3d8de0SEric Fiselier 530d3d8de0SEric Fiselier // 20.7.2.4, modifiers 540d3d8de0SEric Fiselier template <class T, class... Args> 5525514755SEric Fiselier T& emplace(Args&&...); 560d3d8de0SEric Fiselier 570d3d8de0SEric Fiselier template <class T, class U, class... Args> 5825514755SEric Fiselier T& emplace(initializer_list<U>, Args&&...); 590d3d8de0SEric Fiselier 600d3d8de0SEric Fiselier template <size_t I, class... Args> 6125514755SEric Fiselier variant_alternative_t<I, variant>& emplace(Args&&...); 620d3d8de0SEric Fiselier 630d3d8de0SEric Fiselier template <size_t I, class U, class... Args> 6425514755SEric Fiselier variant_alternative_t<I, variant>& emplace(initializer_list<U>, Args&&...); 650d3d8de0SEric Fiselier 660d3d8de0SEric Fiselier // 20.7.2.5, value status 670d3d8de0SEric Fiselier constexpr bool valueless_by_exception() const noexcept; 680d3d8de0SEric Fiselier constexpr size_t index() const noexcept; 690d3d8de0SEric Fiselier 700d3d8de0SEric Fiselier // 20.7.2.6, swap 710d3d8de0SEric Fiselier void swap(variant&) noexcept(see below); 720d3d8de0SEric Fiselier }; 730d3d8de0SEric Fiselier 740d3d8de0SEric Fiselier // 20.7.3, variant helper classes 750d3d8de0SEric Fiselier template <class T> struct variant_size; // undefined 760d3d8de0SEric Fiselier 770d3d8de0SEric Fiselier template <class T> 7840a01d53SMarshall Clow inline constexpr size_t variant_size_v = variant_size<T>::value; 790d3d8de0SEric Fiselier 800d3d8de0SEric Fiselier template <class T> struct variant_size<const T>; 810d3d8de0SEric Fiselier template <class T> struct variant_size<volatile T>; 820d3d8de0SEric Fiselier template <class T> struct variant_size<const volatile T>; 830d3d8de0SEric Fiselier 840d3d8de0SEric Fiselier template <class... Types> 850d3d8de0SEric Fiselier struct variant_size<variant<Types...>>; 860d3d8de0SEric Fiselier 870d3d8de0SEric Fiselier template <size_t I, class T> struct variant_alternative; // undefined 880d3d8de0SEric Fiselier 890d3d8de0SEric Fiselier template <size_t I, class T> 900d3d8de0SEric Fiselier using variant_alternative_t = typename variant_alternative<I, T>::type; 910d3d8de0SEric Fiselier 920d3d8de0SEric Fiselier template <size_t I, class T> struct variant_alternative<I, const T>; 930d3d8de0SEric Fiselier template <size_t I, class T> struct variant_alternative<I, volatile T>; 940d3d8de0SEric Fiselier template <size_t I, class T> struct variant_alternative<I, const volatile T>; 950d3d8de0SEric Fiselier 960d3d8de0SEric Fiselier template <size_t I, class... Types> 970d3d8de0SEric Fiselier struct variant_alternative<I, variant<Types...>>; 980d3d8de0SEric Fiselier 9940a01d53SMarshall Clow inline constexpr size_t variant_npos = -1; 1000d3d8de0SEric Fiselier 1010d3d8de0SEric Fiselier // 20.7.4, value access 1020d3d8de0SEric Fiselier template <class T, class... Types> 1030d3d8de0SEric Fiselier constexpr bool holds_alternative(const variant<Types...>&) noexcept; 1040d3d8de0SEric Fiselier 1050d3d8de0SEric Fiselier template <size_t I, class... Types> 1060d3d8de0SEric Fiselier constexpr variant_alternative_t<I, variant<Types...>>& 1070d3d8de0SEric Fiselier get(variant<Types...>&); 1080d3d8de0SEric Fiselier 1090d3d8de0SEric Fiselier template <size_t I, class... Types> 1100d3d8de0SEric Fiselier constexpr variant_alternative_t<I, variant<Types...>>&& 1110d3d8de0SEric Fiselier get(variant<Types...>&&); 1120d3d8de0SEric Fiselier 1130d3d8de0SEric Fiselier template <size_t I, class... Types> 1140d3d8de0SEric Fiselier constexpr variant_alternative_t<I, variant<Types...>> const& 1150d3d8de0SEric Fiselier get(const variant<Types...>&); 1160d3d8de0SEric Fiselier 1170d3d8de0SEric Fiselier template <size_t I, class... Types> 1180d3d8de0SEric Fiselier constexpr variant_alternative_t<I, variant<Types...>> const&& 1190d3d8de0SEric Fiselier get(const variant<Types...>&&); 1200d3d8de0SEric Fiselier 1210d3d8de0SEric Fiselier template <class T, class... Types> 1220d3d8de0SEric Fiselier constexpr T& get(variant<Types...>&); 1230d3d8de0SEric Fiselier 1240d3d8de0SEric Fiselier template <class T, class... Types> 1250d3d8de0SEric Fiselier constexpr T&& get(variant<Types...>&&); 1260d3d8de0SEric Fiselier 1270d3d8de0SEric Fiselier template <class T, class... Types> 1280d3d8de0SEric Fiselier constexpr const T& get(const variant<Types...>&); 1290d3d8de0SEric Fiselier 1300d3d8de0SEric Fiselier template <class T, class... Types> 1310d3d8de0SEric Fiselier constexpr const T&& get(const variant<Types...>&&); 1320d3d8de0SEric Fiselier 1330d3d8de0SEric Fiselier template <size_t I, class... Types> 1340d3d8de0SEric Fiselier constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>> 1350d3d8de0SEric Fiselier get_if(variant<Types...>*) noexcept; 1360d3d8de0SEric Fiselier 1370d3d8de0SEric Fiselier template <size_t I, class... Types> 1380d3d8de0SEric Fiselier constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>> 1390d3d8de0SEric Fiselier get_if(const variant<Types...>*) noexcept; 1400d3d8de0SEric Fiselier 1410d3d8de0SEric Fiselier template <class T, class... Types> 1420d3d8de0SEric Fiselier constexpr add_pointer_t<T> 1430d3d8de0SEric Fiselier get_if(variant<Types...>*) noexcept; 1440d3d8de0SEric Fiselier 1450d3d8de0SEric Fiselier template <class T, class... Types> 1460d3d8de0SEric Fiselier constexpr add_pointer_t<const T> 1470d3d8de0SEric Fiselier get_if(const variant<Types...>*) noexcept; 1480d3d8de0SEric Fiselier 1490d3d8de0SEric Fiselier // 20.7.5, relational operators 1500d3d8de0SEric Fiselier template <class... Types> 1510d3d8de0SEric Fiselier constexpr bool operator==(const variant<Types...>&, const variant<Types...>&); 1520d3d8de0SEric Fiselier 1530d3d8de0SEric Fiselier template <class... Types> 1540d3d8de0SEric Fiselier constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&); 1550d3d8de0SEric Fiselier 1560d3d8de0SEric Fiselier template <class... Types> 1570d3d8de0SEric Fiselier constexpr bool operator<(const variant<Types...>&, const variant<Types...>&); 1580d3d8de0SEric Fiselier 1590d3d8de0SEric Fiselier template <class... Types> 1600d3d8de0SEric Fiselier constexpr bool operator>(const variant<Types...>&, const variant<Types...>&); 1610d3d8de0SEric Fiselier 1620d3d8de0SEric Fiselier template <class... Types> 1630d3d8de0SEric Fiselier constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&); 1640d3d8de0SEric Fiselier 1650d3d8de0SEric Fiselier template <class... Types> 1660d3d8de0SEric Fiselier constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&); 1670d3d8de0SEric Fiselier 1680d3d8de0SEric Fiselier // 20.7.6, visitation 1690d3d8de0SEric Fiselier template <class Visitor, class... Variants> 1700d3d8de0SEric Fiselier constexpr see below visit(Visitor&&, Variants&&...); 1710d3d8de0SEric Fiselier 17251faba35SRuslan Arutyunyan template <class R, class Visitor, class... Variants> 17351faba35SRuslan Arutyunyan constexpr R visit(Visitor&&, Variants&&...); // since C++20 17451faba35SRuslan Arutyunyan 1750d3d8de0SEric Fiselier // 20.7.7, class monostate 1760d3d8de0SEric Fiselier struct monostate; 1770d3d8de0SEric Fiselier 1780d3d8de0SEric Fiselier // 20.7.8, monostate relational operators 1790d3d8de0SEric Fiselier constexpr bool operator<(monostate, monostate) noexcept; 1800d3d8de0SEric Fiselier constexpr bool operator>(monostate, monostate) noexcept; 1810d3d8de0SEric Fiselier constexpr bool operator<=(monostate, monostate) noexcept; 1820d3d8de0SEric Fiselier constexpr bool operator>=(monostate, monostate) noexcept; 1830d3d8de0SEric Fiselier constexpr bool operator==(monostate, monostate) noexcept; 1840d3d8de0SEric Fiselier constexpr bool operator!=(monostate, monostate) noexcept; 1850d3d8de0SEric Fiselier 1860d3d8de0SEric Fiselier // 20.7.9, specialized algorithms 1870d3d8de0SEric Fiselier template <class... Types> 1880d3d8de0SEric Fiselier void swap(variant<Types...>&, variant<Types...>&) noexcept(see below); 1890d3d8de0SEric Fiselier 1900d3d8de0SEric Fiselier // 20.7.10, class bad_variant_access 1910d3d8de0SEric Fiselier class bad_variant_access; 1920d3d8de0SEric Fiselier 1930d3d8de0SEric Fiselier // 20.7.11, hash support 1940d3d8de0SEric Fiselier template <class T> struct hash; 1950d3d8de0SEric Fiselier template <class... Types> struct hash<variant<Types...>>; 1960d3d8de0SEric Fiselier template <> struct hash<monostate>; 1970d3d8de0SEric Fiselier 1980d3d8de0SEric Fiselier} // namespace std 1990d3d8de0SEric Fiselier 2000d3d8de0SEric Fiselier*/ 2010d3d8de0SEric Fiselier 202385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler 2032eadbc86SLouis Dionne#include <__availability> 204bfbd73f8SArthur O'Dwyer#include <__config> 2051a29403dSzoecarver#include <__functional/hash.h> 206169a66eaSNikolas Klauser#include <__functional/operations.h> 207169a66eaSNikolas Klauser#include <__functional/unary_function.h> 2081a29403dSzoecarver#include <__tuple> 2096adbc83eSChristopher Di Bella#include <__utility/forward.h> 21052915d78SNikolas Klauser#include <__utility/in_place.h> 21152915d78SNikolas Klauser#include <__utility/move.h> 21252915d78SNikolas Klauser#include <__utility/swap.h> 213321c2ea9SMark de Wever#include <__variant/monostate.h> 2140d3d8de0SEric Fiselier#include <exception> 2150d3d8de0SEric Fiselier#include <initializer_list> 216bfbd73f8SArthur O'Dwyer#include <limits> 2170d3d8de0SEric Fiselier#include <new> 2180d3d8de0SEric Fiselier#include <tuple> 2190d3d8de0SEric Fiselier#include <type_traits> 220f56972e2SMarshall Clow#include <version> 2210d3d8de0SEric Fiselier 222de4a57cbSLouis Dionne#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES 223de4a57cbSLouis Dionne# include <typeinfo> 224de4a57cbSLouis Dionne# include <utility> 225de4a57cbSLouis Dionne#endif 226de4a57cbSLouis Dionne 227db1978b6SNikolas Klauser// standard-mandated includes 228db1978b6SNikolas Klauser#include <compare> 229db1978b6SNikolas Klauser 2300d3d8de0SEric Fiselier#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2310d3d8de0SEric Fiselier# pragma GCC system_header 2320d3d8de0SEric Fiselier#endif 2330d3d8de0SEric Fiselier 234afa6f834SEric Fiselier_LIBCPP_PUSH_MACROS 235afa6f834SEric Fiselier#include <__undef_macros> 236afa6f834SEric Fiselier 2370d3d8de0SEric Fiseliernamespace std { // explicitly not using versioning namespace 2380d3d8de0SEric Fiselier 2398a063df1SLouis Dionneclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception { 2400d3d8de0SEric Fiselierpublic: 24121711c45SSaleem Abdulrasool virtual const char* what() const _NOEXCEPT; 2420d3d8de0SEric Fiselier}; 2430d3d8de0SEric Fiselier 2440d3d8de0SEric Fiselier} // namespace std 2450d3d8de0SEric Fiselier 2460d3d8de0SEric Fiselier_LIBCPP_BEGIN_NAMESPACE_STD 2470d3d8de0SEric Fiselier 248a4cb5aefSLouis Dionne#if _LIBCPP_STD_VER > 14 2490d3d8de0SEric Fiselier 2500849427fSzoecarver// Light N-dimensional array of function pointers. Used in place of std::array to avoid 2510849427fSzoecarver// adding a dependency. 2520849427fSzoecarvertemplate<class _Tp, size_t _Size> 2530849427fSzoecarverstruct __farray { 2540849427fSzoecarver static_assert(_Size > 0, "N-dimensional array should never be empty in std::visit"); 2550849427fSzoecarver _Tp __buf_[_Size] = {}; 2560849427fSzoecarver 2570849427fSzoecarver _LIBCPP_INLINE_VISIBILITY constexpr 2580849427fSzoecarver const _Tp &operator[](size_t __n) const noexcept { 2590849427fSzoecarver return __buf_[__n]; 2600849427fSzoecarver } 2610849427fSzoecarver}; 2620849427fSzoecarver 26363322af6SEric Fiselier_LIBCPP_NORETURN 26463322af6SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 2658a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS 26663322af6SEric Fiseliervoid __throw_bad_variant_access() { 26763322af6SEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS 26863322af6SEric Fiselier throw bad_variant_access(); 26963322af6SEric Fiselier#else 27063322af6SEric Fiselier _VSTD::abort(); 27163322af6SEric Fiselier#endif 27263322af6SEric Fiselier} 27363322af6SEric Fiselier 2740d3d8de0SEric Fiseliertemplate <class... _Types> 275e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS variant; 2760d3d8de0SEric Fiselier 2770d3d8de0SEric Fiseliertemplate <class _Tp> 278e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS variant_size; 2790d3d8de0SEric Fiselier 2800d3d8de0SEric Fiseliertemplate <class _Tp> 281cb793e1aSLouis Dionneinline constexpr size_t variant_size_v = variant_size<_Tp>::value; 2820d3d8de0SEric Fiselier 2830d3d8de0SEric Fiseliertemplate <class _Tp> 284e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {}; 2850d3d8de0SEric Fiselier 2860d3d8de0SEric Fiseliertemplate <class _Tp> 287e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {}; 2880d3d8de0SEric Fiselier 2890d3d8de0SEric Fiseliertemplate <class _Tp> 290e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS variant_size<const volatile _Tp> 2910d3d8de0SEric Fiselier : variant_size<_Tp> {}; 2920d3d8de0SEric Fiselier 2930d3d8de0SEric Fiseliertemplate <class... _Types> 294e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>> 2950d3d8de0SEric Fiselier : integral_constant<size_t, sizeof...(_Types)> {}; 2960d3d8de0SEric Fiselier 2970d3d8de0SEric Fiseliertemplate <size_t _Ip, class _Tp> 298e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS variant_alternative; 2990d3d8de0SEric Fiselier 3000d3d8de0SEric Fiseliertemplate <size_t _Ip, class _Tp> 3010d3d8de0SEric Fiselierusing variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type; 3020d3d8de0SEric Fiselier 3030d3d8de0SEric Fiseliertemplate <size_t _Ip, class _Tp> 304e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp> 3050d3d8de0SEric Fiselier : add_const<variant_alternative_t<_Ip, _Tp>> {}; 3060d3d8de0SEric Fiselier 3070d3d8de0SEric Fiseliertemplate <size_t _Ip, class _Tp> 308e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp> 3090d3d8de0SEric Fiselier : add_volatile<variant_alternative_t<_Ip, _Tp>> {}; 3100d3d8de0SEric Fiselier 3110d3d8de0SEric Fiseliertemplate <size_t _Ip, class _Tp> 312e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp> 3130d3d8de0SEric Fiselier : add_cv<variant_alternative_t<_Ip, _Tp>> {}; 3140d3d8de0SEric Fiselier 3150d3d8de0SEric Fiseliertemplate <size_t _Ip, class... _Types> 316e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> { 3170c69d6e9SMarshall Clow static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>"); 3180d3d8de0SEric Fiselier using type = __type_pack_element<_Ip, _Types...>; 3190d3d8de0SEric Fiselier}; 3200d3d8de0SEric Fiselier 321cb793e1aSLouis Dionneinline constexpr size_t variant_npos = static_cast<size_t>(-1); 3220ed52538SEric Fiselier 3230ed52538SEric Fiselierconstexpr int __choose_index_type(unsigned int __num_elem) { 324d586f92cSArthur O'Dwyer if (__num_elem < numeric_limits<unsigned char>::max()) 3250ed52538SEric Fiselier return 0; 326d586f92cSArthur O'Dwyer if (__num_elem < numeric_limits<unsigned short>::max()) 3270ed52538SEric Fiselier return 1; 3280ed52538SEric Fiselier return 2; 3290ed52538SEric Fiselier} 3300ed52538SEric Fiselier 3310ed52538SEric Fiseliertemplate <size_t _NumAlts> 3320ed52538SEric Fiselierusing __variant_index_t = 3330ed52538SEric Fiselier#ifndef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION 3340ed52538SEric Fiselier unsigned int; 3350ed52538SEric Fiselier#else 3360ed52538SEric Fiselier std::tuple_element_t< 3370ed52538SEric Fiselier __choose_index_type(_NumAlts), 3380ed52538SEric Fiselier std::tuple<unsigned char, unsigned short, unsigned int> 3390ed52538SEric Fiselier >; 3400ed52538SEric Fiselier#endif 3410ed52538SEric Fiselier 3420ed52538SEric Fiseliertemplate <class _IndexType> 3430ed52538SEric Fiselierconstexpr _IndexType __variant_npos = static_cast<_IndexType>(-1); 3440d3d8de0SEric Fiselier 3450324b46cSMarek Kurdejtemplate <class... _Types> 3460324b46cSMarek Kurdejclass _LIBCPP_TEMPLATE_VIS variant; 3470324b46cSMarek Kurdej 3480324b46cSMarek Kurdejtemplate <class... _Types> 3490324b46cSMarek Kurdej_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>& 3500324b46cSMarek Kurdej__as_variant(variant<_Types...>& __vs) noexcept { 3510324b46cSMarek Kurdej return __vs; 3520324b46cSMarek Kurdej} 3530324b46cSMarek Kurdej 3540324b46cSMarek Kurdejtemplate <class... _Types> 3550324b46cSMarek Kurdej_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>& 3560324b46cSMarek Kurdej__as_variant(const variant<_Types...>& __vs) noexcept { 3570324b46cSMarek Kurdej return __vs; 3580324b46cSMarek Kurdej} 3590324b46cSMarek Kurdej 3600324b46cSMarek Kurdejtemplate <class... _Types> 3610324b46cSMarek Kurdej_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&& 3620324b46cSMarek Kurdej__as_variant(variant<_Types...>&& __vs) noexcept { 3630324b46cSMarek Kurdej return _VSTD::move(__vs); 3640324b46cSMarek Kurdej} 3650324b46cSMarek Kurdej 3660324b46cSMarek Kurdejtemplate <class... _Types> 3670324b46cSMarek Kurdej_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&& 3680324b46cSMarek Kurdej__as_variant(const variant<_Types...>&& __vs) noexcept { 3690324b46cSMarek Kurdej return _VSTD::move(__vs); 3700324b46cSMarek Kurdej} 3710324b46cSMarek Kurdej 3720d3d8de0SEric Fiseliernamespace __find_detail { 3730d3d8de0SEric Fiselier 3740d3d8de0SEric Fiseliertemplate <class _Tp, class... _Types> 3750d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 3760d3d8de0SEric Fiselierconstexpr size_t __find_index() { 3770d3d8de0SEric Fiselier constexpr bool __matches[] = {is_same_v<_Tp, _Types>...}; 3780d3d8de0SEric Fiselier size_t __result = __not_found; 3790d3d8de0SEric Fiselier for (size_t __i = 0; __i < sizeof...(_Types); ++__i) { 3800d3d8de0SEric Fiselier if (__matches[__i]) { 3810d3d8de0SEric Fiselier if (__result != __not_found) { 3820d3d8de0SEric Fiselier return __ambiguous; 3830d3d8de0SEric Fiselier } 3840d3d8de0SEric Fiselier __result = __i; 3850d3d8de0SEric Fiselier } 3860d3d8de0SEric Fiselier } 3870d3d8de0SEric Fiselier return __result; 3880d3d8de0SEric Fiselier} 3890d3d8de0SEric Fiselier 3900d3d8de0SEric Fiseliertemplate <size_t _Index> 3910d3d8de0SEric Fiselierstruct __find_unambiguous_index_sfinae_impl 3920d3d8de0SEric Fiselier : integral_constant<size_t, _Index> {}; 3930d3d8de0SEric Fiselier 3940d3d8de0SEric Fiseliertemplate <> 3950d3d8de0SEric Fiselierstruct __find_unambiguous_index_sfinae_impl<__not_found> {}; 3960d3d8de0SEric Fiselier 3970d3d8de0SEric Fiseliertemplate <> 3980d3d8de0SEric Fiselierstruct __find_unambiguous_index_sfinae_impl<__ambiguous> {}; 3990d3d8de0SEric Fiselier 4000d3d8de0SEric Fiseliertemplate <class _Tp, class... _Types> 4010d3d8de0SEric Fiselierstruct __find_unambiguous_index_sfinae 4020d3d8de0SEric Fiselier : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {}; 4030d3d8de0SEric Fiselier 4040d3d8de0SEric Fiselier} // namespace __find_detail 4050d3d8de0SEric Fiselier 4060d3d8de0SEric Fiseliernamespace __variant_detail { 4070d3d8de0SEric Fiselier 4080d3d8de0SEric Fiselierstruct __valueless_t {}; 4090d3d8de0SEric Fiselier 4100d3d8de0SEric Fiselierenum class _Trait { _TriviallyAvailable, _Available, _Unavailable }; 4110d3d8de0SEric Fiselier 4129c09757bSEric Fiseliertemplate <typename _Tp, 4139c09757bSEric Fiselier template <typename> class _IsTriviallyAvailable, 4149c09757bSEric Fiselier template <typename> class _IsAvailable> 4150d3d8de0SEric Fiselierconstexpr _Trait __trait = 4160d3d8de0SEric Fiselier _IsTriviallyAvailable<_Tp>::value 4170d3d8de0SEric Fiselier ? _Trait::_TriviallyAvailable 4180d3d8de0SEric Fiselier : _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable; 4190d3d8de0SEric Fiselier 4200d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 4210d3d8de0SEric Fiselierconstexpr _Trait __common_trait(initializer_list<_Trait> __traits) { 4220d3d8de0SEric Fiselier _Trait __result = _Trait::_TriviallyAvailable; 4230d3d8de0SEric Fiselier for (_Trait __t : __traits) { 4240d3d8de0SEric Fiselier if (static_cast<int>(__t) > static_cast<int>(__result)) { 4250d3d8de0SEric Fiselier __result = __t; 4260d3d8de0SEric Fiselier } 4270d3d8de0SEric Fiselier } 4280d3d8de0SEric Fiselier return __result; 4290d3d8de0SEric Fiselier} 4300d3d8de0SEric Fiselier 4319c09757bSEric Fiseliertemplate <typename... _Types> 4320d3d8de0SEric Fiselierstruct __traits { 4330d3d8de0SEric Fiselier static constexpr _Trait __copy_constructible_trait = 4340d3d8de0SEric Fiselier __common_trait({__trait<_Types, 4350d3d8de0SEric Fiselier is_trivially_copy_constructible, 4360d3d8de0SEric Fiselier is_copy_constructible>...}); 4370d3d8de0SEric Fiselier 4380d3d8de0SEric Fiselier static constexpr _Trait __move_constructible_trait = 4390d3d8de0SEric Fiselier __common_trait({__trait<_Types, 4400d3d8de0SEric Fiselier is_trivially_move_constructible, 4410d3d8de0SEric Fiselier is_move_constructible>...}); 4420d3d8de0SEric Fiselier 4430d3d8de0SEric Fiselier static constexpr _Trait __copy_assignable_trait = __common_trait( 4440d3d8de0SEric Fiselier {__copy_constructible_trait, 4450d3d8de0SEric Fiselier __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...}); 4460d3d8de0SEric Fiselier 4470d3d8de0SEric Fiselier static constexpr _Trait __move_assignable_trait = __common_trait( 4480d3d8de0SEric Fiselier {__move_constructible_trait, 4490d3d8de0SEric Fiselier __trait<_Types, is_trivially_move_assignable, is_move_assignable>...}); 4500d3d8de0SEric Fiselier 4510d3d8de0SEric Fiselier static constexpr _Trait __destructible_trait = __common_trait( 4520d3d8de0SEric Fiselier {__trait<_Types, is_trivially_destructible, is_destructible>...}); 4530d3d8de0SEric Fiselier}; 4540d3d8de0SEric Fiselier 4550d3d8de0SEric Fiseliernamespace __access { 4560d3d8de0SEric Fiselier 4570d3d8de0SEric Fiselierstruct __union { 4580d3d8de0SEric Fiselier template <class _Vp> 4590d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 4600d3d8de0SEric Fiselier static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) { 4610d3d8de0SEric Fiselier return _VSTD::forward<_Vp>(__v).__head; 4620d3d8de0SEric Fiselier } 4630d3d8de0SEric Fiselier 4640d3d8de0SEric Fiselier template <class _Vp, size_t _Ip> 4650d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 4660d3d8de0SEric Fiselier static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) { 4670d3d8de0SEric Fiselier return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>); 4680d3d8de0SEric Fiselier } 4690d3d8de0SEric Fiselier}; 4700d3d8de0SEric Fiselier 4710d3d8de0SEric Fiselierstruct __base { 4720d3d8de0SEric Fiselier template <size_t _Ip, class _Vp> 4730d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 4740d3d8de0SEric Fiselier static constexpr auto&& __get_alt(_Vp&& __v) { 4750d3d8de0SEric Fiselier return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data, 4760d3d8de0SEric Fiselier in_place_index<_Ip>); 4770d3d8de0SEric Fiselier } 4780d3d8de0SEric Fiselier}; 4790d3d8de0SEric Fiselier 4800d3d8de0SEric Fiselierstruct __variant { 4810d3d8de0SEric Fiselier template <size_t _Ip, class _Vp> 4820d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 4830d3d8de0SEric Fiselier static constexpr auto&& __get_alt(_Vp&& __v) { 4840d3d8de0SEric Fiselier return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl); 4850d3d8de0SEric Fiselier } 4860d3d8de0SEric Fiselier}; 4870d3d8de0SEric Fiselier 4880d3d8de0SEric Fiselier} // namespace __access 4890d3d8de0SEric Fiselier 4900d3d8de0SEric Fiseliernamespace __visitation { 4910d3d8de0SEric Fiselier 49235d22691SMichael Parkstruct __base { 4939c09757bSEric Fiselier template <class _Visitor, class... _Vs> 4940d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 4959c09757bSEric Fiselier static constexpr decltype(auto) 4969c09757bSEric Fiselier __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { 4979c09757bSEric Fiselier constexpr auto __fdiagonal = 4989c09757bSEric Fiselier __make_fdiagonal<_Visitor&&, 4999c09757bSEric Fiselier decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>(); 5009c09757bSEric Fiselier return __fdiagonal[__index](_VSTD::forward<_Visitor>(__visitor), 5019c09757bSEric Fiselier _VSTD::forward<_Vs>(__vs).__as_base()...); 5029c09757bSEric Fiselier } 5039c09757bSEric Fiselier 5049c09757bSEric Fiselier template <class _Visitor, class... _Vs> 5059c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5069c09757bSEric Fiselier static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, 5079c09757bSEric Fiselier _Vs&&... __vs) { 5089c09757bSEric Fiselier constexpr auto __fmatrix = 5099c09757bSEric Fiselier __make_fmatrix<_Visitor&&, 5109c09757bSEric Fiselier decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>(); 5119c09757bSEric Fiselier return __at(__fmatrix, __vs.index()...)( 5129c09757bSEric Fiselier _VSTD::forward<_Visitor>(__visitor), 5139c09757bSEric Fiselier _VSTD::forward<_Vs>(__vs).__as_base()...); 5149c09757bSEric Fiselier } 5159c09757bSEric Fiselier 5169c09757bSEric Fiselierprivate: 5179c09757bSEric Fiselier template <class _Tp> 5189c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5199c09757bSEric Fiselier static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; } 5209c09757bSEric Fiselier 5219c09757bSEric Fiselier template <class _Tp, size_t _Np, typename... _Indices> 5229c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5230849427fSzoecarver static constexpr auto&& __at(const __farray<_Tp, _Np>& __elems, 5249c09757bSEric Fiselier size_t __index, _Indices... __indices) { 5259c09757bSEric Fiselier return __at(__elems[__index], __indices...); 5269c09757bSEric Fiselier } 5279c09757bSEric Fiselier 5289c09757bSEric Fiselier template <class _Fp, class... _Fs> 5299c09757bSEric Fiselier static constexpr void __std_visit_visitor_return_type_check() { 5309c09757bSEric Fiselier static_assert( 5319c09757bSEric Fiselier __all<is_same_v<_Fp, _Fs>...>::value, 5329c09757bSEric Fiselier "`std::visit` requires the visitor to have a single return type."); 5339c09757bSEric Fiselier } 5349c09757bSEric Fiselier 5359c09757bSEric Fiselier template <class... _Fs> 5369c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5379c09757bSEric Fiselier static constexpr auto __make_farray(_Fs&&... __fs) { 5389c09757bSEric Fiselier __std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>(); 5390849427fSzoecarver using __result = __farray<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>; 5409c09757bSEric Fiselier return __result{{_VSTD::forward<_Fs>(__fs)...}}; 5419c09757bSEric Fiselier } 5429c09757bSEric Fiselier 543d586f92cSArthur O'Dwyer template <size_t... _Is> 5449c09757bSEric Fiselier struct __dispatcher { 5459c09757bSEric Fiselier template <class _Fp, class... _Vs> 5469c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5479c09757bSEric Fiselier static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) { 5481b9c5f60SNikolas Klauser return _VSTD::__invoke( 5499c09757bSEric Fiselier static_cast<_Fp>(__f), 5509c09757bSEric Fiselier __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...); 55135d22691SMichael Park } 55235d22691SMichael Park }; 55335d22691SMichael Park 5549c09757bSEric Fiselier template <class _Fp, class... _Vs, size_t... _Is> 555057028edSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5569c09757bSEric Fiselier static constexpr auto __make_dispatch(index_sequence<_Is...>) { 5579c09757bSEric Fiselier return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>; 5580d3d8de0SEric Fiselier } 559057028edSEric Fiselier 5609c09757bSEric Fiselier template <size_t _Ip, class _Fp, class... _Vs> 5619c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5629c09757bSEric Fiselier static constexpr auto __make_fdiagonal_impl() { 5639c09757bSEric Fiselier return __make_dispatch<_Fp, _Vs...>( 5643c6bd176SNikolas Klauser index_sequence<((void)__type_identity<_Vs>{}, _Ip)...>{}); 565a175a965SMichael Park } 5669c09757bSEric Fiselier 5679c09757bSEric Fiselier template <class _Fp, class... _Vs, size_t... _Is> 5689c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5699c09757bSEric Fiselier static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) { 5709c09757bSEric Fiselier return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...); 571057028edSEric Fiselier } 5729c09757bSEric Fiselier 5739c09757bSEric Fiselier template <class _Fp, class _Vp, class... _Vs> 5749c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5759c09757bSEric Fiselier static constexpr auto __make_fdiagonal() { 5769c09757bSEric Fiselier constexpr size_t _Np = __uncvref_t<_Vp>::__size(); 5779c09757bSEric Fiselier static_assert(__all<(_Np == __uncvref_t<_Vs>::__size())...>::value); 5789c09757bSEric Fiselier return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{}); 57935d22691SMichael Park } 5809c09757bSEric Fiselier 5819c09757bSEric Fiselier template <class _Fp, class... _Vs, size_t... _Is> 5829c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5839c09757bSEric Fiselier static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) { 5849c09757bSEric Fiselier return __make_dispatch<_Fp, _Vs...>(__is); 5859c09757bSEric Fiselier } 5869c09757bSEric Fiselier 5879c09757bSEric Fiselier template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls> 5889c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5899c09757bSEric Fiselier static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>, 5909c09757bSEric Fiselier index_sequence<_Js...>, 5919c09757bSEric Fiselier _Ls... __ls) { 5929c09757bSEric Fiselier return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>( 5939c09757bSEric Fiselier index_sequence<_Is..., _Js>{}, __ls...)...); 5949c09757bSEric Fiselier } 5959c09757bSEric Fiselier 5969c09757bSEric Fiselier template <class _Fp, class... _Vs> 5979c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 5989c09757bSEric Fiselier static constexpr auto __make_fmatrix() { 5999c09757bSEric Fiselier return __make_fmatrix_impl<_Fp, _Vs...>( 6009c09757bSEric Fiselier index_sequence<>{}, make_index_sequence<__uncvref_t<_Vs>::__size()>{}...); 6010d3d8de0SEric Fiselier } 6020d3d8de0SEric Fiselier}; 6030d3d8de0SEric Fiselier 6040d3d8de0SEric Fiselierstruct __variant { 6059c09757bSEric Fiselier template <class _Visitor, class... _Vs> 6060d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 6070d3d8de0SEric Fiselier static constexpr decltype(auto) 6089c09757bSEric Fiselier __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { 6090d3d8de0SEric Fiselier return __base::__visit_alt_at(__index, 6109c09757bSEric Fiselier _VSTD::forward<_Visitor>(__visitor), 611057028edSEric Fiselier _VSTD::forward<_Vs>(__vs).__impl...); 6120d3d8de0SEric Fiselier } 6130d3d8de0SEric Fiselier 6149c09757bSEric Fiselier template <class _Visitor, class... _Vs> 6150d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 6169c09757bSEric Fiselier static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, 6179c09757bSEric Fiselier _Vs&&... __vs) { 6180324b46cSMarek Kurdej return __base::__visit_alt( 6190324b46cSMarek Kurdej _VSTD::forward<_Visitor>(__visitor), 6200324b46cSMarek Kurdej _VSTD::__as_variant(_VSTD::forward<_Vs>(__vs)).__impl...); 621057028edSEric Fiselier } 622057028edSEric Fiselier 6239c09757bSEric Fiselier template <class _Visitor, class... _Vs> 624057028edSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 6259c09757bSEric Fiselier static constexpr decltype(auto) 6269c09757bSEric Fiselier __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { 6279c09757bSEric Fiselier return __visit_alt_at( 6289c09757bSEric Fiselier __index, 6299c09757bSEric Fiselier __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)), 6309c09757bSEric Fiselier _VSTD::forward<_Vs>(__vs)...); 6319c09757bSEric Fiselier } 6329c09757bSEric Fiselier 6339c09757bSEric Fiselier template <class _Visitor, class... _Vs> 6349c09757bSEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 6359c09757bSEric Fiselier static constexpr decltype(auto) __visit_value(_Visitor&& __visitor, 6369c09757bSEric Fiselier _Vs&&... __vs) { 6379c09757bSEric Fiselier return __visit_alt( 6389c09757bSEric Fiselier __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)), 6390d3d8de0SEric Fiselier _VSTD::forward<_Vs>(__vs)...); 6400d3d8de0SEric Fiselier } 6410324b46cSMarek Kurdej 64251faba35SRuslan Arutyunyan#if _LIBCPP_STD_VER > 17 64351faba35SRuslan Arutyunyan template <class _Rp, class _Visitor, class... _Vs> 64451faba35SRuslan Arutyunyan inline _LIBCPP_INLINE_VISIBILITY 64551faba35SRuslan Arutyunyan static constexpr _Rp __visit_value(_Visitor&& __visitor, 64651faba35SRuslan Arutyunyan _Vs&&... __vs) { 64751faba35SRuslan Arutyunyan return __visit_alt( 64851faba35SRuslan Arutyunyan __make_value_visitor<_Rp>(_VSTD::forward<_Visitor>(__visitor)), 64951faba35SRuslan Arutyunyan _VSTD::forward<_Vs>(__vs)...); 65051faba35SRuslan Arutyunyan } 65151faba35SRuslan Arutyunyan#endif 6520d3d8de0SEric Fiselier 6530d3d8de0SEric Fiselierprivate: 6549c09757bSEric Fiselier template <class _Visitor, class... _Values> 6550d3d8de0SEric Fiselier static constexpr void __std_visit_exhaustive_visitor_check() { 6569c09757bSEric Fiselier static_assert(is_invocable_v<_Visitor, _Values...>, 6570d3d8de0SEric Fiselier "`std::visit` requires the visitor to be exhaustive."); 6580d3d8de0SEric Fiselier } 6590d3d8de0SEric Fiselier 6609c09757bSEric Fiselier template <class _Visitor> 6610d3d8de0SEric Fiselier struct __value_visitor { 6620d3d8de0SEric Fiselier template <class... _Alts> 6630d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 6640d3d8de0SEric Fiselier constexpr decltype(auto) operator()(_Alts&&... __alts) const { 6650d3d8de0SEric Fiselier __std_visit_exhaustive_visitor_check< 6669c09757bSEric Fiselier _Visitor, 6679c09757bSEric Fiselier decltype((_VSTD::forward<_Alts>(__alts).__value))...>(); 6681b9c5f60SNikolas Klauser return _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor), 6690d3d8de0SEric Fiselier _VSTD::forward<_Alts>(__alts).__value...); 6700d3d8de0SEric Fiselier } 6719c09757bSEric Fiselier _Visitor&& __visitor; 6720d3d8de0SEric Fiselier }; 6730d3d8de0SEric Fiselier 67451faba35SRuslan Arutyunyan#if _LIBCPP_STD_VER > 17 67551faba35SRuslan Arutyunyan template <class _Rp, class _Visitor> 67651faba35SRuslan Arutyunyan struct __value_visitor_return_type { 67751faba35SRuslan Arutyunyan template <class... _Alts> 67851faba35SRuslan Arutyunyan inline _LIBCPP_INLINE_VISIBILITY 67951faba35SRuslan Arutyunyan constexpr _Rp operator()(_Alts&&... __alts) const { 68051faba35SRuslan Arutyunyan __std_visit_exhaustive_visitor_check< 68151faba35SRuslan Arutyunyan _Visitor, 68251faba35SRuslan Arutyunyan decltype((_VSTD::forward<_Alts>(__alts).__value))...>(); 68351faba35SRuslan Arutyunyan if constexpr (is_void_v<_Rp>) { 6841b9c5f60SNikolas Klauser _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor), 68551faba35SRuslan Arutyunyan _VSTD::forward<_Alts>(__alts).__value...); 68651faba35SRuslan Arutyunyan } 68751faba35SRuslan Arutyunyan else { 6881b9c5f60SNikolas Klauser return _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor), 68951faba35SRuslan Arutyunyan _VSTD::forward<_Alts>(__alts).__value...); 69051faba35SRuslan Arutyunyan } 69151faba35SRuslan Arutyunyan } 69251faba35SRuslan Arutyunyan 69351faba35SRuslan Arutyunyan _Visitor&& __visitor; 69451faba35SRuslan Arutyunyan }; 69551faba35SRuslan Arutyunyan#endif 69651faba35SRuslan Arutyunyan 6979c09757bSEric Fiselier template <class _Visitor> 6980d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 6999c09757bSEric Fiselier static constexpr auto __make_value_visitor(_Visitor&& __visitor) { 7009c09757bSEric Fiselier return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)}; 7010d3d8de0SEric Fiselier } 70251faba35SRuslan Arutyunyan 70351faba35SRuslan Arutyunyan#if _LIBCPP_STD_VER > 17 70451faba35SRuslan Arutyunyan template <class _Rp, class _Visitor> 70551faba35SRuslan Arutyunyan inline _LIBCPP_INLINE_VISIBILITY 70651faba35SRuslan Arutyunyan static constexpr auto __make_value_visitor(_Visitor&& __visitor) { 70751faba35SRuslan Arutyunyan return __value_visitor_return_type<_Rp, _Visitor>{_VSTD::forward<_Visitor>(__visitor)}; 70851faba35SRuslan Arutyunyan } 70951faba35SRuslan Arutyunyan#endif 710a206d991SNico Weber}; 7110d3d8de0SEric Fiselier 7120d3d8de0SEric Fiselier} // namespace __visitation 7130d3d8de0SEric Fiselier 7140d3d8de0SEric Fiseliertemplate <size_t _Index, class _Tp> 715e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS __alt { 7160d3d8de0SEric Fiselier using __value_type = _Tp; 7170d3d8de0SEric Fiselier 7180d3d8de0SEric Fiselier template <class... _Args> 7190d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 7200d3d8de0SEric Fiselier explicit constexpr __alt(in_place_t, _Args&&... __args) 7210d3d8de0SEric Fiselier : __value(_VSTD::forward<_Args>(__args)...) {} 7220d3d8de0SEric Fiselier 7230d3d8de0SEric Fiselier __value_type __value; 7240d3d8de0SEric Fiselier}; 7250d3d8de0SEric Fiselier 7260d3d8de0SEric Fiseliertemplate <_Trait _DestructibleTrait, size_t _Index, class... _Types> 727e2f2d1edSEric Fiselierunion _LIBCPP_TEMPLATE_VIS __union; 7280d3d8de0SEric Fiselier 7290d3d8de0SEric Fiseliertemplate <_Trait _DestructibleTrait, size_t _Index> 730e2f2d1edSEric Fiselierunion _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {}; 7310d3d8de0SEric Fiselier 7320d3d8de0SEric Fiselier#define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \ 7330d3d8de0SEric Fiselier template <size_t _Index, class _Tp, class... _Types> \ 734e2f2d1edSEric Fiselier union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, \ 7350d3d8de0SEric Fiselier _Index, \ 7360d3d8de0SEric Fiselier _Tp, \ 7370d3d8de0SEric Fiselier _Types...> { \ 7380d3d8de0SEric Fiselier public: \ 7390d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY \ 7400d3d8de0SEric Fiselier explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \ 7410d3d8de0SEric Fiselier \ 7420d3d8de0SEric Fiselier template <class... _Args> \ 7430d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY \ 7440d3d8de0SEric Fiselier explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \ 7450d3d8de0SEric Fiselier : __head(in_place, _VSTD::forward<_Args>(__args)...) {} \ 7460d3d8de0SEric Fiselier \ 7470d3d8de0SEric Fiselier template <size_t _Ip, class... _Args> \ 7480d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY \ 7490d3d8de0SEric Fiselier explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \ 7500d3d8de0SEric Fiselier : __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \ 7510d3d8de0SEric Fiselier \ 7520d3d8de0SEric Fiselier __union(const __union&) = default; \ 7530d3d8de0SEric Fiselier __union(__union&&) = default; \ 7540d3d8de0SEric Fiselier \ 7550d3d8de0SEric Fiselier destructor \ 7560d3d8de0SEric Fiselier \ 7570d3d8de0SEric Fiselier __union& operator=(const __union&) = default; \ 7580d3d8de0SEric Fiselier __union& operator=(__union&&) = default; \ 7590d3d8de0SEric Fiselier \ 7600d3d8de0SEric Fiselier private: \ 7610d3d8de0SEric Fiselier char __dummy; \ 7620d3d8de0SEric Fiselier __alt<_Index, _Tp> __head; \ 7630d3d8de0SEric Fiselier __union<destructible_trait, _Index + 1, _Types...> __tail; \ 7640d3d8de0SEric Fiselier \ 7650d3d8de0SEric Fiselier friend struct __access::__union; \ 7660d3d8de0SEric Fiselier } 7670d3d8de0SEric Fiselier 7680d3d8de0SEric Fiselier_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;); 7690d3d8de0SEric Fiselier_LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union() {}); 7700d3d8de0SEric Fiselier_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;); 7710d3d8de0SEric Fiselier 7720d3d8de0SEric Fiselier#undef _LIBCPP_VARIANT_UNION 7730d3d8de0SEric Fiselier 7740d3d8de0SEric Fiseliertemplate <_Trait _DestructibleTrait, class... _Types> 775e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __base { 7760d3d8de0SEric Fiselierpublic: 7770ed52538SEric Fiselier using __index_t = __variant_index_t<sizeof...(_Types)>; 7780ed52538SEric Fiselier 7790d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 780*b48c5010SNikolas Klauser explicit constexpr __base(__valueless_t __tag) noexcept 781*b48c5010SNikolas Klauser : __data(__tag), __index(__variant_npos<__index_t>) {} 7820d3d8de0SEric Fiselier 7830d3d8de0SEric Fiselier template <size_t _Ip, class... _Args> 7840d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 7850d3d8de0SEric Fiselier explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args) 786cb3ef156SEric Fiselier : 787cb3ef156SEric Fiselier __data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...), 788cb3ef156SEric Fiselier __index(_Ip) {} 7890d3d8de0SEric Fiselier 7900d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 7910d3d8de0SEric Fiselier constexpr bool valueless_by_exception() const noexcept { 7920d3d8de0SEric Fiselier return index() == variant_npos; 7930d3d8de0SEric Fiselier } 7940d3d8de0SEric Fiselier 7950d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 7960d3d8de0SEric Fiselier constexpr size_t index() const noexcept { 7970ed52538SEric Fiselier return __index == __variant_npos<__index_t> ? variant_npos : __index; 7980d3d8de0SEric Fiselier } 7990d3d8de0SEric Fiselier 8000d3d8de0SEric Fiselierprotected: 8010d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 8020d3d8de0SEric Fiselier constexpr auto&& __as_base() & { return *this; } 8030d3d8de0SEric Fiselier 8040d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 8050d3d8de0SEric Fiselier constexpr auto&& __as_base() && { return _VSTD::move(*this); } 8060d3d8de0SEric Fiselier 8070d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 8080d3d8de0SEric Fiselier constexpr auto&& __as_base() const & { return *this; } 8090d3d8de0SEric Fiselier 8100d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 8110d3d8de0SEric Fiselier constexpr auto&& __as_base() const && { return _VSTD::move(*this); } 8120d3d8de0SEric Fiselier 8130d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 8140d3d8de0SEric Fiselier static constexpr size_t __size() { return sizeof...(_Types); } 8150d3d8de0SEric Fiselier 8160d3d8de0SEric Fiselier __union<_DestructibleTrait, 0, _Types...> __data; 8170ed52538SEric Fiselier __index_t __index; 8180d3d8de0SEric Fiselier 8190d3d8de0SEric Fiselier friend struct __access::__base; 8200d3d8de0SEric Fiselier friend struct __visitation::__base; 8210d3d8de0SEric Fiselier}; 8220d3d8de0SEric Fiselier 8230d3d8de0SEric Fiseliertemplate <class _Traits, _Trait = _Traits::__destructible_trait> 824fe7245b7SLouis Dionneclass _LIBCPP_TEMPLATE_VIS __dtor; 8250d3d8de0SEric Fiselier 8260d3d8de0SEric Fiselier#define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor, destroy) \ 8270d3d8de0SEric Fiselier template <class... _Types> \ 828fe7245b7SLouis Dionne class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, \ 8290d3d8de0SEric Fiselier destructible_trait> \ 8300d3d8de0SEric Fiselier : public __base<destructible_trait, _Types...> { \ 8310d3d8de0SEric Fiselier using __base_type = __base<destructible_trait, _Types...>; \ 8320ed52538SEric Fiselier using __index_t = typename __base_type::__index_t; \ 8330d3d8de0SEric Fiselier \ 8340d3d8de0SEric Fiselier public: \ 8350d3d8de0SEric Fiselier using __base_type::__base_type; \ 8360d3d8de0SEric Fiselier using __base_type::operator=; \ 8370d3d8de0SEric Fiselier \ 838fe7245b7SLouis Dionne __dtor(const __dtor&) = default; \ 839fe7245b7SLouis Dionne __dtor(__dtor&&) = default; \ 8400d3d8de0SEric Fiselier destructor \ 841fe7245b7SLouis Dionne __dtor& operator=(const __dtor&) = default; \ 842fe7245b7SLouis Dionne __dtor& operator=(__dtor&&) = default; \ 8430d3d8de0SEric Fiselier \ 8440d3d8de0SEric Fiselier protected: \ 8450d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY \ 8460d3d8de0SEric Fiselier destroy \ 8470d3d8de0SEric Fiselier } 8480d3d8de0SEric Fiselier 8490d3d8de0SEric Fiselier_LIBCPP_VARIANT_DESTRUCTOR( 8500d3d8de0SEric Fiselier _Trait::_TriviallyAvailable, 851fe7245b7SLouis Dionne ~__dtor() = default;, 8520ed52538SEric Fiselier void __destroy() noexcept { this->__index = __variant_npos<__index_t>; }); 8530d3d8de0SEric Fiselier 8540d3d8de0SEric Fiselier_LIBCPP_VARIANT_DESTRUCTOR( 8550d3d8de0SEric Fiselier _Trait::_Available, 856fe7245b7SLouis Dionne ~__dtor() { __destroy(); }, 8570d3d8de0SEric Fiselier void __destroy() noexcept { 8580d3d8de0SEric Fiselier if (!this->valueless_by_exception()) { 8590d3d8de0SEric Fiselier __visitation::__base::__visit_alt( 8600d3d8de0SEric Fiselier [](auto& __alt) noexcept { 8618ea7ede7SMarshall Clow using __alt_type = __uncvref_t<decltype(__alt)>; 8620d3d8de0SEric Fiselier __alt.~__alt_type(); 8630d3d8de0SEric Fiselier }, 8640d3d8de0SEric Fiselier *this); 8650d3d8de0SEric Fiselier } 8660ed52538SEric Fiselier this->__index = __variant_npos<__index_t>; 8670d3d8de0SEric Fiselier }); 8680d3d8de0SEric Fiselier 8690d3d8de0SEric Fiselier_LIBCPP_VARIANT_DESTRUCTOR( 8700d3d8de0SEric Fiselier _Trait::_Unavailable, 871fe7245b7SLouis Dionne ~__dtor() = delete;, 8720d3d8de0SEric Fiselier void __destroy() noexcept = delete;); 8730d3d8de0SEric Fiselier 8740d3d8de0SEric Fiselier#undef _LIBCPP_VARIANT_DESTRUCTOR 8750d3d8de0SEric Fiselier 8760d3d8de0SEric Fiseliertemplate <class _Traits> 877fe7245b7SLouis Dionneclass _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> { 878fe7245b7SLouis Dionne using __base_type = __dtor<_Traits>; 8790d3d8de0SEric Fiselier 8800d3d8de0SEric Fiselierpublic: 8810d3d8de0SEric Fiselier using __base_type::__base_type; 8820d3d8de0SEric Fiselier using __base_type::operator=; 8830d3d8de0SEric Fiselier 8840d3d8de0SEric Fiselierprotected: 8850d3d8de0SEric Fiselier template <size_t _Ip, class _Tp, class... _Args> 8860d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 88725514755SEric Fiselier static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) { 8889c09757bSEric Fiselier ::new ((void*)_VSTD::addressof(__a)) 8890d3d8de0SEric Fiselier __alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...); 8909c09757bSEric Fiselier return __a.__value; 8910d3d8de0SEric Fiselier } 8920d3d8de0SEric Fiselier 8930d3d8de0SEric Fiselier template <class _Rhs> 8940d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 895fe7245b7SLouis Dionne static void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) { 8960d3d8de0SEric Fiselier __lhs.__destroy(); 8970d3d8de0SEric Fiselier if (!__rhs.valueless_by_exception()) { 8980d3d8de0SEric Fiselier __visitation::__base::__visit_alt_at( 8990d3d8de0SEric Fiselier __rhs.index(), 9000d3d8de0SEric Fiselier [](auto& __lhs_alt, auto&& __rhs_alt) { 9010d3d8de0SEric Fiselier __construct_alt( 9020d3d8de0SEric Fiselier __lhs_alt, 9030d3d8de0SEric Fiselier _VSTD::forward<decltype(__rhs_alt)>(__rhs_alt).__value); 9040d3d8de0SEric Fiselier }, 9050d3d8de0SEric Fiselier __lhs, _VSTD::forward<_Rhs>(__rhs)); 9060d3d8de0SEric Fiselier __lhs.__index = __rhs.index(); 9070d3d8de0SEric Fiselier } 9080d3d8de0SEric Fiselier } 9090d3d8de0SEric Fiselier}; 9100d3d8de0SEric Fiselier 9110d3d8de0SEric Fiseliertemplate <class _Traits, _Trait = _Traits::__move_constructible_trait> 912e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __move_constructor; 9130d3d8de0SEric Fiselier 9140d3d8de0SEric Fiselier#define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, \ 9150d3d8de0SEric Fiselier move_constructor) \ 9160d3d8de0SEric Fiselier template <class... _Types> \ 917e2f2d1edSEric Fiselier class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, \ 9180d3d8de0SEric Fiselier move_constructible_trait> \ 919fe7245b7SLouis Dionne : public __ctor<__traits<_Types...>> { \ 920fe7245b7SLouis Dionne using __base_type = __ctor<__traits<_Types...>>; \ 9210d3d8de0SEric Fiselier \ 9220d3d8de0SEric Fiselier public: \ 9230d3d8de0SEric Fiselier using __base_type::__base_type; \ 9240d3d8de0SEric Fiselier using __base_type::operator=; \ 9250d3d8de0SEric Fiselier \ 9260d3d8de0SEric Fiselier __move_constructor(const __move_constructor&) = default; \ 9270d3d8de0SEric Fiselier move_constructor \ 9280d3d8de0SEric Fiselier ~__move_constructor() = default; \ 9290d3d8de0SEric Fiselier __move_constructor& operator=(const __move_constructor&) = default; \ 9300d3d8de0SEric Fiselier __move_constructor& operator=(__move_constructor&&) = default; \ 9310d3d8de0SEric Fiselier } 9320d3d8de0SEric Fiselier 9330d3d8de0SEric Fiselier_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( 9340d3d8de0SEric Fiselier _Trait::_TriviallyAvailable, 9350d3d8de0SEric Fiselier __move_constructor(__move_constructor&& __that) = default;); 9360d3d8de0SEric Fiselier 9370d3d8de0SEric Fiselier_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( 9380d3d8de0SEric Fiselier _Trait::_Available, 9390d3d8de0SEric Fiselier __move_constructor(__move_constructor&& __that) noexcept( 9400d3d8de0SEric Fiselier __all<is_nothrow_move_constructible_v<_Types>...>::value) 9410d3d8de0SEric Fiselier : __move_constructor(__valueless_t{}) { 9420d3d8de0SEric Fiselier this->__generic_construct(*this, _VSTD::move(__that)); 9430d3d8de0SEric Fiselier }); 9440d3d8de0SEric Fiselier 9450d3d8de0SEric Fiselier_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( 9460d3d8de0SEric Fiselier _Trait::_Unavailable, 9470d3d8de0SEric Fiselier __move_constructor(__move_constructor&&) = delete;); 9480d3d8de0SEric Fiselier 9490d3d8de0SEric Fiselier#undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR 9500d3d8de0SEric Fiselier 9510d3d8de0SEric Fiseliertemplate <class _Traits, _Trait = _Traits::__copy_constructible_trait> 952e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __copy_constructor; 9530d3d8de0SEric Fiselier 9540d3d8de0SEric Fiselier#define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \ 9550d3d8de0SEric Fiselier copy_constructor) \ 9560d3d8de0SEric Fiselier template <class... _Types> \ 957e2f2d1edSEric Fiselier class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \ 9580d3d8de0SEric Fiselier copy_constructible_trait> \ 9590d3d8de0SEric Fiselier : public __move_constructor<__traits<_Types...>> { \ 9600d3d8de0SEric Fiselier using __base_type = __move_constructor<__traits<_Types...>>; \ 9610d3d8de0SEric Fiselier \ 9620d3d8de0SEric Fiselier public: \ 9630d3d8de0SEric Fiselier using __base_type::__base_type; \ 9640d3d8de0SEric Fiselier using __base_type::operator=; \ 9650d3d8de0SEric Fiselier \ 9660d3d8de0SEric Fiselier copy_constructor \ 9670d3d8de0SEric Fiselier __copy_constructor(__copy_constructor&&) = default; \ 9680d3d8de0SEric Fiselier ~__copy_constructor() = default; \ 9690d3d8de0SEric Fiselier __copy_constructor& operator=(const __copy_constructor&) = default; \ 9700d3d8de0SEric Fiselier __copy_constructor& operator=(__copy_constructor&&) = default; \ 9710d3d8de0SEric Fiselier } 9720d3d8de0SEric Fiselier 9730d3d8de0SEric Fiselier_LIBCPP_VARIANT_COPY_CONSTRUCTOR( 9740d3d8de0SEric Fiselier _Trait::_TriviallyAvailable, 9750d3d8de0SEric Fiselier __copy_constructor(const __copy_constructor& __that) = default;); 9760d3d8de0SEric Fiselier 9770d3d8de0SEric Fiselier_LIBCPP_VARIANT_COPY_CONSTRUCTOR( 9780d3d8de0SEric Fiselier _Trait::_Available, 9790d3d8de0SEric Fiselier __copy_constructor(const __copy_constructor& __that) 9800d3d8de0SEric Fiselier : __copy_constructor(__valueless_t{}) { 9810d3d8de0SEric Fiselier this->__generic_construct(*this, __that); 9820d3d8de0SEric Fiselier }); 9830d3d8de0SEric Fiselier 9840d3d8de0SEric Fiselier_LIBCPP_VARIANT_COPY_CONSTRUCTOR( 9850d3d8de0SEric Fiselier _Trait::_Unavailable, 9860d3d8de0SEric Fiselier __copy_constructor(const __copy_constructor&) = delete;); 9870d3d8de0SEric Fiselier 9880d3d8de0SEric Fiselier#undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR 9890d3d8de0SEric Fiselier 9900d3d8de0SEric Fiseliertemplate <class _Traits> 991e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> { 9920d3d8de0SEric Fiselier using __base_type = __copy_constructor<_Traits>; 9930d3d8de0SEric Fiselier 9940d3d8de0SEric Fiselierpublic: 9950d3d8de0SEric Fiselier using __base_type::__base_type; 9960d3d8de0SEric Fiselier using __base_type::operator=; 9970d3d8de0SEric Fiselier 9980d3d8de0SEric Fiselier template <size_t _Ip, class... _Args> 9990d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 100025514755SEric Fiselier auto& __emplace(_Args&&... __args) { 10010d3d8de0SEric Fiselier this->__destroy(); 100225514755SEric Fiselier auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this), 10030d3d8de0SEric Fiselier _VSTD::forward<_Args>(__args)...); 10040d3d8de0SEric Fiselier this->__index = _Ip; 100525514755SEric Fiselier return __res; 10060d3d8de0SEric Fiselier } 10070d3d8de0SEric Fiselier 10080d3d8de0SEric Fiselierprotected: 1009a8b05748SMichael Park template <size_t _Ip, class _Tp, class _Arg> 10100d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 1011a8b05748SMichael Park void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) { 10120d3d8de0SEric Fiselier if (this->index() == _Ip) { 10130d3d8de0SEric Fiselier __a.__value = _VSTD::forward<_Arg>(__arg); 10140d3d8de0SEric Fiselier } else { 10150d3d8de0SEric Fiselier struct { 10160d3d8de0SEric Fiselier void operator()(true_type) const { 1017a8b05748SMichael Park __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg)); 10180d3d8de0SEric Fiselier } 10190d3d8de0SEric Fiselier void operator()(false_type) const { 1020a8b05748SMichael Park __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg))); 10210d3d8de0SEric Fiselier } 10220d3d8de0SEric Fiselier __assignment* __this; 10230d3d8de0SEric Fiselier _Arg&& __arg; 10240d3d8de0SEric Fiselier } __impl{this, _VSTD::forward<_Arg>(__arg)}; 1025a8b05748SMichael Park __impl(bool_constant<is_nothrow_constructible_v<_Tp, _Arg> || 1026a8b05748SMichael Park !is_nothrow_move_constructible_v<_Tp>>{}); 10270d3d8de0SEric Fiselier } 10280d3d8de0SEric Fiselier } 10290d3d8de0SEric Fiselier 10300d3d8de0SEric Fiselier template <class _That> 10310d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 10320d3d8de0SEric Fiselier void __generic_assign(_That&& __that) { 10330d3d8de0SEric Fiselier if (this->valueless_by_exception() && __that.valueless_by_exception()) { 10340d3d8de0SEric Fiselier // do nothing. 10350d3d8de0SEric Fiselier } else if (__that.valueless_by_exception()) { 10360d3d8de0SEric Fiselier this->__destroy(); 10370d3d8de0SEric Fiselier } else { 10380d3d8de0SEric Fiselier __visitation::__base::__visit_alt_at( 10390d3d8de0SEric Fiselier __that.index(), 10400d3d8de0SEric Fiselier [this](auto& __this_alt, auto&& __that_alt) { 10410d3d8de0SEric Fiselier this->__assign_alt( 10420d3d8de0SEric Fiselier __this_alt, 1043a8b05748SMichael Park _VSTD::forward<decltype(__that_alt)>(__that_alt).__value); 10440d3d8de0SEric Fiselier }, 10450d3d8de0SEric Fiselier *this, _VSTD::forward<_That>(__that)); 10460d3d8de0SEric Fiselier } 10470d3d8de0SEric Fiselier } 10480d3d8de0SEric Fiselier}; 10490d3d8de0SEric Fiselier 10500d3d8de0SEric Fiseliertemplate <class _Traits, _Trait = _Traits::__move_assignable_trait> 1051e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __move_assignment; 10520d3d8de0SEric Fiselier 10530d3d8de0SEric Fiselier#define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \ 10540d3d8de0SEric Fiselier move_assignment) \ 10550d3d8de0SEric Fiselier template <class... _Types> \ 1056e2f2d1edSEric Fiselier class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \ 10570d3d8de0SEric Fiselier move_assignable_trait> \ 10580d3d8de0SEric Fiselier : public __assignment<__traits<_Types...>> { \ 10590d3d8de0SEric Fiselier using __base_type = __assignment<__traits<_Types...>>; \ 10600d3d8de0SEric Fiselier \ 10610d3d8de0SEric Fiselier public: \ 10620d3d8de0SEric Fiselier using __base_type::__base_type; \ 10630d3d8de0SEric Fiselier using __base_type::operator=; \ 10640d3d8de0SEric Fiselier \ 10650d3d8de0SEric Fiselier __move_assignment(const __move_assignment&) = default; \ 10660d3d8de0SEric Fiselier __move_assignment(__move_assignment&&) = default; \ 10670d3d8de0SEric Fiselier ~__move_assignment() = default; \ 10680d3d8de0SEric Fiselier __move_assignment& operator=(const __move_assignment&) = default; \ 10690d3d8de0SEric Fiselier move_assignment \ 10700d3d8de0SEric Fiselier } 10710d3d8de0SEric Fiselier 10720d3d8de0SEric Fiselier_LIBCPP_VARIANT_MOVE_ASSIGNMENT( 10730d3d8de0SEric Fiselier _Trait::_TriviallyAvailable, 10740d3d8de0SEric Fiselier __move_assignment& operator=(__move_assignment&& __that) = default;); 10750d3d8de0SEric Fiselier 10760d3d8de0SEric Fiselier_LIBCPP_VARIANT_MOVE_ASSIGNMENT( 10770d3d8de0SEric Fiselier _Trait::_Available, 10780d3d8de0SEric Fiselier __move_assignment& operator=(__move_assignment&& __that) noexcept( 10790d3d8de0SEric Fiselier __all<(is_nothrow_move_constructible_v<_Types> && 10800d3d8de0SEric Fiselier is_nothrow_move_assignable_v<_Types>)...>::value) { 10810d3d8de0SEric Fiselier this->__generic_assign(_VSTD::move(__that)); 10820d3d8de0SEric Fiselier return *this; 10830d3d8de0SEric Fiselier }); 10840d3d8de0SEric Fiselier 10850d3d8de0SEric Fiselier_LIBCPP_VARIANT_MOVE_ASSIGNMENT( 10860d3d8de0SEric Fiselier _Trait::_Unavailable, 10870d3d8de0SEric Fiselier __move_assignment& operator=(__move_assignment&&) = delete;); 10880d3d8de0SEric Fiselier 10890d3d8de0SEric Fiselier#undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT 10900d3d8de0SEric Fiselier 10910d3d8de0SEric Fiseliertemplate <class _Traits, _Trait = _Traits::__copy_assignable_trait> 1092e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __copy_assignment; 10930d3d8de0SEric Fiselier 10940d3d8de0SEric Fiselier#define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \ 10950d3d8de0SEric Fiselier copy_assignment) \ 10960d3d8de0SEric Fiselier template <class... _Types> \ 1097e2f2d1edSEric Fiselier class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \ 10980d3d8de0SEric Fiselier copy_assignable_trait> \ 10990d3d8de0SEric Fiselier : public __move_assignment<__traits<_Types...>> { \ 11000d3d8de0SEric Fiselier using __base_type = __move_assignment<__traits<_Types...>>; \ 11010d3d8de0SEric Fiselier \ 11020d3d8de0SEric Fiselier public: \ 11030d3d8de0SEric Fiselier using __base_type::__base_type; \ 11040d3d8de0SEric Fiselier using __base_type::operator=; \ 11050d3d8de0SEric Fiselier \ 11060d3d8de0SEric Fiselier __copy_assignment(const __copy_assignment&) = default; \ 11070d3d8de0SEric Fiselier __copy_assignment(__copy_assignment&&) = default; \ 11080d3d8de0SEric Fiselier ~__copy_assignment() = default; \ 11090d3d8de0SEric Fiselier copy_assignment \ 11100d3d8de0SEric Fiselier __copy_assignment& operator=(__copy_assignment&&) = default; \ 11110d3d8de0SEric Fiselier } 11120d3d8de0SEric Fiselier 11130d3d8de0SEric Fiselier_LIBCPP_VARIANT_COPY_ASSIGNMENT( 11140d3d8de0SEric Fiselier _Trait::_TriviallyAvailable, 11150d3d8de0SEric Fiselier __copy_assignment& operator=(const __copy_assignment& __that) = default;); 11160d3d8de0SEric Fiselier 11170d3d8de0SEric Fiselier_LIBCPP_VARIANT_COPY_ASSIGNMENT( 11180d3d8de0SEric Fiselier _Trait::_Available, 11190d3d8de0SEric Fiselier __copy_assignment& operator=(const __copy_assignment& __that) { 11200d3d8de0SEric Fiselier this->__generic_assign(__that); 11210d3d8de0SEric Fiselier return *this; 11220d3d8de0SEric Fiselier }); 11230d3d8de0SEric Fiselier 11240d3d8de0SEric Fiselier_LIBCPP_VARIANT_COPY_ASSIGNMENT( 11250d3d8de0SEric Fiselier _Trait::_Unavailable, 11260d3d8de0SEric Fiselier __copy_assignment& operator=(const __copy_assignment&) = delete;); 11270d3d8de0SEric Fiselier 11280d3d8de0SEric Fiselier#undef _LIBCPP_VARIANT_COPY_ASSIGNMENT 11290d3d8de0SEric Fiselier 11300d3d8de0SEric Fiseliertemplate <class... _Types> 1131e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS __impl 11320d3d8de0SEric Fiselier : public __copy_assignment<__traits<_Types...>> { 11330d3d8de0SEric Fiselier using __base_type = __copy_assignment<__traits<_Types...>>; 11340d3d8de0SEric Fiselier 11350d3d8de0SEric Fiselierpublic: 1136e39095a3SLouis Dionne using __base_type::__base_type; // get in_place_index_t constructor & friends 1137e39095a3SLouis Dionne __impl(__impl const&) = default; 1138e39095a3SLouis Dionne __impl(__impl&&) = default; 1139e39095a3SLouis Dionne __impl& operator=(__impl const&) = default; 1140e39095a3SLouis Dionne __impl& operator=(__impl&&) = default; 11410d3d8de0SEric Fiselier 11420d3d8de0SEric Fiselier template <size_t _Ip, class _Arg> 11430d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 11440d3d8de0SEric Fiselier void __assign(_Arg&& __arg) { 11450d3d8de0SEric Fiselier this->__assign_alt(__access::__base::__get_alt<_Ip>(*this), 1146a8b05748SMichael Park _VSTD::forward<_Arg>(__arg)); 11470d3d8de0SEric Fiselier } 11480d3d8de0SEric Fiselier 11490d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 11500d3d8de0SEric Fiselier void __swap(__impl& __that) { 11510d3d8de0SEric Fiselier if (this->valueless_by_exception() && __that.valueless_by_exception()) { 11520d3d8de0SEric Fiselier // do nothing. 11530d3d8de0SEric Fiselier } else if (this->index() == __that.index()) { 11540d3d8de0SEric Fiselier __visitation::__base::__visit_alt_at( 11550d3d8de0SEric Fiselier this->index(), 11560d3d8de0SEric Fiselier [](auto& __this_alt, auto& __that_alt) { 11570d3d8de0SEric Fiselier using _VSTD::swap; 11580d3d8de0SEric Fiselier swap(__this_alt.__value, __that_alt.__value); 11590d3d8de0SEric Fiselier }, 11600d3d8de0SEric Fiselier *this, 11610d3d8de0SEric Fiselier __that); 11620d3d8de0SEric Fiselier } else { 11630d3d8de0SEric Fiselier __impl* __lhs = this; 11640d3d8de0SEric Fiselier __impl* __rhs = _VSTD::addressof(__that); 11650d3d8de0SEric Fiselier if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) { 11660d3d8de0SEric Fiselier _VSTD::swap(__lhs, __rhs); 11670d3d8de0SEric Fiselier } 11680d3d8de0SEric Fiselier __impl __tmp(_VSTD::move(*__rhs)); 11698fbd6d99SMichael Park#ifndef _LIBCPP_NO_EXCEPTIONS 11706ab3208dSMichael Park if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) { 1171ada2a8eaSMichael Park this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); 1172ada2a8eaSMichael Park } else { 11730d3d8de0SEric Fiselier // EXTENSION: When the move construction of `__lhs` into `__rhs` throws 11740d3d8de0SEric Fiselier // and `__tmp` is nothrow move constructible then we move `__tmp` back 11755517aa61SLouis Dionne // into `__rhs` and provide the strong exception safety guarantee. 11760d3d8de0SEric Fiselier try { 11770d3d8de0SEric Fiselier this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); 11780d3d8de0SEric Fiselier } catch (...) { 11790d3d8de0SEric Fiselier if (__tmp.__move_nothrow()) { 11800d3d8de0SEric Fiselier this->__generic_construct(*__rhs, _VSTD::move(__tmp)); 11810d3d8de0SEric Fiselier } 11820d3d8de0SEric Fiselier throw; 11830d3d8de0SEric Fiselier } 1184ada2a8eaSMichael Park } 11858fbd6d99SMichael Park#else 11868fbd6d99SMichael Park // this isn't consolidated with the `if constexpr` branch above due to 11878fbd6d99SMichael Park // `throw` being ill-formed with exceptions disabled even when discarded. 11888fbd6d99SMichael Park this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); 11898fbd6d99SMichael Park#endif 11900d3d8de0SEric Fiselier this->__generic_construct(*__lhs, _VSTD::move(__tmp)); 11910d3d8de0SEric Fiselier } 11920d3d8de0SEric Fiselier } 11930d3d8de0SEric Fiselier 11940d3d8de0SEric Fiselierprivate: 11950d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 11960d3d8de0SEric Fiselier bool __move_nothrow() const { 11970d3d8de0SEric Fiselier constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...}; 11980d3d8de0SEric Fiselier return this->valueless_by_exception() || __results[this->index()]; 11990d3d8de0SEric Fiselier } 12000d3d8de0SEric Fiselier}; 12010d3d8de0SEric Fiselier 1202194b337fSEric Fiselierstruct __no_narrowing_check { 1203194b337fSEric Fiselier template <class _Dest, class _Source> 12043c6bd176SNikolas Klauser using _Apply = __type_identity<_Dest>; 1205194b337fSEric Fiselier}; 1206194b337fSEric Fiselier 1207194b337fSEric Fiselierstruct __narrowing_check { 1208194b337fSEric Fiselier template <class _Dest> 12093c6bd176SNikolas Klauser static auto __test_impl(_Dest (&&)[1]) -> __type_identity<_Dest>; 1210194b337fSEric Fiselier template <class _Dest, class _Source> 12113557c7c1SLouis Dionne using _Apply _LIBCPP_NODEBUG = decltype(__test_impl<_Dest>({declval<_Source>()})); 1212194b337fSEric Fiselier}; 1213194b337fSEric Fiselier 1214194b337fSEric Fiseliertemplate <class _Dest, class _Source> 12153557c7c1SLouis Dionneusing __check_for_narrowing _LIBCPP_NODEBUG = 12164066978cSEric Fiselier typename _If< 1217194b337fSEric Fiselier#ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT 1218194b337fSEric Fiselier false && 1219194b337fSEric Fiselier#endif 1220194b337fSEric Fiselier is_arithmetic<_Dest>::value, 1221194b337fSEric Fiselier __narrowing_check, 1222194b337fSEric Fiselier __no_narrowing_check 1223194b337fSEric Fiselier >::template _Apply<_Dest, _Source>; 1224194b337fSEric Fiselier 12254066978cSEric Fiseliertemplate <class _Tp, size_t _Idx> 12264066978cSEric Fiselierstruct __overload { 12274513f0f0SZhihao Yuan template <class _Up> 1228aae0cb67SEric Fiselier auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>; 12290d3d8de0SEric Fiselier}; 12300d3d8de0SEric Fiselier 12314066978cSEric Fiseliertemplate <class _Tp, size_t> 12324066978cSEric Fiselierstruct __overload_bool { 12334513f0f0SZhihao Yuan template <class _Up, class _Ap = __uncvref_t<_Up>> 12344513f0f0SZhihao Yuan auto operator()(bool, _Up&&) const 12353c6bd176SNikolas Klauser -> enable_if_t<is_same_v<_Ap, bool>, __type_identity<_Tp>>; 12364513f0f0SZhihao Yuan}; 12374513f0f0SZhihao Yuan 12384066978cSEric Fiseliertemplate <size_t _Idx> 12394066978cSEric Fiselierstruct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {}; 12404066978cSEric Fiseliertemplate <size_t _Idx> 12414066978cSEric Fiselierstruct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {}; 12424066978cSEric Fiseliertemplate <size_t _Idx> 12434066978cSEric Fiselierstruct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {}; 12444066978cSEric Fiseliertemplate <size_t _Idx> 12454066978cSEric Fiselierstruct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {}; 12464066978cSEric Fiselier 12474066978cSEric Fiseliertemplate <class ..._Bases> 12484066978cSEric Fiselierstruct __all_overloads : _Bases... { 12494066978cSEric Fiselier void operator()() const; 12504066978cSEric Fiselier using _Bases::operator()...; 12514066978cSEric Fiselier}; 12524066978cSEric Fiselier 12534066978cSEric Fiseliertemplate <class IdxSeq> 12544066978cSEric Fiselierstruct __make_overloads_imp; 12554066978cSEric Fiselier 12564066978cSEric Fiseliertemplate <size_t ..._Idx> 12574066978cSEric Fiselierstruct __make_overloads_imp<__tuple_indices<_Idx...> > { 12584513f0f0SZhihao Yuan template <class ..._Types> 12593557c7c1SLouis Dionne using _Apply _LIBCPP_NODEBUG = __all_overloads<__overload<_Types, _Idx>...>; 12604066978cSEric Fiselier}; 12614066978cSEric Fiselier 12624513f0f0SZhihao Yuantemplate <class ..._Types> 12633557c7c1SLouis Dionneusing _MakeOverloads _LIBCPP_NODEBUG = typename __make_overloads_imp< 12644066978cSEric Fiselier __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>; 12654513f0f0SZhihao Yuan 12660d3d8de0SEric Fiseliertemplate <class _Tp, class... _Types> 12674513f0f0SZhihao Yuanusing __best_match_t = 12684066978cSEric Fiselier typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type; 12690d3d8de0SEric Fiselier 12709c52a19eSNikolas Klauser} // namespace __variant_detail 12710d3d8de0SEric Fiselier 12720d3d8de0SEric Fiseliertemplate <class... _Types> 1273e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS variant 12740d3d8de0SEric Fiselier : private __sfinae_ctor_base< 12750d3d8de0SEric Fiselier __all<is_copy_constructible_v<_Types>...>::value, 12760d3d8de0SEric Fiselier __all<is_move_constructible_v<_Types>...>::value>, 12770d3d8de0SEric Fiselier private __sfinae_assign_base< 12780d3d8de0SEric Fiselier __all<(is_copy_constructible_v<_Types> && 12790d3d8de0SEric Fiselier is_copy_assignable_v<_Types>)...>::value, 12800d3d8de0SEric Fiselier __all<(is_move_constructible_v<_Types> && 12810d3d8de0SEric Fiselier is_move_assignable_v<_Types>)...>::value> { 12820d3d8de0SEric Fiselier static_assert(0 < sizeof...(_Types), 12830d3d8de0SEric Fiselier "variant must consist of at least one alternative."); 12840d3d8de0SEric Fiselier 12850d3d8de0SEric Fiselier static_assert(__all<!is_array_v<_Types>...>::value, 12860d3d8de0SEric Fiselier "variant can not have an array type as an alternative."); 12870d3d8de0SEric Fiselier 12880d3d8de0SEric Fiselier static_assert(__all<!is_reference_v<_Types>...>::value, 12890d3d8de0SEric Fiselier "variant can not have a reference type as an alternative."); 12900d3d8de0SEric Fiselier 12910d3d8de0SEric Fiselier static_assert(__all<!is_void_v<_Types>...>::value, 12920d3d8de0SEric Fiselier "variant can not have a void type as an alternative."); 12930d3d8de0SEric Fiselier 12940d3d8de0SEric Fiselier using __first_type = variant_alternative_t<0, variant>; 12950d3d8de0SEric Fiselier 12960d3d8de0SEric Fiselierpublic: 12970d3d8de0SEric Fiselier template <bool _Dummy = true, 12980d3d8de0SEric Fiselier enable_if_t<__dependent_type<is_default_constructible<__first_type>, 12990d3d8de0SEric Fiselier _Dummy>::value, 13000d3d8de0SEric Fiselier int> = 0> 13010d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 13020d3d8de0SEric Fiselier constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>) 13030d3d8de0SEric Fiselier : __impl(in_place_index<0>) {} 13040d3d8de0SEric Fiselier 13050d3d8de0SEric Fiselier variant(const variant&) = default; 13060d3d8de0SEric Fiselier variant(variant&&) = default; 13070d3d8de0SEric Fiselier 13080d3d8de0SEric Fiselier template < 13090d3d8de0SEric Fiselier class _Arg, 1310655c4695SMarshall Clow enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0, 1311655c4695SMarshall Clow enable_if_t<!__is_inplace_type<__uncvref_t<_Arg>>::value, int> = 0, 1312655c4695SMarshall Clow enable_if_t<!__is_inplace_index<__uncvref_t<_Arg>>::value, int> = 0, 13130d3d8de0SEric Fiselier class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, 13140d3d8de0SEric Fiselier size_t _Ip = 13150d3d8de0SEric Fiselier __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 13160d3d8de0SEric Fiselier enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0> 13170d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 13180d3d8de0SEric Fiselier constexpr variant(_Arg&& __arg) noexcept( 13190d3d8de0SEric Fiselier is_nothrow_constructible_v<_Tp, _Arg>) 13200d3d8de0SEric Fiselier : __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {} 13210d3d8de0SEric Fiselier 13220d3d8de0SEric Fiselier template <size_t _Ip, class... _Args, 1323cd5e6a35SEric Fiselier class = enable_if_t<(_Ip < sizeof...(_Types)), int>, 1324cd5e6a35SEric Fiselier class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 1325cd5e6a35SEric Fiselier enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 13260d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 1327cd5e6a35SEric Fiselier explicit constexpr variant( 1328cd5e6a35SEric Fiselier in_place_index_t<_Ip>, 1329cd5e6a35SEric Fiselier _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>) 13300d3d8de0SEric Fiselier : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {} 13310d3d8de0SEric Fiselier 1332cd5e6a35SEric Fiselier template < 1333cd5e6a35SEric Fiselier size_t _Ip, 1334cd5e6a35SEric Fiselier class _Up, 1335cd5e6a35SEric Fiselier class... _Args, 1336cd5e6a35SEric Fiselier enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, 1337cd5e6a35SEric Fiselier class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 13380d3d8de0SEric Fiselier enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, 13390d3d8de0SEric Fiselier int> = 0> 13400d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 1341cd5e6a35SEric Fiselier explicit constexpr variant( 1342cd5e6a35SEric Fiselier in_place_index_t<_Ip>, 1343cd5e6a35SEric Fiselier initializer_list<_Up> __il, 1344cd5e6a35SEric Fiselier _Args&&... __args) noexcept( 1345cd5e6a35SEric Fiselier is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) 13460d3d8de0SEric Fiselier : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {} 13470d3d8de0SEric Fiselier 13480d3d8de0SEric Fiselier template < 13490d3d8de0SEric Fiselier class _Tp, 13500d3d8de0SEric Fiselier class... _Args, 13510d3d8de0SEric Fiselier size_t _Ip = 13520d3d8de0SEric Fiselier __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 13530d3d8de0SEric Fiselier enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 13540d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 13550d3d8de0SEric Fiselier explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept( 13560d3d8de0SEric Fiselier is_nothrow_constructible_v<_Tp, _Args...>) 13570d3d8de0SEric Fiselier : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {} 13580d3d8de0SEric Fiselier 13590d3d8de0SEric Fiselier template < 13600d3d8de0SEric Fiselier class _Tp, 13610d3d8de0SEric Fiselier class _Up, 13620d3d8de0SEric Fiselier class... _Args, 13630d3d8de0SEric Fiselier size_t _Ip = 13640d3d8de0SEric Fiselier __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 13650d3d8de0SEric Fiselier enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, 13660d3d8de0SEric Fiselier int> = 0> 13670d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 13680d3d8de0SEric Fiselier explicit constexpr variant( 13690d3d8de0SEric Fiselier in_place_type_t<_Tp>, 13700d3d8de0SEric Fiselier initializer_list<_Up> __il, 13710d3d8de0SEric Fiselier _Args&&... __args) noexcept( 13720d3d8de0SEric Fiselier is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>) 13730d3d8de0SEric Fiselier : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {} 13740d3d8de0SEric Fiselier 13750d3d8de0SEric Fiselier ~variant() = default; 13760d3d8de0SEric Fiselier 13770d3d8de0SEric Fiselier variant& operator=(const variant&) = default; 13780d3d8de0SEric Fiselier variant& operator=(variant&&) = default; 13790d3d8de0SEric Fiselier 13800d3d8de0SEric Fiselier template < 13810d3d8de0SEric Fiselier class _Arg, 1382655c4695SMarshall Clow enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0, 13830d3d8de0SEric Fiselier class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, 13840d3d8de0SEric Fiselier size_t _Ip = 13850d3d8de0SEric Fiselier __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 13860d3d8de0SEric Fiselier enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>, 13870d3d8de0SEric Fiselier int> = 0> 13880d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 13890d3d8de0SEric Fiselier variant& operator=(_Arg&& __arg) noexcept( 13900d3d8de0SEric Fiselier is_nothrow_assignable_v<_Tp&, _Arg> && 13910d3d8de0SEric Fiselier is_nothrow_constructible_v<_Tp, _Arg>) { 13920d3d8de0SEric Fiselier __impl.template __assign<_Ip>(_VSTD::forward<_Arg>(__arg)); 13930d3d8de0SEric Fiselier return *this; 13940d3d8de0SEric Fiselier } 13950d3d8de0SEric Fiselier 13960d3d8de0SEric Fiselier template < 13970d3d8de0SEric Fiselier size_t _Ip, 13980d3d8de0SEric Fiselier class... _Args, 13990d3d8de0SEric Fiselier enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, 14000d3d8de0SEric Fiselier class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 14010d3d8de0SEric Fiselier enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 14020d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 140325514755SEric Fiselier _Tp& emplace(_Args&&... __args) { 140425514755SEric Fiselier return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...); 14050d3d8de0SEric Fiselier } 14060d3d8de0SEric Fiselier 14070d3d8de0SEric Fiselier template < 14080d3d8de0SEric Fiselier size_t _Ip, 14090d3d8de0SEric Fiselier class _Up, 14100d3d8de0SEric Fiselier class... _Args, 14110d3d8de0SEric Fiselier enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, 14120d3d8de0SEric Fiselier class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, 14130d3d8de0SEric Fiselier enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, 14140d3d8de0SEric Fiselier int> = 0> 14150d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 141625514755SEric Fiselier _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) { 141725514755SEric Fiselier return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...); 14180d3d8de0SEric Fiselier } 14190d3d8de0SEric Fiselier 14200d3d8de0SEric Fiselier template < 14210d3d8de0SEric Fiselier class _Tp, 14220d3d8de0SEric Fiselier class... _Args, 14230d3d8de0SEric Fiselier size_t _Ip = 14240d3d8de0SEric Fiselier __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 14250d3d8de0SEric Fiselier enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> 14260d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 142725514755SEric Fiselier _Tp& emplace(_Args&&... __args) { 142825514755SEric Fiselier return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...); 14290d3d8de0SEric Fiselier } 14300d3d8de0SEric Fiselier 14310d3d8de0SEric Fiselier template < 14320d3d8de0SEric Fiselier class _Tp, 14330d3d8de0SEric Fiselier class _Up, 14340d3d8de0SEric Fiselier class... _Args, 14350d3d8de0SEric Fiselier size_t _Ip = 14360d3d8de0SEric Fiselier __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, 14370d3d8de0SEric Fiselier enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, 14380d3d8de0SEric Fiselier int> = 0> 14390d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 144025514755SEric Fiselier _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) { 144125514755SEric Fiselier return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...); 14420d3d8de0SEric Fiselier } 14430d3d8de0SEric Fiselier 14440d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 14450d3d8de0SEric Fiselier constexpr bool valueless_by_exception() const noexcept { 14460d3d8de0SEric Fiselier return __impl.valueless_by_exception(); 14470d3d8de0SEric Fiselier } 14480d3d8de0SEric Fiselier 14490d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 14500d3d8de0SEric Fiselier constexpr size_t index() const noexcept { return __impl.index(); } 14510d3d8de0SEric Fiselier 14520d3d8de0SEric Fiselier template < 14530d3d8de0SEric Fiselier bool _Dummy = true, 14540d3d8de0SEric Fiselier enable_if_t< 14550d3d8de0SEric Fiselier __all<( 14560d3d8de0SEric Fiselier __dependent_type<is_move_constructible<_Types>, _Dummy>::value && 14570d3d8de0SEric Fiselier __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value, 14580d3d8de0SEric Fiselier int> = 0> 14590d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 14600d3d8de0SEric Fiselier void swap(variant& __that) noexcept( 14610d3d8de0SEric Fiselier __all<(is_nothrow_move_constructible_v<_Types> && 14620d3d8de0SEric Fiselier is_nothrow_swappable_v<_Types>)...>::value) { 14630d3d8de0SEric Fiselier __impl.__swap(__that.__impl); 14640d3d8de0SEric Fiselier } 14650d3d8de0SEric Fiselier 14660d3d8de0SEric Fiselierprivate: 14670d3d8de0SEric Fiselier __variant_detail::__impl<_Types...> __impl; 14680d3d8de0SEric Fiselier 14690d3d8de0SEric Fiselier friend struct __variant_detail::__access::__variant; 14700d3d8de0SEric Fiselier friend struct __variant_detail::__visitation::__variant; 14710d3d8de0SEric Fiselier}; 14720d3d8de0SEric Fiselier 14730d3d8de0SEric Fiseliertemplate <size_t _Ip, class... _Types> 14740d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 14750d3d8de0SEric Fiselierconstexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept { 14760d3d8de0SEric Fiselier return __v.index() == _Ip; 14770d3d8de0SEric Fiselier} 14780d3d8de0SEric Fiselier 14790d3d8de0SEric Fiseliertemplate <class _Tp, class... _Types> 14800d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 14810d3d8de0SEric Fiselierconstexpr bool holds_alternative(const variant<_Types...>& __v) noexcept { 14820d3d8de0SEric Fiselier return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 14830d3d8de0SEric Fiselier} 14840d3d8de0SEric Fiselier 14850d3d8de0SEric Fiseliertemplate <size_t _Ip, class _Vp> 14860d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 14878a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS 148867c364ddSRichard Smithconstexpr auto&& __generic_get(_Vp&& __v) { 14890d3d8de0SEric Fiselier using __variant_detail::__access::__variant; 14900d3d8de0SEric Fiselier if (!__holds_alternative<_Ip>(__v)) { 149163322af6SEric Fiselier __throw_bad_variant_access(); 14920d3d8de0SEric Fiselier } 14930d3d8de0SEric Fiselier return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value; 14940d3d8de0SEric Fiselier} 14950d3d8de0SEric Fiselier 14960d3d8de0SEric Fiseliertemplate <size_t _Ip, class... _Types> 14970d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 14988a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS 14990d3d8de0SEric Fiselierconstexpr variant_alternative_t<_Ip, variant<_Types...>>& get( 15000d3d8de0SEric Fiselier variant<_Types...>& __v) { 15010d3d8de0SEric Fiselier static_assert(_Ip < sizeof...(_Types)); 15020d3d8de0SEric Fiselier static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 15030d3d8de0SEric Fiselier return __generic_get<_Ip>(__v); 15040d3d8de0SEric Fiselier} 15050d3d8de0SEric Fiselier 15060d3d8de0SEric Fiseliertemplate <size_t _Ip, class... _Types> 15070d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 15088a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS 15090d3d8de0SEric Fiselierconstexpr variant_alternative_t<_Ip, variant<_Types...>>&& get( 15100d3d8de0SEric Fiselier variant<_Types...>&& __v) { 15110d3d8de0SEric Fiselier static_assert(_Ip < sizeof...(_Types)); 15120d3d8de0SEric Fiselier static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 15130d3d8de0SEric Fiselier return __generic_get<_Ip>(_VSTD::move(__v)); 15140d3d8de0SEric Fiselier} 15150d3d8de0SEric Fiselier 15160d3d8de0SEric Fiseliertemplate <size_t _Ip, class... _Types> 15170d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 15188a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS 15190d3d8de0SEric Fiselierconstexpr const variant_alternative_t<_Ip, variant<_Types...>>& get( 15200d3d8de0SEric Fiselier const variant<_Types...>& __v) { 15210d3d8de0SEric Fiselier static_assert(_Ip < sizeof...(_Types)); 15220d3d8de0SEric Fiselier static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 15230d3d8de0SEric Fiselier return __generic_get<_Ip>(__v); 15240d3d8de0SEric Fiselier} 15250d3d8de0SEric Fiselier 15260d3d8de0SEric Fiseliertemplate <size_t _Ip, class... _Types> 15270d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 15288a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS 15290d3d8de0SEric Fiselierconstexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get( 15300d3d8de0SEric Fiselier const variant<_Types...>&& __v) { 15310d3d8de0SEric Fiselier static_assert(_Ip < sizeof...(_Types)); 15320d3d8de0SEric Fiselier static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 15330d3d8de0SEric Fiselier return __generic_get<_Ip>(_VSTD::move(__v)); 15340d3d8de0SEric Fiselier} 15350d3d8de0SEric Fiselier 15360d3d8de0SEric Fiseliertemplate <class _Tp, class... _Types> 15370d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 15388a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS 15390d3d8de0SEric Fiselierconstexpr _Tp& get(variant<_Types...>& __v) { 15400d3d8de0SEric Fiselier static_assert(!is_void_v<_Tp>); 15410d3d8de0SEric Fiselier return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 15420d3d8de0SEric Fiselier} 15430d3d8de0SEric Fiselier 15440d3d8de0SEric Fiseliertemplate <class _Tp, class... _Types> 15450d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 15468a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS 15470d3d8de0SEric Fiselierconstexpr _Tp&& get(variant<_Types...>&& __v) { 15480d3d8de0SEric Fiselier static_assert(!is_void_v<_Tp>); 15490d3d8de0SEric Fiselier return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>( 15500d3d8de0SEric Fiselier _VSTD::move(__v)); 15510d3d8de0SEric Fiselier} 15520d3d8de0SEric Fiselier 15530d3d8de0SEric Fiseliertemplate <class _Tp, class... _Types> 15540d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 15558a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS 15560d3d8de0SEric Fiselierconstexpr const _Tp& get(const variant<_Types...>& __v) { 15570d3d8de0SEric Fiselier static_assert(!is_void_v<_Tp>); 15580d3d8de0SEric Fiselier return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 15590d3d8de0SEric Fiselier} 15600d3d8de0SEric Fiselier 15610d3d8de0SEric Fiseliertemplate <class _Tp, class... _Types> 15620d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 15638a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS 15640d3d8de0SEric Fiselierconstexpr const _Tp&& get(const variant<_Types...>&& __v) { 15650d3d8de0SEric Fiselier static_assert(!is_void_v<_Tp>); 15660d3d8de0SEric Fiselier return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>( 15670d3d8de0SEric Fiselier _VSTD::move(__v)); 15680d3d8de0SEric Fiselier} 15690d3d8de0SEric Fiselier 15700d3d8de0SEric Fiseliertemplate <size_t _Ip, class _Vp> 15710d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 15720d3d8de0SEric Fiselierconstexpr auto* __generic_get_if(_Vp* __v) noexcept { 15730d3d8de0SEric Fiselier using __variant_detail::__access::__variant; 15740d3d8de0SEric Fiselier return __v && __holds_alternative<_Ip>(*__v) 15750d3d8de0SEric Fiselier ? _VSTD::addressof(__variant::__get_alt<_Ip>(*__v).__value) 15760d3d8de0SEric Fiselier : nullptr; 15770d3d8de0SEric Fiselier} 15780d3d8de0SEric Fiselier 15790d3d8de0SEric Fiseliertemplate <size_t _Ip, class... _Types> 15800d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 15810d3d8de0SEric Fiselierconstexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>> 15820d3d8de0SEric Fiselierget_if(variant<_Types...>* __v) noexcept { 15830d3d8de0SEric Fiselier static_assert(_Ip < sizeof...(_Types)); 15840d3d8de0SEric Fiselier static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 15850d3d8de0SEric Fiselier return __generic_get_if<_Ip>(__v); 15860d3d8de0SEric Fiselier} 15870d3d8de0SEric Fiselier 15880d3d8de0SEric Fiseliertemplate <size_t _Ip, class... _Types> 15890d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 15900d3d8de0SEric Fiselierconstexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>> 15910d3d8de0SEric Fiselierget_if(const variant<_Types...>* __v) noexcept { 15920d3d8de0SEric Fiselier static_assert(_Ip < sizeof...(_Types)); 15930d3d8de0SEric Fiselier static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); 15940d3d8de0SEric Fiselier return __generic_get_if<_Ip>(__v); 15950d3d8de0SEric Fiselier} 15960d3d8de0SEric Fiselier 15970d3d8de0SEric Fiseliertemplate <class _Tp, class... _Types> 15980d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 15990d3d8de0SEric Fiselierconstexpr add_pointer_t<_Tp> 16000d3d8de0SEric Fiselierget_if(variant<_Types...>* __v) noexcept { 16010d3d8de0SEric Fiselier static_assert(!is_void_v<_Tp>); 16020d3d8de0SEric Fiselier return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 16030d3d8de0SEric Fiselier} 16040d3d8de0SEric Fiselier 16050d3d8de0SEric Fiseliertemplate <class _Tp, class... _Types> 16060d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 16070d3d8de0SEric Fiselierconstexpr add_pointer_t<const _Tp> 16080d3d8de0SEric Fiselierget_if(const variant<_Types...>* __v) noexcept { 16090d3d8de0SEric Fiselier static_assert(!is_void_v<_Tp>); 16100d3d8de0SEric Fiselier return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 16110d3d8de0SEric Fiselier} 16120d3d8de0SEric Fiselier 16137dca3127SEric Fiseliertemplate <class _Operator> 16147dca3127SEric Fiselierstruct __convert_to_bool { 16157dca3127SEric Fiselier template <class _T1, class _T2> 16167dca3127SEric Fiselier _LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const { 1617d586f92cSArthur O'Dwyer static_assert(is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value, 16187dca3127SEric Fiselier "the relational operator does not return a type which is implicitly convertible to bool"); 16197dca3127SEric Fiselier return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2)); 16207dca3127SEric Fiselier } 16217dca3127SEric Fiselier}; 16227dca3127SEric Fiselier 16230d3d8de0SEric Fiseliertemplate <class... _Types> 16240d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 16250d3d8de0SEric Fiselierconstexpr bool operator==(const variant<_Types...>& __lhs, 16260d3d8de0SEric Fiselier const variant<_Types...>& __rhs) { 16270d3d8de0SEric Fiselier using __variant_detail::__visitation::__variant; 16280d3d8de0SEric Fiselier if (__lhs.index() != __rhs.index()) return false; 16290d3d8de0SEric Fiselier if (__lhs.valueless_by_exception()) return true; 16307dca3127SEric Fiselier return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs); 16310d3d8de0SEric Fiselier} 16320d3d8de0SEric Fiselier 16330d3d8de0SEric Fiseliertemplate <class... _Types> 16340d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 16350d3d8de0SEric Fiselierconstexpr bool operator!=(const variant<_Types...>& __lhs, 16360d3d8de0SEric Fiselier const variant<_Types...>& __rhs) { 16370d3d8de0SEric Fiselier using __variant_detail::__visitation::__variant; 16380d3d8de0SEric Fiselier if (__lhs.index() != __rhs.index()) return true; 16390d3d8de0SEric Fiselier if (__lhs.valueless_by_exception()) return false; 16400d3d8de0SEric Fiselier return __variant::__visit_value_at( 16417dca3127SEric Fiselier __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs); 16420d3d8de0SEric Fiselier} 16430d3d8de0SEric Fiselier 16440d3d8de0SEric Fiseliertemplate <class... _Types> 16450d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 16460d3d8de0SEric Fiselierconstexpr bool operator<(const variant<_Types...>& __lhs, 16470d3d8de0SEric Fiselier const variant<_Types...>& __rhs) { 16480d3d8de0SEric Fiselier using __variant_detail::__visitation::__variant; 16490d3d8de0SEric Fiselier if (__rhs.valueless_by_exception()) return false; 16500d3d8de0SEric Fiselier if (__lhs.valueless_by_exception()) return true; 16510d3d8de0SEric Fiselier if (__lhs.index() < __rhs.index()) return true; 16520d3d8de0SEric Fiselier if (__lhs.index() > __rhs.index()) return false; 16537dca3127SEric Fiselier return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs); 16540d3d8de0SEric Fiselier} 16550d3d8de0SEric Fiselier 16560d3d8de0SEric Fiseliertemplate <class... _Types> 16570d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 16580d3d8de0SEric Fiselierconstexpr bool operator>(const variant<_Types...>& __lhs, 16590d3d8de0SEric Fiselier const variant<_Types...>& __rhs) { 16600d3d8de0SEric Fiselier using __variant_detail::__visitation::__variant; 16610d3d8de0SEric Fiselier if (__lhs.valueless_by_exception()) return false; 16620d3d8de0SEric Fiselier if (__rhs.valueless_by_exception()) return true; 16630d3d8de0SEric Fiselier if (__lhs.index() > __rhs.index()) return true; 16640d3d8de0SEric Fiselier if (__lhs.index() < __rhs.index()) return false; 16657dca3127SEric Fiselier return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs); 16660d3d8de0SEric Fiselier} 16670d3d8de0SEric Fiselier 16680d3d8de0SEric Fiseliertemplate <class... _Types> 16690d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 16700d3d8de0SEric Fiselierconstexpr bool operator<=(const variant<_Types...>& __lhs, 16710d3d8de0SEric Fiselier const variant<_Types...>& __rhs) { 16720d3d8de0SEric Fiselier using __variant_detail::__visitation::__variant; 16730d3d8de0SEric Fiselier if (__lhs.valueless_by_exception()) return true; 16740d3d8de0SEric Fiselier if (__rhs.valueless_by_exception()) return false; 16750d3d8de0SEric Fiselier if (__lhs.index() < __rhs.index()) return true; 16760d3d8de0SEric Fiselier if (__lhs.index() > __rhs.index()) return false; 16770d3d8de0SEric Fiselier return __variant::__visit_value_at( 16787dca3127SEric Fiselier __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs); 16790d3d8de0SEric Fiselier} 16800d3d8de0SEric Fiselier 16810d3d8de0SEric Fiseliertemplate <class... _Types> 16820d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 16830d3d8de0SEric Fiselierconstexpr bool operator>=(const variant<_Types...>& __lhs, 16840d3d8de0SEric Fiselier const variant<_Types...>& __rhs) { 16850d3d8de0SEric Fiselier using __variant_detail::__visitation::__variant; 16860d3d8de0SEric Fiselier if (__rhs.valueless_by_exception()) return true; 16870d3d8de0SEric Fiselier if (__lhs.valueless_by_exception()) return false; 16880d3d8de0SEric Fiselier if (__lhs.index() > __rhs.index()) return true; 16890d3d8de0SEric Fiselier if (__lhs.index() < __rhs.index()) return false; 16900d3d8de0SEric Fiselier return __variant::__visit_value_at( 16917dca3127SEric Fiselier __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs); 16920d3d8de0SEric Fiselier} 16930d3d8de0SEric Fiselier 16949d509587SRuslan Arutyunyantemplate <class... _Vs> 16950d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 16960324b46cSMarek Kurdej _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr void 16970324b46cSMarek Kurdej __throw_if_valueless(_Vs&&... __vs) { 16980324b46cSMarek Kurdej const bool __valueless = 16990324b46cSMarek Kurdej (... || _VSTD::__as_variant(__vs).valueless_by_exception()); 170051faba35SRuslan Arutyunyan if (__valueless) { 17019c09757bSEric Fiselier __throw_bad_variant_access(); 17029c09757bSEric Fiselier } 17039c09757bSEric Fiselier} 170451faba35SRuslan Arutyunyan 17050324b46cSMarek Kurdejtemplate < 17060324b46cSMarek Kurdej class _Visitor, class... _Vs, 1707ab3fcc50SArthur O'Dwyer typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> > 170851faba35SRuslan Arutyunyaninline _LIBCPP_INLINE_VISIBILITY 17090324b46cSMarek Kurdej _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr 17100324b46cSMarek Kurdej decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) { 171151faba35SRuslan Arutyunyan using __variant_detail::__visitation::__variant; 17129d509587SRuslan Arutyunyan _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...); 17139c09757bSEric Fiselier return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor), 17140d3d8de0SEric Fiselier _VSTD::forward<_Vs>(__vs)...); 17150d3d8de0SEric Fiselier} 17160d3d8de0SEric Fiselier 171751faba35SRuslan Arutyunyan#if _LIBCPP_STD_VER > 17 17180324b46cSMarek Kurdejtemplate < 17190324b46cSMarek Kurdej class _Rp, class _Visitor, class... _Vs, 1720ab3fcc50SArthur O'Dwyer typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> > 172151faba35SRuslan Arutyunyaninline _LIBCPP_INLINE_VISIBILITY 17220324b46cSMarek Kurdej _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp 17230324b46cSMarek Kurdej visit(_Visitor&& __visitor, _Vs&&... __vs) { 172451faba35SRuslan Arutyunyan using __variant_detail::__visitation::__variant; 17259d509587SRuslan Arutyunyan _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...); 172651faba35SRuslan Arutyunyan return __variant::__visit_value<_Rp>(_VSTD::forward<_Visitor>(__visitor), 172751faba35SRuslan Arutyunyan _VSTD::forward<_Vs>(__vs)...); 172851faba35SRuslan Arutyunyan} 172951faba35SRuslan Arutyunyan#endif 173051faba35SRuslan Arutyunyan 17310d3d8de0SEric Fiseliertemplate <class... _Types> 17320d3d8de0SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 1733b28cb53eSLouis Dionneauto swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs) 1734b28cb53eSLouis Dionne noexcept(noexcept(__lhs.swap(__rhs))) 1735b28cb53eSLouis Dionne -> decltype( __lhs.swap(__rhs)) 1736b28cb53eSLouis Dionne { return __lhs.swap(__rhs); } 17370d3d8de0SEric Fiselier 17380d3d8de0SEric Fiseliertemplate <class... _Types> 1739f9127593SEric Fiselierstruct _LIBCPP_TEMPLATE_VIS hash< 1740f9127593SEric Fiselier __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> { 17410d3d8de0SEric Fiselier using argument_type = variant<_Types...>; 17420d3d8de0SEric Fiselier using result_type = size_t; 17430d3d8de0SEric Fiselier 17440d3d8de0SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 17450d3d8de0SEric Fiselier result_type operator()(const argument_type& __v) const { 17460d3d8de0SEric Fiselier using __variant_detail::__visitation::__variant; 1747918f32fcSEric Fiselier size_t __res = 1748918f32fcSEric Fiselier __v.valueless_by_exception() 174902460bacSEric Fiselier ? 299792458 // Random value chosen by the universe upon creation 17500d3d8de0SEric Fiselier : __variant::__visit_alt( 17510d3d8de0SEric Fiselier [](const auto& __alt) { 17528ea7ede7SMarshall Clow using __alt_type = __uncvref_t<decltype(__alt)>; 1753f9127593SEric Fiselier using __value_type = remove_const_t< 1754f9127593SEric Fiselier typename __alt_type::__value_type>; 17550d3d8de0SEric Fiselier return hash<__value_type>{}(__alt.__value); 17560d3d8de0SEric Fiselier }, 17570d3d8de0SEric Fiselier __v); 1758918f32fcSEric Fiselier return __hash_combine(__res, hash<size_t>{}(__v.index())); 17590d3d8de0SEric Fiselier } 17600d3d8de0SEric Fiselier}; 17610d3d8de0SEric Fiselier 17621a29403dSzoecarver// __unchecked_get is the same as std::get, except, it is UB to use it with the wrong 17631a29403dSzoecarver// type whereas std::get will throw or returning nullptr. This makes it faster than 17641a29403dSzoecarver// std::get. 17651a29403dSzoecarvertemplate <size_t _Ip, class _Vp> 17661a29403dSzoecarverinline _LIBCPP_INLINE_VISIBILITY 17671a29403dSzoecarverconstexpr auto&& __unchecked_get(_Vp&& __v) noexcept { 17681a29403dSzoecarver using __variant_detail::__access::__variant; 17691a29403dSzoecarver return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value; 17701a29403dSzoecarver} 17711a29403dSzoecarver 17721a29403dSzoecarvertemplate <class _Tp, class... _Types> 17731a29403dSzoecarverinline _LIBCPP_INLINE_VISIBILITY 17741a29403dSzoecarverconstexpr auto&& __unchecked_get(const variant<_Types...>& __v) noexcept { 17751a29403dSzoecarver return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 17761a29403dSzoecarver} 17771a29403dSzoecarver 17781a29403dSzoecarvertemplate <class _Tp, class... _Types> 17791a29403dSzoecarverinline _LIBCPP_INLINE_VISIBILITY 17801a29403dSzoecarverconstexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept { 17811a29403dSzoecarver return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); 17821a29403dSzoecarver} 17831a29403dSzoecarver 17840d3d8de0SEric Fiselier#endif // _LIBCPP_STD_VER > 14 17850d3d8de0SEric Fiselier 17860d3d8de0SEric Fiselier_LIBCPP_END_NAMESPACE_STD 17870d3d8de0SEric Fiselier 1788afa6f834SEric Fiselier_LIBCPP_POP_MACROS 1789afa6f834SEric Fiselier 17900d3d8de0SEric Fiselier#endif // _LIBCPP_VARIANT 1791