Index: include/variant =================================================================== --- include/variant +++ include/variant @@ -16,7 +16,7 @@ namespace std { - // 20.7.2, variant of value types + // 20.7.2, class template variant template class variant { public: @@ -28,13 +28,6 @@ template constexpr variant(T&&) noexcept(see below); - template - constexpr explicit variant(in_place_index_t, Args&&...); - - template - constexpr explicit variant( - in_place_index_t, initializer_list, Args&&...); - template constexpr explicit variant(in_place_type_t, Args&&...); @@ -42,38 +35,12 @@ constexpr explicit variant( in_place_type_t, initializer_list, Args&&...); - // allocator-extended constructors - template - variant(allocator_arg_t, const Alloc&); - - template - variant(allocator_arg_t, const Alloc&, const variant&); - - template - variant(allocator_arg_t, const Alloc&, variant&&); - - template - variant(allocator_arg_t, const Alloc&, T&&); - - template - variant(allocator_arg_t, const Alloc&, in_place_index_t, Args&&...); - - template - variant(allocator_arg_t, - const Alloc&, - in_place_index_t, - initializer_list, - Args&&...); - - template - variant(allocator_arg_t, const Alloc&, in_place_type_t, Args&&...); + template + constexpr explicit variant(in_place_index_t, Args&&...); - template - variant(allocator_arg_t, - const Alloc&, - in_place_type_t, - initializer_list, - Args&&...); + template + constexpr explicit variant( + in_place_index_t, initializer_list, Args&&...); // 20.7.2.2, destructor ~variant(); @@ -226,11 +193,6 @@ template struct hash>; template <> struct hash; - // 20.7.12, allocator-related traits - template struct uses_allocator; - template - struct uses_allocator, Alloc>; - } // namespace std */ @@ -250,6 +212,15 @@ #pragma GCC system_header #endif +namespace std { // explicitly not using versioning namespace + +class _LIBCPP_EXCEPTION_ABI bad_variant_access : public exception { +public: + virtual const char* what() const noexcept; +}; + +} // namespace std + #define _LIBCPP_NOEXCEPT_SFINAE_RETURN(...) \ noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { \ return __VA_ARGS__; \ @@ -260,23 +231,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -constexpr bool __all_v = __all::value; - template using __size_constant = integral_constant; -class _LIBCPP_EXCEPTION_ABI bad_variant_access : public exception { -public: - virtual ~bad_variant_access(); - virtual const char* what() const noexcept; -}; - #if _LIBCPP_STD_VER > 14 -template -class variant; - template struct _LIBCPP_TYPE_VIS_ONLY variant_size; @@ -307,15 +266,15 @@ template struct _LIBCPP_TYPE_VIS_ONLY variant_alternative<_Ip, const _Tp> - : __identity>> {}; + : add_const> {}; template struct _LIBCPP_TYPE_VIS_ONLY variant_alternative<_Ip, volatile _Tp> - : __identity>> {}; + : add_volatile> {}; template struct _LIBCPP_TYPE_VIS_ONLY variant_alternative<_Ip, const volatile _Tp> - : __identity>> {}; + : add_cv> {}; template struct _LIBCPP_TYPE_VIS_ONLY variant_alternative<_Ip, variant<_Types...>> @@ -326,14 +285,6 @@ struct __variant_valueless_t {}; constexpr __variant_valueless_t __variant_valueless = __variant_valueless_t{}; -struct __variant_void { - __variant_void() = delete; - __variant_void(const __variant_void&) = default; - __variant_void(__variant_void&&) = default; - __variant_void& operator=(const __variant_void&) = default; - __variant_void& operator=(__variant_void&&) = default; -}; - namespace __find_detail { template @@ -483,7 +434,7 @@ template constexpr auto __make_fdiagonal() { constexpr size_t _Np = decay_t<_Vp>::__size(); - static_assert(__all_v<(_Np == decay_t<_Vs>::__size())...>); + static_assert(__all<(_Np == decay_t<_Vs>::__size())...>::value); return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{}); } @@ -604,27 +555,6 @@ explicit constexpr __variant_alt(in_place_t, _Args&&... __args) : __value(_VSTD::forward<_Args>(__args)...) {} - template - explicit __variant_alt(allocator_arg_t, - const _Alloc&, - integral_constant, - _Args&&... __args) - : __value(_VSTD::forward<_Args>(__args)...) {} - - template - explicit __variant_alt(allocator_arg_t, - const _Alloc& __alloc, - integral_constant, - _Args&&... __args) - : __value(allocator_arg, __alloc, _VSTD::forward<_Args>(__args)...) {} - - template - explicit __variant_alt(allocator_arg_t, - const _Alloc& __alloc, - integral_constant, - _Args&&... __args) - : __value(_VSTD::forward<_Args>(__args)..., __alloc) {} - constexpr auto&& __get_value() & { return static_cast<__value_type&>(__value); } @@ -667,26 +597,6 @@ _Args&&... __args) \ : __tail(in_place<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \ \ - template \ - explicit constexpr __variant_union(allocator_arg_t, \ - const _Alloc& __alloc, \ - in_place_index_t<0>, \ - _Args&&... __args) \ - : __head(allocator_arg, \ - __alloc, \ - __uses_alloc_ctor<_Tp, _Alloc, _Args&&...>{}, \ - _VSTD::forward<_Args>(__args)...) {} \ - \ - template \ - explicit constexpr __variant_union(allocator_arg_t, \ - const _Alloc& __alloc, \ - in_place_index_t<_Ip>, \ - _Args&&... __args) \ - : __tail(allocator_arg, \ - __alloc, \ - in_place<_Ip - 1>, \ - _VSTD::forward<_Args>(__args)...) {} \ - \ dtor \ \ private: \ @@ -720,22 +630,6 @@ _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args&&...>) : __index(_Ip), __data(in_place<_Ip>, _VSTD::forward<_Args>(__args)...) {} - template = 0, - class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, - enable_if_t, int> = 0> - explicit __variant_base(allocator_arg_t, - const _Alloc& __alloc, - in_place_index_t<_Ip>, - _Args&&... __args) - : __index(_Ip), - __data(allocator_arg, - __alloc, - in_place<_Ip>, - _VSTD::forward<_Args>(__args)...) {} - constexpr bool valueless_by_exception() const noexcept { return index() == variant_npos; } @@ -798,17 +692,17 @@ template struct __variant_impl - : public __variant_dtor<__all_v...>, - _Types...> { + : public __variant_dtor< + __all...>::value, _Types...> { using __base_type = - __variant_dtor<__all_v...>, + __variant_dtor<__all...>::value, _Types...>; public: using __base_type::__base_type; __variant_impl( - const conditional_t<__all_v...>, + const conditional_t<__all...>::value, __variant_impl, __nat>& __that) : __variant_impl(__variant_valueless) { @@ -817,43 +711,20 @@ } __variant_impl( - conditional_t<__all_v...>, + conditional_t<__all...>::value, __variant_impl, __nat>&& - __that) noexcept(__all_v...>) + __that) + noexcept(__all...>::value) : __variant_impl(__variant_valueless) { static_assert(!is_same_v, __nat>); __generic_construct(*this, _VSTD::move(__that)); } - template , - __dummy>::value...>, - int> = 0> - __variant_impl(allocator_arg_t, - const _Alloc& __alloc, - const __variant_impl& __that) - : __variant_impl(__variant_valueless) { - __generic_construct(*this, allocator_arg, __alloc, __that); - } - - template , - __dummy>::value...>, - int> = 0> - __variant_impl(allocator_arg_t, - const _Alloc& __alloc, - __variant_impl&& __that) - : __variant_impl(__variant_valueless) { - __generic_construct(*this, allocator_arg, __alloc, _VSTD::move(__that)); - } - __variant_impl& operator=( - const conditional_t<__all_v<(is_copy_constructible_v<_Types> && + const conditional_t<__all<(is_copy_constructible_v<_Types> && is_move_constructible_v<_Types> && - is_copy_assignable_v<_Types>)...>, + is_copy_assignable_v<_Types>)...>::value, __variant_impl, __nat>& __that) { static_assert(!is_same_v, __nat>); @@ -861,12 +732,12 @@ } __variant_impl& operator=( - conditional_t<__all_v<(is_move_constructible_v<_Types> && - is_move_assignable_v<_Types>)...>, + conditional_t<__all<(is_move_constructible_v<_Types> && + is_move_assignable_v<_Types>)...>::value, __variant_impl, __nat>&& - __that) noexcept(__all_v<(is_nothrow_move_constructible_v<_Types> && - is_nothrow_move_assignable_v<_Types>)...>) { + __that) noexcept(__all<(is_nothrow_move_constructible_v<_Types> && + is_nothrow_move_assignable_v<_Types>)...>::value) { static_assert(!is_same_v, __nat>); return __generic_assign(_VSTD::move(__that)); } @@ -894,7 +765,6 @@ void emplace(_Args&&... __args) { this->__destroy(); __construct_alt(__variant_impl_access::__get_alt<_Ip>(*this), - in_place, _VSTD::forward<_Args>(__args)...); this->__index = _Ip; } @@ -902,13 +772,13 @@ template < bool __dummy = false, enable_if_t< - __all_v<( + __all<( __dependent_type, __dummy>::value && - __dependent_type, __dummy>::value)...>, + __dependent_type, __dummy>::value)...>::value, int> = 0> void swap(__variant_impl& __that) noexcept( - __all_v<(is_nothrow_move_constructible_v<_Types> && - is_nothrow_swappable_v<_Types>)...>) { + __all<(is_nothrow_move_constructible_v<_Types> && + is_nothrow_swappable_v<_Types>)...>::value) { if (this->valueless_by_exception() && __that.valueless_by_exception()) { // do nothing. } else if (this->index() == __that.index()) { @@ -998,24 +868,11 @@ template static void __construct_alt(__variant_alt<_Ip, _Tp>& __alt, - in_place_t, _Args&&... __args) { ::new (_VSTD::addressof(__alt)) __variant_alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...); } - template - static void __construct_alt(__variant_alt<_Ip, _Tp>& __alt, - allocator_arg_t, - const _Alloc& __alloc, - _Args&&... __args) { - ::new (_VSTD::addressof(__alt)) - __variant_alt<_Ip, _Tp>(allocator_arg, - __alloc, - __uses_alloc_ctor<_Tp, _Alloc, _Args&&...>{}, - _VSTD::forward<_Args>(__args)...); - } - template static void __generic_construct(__variant_impl& __lhs, _Rhs&& __rhs) { static_assert(is_same_v, __variant_impl>); @@ -1026,7 +883,6 @@ [](auto& __lhs_alt, auto&& __rhs_alt) { __construct_alt( __lhs_alt, - in_place, _VSTD::forward(__rhs_alt).__get_value()); }, __lhs, @@ -1034,54 +890,20 @@ __lhs.__index = __rhs.index(); } } - - template - static void __generic_construct(__variant_impl& __lhs, - allocator_arg_t, - const _Alloc& __alloc, - _Rhs&& __rhs) { - static_assert(is_same_v, __variant_impl>); - __lhs.__destroy(); - if (!__rhs.valueless_by_exception()) { - __variant_impl_visitation::__visit_alt_at( - __rhs.index(), - [&__alloc](auto& __lhs_alt, auto&& __rhs_alt) { - __construct_alt( - __lhs_alt, - allocator_arg, - __alloc, - _VSTD::forward(__rhs_alt).__get_value()); - }, - __lhs, - _VSTD::forward<_Rhs>(__rhs)); - __lhs.__index = __rhs.index(); - } - } -}; - -template <> -class variant<> { - variant() = delete; - variant(const variant&) = delete; - variant(variant&&) = delete; - variant& operator=(const variant&) = delete; - variant& operator=(variant&&) = delete; }; template class variant { - template - using __transform = conditional_t, __variant_void, _Tp>; + static_assert(sizeof...(_Types) > 0, + "variant must consist of at least one alternative."); - template - using __variant_best_match = - __variant_best_match<_Arg, __transform<_Types>...>; + static_assert(__all...>::value, + "variant can not have `void` as an alternative."); - template - using __find_unambiguous_index_sfinae = - __find_unambiguous_index_sfinae<_Tp, __transform<_Types>...>; + static_assert(__all...>::value, + "variant can not have a reference type as an alternative."); - using __impl_type = __variant_impl<__transform<_Types>...>; + using __impl_type = __variant_impl<_Types...>; __impl_type __impl; @@ -1096,8 +918,8 @@ template , variant>, int> = 0, - class _Tp = __variant_best_match<_Arg&&>, - size_t _Ip = __find_unambiguous_index_sfinae<_Tp>::value, + class _Tp = __variant_best_match<_Arg&&, _Types...>, + size_t _Ip = __find_unambiguous_index_sfinae<_Tp, _Types...>::value, enable_if_t< is_constructible_v<__impl_type, in_place_index_t<_Ip>, _Arg&&>, int> = 0> @@ -1136,7 +958,7 @@ template < class _Tp, class... _Args, - size_t _Ip = __find_unambiguous_index_sfinae<_Tp>::value, + size_t _Ip = __find_unambiguous_index_sfinae<_Tp, _Types...>::value, enable_if_t< is_constructible_v<__impl_type, in_place_index_t<_Ip>, _Args&&...>, int> = 0> @@ -1148,7 +970,7 @@ template ::value, + size_t _Ip = __find_unambiguous_index_sfinae<_Tp, _Types...>::value, enable_if_t, initializer_list<_Up>&, @@ -1162,140 +984,6 @@ __il, _VSTD::forward<_Args>(__args)...) {} - template >, - int> = 0> - variant(allocator_arg_t, const _Alloc& __alloc) - _LIBCPP_NOEXCEPT_INIT(__impl, allocator_arg, __alloc, in_place<0>) {} - - template , - int> = 0> - variant(allocator_arg_t, const _Alloc& __alloc, const variant& __that) - _LIBCPP_NOEXCEPT_INIT(__impl, allocator_arg, __alloc, __that.__impl) {} - - template , - int> = 0> - variant(allocator_arg_t, const _Alloc& __alloc, variant&& __that) - _LIBCPP_NOEXCEPT_INIT(__impl, - allocator_arg, - __alloc, - _VSTD::move(__that).__impl) {} - - template , variant>, int> = 0, - class _Tp = __variant_best_match<_Arg&&>, - size_t _Ip = __find_unambiguous_index_sfinae<_Tp>::value, - enable_if_t, - _Arg&&>, - int> = 0> - variant(allocator_arg_t, const _Alloc& __alloc, _Arg&& __arg) - _LIBCPP_NOEXCEPT_INIT(__impl, - allocator_arg, - __alloc, - in_place<_Ip>, - _VSTD::forward<_Arg>(__arg)) {} - - template , - _Args&&...>, - int> = 0> - variant(allocator_arg_t, - const _Alloc& __alloc, - in_place_index_t<_Ip>, - _Args&&... __args) - _LIBCPP_NOEXCEPT_INIT(__impl, - allocator_arg, - __alloc, - in_place<_Ip>, - _VSTD::forward<_Args>(__args)...) {} - - template , - initializer_list<_Up>&, - _Args&&...>, - int> = 0> - variant(allocator_arg_t, - const _Alloc& __alloc, - in_place_index_t<_Ip>, - initializer_list<_Up> __il, - _Args&&... __args) - _LIBCPP_NOEXCEPT_INIT(__impl, - allocator_arg, - __alloc, - in_place<_Ip>, - __il, - _VSTD::forward<_Args>(__args)...) {} - - template ::value, - enable_if_t, - _Args&&...>, - int> = 0> - variant(allocator_arg_t, - const _Alloc& __alloc, - in_place_type_t<_Tp>, - _Args&&... __args) - _LIBCPP_NOEXCEPT_INIT(__impl, - allocator_arg, - __alloc, - in_place<_Ip>, - _VSTD::forward<_Args>(__args)...) {} - - template ::value, - enable_if_t, - initializer_list<_Up>&, - _Args&&...>, - int> = 0> - variant(allocator_arg_t, - const _Alloc& __alloc, - in_place_type_t<_Tp>, - initializer_list<_Up> __il, - _Args&&... __args) - _LIBCPP_NOEXCEPT_INIT(__impl, - allocator_arg, - __alloc, - in_place<_Ip>, - __il, - _VSTD::forward<_Args>(__args)...) {} - ~variant() = default; variant& operator=(const variant&) = default; @@ -1303,8 +991,8 @@ template , variant>, int> = 0, - class _Tp = __variant_best_match<_Arg&&>, - size_t _Ip = __find_unambiguous_index_sfinae<_Tp>::value> + class _Tp = __variant_best_match<_Arg&&, _Types...>, + size_t _Ip = __find_unambiguous_index_sfinae<_Tp, _Types...>::value> auto operator=(_Arg&& __arg) _LIBCPP_NOEXCEPT_SFINAE_RETURN( __impl.template __assign<_Ip>(_VSTD::forward<_Arg>(__arg))) @@ -1321,7 +1009,7 @@ template ::value> + size_t _Ip = __find_unambiguous_index_sfinae<_Tp, _Types...>::value> auto emplace(_Args&&... __args) _LIBCPP_NOEXCEPT_SFINAE_RETURN( __impl.template emplace<_Ip>(_VSTD::forward<_Args>(__args)...)) @@ -1329,7 +1017,7 @@ template ::value> + size_t _Ip = __find_unambiguous_index_sfinae<_Tp, _Types...>::value> auto emplace(initializer_list<_Up> __il, _Args&&... __args) _LIBCPP_NOEXCEPT_SFINAE_RETURN( __impl.template emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...)) @@ -1550,15 +1238,6 @@ auto swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs) _LIBCPP_NOEXCEPT_SFINAE_RETURN(__lhs.swap(__rhs)) -template <> -struct _LIBCPP_TYPE_VIS_ONLY hash> { - hash() = delete; - hash(const hash&) = delete; - hash(hash&&) = delete; - hash& operator=(const hash&) = delete; - hash& operator=(hash&&) = delete; -}; - template struct _LIBCPP_TYPE_VIS_ONLY hash> { using argument_type = variant<_Types...>; @@ -1585,10 +1264,6 @@ result_type operator()(const argument_type&) const { return 0; } }; -template -struct _LIBCPP_TYPE_VIS_ONLY uses_allocator, _Alloc> - : true_type {}; - #endif // _LIBCPP_STD_VER > 14 _LIBCPP_END_NAMESPACE_STD Index: src/variant.cpp =================================================================== --- src/variant.cpp +++ src/variant.cpp @@ -9,12 +9,10 @@ #include "variant" -_LIBCPP_BEGIN_NAMESPACE_STD - -bad_variant_access::~bad_variant_access() = default; +namespace std { const char* bad_variant_access::what() const noexcept { return "bad_variant_access"; } -_LIBCPP_END_NAMESPACE_STD +}