// Copyright (c) 2015, Just Software Solutions Ltd // All rights reserved. // // Redistribution and use in source and binary forms, with or // without modification, are permitted provided that the // following conditions are met: // // 1. Redistributions of source code must retain the above // copyright notice, this list of conditions and the following // disclaimer. // // 2. Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials // provided with the distribution. // // 3. Neither the name of the copyright holder nor the names of // its contributors may be used to endorse or promote products // derived from this software without specific prior written // permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND // CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Copied from https://bitbucket.org/anthonyw/variant/src (5bce47fa788648f79e5ea1d77b0eef2e8f0b2999) // Modified to make it compile with exceptions disabled. #pragma once #include #include #include #include #include #include #include #include #include #include #if COMPILER(MSVC) #pragma warning(push) #pragma warning(disable:4245) #pragma warning(disable:4521) #pragma warning(disable:4522) #pragma warning(disable:4814) #endif #if !COMPILER(CLANG) || WTF_CPP_STD_VER >= 14 namespace WTF { #if COMPILER_SUPPORTS(EXCEPTIONS) #define __THROW_EXCEPTION(__exception) throw __exception; #define __NOEXCEPT noexcept #define __NOEXCEPT_(__exception) noexcept(__exception) #else #define __THROW_EXCEPTION(__exception) do { (void)__exception; CRASH(); } while (0); #define __NOEXCEPT #define __NOEXCEPT_(...) #endif struct __in_place_private{ template struct __type_holder; template struct __value_holder; }; struct in_place_tag { in_place_tag() = delete; }; using in_place_t = in_place_tag(&)(__in_place_private&); template using in_place_type_t = in_place_tag(&)(__in_place_private::__type_holder<_Type>&); template using in_place_index_t = in_place_tag(&)(__in_place_private::__value_holder<_Index>&); in_place_tag in_place(__in_place_private&); template in_place_tag in_place(__in_place_private::__type_holder<_Type> &) { __THROW_EXCEPTION(__in_place_private()); } template in_place_tag in_place(__in_place_private::__value_holder<_Index> &) { __THROW_EXCEPTION(__in_place_private()); } class bad_variant_access: public std::logic_error{ public: explicit bad_variant_access(const std::string& what_arg): std::logic_error(what_arg) {} explicit bad_variant_access(const char* what_arg): std::logic_error(what_arg) {} }; template NO_RETURN_DUE_TO_CRASH inline T __throw_bad_variant_access(const char* what_arg){ __THROW_EXCEPTION(bad_variant_access(what_arg)) } template struct __type_index_helper; template struct __type_index_helper<_Offset,_Type,_Head,_Rest...>{ static constexpr ptrdiff_t __value= __type_index_helper<_Offset+1,_Type,_Rest...>::__value; }; template struct __type_index_helper<_Offset,_Type,_Type,_Rest...>{ static constexpr ptrdiff_t __value=_Offset; }; template struct __type_index{ static constexpr ptrdiff_t __value= __type_index_helper<0,_Type,_Types...>::__value; }; template struct __indexed_type; template struct __indexed_type<0,_Head,_Rest...>{ typedef _Head __type; }; template struct __indexed_type<-1,_Head,_Rest...>{ typedef void __type; }; template struct __indexed_type<_Index,_Head,_Rest...>{ typedef typename __indexed_type<_Index-1,_Rest...>::__type __type; }; template struct __next_index{ static constexpr ptrdiff_t __value= (_Index>=ptrdiff_t(sizeof...(_Types)-1))?-1:_Index+1; }; template class Variant; template struct variant_size; template struct variant_size : variant_size<_Type> {}; template struct variant_size : variant_size<_Type> {}; template struct variant_size : variant_size<_Type> {}; template struct variant_size> : std::integral_constant {}; template struct variant_alternative; template using variant_alternative_t=typename variant_alternative<_Index,_Type>::type; template struct variant_alternative<_Index, const _Type>{ using type=std::add_const_t>; }; template struct variant_alternative<_Index, volatile _Type>{ using type=std::add_volatile_t>; }; template struct variant_alternative<_Index, volatile const _Type>{ using type=std::add_volatile_t>>; }; template struct variant_alternative<_Index,Variant<_Types...>>{ using type=typename __indexed_type<_Index,_Types...>::__type; }; constexpr size_t variant_npos=-1; template constexpr _Type& get(Variant<_Types...>&); template constexpr _Type const& get(Variant<_Types...> const&); template constexpr _Type&& get(Variant<_Types...>&&); template constexpr const _Type&& get(Variant<_Types...> const&&); template constexpr typename __indexed_type<_Index,_Types...>::__type& get(Variant<_Types...>&); template constexpr typename __indexed_type<_Index,_Types...>::__type&& get(Variant<_Types...>&&); template constexpr typename __indexed_type<_Index,_Types...>::__type const& get( Variant<_Types...> const&); template constexpr const typename __indexed_type<_Index, _Types...>::__type && get(Variant<_Types...> const &&); template constexpr std::add_pointer_t<_Type> get_if(Variant<_Types...>&); template constexpr std::add_pointer_t<_Type const> get_if(Variant<_Types...> const&); template constexpr std::add_pointer_t::__type> get_if(Variant<_Types...>&); template constexpr std::add_pointer_t::__type const> get_if( Variant<_Types...> const&); template struct __variant_accessor; templateSCHAR_MAX), bool __larger_than_short=(__count>SHRT_MAX), bool __larger_than_int=(__count>INT_MAX)> struct __discriminator_type{ typedef signed char __type; }; template struct __discriminator_type<__count,true,false,false>{ typedef signed short __type; }; template struct __discriminator_type<__count,true,true,false>{ typedef int __type; }; template struct __discriminator_type<__count,true,true,true>{ typedef signed long __type; }; template struct __stored_type{ typedef _Type __type; }; template struct __stored_type<_Type&>{ typedef _Type* __type; }; template struct __all_trivially_destructible; template<> struct __all_trivially_destructible<> { static constexpr bool __value=true; }; template struct __all_trivially_destructible<_Type> { static constexpr bool __value= std::is_trivially_destructible::__type>::value; }; template struct __all_trivially_destructible<_Head,_Rest...> { static constexpr bool __value= __all_trivially_destructible<_Head>::__value && __all_trivially_destructible<_Rest...>::__value; }; template struct __storage_nothrow_constructible{ static const bool __value= std::is_nothrow_constructible<_Target, _Args...>::value; }; template struct __storage_nothrow_move_constructible; template<> struct __storage_nothrow_move_constructible<> { static constexpr bool __value=true; }; template struct __storage_nothrow_move_constructible<_Type> { static constexpr bool __value= std::is_nothrow_move_constructible< typename __stored_type<_Type>::__type>::value; }; template struct __storage_nothrow_move_constructible<_Head,_Rest...> { static constexpr bool __value= __storage_nothrow_move_constructible<_Head>::__value && __storage_nothrow_move_constructible<_Rest...>::__value; }; template struct __other_storage_nothrow_move_constructible; template struct __other_storage_nothrow_move_constructible<0,_Head,_Rest...>{ static const bool __value=__storage_nothrow_move_constructible<_Rest...>::__value; }; template struct __other_storage_nothrow_move_constructible<-1,_Head,_Rest...>{ static const bool __value= __storage_nothrow_move_constructible<_Head,_Rest...>::__value; }; template struct __other_storage_nothrow_move_constructible<_Index,_Head,_Rest...>{ static const bool __value= __storage_nothrow_move_constructible<_Head>::__value && __other_storage_nothrow_move_constructible<_Index-1,_Rest...>::__value; }; template struct __backup_storage_required{ static const bool __value= !__storage_nothrow_move_constructible< typename __indexed_type<_Index,_Types...>::__type>::__value && !__other_storage_nothrow_move_constructible<_Index,_Types...>::__value; }; template struct __any_backup_storage_required_impl{ static const bool __value= __backup_storage_required<_Index,_Types...>::__value || __any_backup_storage_required_impl<_Index+1,_Count-1,_Types...>::__value; }; template struct __any_backup_storage_required_impl<_Index,0,_Types...>{ static const bool __value=false; }; template struct __any_backup_storage_required; template struct __any_backup_storage_required >{ static const bool __value= __any_backup_storage_required_impl<0,sizeof...(_Types),_Types...>::__value; }; template union __variant_data; // std::is_literal_type is deprecated in C++17 and removed in C++20 ALLOW_DEPRECATED_DECLARATIONS_BEGIN template::value> struct __variant_storage{ typedef _Type __type; static constexpr _Type& __get(__type& __val){ return __val; } static constexpr _Type&& __get_rref(__type& __val){ return std::move(__val); } static constexpr const _Type& __get(__type const& __val){ return __val; } static constexpr const _Type&& __get_rref(__type const& __val){ return std::move(__val); } static void __destroy(__type&){} }; ALLOW_DEPRECATED_DECLARATIONS_END template struct __storage_wrapper{ typename std::aligned_storage::type __storage; template static constexpr void __construct(void* __p,_Args&& ... __args){ new (__p) _Type(std::forward<_Args>(__args)...); } template __storage_wrapper( typename std::enable_if::value, void (__storage_wrapper::*)()>::type = nullptr) { __construct(&__storage); } template __storage_wrapper( typename std::enable_if::value, void (__storage_wrapper::*)()>::type = nullptr) { } template __storage_wrapper(_First&& __first,_Args&& ... __args){ __construct(&__storage,std::forward<_First>(__first),std::forward<_Args>(__args)...); } _Type& __get(){ return *static_cast<_Type*>(static_cast(&__storage)); } constexpr _Type const& __get() const{ return *static_cast<_Type const*>(static_cast(&__storage)); } void __destroy(){ __get().~_Type(); } }; template struct __storage_wrapper<_Type&>{ _Type* __storage; template constexpr __storage_wrapper(_Arg& __arg): __storage(&__arg){} _Type& __get(){ return *__storage; } constexpr _Type const& __get() const{ return *__storage; } }; template struct __variant_storage<_Type,false>{ typedef __storage_wrapper<_Type> __type; static constexpr _Type& __get(__type& __val){ return __val.__get(); } static constexpr _Type&& __get_rref(__type& __val){ return std::move(__val.__get()); } static constexpr const _Type& __get(__type const& __val){ return __val.__get(); } static constexpr const _Type&& __get_rref(__type const& __val){ return std::move(__val.__get()); } static void __destroy(__type& __val){ __val.__destroy(); } }; template struct __variant_storage<_Type&,__b>{ typedef _Type* __type; static constexpr _Type& __get(__type& __val){ return *__val; } static constexpr _Type& __get_rref(__type& __val){ return *__val; } static constexpr _Type& __get(__type const& __val){ return *__val; } static constexpr _Type& __get_rref(__type const& __val){ return *__val; } static void __destroy(__type&){} }; template struct __variant_storage<_Type&&,__b>{ typedef _Type* __type; static constexpr _Type&& __get(__type& __val){ return static_cast<_Type&&>(*__val); } static constexpr _Type&& __get_rref(__type& __val){ return static_cast<_Type&&>(*__val); } static constexpr _Type&& __get(__type const& __val){ return static_cast<_Type&&>(*__val); } static constexpr _Type&& __get_rref(__type const& __val){ return static_cast<_Type&&>(*__val); } static void __destroy(__type&){} }; template<> union __variant_data<>{ constexpr __variant_data(){} }; template union __variant_data<_Type>{ typename __variant_storage<_Type>::__type __val; struct __dummy_type{} __dummy; constexpr __variant_data():__dummy(){} template constexpr __variant_data(in_place_index_t<0>,_Args&& ... __args): __val(std::forward<_Args>(__args)...){} _Type& __get(in_place_index_t<0>){ return __variant_storage<_Type>::__get(__val); } /*constexpr*/ _Type&& __get_rref(in_place_index_t<0>){ return __variant_storage<_Type>::__get_rref(__val); } constexpr const _Type& __get(in_place_index_t<0>) const{ return __variant_storage<_Type>::__get(__val); } constexpr const _Type&& __get_rref(in_place_index_t<0>) const{ return __variant_storage<_Type>::__get_rref(__val); } void __destroy(in_place_index_t<0>){ __variant_storage<_Type>::__destroy(__val); } }; template union __variant_data<_Type&>{ typename __variant_storage<_Type&>::__type __val; struct __dummy_type{} __dummy; constexpr __variant_data():__dummy(){} template constexpr __variant_data(in_place_index_t<0>,_Args&& ... __args): __val(&std::forward<_Args>(__args)...){} _Type& __get(in_place_index_t<0>){ return __variant_storage<_Type&>::__get(__val); } constexpr _Type& __get(in_place_index_t<0>) const{ return __variant_storage<_Type&>::__get(__val); } _Type& __get_rref(in_place_index_t<0>){ return __variant_storage<_Type&>::__get_rref(__val); } constexpr _Type& __get_rref(in_place_index_t<0>) const{ return __variant_storage<_Type&>::__get_rref(__val); } void __destroy(in_place_index_t<0>){ __variant_storage<_Type&>::__destroy(__val); } }; template union __variant_data<_Type&&>{ typename __variant_storage<_Type&&>::__type __val; struct __dummy_type{} __dummy; constexpr __variant_data():__dummy(){} template __variant_data(in_place_index_t<0>,_Arg&& __arg): __val(&__arg){} _Type&& __get(in_place_index_t<0>){ return __variant_storage<_Type&&>::__get(__val); } constexpr _Type&& __get(in_place_index_t<0>) const{ return __variant_storage<_Type&&>::__get(__val); } _Type&& __get_rref(in_place_index_t<0>){ return __variant_storage<_Type&&>::__get_rref(__val); } constexpr _Type&& __get_rref(in_place_index_t<0>) const{ return __variant_storage<_Type&&>::__get_rref(__val); } void __destroy(in_place_index_t<0>){ __variant_storage<_Type&&>::__destroy(__val); } }; template union __variant_data<_Head,_Rest...>{ __variant_data<_Head> __head; __variant_data<_Rest...> __rest; constexpr __variant_data(): __head(){} template constexpr __variant_data(in_place_index_t<0>,_Args&& ... __args): __head(in_place<0>,std::forward<_Args>(__args)...){} template constexpr __variant_data(in_place_index_t<_Index>,_Args&& ... __args): __rest(in_place<_Index-1>,std::forward<_Args>(__args)...){} _Head& __get(in_place_index_t<0>){ return __head.__get(in_place<0>); } /*constexpr*/ _Head&& __get_rref(in_place_index_t<0>){ return __head.__get_rref(in_place<0>); } constexpr const _Head& __get(in_place_index_t<0>) const{ return __head.__get(in_place<0>); } constexpr const _Head&& __get_rref(in_place_index_t<0>) const{ return __head.__get_rref(in_place<0>); } template typename __indexed_type<_Index-1,_Rest...>::__type& __get( in_place_index_t<_Index>){ return __rest.__get(in_place<_Index-1>); } template /*constexpr*/ typename __indexed_type<_Index-1,_Rest...>::__type&& __get_rref( in_place_index_t<_Index>){ return __rest.__get_rref(in_place<_Index-1>); } template constexpr const typename __indexed_type<_Index-1,_Rest...>::__type& __get( in_place_index_t<_Index>) const{ return __rest.__get(in_place<_Index-1>); } template constexpr const typename __indexed_type<_Index-1,_Rest...>::__type&& __get_rref( in_place_index_t<_Index>) const{ return __rest.__get_rref(in_place<_Index-1>); } void __destroy(in_place_index_t<0>){ __head.__destroy(in_place<0>); } template void __destroy(in_place_index_t<_Index>){ __rest.__destroy(in_place<_Index-1>); } }; template struct __index_sequence{ typedef __index_sequence<_Indices...,sizeof...(_Indices)> __next; static constexpr size_t __length=sizeof...(_Indices); }; template struct __type_indices; template<> struct __type_indices<>{ typedef __index_sequence<> __type; }; template struct __type_indices<_Type>{ typedef __index_sequence<0> __type; }; template struct __type_indices<_Type,_Rest...>{ typedef typename __type_indices<_Rest...>::__type::__next __type; }; template struct __variant_indices; template struct __variant_indices>{ typedef typename __type_indices<_Types...>::__type __type; }; template::__type> struct __move_construct_op_table; template struct __move_construct_op_table<_Variant,__index_sequence<_Indices...>>{ typedef void(* const __func_type)(_Variant*,_Variant&); template static void __move_construct_func( _Variant * __lhs,_Variant& __rhs){ __lhs->template __emplace_construct<_Index>( std::move(get<_Index>(__rhs))); } static const __func_type __apply[sizeof...(_Indices)]; }; template const typename __move_construct_op_table<_Variant,__index_sequence<_Indices...>>:: __func_type __move_construct_op_table<_Variant,__index_sequence<_Indices...>>::__apply[ sizeof...(_Indices)]={ &__move_construct_func<_Indices>... }; template::__type> struct __move_assign_op_table; template struct __move_assign_op_table<_Variant,__index_sequence<_Indices...>>{ typedef void(* const __func_type)(_Variant*,_Variant&); template static void __move_assign_func( _Variant * __lhs,_Variant& __rhs){ get<_Index>(*__lhs)=std::move(get<_Index>(__rhs)); } static const __func_type __apply[sizeof...(_Indices)]; }; template const typename __move_assign_op_table<_Variant,__index_sequence<_Indices...>>:: __func_type __move_assign_op_table<_Variant,__index_sequence<_Indices...>>::__apply[ sizeof...(_Indices)]={ &__move_assign_func<_Indices>... }; template::__type> struct __copy_construct_op_table; template struct __copy_construct_op_table<_Variant,__index_sequence<_Indices...>>{ typedef void(* const __func_type)(_Variant*,_Variant const&); template static void __copy_construct_func( _Variant * __lhs,_Variant const& __rhs){ __lhs->template __emplace_construct<_Index>( get<_Index>(__rhs)); } static const __func_type __apply[sizeof...(_Indices)]; }; template const typename __copy_construct_op_table<_Variant,__index_sequence<_Indices...>>:: __func_type __copy_construct_op_table<_Variant,__index_sequence<_Indices...>>::__apply[ sizeof...(_Indices)]={ &__copy_construct_func<_Indices>... }; template::__type> struct __copy_assign_op_table; template struct __copy_assign_op_table<_Variant,__index_sequence<_Indices...>>{ typedef void(* const __func_type)(_Variant*,_Variant const&); template static void __copy_assign_func( _Variant * __lhs,_Variant const& __rhs){ get<_Index>(*__lhs)=get<_Index>(__rhs); } static const __func_type __apply[sizeof...(_Indices)]; }; template const typename __copy_assign_op_table<_Variant,__index_sequence<_Indices...>>:: __func_type __copy_assign_op_table<_Variant,__index_sequence<_Indices...>>::__apply[ sizeof...(_Indices)]={ &__copy_assign_func<_Indices>... }; template::__type> struct __destroy_op_table; template struct __destroy_op_table<_Variant,__index_sequence<_Indices...>>{ typedef void(* const __func_type)(_Variant*); template static void __destroy_func( _Variant * __self){ if(__self->__index>=0){ __self->__storage.__destroy(in_place<_Index>); } } static const __func_type __apply[sizeof...(_Indices)]; }; template const typename __destroy_op_table<_Variant,__index_sequence<_Indices...>>:: __func_type __destroy_op_table<_Variant,__index_sequence<_Indices...>>::__apply[ sizeof...(_Indices)]={ &__destroy_func<_Indices>... }; template::__type> struct __swap_op_table; template struct __swap_op_table<_Variant,__index_sequence<_Indices...>>{ typedef void(* const __func_type)(_Variant&,_Variant&); template static void __swap_func( _Variant & __lhs,_Variant & __rhs){ swap(get<_Index>(__lhs),get<_Index>(__rhs)); } static const __func_type __apply[sizeof...(_Indices)]; }; template const typename __swap_op_table<_Variant,__index_sequence<_Indices...>>:: __func_type __swap_op_table<_Variant,__index_sequence<_Indices...>>::__apply[ sizeof...(_Indices)]={ &__swap_func<_Indices>... }; template::__type> struct __equality_op_table; template struct __equality_op_table<_Variant,__index_sequence<_Indices...>>{ typedef bool(* const __compare_func_type)(_Variant const&,_Variant const&); template static constexpr bool __equality_compare_func( _Variant const& __lhs,_Variant const& __rhs){ return get<_Index>(__lhs)==get<_Index>(__rhs); } static constexpr __compare_func_type __equality_compare[sizeof...(_Indices)]={ &__equality_compare_func<_Indices>... }; }; template constexpr typename __equality_op_table<_Variant,__index_sequence<_Indices...>>:: __compare_func_type __equality_op_table<_Variant,__index_sequence<_Indices...>>::__equality_compare[ sizeof...(_Indices)]; template::__type> struct __less_than_op_table; template struct __less_than_op_table<_Variant,__index_sequence<_Indices...>>{ typedef bool(* const __compare_func_type)(_Variant const&,_Variant const&); template static constexpr bool __less_than_compare_func( _Variant const& __lhs,_Variant const& __rhs){ return get<_Index>(__lhs)(__rhs); } static constexpr __compare_func_type __less_than_compare[sizeof...(_Indices)]={ &__less_than_compare_func<_Indices>... }; }; template constexpr typename __less_than_op_table<_Variant,__index_sequence<_Indices...>>:: __compare_func_type __less_than_op_table<_Variant,__index_sequence<_Indices...>>::__less_than_compare[ sizeof...(_Indices)]; template struct __variant_storage_type; template struct __variant_base { ~__variant_base(){ static_cast<_Derived*>(this)->__destroy_self(); } }; template struct __variant_base<_Derived,true>{ }; template struct __all_indices_helper; template struct __all_indices_helper< _Offset,__index_sequence<_Indices...>, _Type,_Type,_Rest...>{ typedef typename __all_indices_helper< _Offset+1,__index_sequence<_Indices...,_Offset>,_Type,_Rest...>::__type __type; }; template struct __all_indices_helper<_Offset,_CurrentSequence,_Type,_Head,_Rest...>{ typedef typename __all_indices_helper< _Offset+1,_CurrentSequence,_Type,_Rest...>::__type __type; }; template struct __all_indices_helper<_Offset,_CurrentSequence,_Type>{ typedef _CurrentSequence __type; }; template struct __all_indices{ typedef typename __all_indices_helper< 0,__index_sequence<>,_Type,_Types...>::__type __type; }; template struct __combine_sequences; template struct __combine_sequences< __index_sequence<_Indices1...>,__index_sequence<_Indices2...>>{ typedef __index_sequence<_Indices1...,_Indices2...> __type; }; template struct __combine_sequences<_Sequence,_Rest...>{ typedef typename __combine_sequences< _Sequence, typename __combine_sequences<_Rest...>::__type>::__type __type; }; template struct __first_index; template struct __first_index<__index_sequence<_FirstIndex,_Rest...>>{ static constexpr ptrdiff_t __value=_FirstIndex; }; template struct __constructible_matches_helper; template struct __constructible_matches_helper< _Offset,_Sequence,_Type>{ typedef _Sequence __type; }; template struct __sequence_or_empty{ typedef __index_sequence<> __type; }; template struct __sequence_or_empty{ typedef __index_sequence<_Entry> __type; }; template struct __constructible_matches_helper< _Offset,_CurrentSequence,_Type,_Head,_Rest...>{ typedef typename __constructible_matches_helper< _Offset+1, typename __combine_sequences< _CurrentSequence, typename __sequence_or_empty< std::is_constructible<_Head,_Type>::value, _Offset>::__type>::__type, _Type,_Rest...>::__type __type; }; template struct __constructible_matches{ typedef typename __constructible_matches_helper< 0,__index_sequence<>,_Type,_Types...>::__type __type; }; template struct __type_index_to_construct{ typedef typename __all_indices<_Type,_Types...>::__type __direct_matches; typedef typename __all_indices< typename std::remove_const< typename std::remove_reference<_Type>::type >::type,_Types...>::__type __value_matches; typedef typename __all_indices< _Type, typename std::remove_const< typename std::remove_reference<_Types>::type >::type...>::__type __rref_matches; typedef typename __constructible_matches<_Type,_Types...>::__type __constructibles; static_assert( (__direct_matches::__length>0) || (__value_matches::__length>0) || (__rref_matches::__length>0) || (__constructibles::__length==1), "For conversion construction of variants, exactly one type must be constructible"); typedef typename __combine_sequences< __direct_matches,__value_matches,__rref_matches, __constructibles>::__type __all_matches; static constexpr ptrdiff_t __value=__first_index<__all_matches>::__value; }; struct __replace_construct_helper{ template< ptrdiff_t _Index, bool __construct_directly, bool __indexed_type_has_nothrow_move, bool __other_types_have_nothrow_move> struct __helper; template::__type> struct __op_table; }; template< ptrdiff_t _Index, bool __other_types_have_nothrow_move> struct __replace_construct_helper::__helper< _Index,false,true,__other_types_have_nothrow_move>{ template static void __trampoline(_Variant& __v,_Args&& ... __args){ __v.template __two_stage_replace<_Index>(__args...); } }; template< ptrdiff_t _Index, bool __indexed_type_has_nothrow_move, bool __other_types_have_nothrow_move> struct __replace_construct_helper::__helper< _Index,true,__indexed_type_has_nothrow_move, __other_types_have_nothrow_move>{ template static void __trampoline(_Variant& __v,_Args&& ... __args){ __v.template __direct_replace<_Index>(std::forward<_Args>(__args)...); } }; template< ptrdiff_t _Index> struct __replace_construct_helper::__helper< _Index,false,false,true>{ template static void __trampoline(_Variant& __v,_Args&& ... __args){ __v.template __local_backup_replace<_Index>(std::forward<_Args>(__args)...); } }; template< ptrdiff_t _Index> struct __replace_construct_helper::__helper< _Index,false,false,false>{ template static void __trampoline(_Variant& __v,_Args&& ... __args){ __v.template __direct_replace<_Index>(std::forward<_Args>(__args)...); } }; template struct __replace_construct_helper::__op_table<_Variant,__index_sequence<_Indices...>>{ typedef void(* const __move_func_type)(_Variant*,_Variant&); typedef void(* const __copy_func_type)(_Variant*,_Variant const&); template static void __move_assign_func( _Variant * __lhs,_Variant& __rhs){ __lhs->template __replace_construct<_Index>(std::move(get<_Index>(__rhs))); __rhs.__destroy_self(); } template static void __copy_assign_func( _Variant * __lhs,_Variant const& __rhs){ __lhs->template __replace_construct<_Index>(get<_Index>(__rhs)); } static const __move_func_type __move_assign[sizeof...(_Indices)]; static const __copy_func_type __copy_assign[sizeof...(_Indices)]; }; template const typename __replace_construct_helper::__op_table< _Variant,__index_sequence<_Indices...>>::__move_func_type __replace_construct_helper::__op_table< _Variant,__index_sequence<_Indices...>>::__move_assign[ sizeof...(_Indices)]={ &__move_assign_func<_Indices>... }; template const typename __replace_construct_helper::__op_table< _Variant,__index_sequence<_Indices...>>::__copy_func_type __replace_construct_helper::__op_table< _Variant,__index_sequence<_Indices...>>::__copy_assign[ sizeof...(_Indices)]={ &__copy_assign_func<_Indices>... }; template struct __backup_storage_ops{ static void __move_construct_func( _Storage * __dest,_Storage& __source){ new(__dest) _Storage( in_place<_Index>, std::move(__source.__get(in_place<_Index>))); } static void __destroy_func(_Storage * __obj){ __obj->__destroy(in_place<_Index>); }; }; template struct __backup_storage_ops<_Index,_Index,_Storage>{ static void __move_construct_func(_Storage *,_Storage&){ __THROW_EXCEPTION(std::bad_alloc()); }; static void __destroy_func(_Storage *){ __THROW_EXCEPTION(std::bad_alloc()); }; }; template struct __backup_storage_op_table; template struct __backup_storage_op_table< _MaskIndex,_Storage,__index_sequence<_Indices...> > { typedef void (*__move_func_type)(_Storage * __dest,_Storage& __source); typedef void (*__destroy_func_type)(_Storage * __obj); template struct __helper{ typedef __backup_storage_ops<_Index,_MaskIndex,_Storage> __ops; }; static const __move_func_type __move_ops[sizeof...(_Indices)]; static const __destroy_func_type __destroy_ops[sizeof...(_Indices)]; }; template const typename __backup_storage_op_table< _MaskIndex,_Storage,__index_sequence<_Indices...> >::__move_func_type __backup_storage_op_table< _MaskIndex,_Storage,__index_sequence<_Indices...> >::__move_ops[ sizeof...(_Indices)]={ &__helper<_Indices>::__ops::__move_construct_func... }; template const typename __backup_storage_op_table< _MaskIndex,_Storage,__index_sequence<_Indices...> >::__destroy_func_type __backup_storage_op_table< _MaskIndex,_Storage,__index_sequence<_Indices...> >::__destroy_ops[ sizeof...(_Indices)]={ &__helper<_Indices>::__ops::__destroy_func... }; template struct __backup_storage{ typedef __variant_data<_Types...> __storage_type; typedef __backup_storage_op_table< _Index,__storage_type,typename __type_indices<_Types...>::__type> __op_table_type; ptrdiff_t __backup_index; __storage_type& __live_storage; __storage_type __backup; __backup_storage(ptrdiff_t __live_index_,__storage_type& __live_storage_): __backup_index(__live_index_),__live_storage(__live_storage_){ if(__backup_index>=0){ __op_table_type::__move_ops[__backup_index]( &__backup,__live_storage); __op_table_type::__destroy_ops[__backup_index]( &__live_storage); } } void __destroy(){ if(__backup_index>=0) __op_table_type::__destroy_ops[__backup_index]( &__backup); __backup_index=-1; } ~__backup_storage(){ if(__backup_index>=0){ __op_table_type::__move_ops[__backup_index]( &__live_storage,__backup); __destroy(); } } }; template struct __all_move_constructible; template struct __all_move_constructible<_Head,_Rest...> { static constexpr bool value=std::is_move_constructible<_Head>::value && __all_move_constructible<_Rest...>::value; }; template<> struct __all_move_constructible<>: std::true_type{}; template struct __all_move_assignable; template struct __all_move_assignable<_Head,_Rest...> { static constexpr bool value=std::is_move_assignable<_Head>::value && __all_move_assignable<_Rest...>::value; }; template<> struct __all_move_assignable<>: std::true_type{}; template struct __all_copy_assignable; template struct __all_copy_assignable<_Head,_Rest...> { static constexpr bool value=std::is_copy_assignable<_Head>::value && __all_copy_assignable<_Rest...>::value; }; template<> struct __all_copy_assignable<>: std::true_type{}; namespace __swap_test_detail{ using std::swap; template struct __swap_result{}; template static char __test(...); template static std::pair(),std::declval<_Other &>()))>>> __test(_Other *); } template struct __is_swappable { static constexpr bool value = sizeof(__swap_test_detail::__test<_Type>(nullptr)) != 1; }; template struct __all_swappable; template struct __all_swappable<_Head,_Rest...> { static constexpr bool value=__is_swappable<_Head>::value && __all_swappable<_Rest...>::value; }; template<> struct __all_swappable<>: std::true_type{}; template struct __noexcept_variant_move_construct_impl{}; template struct __noexcept_variant_move_construct_impl{ static constexpr bool value=noexcept(_Head(std::declval<_Head&&>())) && __noexcept_variant_move_construct_impl::value; }; template<> struct __noexcept_variant_move_construct_impl{ static constexpr bool value=true; }; template struct __noexcept_variant_move_construct: __noexcept_variant_move_construct_impl<__all_move_constructible<_Types...>::value,_Types...> {}; template struct __noexcept_variant_move_assign_impl{}; template struct __noexcept_variant_move_assign_impl { static constexpr bool value = std::is_nothrow_move_assignable<_Head>::value && std::is_nothrow_move_constructible<_Head>::value && __noexcept_variant_move_assign_impl::value; }; template<> struct __noexcept_variant_move_assign_impl{ static constexpr bool value=true; }; template struct __noexcept_variant_move_assign : __noexcept_variant_move_assign_impl< __all_move_assignable<_Types...>::value && __all_move_constructible<_Types...>::value, _Types...> {}; template struct __all_copy_constructible; template struct __all_copy_constructible<_Head,_Rest...> { static constexpr bool value=std::is_copy_constructible<_Head>::value && __all_copy_constructible<_Rest...>::value; }; template<> struct __all_copy_constructible<>: std::true_type{}; template struct __noexcept_variant_const_copy_construct_impl{}; template struct __noexcept_variant_const_copy_construct_impl{ static constexpr bool value=noexcept(_Head(std::declval<_Head const&>())) && __noexcept_variant_const_copy_construct_impl::value; }; template<> struct __noexcept_variant_const_copy_construct_impl{ static constexpr bool value=true; }; template struct __noexcept_variant_const_copy_construct: __noexcept_variant_const_copy_construct_impl<__all_copy_constructible<_Types...>::value,_Types...> {}; template struct __noexcept_variant_non_const_copy_construct_impl{}; template struct __noexcept_variant_non_const_copy_construct_impl{ static constexpr bool value=noexcept(_Head(std::declval<_Head&>())) && __noexcept_variant_non_const_copy_construct_impl::value; }; template<> struct __noexcept_variant_non_const_copy_construct_impl{ static constexpr bool value=true; }; template struct __noexcept_variant_non_const_copy_construct: __noexcept_variant_non_const_copy_construct_impl<__all_copy_constructible<_Types...>::value,_Types...> {}; template struct __noexcept_variant_swap_impl{}; template struct __noexcept_variant_swap_impl { static constexpr bool value = noexcept(swap(std::declval<_Head&>(),std::declval<_Head&>())) && __noexcept_variant_swap_impl::value; }; template<> struct __noexcept_variant_swap_impl{ static constexpr bool value=true; }; template struct __noexcept_variant_swap: __noexcept_variant_swap_impl<__all_swappable<_Types...>::value,_Types...> {}; template class Variant: private __variant_base< Variant<_Types...>,__all_trivially_destructible<_Types...>::__value> { WTF_MAKE_FAST_ALLOCATED; typedef __variant_base,__all_trivially_destructible<_Types...>::__value> __base_type; friend __base_type; friend struct __copy_construct_op_table; friend struct __copy_assign_op_table; friend struct __move_construct_op_table; friend struct __move_assign_op_table; friend struct __destroy_op_table; template friend struct __variant_accessor; friend struct __replace_construct_helper; typedef __variant_data<_Types...> __storage_type; __storage_type __storage; typename __discriminator_type::__type __index; template size_t __emplace_construct(_Args&& ... __args){ new(&__storage) __storage_type( in_place<_Index>,std::forward<_Args>(__args)...); return _Index; } void __destroy_self(){ if(valueless_by_exception()) return; __destroy_op_table::__apply[index()](this); __index=-1; } ptrdiff_t __move_construct(Variant& __other){ ptrdiff_t const __other_index=__other.index(); if(__other_index==-1) return -1; __move_construct_op_table::__apply[__other_index](this,__other); __other.__destroy_self(); return __other_index; } ptrdiff_t __copy_construct(Variant const& __other){ ptrdiff_t const __other_index=__other.index(); if(__other_index==-1) return -1; __copy_construct_op_table::__apply[__other_index](this,__other); return __other_index; } template void __replace_construct(_Args&& ... __args){ typedef typename __indexed_type<_Index,_Types...>::__type __this_type; __replace_construct_helper::__helper< _Index, __storage_nothrow_constructible<__this_type,_Args...>::__value || (sizeof...(_Types)==1), __storage_nothrow_move_constructible<__this_type>::__value, __other_storage_nothrow_move_constructible< _Index,_Types...>::__value >::__trampoline(*this,std::forward<_Args>(__args)...); } template void __two_stage_replace(_Args&& ... __args){ typedef typename __indexed_type<_Index,_Types...>::__type __type; __variant_data<__type> __local( in_place<0>,std::forward<_Args>(__args)...); __destroy_self(); __emplace_construct<_Index>( std::move(__local.__get(in_place<0>))); __index=_Index; __local.__destroy(in_place<0>); } template void __local_backup_replace(_Args&& ... __args){ __backup_storage<_Index,_Types...> __backup(__index,__storage); __emplace_construct<_Index>(std::forward<_Args>(__args)...); __index=_Index; __backup.__destroy(); } template void __direct_replace(_Args&& ... __args) { __destroy_self(); __emplace_construct<_Index>(std::forward<_Args>(__args)...); __index=_Index; } struct __private_type{}; public: constexpr Variant() __NOEXCEPT_(noexcept(typename __indexed_type<0,_Types...>::__type())): __storage(in_place<0>), __index(0) {} constexpr Variant(typename std::conditional<__all_move_constructible<_Types...>::value,Variant,__private_type>::type&& __other) __NOEXCEPT_(__noexcept_variant_move_construct<_Types...>::value): __index(__move_construct(__other)) {} constexpr Variant(typename std::conditional::value,Variant,__private_type>::type&& __other)=delete; constexpr Variant(typename std::conditional<__all_copy_constructible<_Types...>::value,Variant,__private_type>::type& __other) __NOEXCEPT_(__noexcept_variant_non_const_copy_construct<_Types...>::value): __index(__copy_construct(__other)) {} constexpr Variant(typename std::conditional::value,Variant,__private_type>::type& __other)=delete; constexpr Variant(typename std::conditional<__all_copy_constructible<_Types...>::value,Variant,__private_type>::type const& __other) __NOEXCEPT_(__noexcept_variant_const_copy_construct<_Types...>::value): __index(__copy_construct(__other)) {} constexpr Variant(typename std::conditional::value,Variant,__private_type>::type const& __other)=delete; template explicit constexpr Variant(in_place_type_t<_Type>,_Args&& ... __args): __storage( in_place<__type_index<_Type,_Types...>::__value>, std::forward<_Args>(__args)...), __index(__type_index<_Type,_Types...>::__value) { static_assert(std::is_constructible<_Type,_Args...>::value,"Type must be constructible from args"); } template explicit constexpr Variant(in_place_index_t<_Index>,_Args&& ... __args): __storage(in_place<_Index>,std::forward<_Args>(__args)...), __index(_Index) { static_assert(std::is_constructible::__type,_Args...>::value,"Type must be constructible from args"); } template constexpr Variant(_Type&& __x): __storage( in_place< __type_index_to_construct<_Type,_Types...>::__value>, std::forward<_Type>(__x)), __index(__type_index_to_construct<_Type,_Types...>::__value) {} template,_Types...>::__type::__length>0) >::type> constexpr Variant(std::initializer_list<_Type> __x): __storage( in_place< __type_index_to_construct,_Types...>::__value>, __x), __index(__type_index_to_construct,_Types...>::__value) {} template Variant& operator=(_Type&& __x){ constexpr size_t _Index= __type_index_to_construct<_Type,_Types...>::__value; if(_Index==__index){ get<_Index>(*this)=std::forward<_Type>(__x); } else{ __replace_construct<_Index>(std::forward<_Type>(__x)); } return *this; } Variant &operator=( typename std::conditional< !(__all_copy_constructible<_Types...>::value && __all_move_constructible<_Types...>::value && __all_copy_assignable<_Types...>::value), Variant, __private_type>::type const &__other) = delete; Variant &operator=( typename std::conditional< __all_copy_constructible<_Types...>::value && __all_move_constructible<_Types...>::value && __all_copy_assignable<_Types...>::value, Variant, __private_type>::type const &__other) { if (__other.valueless_by_exception()) { __destroy_self(); } else if(__other.index()==index()){ __copy_assign_op_table::__apply[index()](this,__other); } else{ __replace_construct_helper::__op_table::__copy_assign[ __other.index()](this,__other); } return *this; } Variant &operator=( typename std::conditional< !(__all_copy_constructible<_Types...>::value && __all_move_constructible<_Types...>::value && __all_copy_assignable<_Types...>::value), Variant, __private_type>::type &__other) = delete; Variant &operator=( typename std::conditional< __all_copy_constructible<_Types...>::value && __all_move_constructible<_Types...>::value && __all_copy_assignable<_Types...>::value, Variant, __private_type>::type &__other) { if(__other.valueless_by_exception()){ __destroy_self(); } else if(__other.index()==index()){ __copy_assign_op_table::__apply[index()](this,__other); } else{ __replace_construct_helper::__op_table::__copy_assign[ __other.index()](this,__other); } return *this; } Variant &operator=( typename std::conditional< !(__all_move_constructible<_Types...>::value && __all_move_assignable<_Types...>::value), Variant, __private_type>::type &&__other) = delete; Variant &operator=( typename std::conditional<__all_move_constructible<_Types...>::value && __all_move_assignable<_Types...>::value, Variant, __private_type>::type && __other) __NOEXCEPT_(__noexcept_variant_move_assign<_Types...>::value) { if (__other.valueless_by_exception()) { __destroy_self(); } else if(__other.index()==index()){ __move_assign_op_table::__apply[index()](this,__other); __other.__destroy_self(); } else{ __replace_construct_helper::__op_table::__move_assign[ __other.index()](this,__other); } return *this; } template void emplace(_Args&& ... __args){ __direct_replace<__type_index<_Type,_Types...>::__value>( std::forward<_Args>(__args)...); } template void emplace(_Args&& ... __args){ __direct_replace<_Index>(std::forward<_Args>(__args)...); } constexpr bool valueless_by_exception() const __NOEXCEPT{ return __index==-1; } constexpr ptrdiff_t index() const __NOEXCEPT{ return __index; } void swap( typename std::conditional< __all_swappable<_Types...>::value && __all_move_constructible<_Types...>::value, Variant, __private_type>::type &__other) __NOEXCEPT_(__noexcept_variant_swap<_Types...>::value) { if (__other.index() == index()) { if(!valueless_by_exception()) __swap_op_table::__apply[index()](*this,__other); } else{ Variant __temp(std::move(__other)); __other.__index=__other.__move_construct(*this); __index=__move_construct(__temp); } } }; template<> class Variant<>{ public: WTF_MAKE_FAST_ALLOCATED; Variant()=delete; constexpr bool valueless_by_exception() const __NOEXCEPT{ return true; } constexpr ptrdiff_t index() const __NOEXCEPT{ return -1; } void swap(Variant&){} }; template typename std::enable_if<__all_swappable<_Types...>::value && __all_move_constructible<_Types...>::value, void>::type swap(Variant<_Types...> &__lhs, Variant<_Types...> &__rhs) __NOEXCEPT_( __noexcept_variant_swap<_Types...>::value) { __lhs.swap(__rhs); } template struct __variant_accessor{ typedef typename __indexed_type<_Index,_Types...>::__type __type; static constexpr __type& get(Variant<_Types...>& __v){ return __v.__storage.__get(in_place<_Index>); } static constexpr __type const& get(Variant<_Types...> const& __v){ return __v.__storage.__get(in_place<_Index>); } static constexpr __type&& get(Variant<_Types...>&& __v){ return __v.__storage.__get_rref(in_place<_Index>); } static constexpr const __type&& get(Variant<_Types...> const&& __v){ return __v.__storage.__get_rref(in_place<_Index>); } }; template constexpr _Type& get(Variant<_Types...>& __v){ return get<__type_index<_Type,_Types...>::__value>(__v); } template constexpr _Type&& get(Variant<_Types...>&& __v){ return get<__type_index<_Type,_Types...>::__value>(std::move(__v)); } template constexpr _Type const& get(Variant<_Types...> const& __v){ return get<__type_index<_Type,_Types...>::__value>(__v); } template constexpr const _Type&& get(Variant<_Types...> const&& __v){ return get<__type_index<_Type,_Types...>::__value>(std::move(__v)); } template constexpr typename __indexed_type<_Index,_Types...>::__type const& get(Variant<_Types...> const& __v){ return *( (_Index!=__v.index()) ? std::addressof(__throw_bad_variant_access::__type const&>("Bad Variant index in get")) : std::addressof(__variant_accessor<_Index,_Types...>::get(__v)) ); } template constexpr typename __indexed_type<_Index,_Types...>::__type& get(Variant<_Types...>& __v){ return *( (_Index!=__v.index()) ? std::addressof(__throw_bad_variant_access::__type&>("Bad Variant index in get")) : std::addressof(__variant_accessor<_Index,_Types...>::get(__v)) ); } template constexpr typename __indexed_type<_Index,_Types...>::__type&& get(Variant<_Types...>&& __v){ return __variant_accessor<_Index,_Types...>::get( (((_Index!=__v.index()) ? __throw_bad_variant_access("Bad Variant index in get") : 0), std::move(__v)) ); } template constexpr const typename __indexed_type<_Index,_Types...>::__type&& get(Variant<_Types...> const&& __v){ return __variant_accessor<_Index,_Types...>::get( (((_Index!=__v.index()) ? __throw_bad_variant_access("Bad Variant index in get") : 0), std::move(__v)) ); } template constexpr std::add_pointer_t<_Type> get_if(Variant<_Types...>& __v){ return (__type_index<_Type,_Types...>::__value!=__v.index())?nullptr:std::addressof(get<_Type>(__v)); } template constexpr std::add_pointer_t<_Type const> get_if(Variant<_Types...> const& __v){ return (__type_index<_Type,_Types...>::__value!=__v.index())?nullptr:std::addressof(get<_Type>(__v)); } template constexpr std::add_pointer_t::__type> get_if(Variant<_Types...>& __v){ return ((_Index!=__v.index())?nullptr: std::addressof(__variant_accessor<_Index,_Types...>::get(__v))); } template constexpr std::add_pointer_t::__type const> get_if( Variant<_Types...> const& __v){ return ((_Index!=__v.index())?nullptr: std::addressof(__variant_accessor<_Index,_Types...>::get(__v))); } template constexpr bool holds_alternative(Variant<_Types...> const& __v) __NOEXCEPT{ return __v.index()==__type_index<_Type,_Types...>::__value; } template struct __visitor_return_type; template struct __visitor_return_type<_Visitor>{ typedef decltype(std::declval<_Visitor&>()()) __type; }; template struct __visitor_return_type<_Visitor,_Head,_Rest...>{ typedef decltype(std::declval<_Visitor&>()(std::declval<_Head&>())) __type; }; template struct __visitor_table{ typedef Variant<_Types...> __variant_type; typedef typename __visitor_return_type<_Visitor,_Types...>::__type __return_type; typedef __return_type (*__func_type)(_Visitor&,__variant_type&); template static __return_type __trampoline_func(_Visitor& __visitor,__variant_type& __v){ return __visitor(get<_Type>(__v)); } static const __func_type __trampoline[sizeof...(_Types)]; }; template const typename __visitor_table<_Visitor,_Types...>::__func_type __visitor_table<_Visitor,_Types...>::__trampoline[sizeof...(_Types)]={ &__trampoline_func<_Types>... }; template constexpr typename __visitor_return_type<_Visitor,_Types...>::__type visit(_Visitor&& __visitor,Variant<_Types...>& __v){ return (__v.valueless_by_exception()) ? __throw_bad_variant_access::__type>("Visiting of empty Variant") : __visitor_table<_Visitor,_Types...>::__trampoline[__v.index()](__visitor,__v); } template struct __multi_visitor_return_type{ typedef decltype(std::declval<_Visitor&>()(get<0>(std::declval<_Variants>())...)) __type; }; template struct __visit_helper; template struct __visit_helper<0,__index_sequence<_Indices...>>{ template static constexpr typename __multi_visitor_return_type<_Visitor,_Variants...>::__type __visit(_Visitor& __visitor,_Variants& ... __v){ return __visitor(get<_Indices>(__v)...); } }; template struct __arg_selector_t; template struct __arg_selector_t<0,_Head,_Rest...>{ typedef _Head __type; static constexpr __type& __select(_Head& __head,_Rest& ...){ return __head; } }; template struct __arg_selector_t<_Index,_Head,_Rest...>{ typedef typename __arg_selector_t<_Index-1,_Rest...>::__type __type; static constexpr __type& __select(_Head&,_Rest& ... __rest){ return __arg_selector_t<_Index-1,_Rest...>::__select(__rest...); } }; template constexpr typename __arg_selector_t<_Index,_Args...>::__type&& __arg_selector(_Args&& ... __args){ return std::forward::__type>( __arg_selector_t<_Index,_Args...>::__select(__args...)); } template struct __visit_helper2{ template static constexpr typename __multi_visitor_return_type<_Visitor,_Variants...>::__type __visit(_Visitor& __visitor,_Variants&& ... __v){ return (__arg_selector<_VariantIndex-1>(__v...).index()==_Index) ? __visit_helper<_VariantIndex-1,__index_sequence<_Index,_Indices...>>::__visit(__visitor,std::forward<_Variants>(__v)...) : __visit_helper2<_Index-1,_VariantIndex,_Indices...>::__visit(__visitor,std::forward<_Variants>(__v)...); } }; template struct __visit_helper2<-1,_VariantIndex,_Indices...>{ template static constexpr typename __multi_visitor_return_type<_Visitor,_Variants...>::__type __visit(_Visitor&,_Variants&& ...){ return __throw_bad_variant_access::__type>("Visiting of empty Variant"); } }; template struct __variant_type_count; template struct __variant_type_count>{ static constexpr size_t __value=sizeof...(_Types); }; template struct __variant_type_count<_Variant&>{ static constexpr size_t __value=__variant_type_count<_Variant>::__value; }; template struct __variant_type_count<_Variant const&>{ static constexpr size_t __value=__variant_type_count<_Variant>::__value; }; template struct __visit_helper<_VariantIndex,__index_sequence<_Indices...>>{ template static constexpr typename __multi_visitor_return_type<_Visitor,_Variants...>::__type __visit(_Visitor& __visitor,_Variants&& ... __v){ return __visit_helper2< __variant_type_count< typename __arg_selector_t< _VariantIndex-1,_Variants...>::__type>::__value-1, _VariantIndex,_Indices...>::__visit( __visitor,std::forward<_Variants&&>(__v)...); } }; template constexpr typename __multi_visitor_return_type<_Visitor,_Variants...>::__type visit(_Visitor&& __visitor,_Variants&& ... __v){ return __visit_helper>::__visit( __visitor,std::forward<_Variants>(__v)...); } template constexpr bool operator==(Variant<_Types...> const& __lhs,Variant<_Types...> const& __rhs){ return (__lhs.index()==__rhs.index()) && ((__lhs.index()==-1) || __equality_op_table>::__equality_compare[__lhs.index()]( __lhs,__rhs)); } template constexpr bool operator!=(Variant<_Types...> const& __lhs,Variant<_Types...> const& __rhs){ return !(__lhs==__rhs); } template constexpr bool operator<(Variant<_Types...> const& __lhs,Variant<_Types...> const& __rhs){ return (__lhs.index()<__rhs.index()) || ((__lhs.index()==__rhs.index()) && ((__lhs.index()!=-1) && __less_than_op_table>:: __less_than_compare[__lhs.index()](__lhs,__rhs))); } template constexpr bool operator>(Variant<_Types...> const& __lhs,Variant<_Types...> const& __rhs){ return __rhs<__lhs; } template constexpr bool operator>=(Variant<_Types...> const& __lhs,Variant<_Types...> const& __rhs){ return !(__lhs<__rhs); } template constexpr bool operator<=(Variant<_Types...> const& __lhs,Variant<_Types...> const& __rhs){ return !(__lhs>__rhs); } struct Monostate{}; constexpr bool operator==(Monostate const&, Monostate const&) { return true; } constexpr bool operator!=(Monostate const&, Monostate const&) { return false; } constexpr bool operator>=(Monostate const&, Monostate const&) { return true; } constexpr bool operator<=(Monostate const&, Monostate const&) { return true; } constexpr bool operator>(Monostate const&, Monostate const&) { return false; } constexpr bool operator<(Monostate const&, Monostate const&) { return false; } struct __hash_visitor{ template size_t operator()(_Type const& __x){ return std::hash<_Type>()(__x); } }; // -- WebKit Additions -- template auto switchOn(V&& v, F&&... f) -> decltype(WTF::visit(makeVisitor(std::forward(f)...), std::forward(v))) { return WTF::visit(makeVisitor(std::forward(f)...), std::forward(v)); } } // namespace WTF namespace std { template<> struct hash{ size_t operator()(WTF::Monostate) __NOEXCEPT{ return 42; } }; template struct hash>{ size_t operator()(WTF::Variant<_Types...> const &v) __NOEXCEPT { return std::hash()(v.index()) ^ WTF::visit(WTF::__hash_visitor(), v); } }; } // namespace std using WTF::Monostate; using WTF::Variant; #endif // !COMPILER(CLANG) || WTF_CPP_STD_VER >= 14 #if COMPILER(MSVC) #pragma warning(pop) #endif