mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-09 15:11:38 +02:00
Merge pull request #6818 from JonnyH/WIP/variant-update
Update mpark::variant implementation to 1.3.0
This commit is contained in:
commit
b938e15699
@ -13,7 +13,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace std
|
||||
namespace mpark
|
||||
{
|
||||
struct in_place_t
|
||||
{
|
||||
@ -32,6 +32,7 @@ struct in_place_type_t
|
||||
explicit in_place_type_t() = default;
|
||||
};
|
||||
|
||||
#ifdef MPARK_VARIABLE_TEMPLATES
|
||||
constexpr in_place_t in_place{};
|
||||
|
||||
template <std::size_t I>
|
||||
@ -39,5 +40,6 @@ constexpr in_place_index_t<I> in_place_index{};
|
||||
|
||||
template <typename T>
|
||||
constexpr in_place_type_t<T> in_place_type{};
|
||||
#endif
|
||||
|
||||
} // namespace std
|
||||
} // namespace mpark
|
||||
|
@ -32,18 +32,18 @@ namespace std {
|
||||
template <class T> constexpr variant(T&&) noexcept(see below);
|
||||
|
||||
template <class T, class... Args>
|
||||
constexpr explicit variant(::std::in_place_type_t<T>, Args&&...);
|
||||
constexpr explicit variant(in_place_type_t<T>, Args&&...);
|
||||
|
||||
template <class T, class U, class... Args>
|
||||
constexpr explicit variant(
|
||||
::std::in_place_type_t<T>, initializer_list<U>, Args&&...);
|
||||
in_place_type_t<T>, initializer_list<U>, Args&&...);
|
||||
|
||||
template <size_t I, class... Args>
|
||||
constexpr explicit variant(::std::in_place_index_t<I>, Args&&...);
|
||||
constexpr explicit variant(in_place_index_t<I>, Args&&...);
|
||||
|
||||
template <size_t I, class U, class... Args>
|
||||
constexpr explicit variant(
|
||||
::std::in_place_index_t<I>, initializer_list<U>, Args&&...);
|
||||
in_place_index_t<I>, initializer_list<U>, Args&&...);
|
||||
|
||||
// 20.7.2.2, destructor
|
||||
~variant();
|
||||
@ -207,7 +207,6 @@ namespace std {
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "in_place.h"
|
||||
|
||||
// MPark.Variant
|
||||
//
|
||||
@ -220,7 +219,7 @@ namespace std {
|
||||
#define MPARK_CONFIG_HPP
|
||||
|
||||
// MSVC 2015 Update 3.
|
||||
#if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024215)
|
||||
#if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024210)
|
||||
#error "MPark.Variant requires C++11 support."
|
||||
#endif
|
||||
|
||||
@ -228,14 +227,22 @@ namespace std {
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef __has_include
|
||||
#define __has_include(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
#if __has_builtin(__builtin_addressof) || __GNUC__ >= 7 || defined(_MSC_VER)
|
||||
#if __has_builtin(__builtin_addressof) || (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER)
|
||||
#define MPARK_BUILTIN_ADDRESSOF
|
||||
#endif
|
||||
|
||||
#if __has_builtin(__builtin_unreachable)
|
||||
#define MPARK_BUILTIN_UNREACHABLE
|
||||
#endif
|
||||
|
||||
#if __has_builtin(__type_pack_element)
|
||||
#define MPARK_TYPE_PACK_ELEMENT
|
||||
#endif
|
||||
@ -244,7 +251,8 @@ namespace std {
|
||||
#define MPARK_CPP14_CONSTEXPR
|
||||
#endif
|
||||
|
||||
#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions)
|
||||
#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || \
|
||||
(defined(_MSC_VER) && defined(_CPPUNWIND))
|
||||
#define MPARK_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
@ -268,8 +276,14 @@ namespace std {
|
||||
#define MPARK_VARIABLE_TEMPLATES
|
||||
#endif
|
||||
|
||||
#if !defined(__GLIBCXX__) || __has_include(<codecvt>) // >= libstdc++-5
|
||||
#define MPARK_TRIVIALITY_TYPE_TRAITS
|
||||
#endif
|
||||
|
||||
#endif // MPARK_CONFIG_HPP
|
||||
|
||||
#include "in_place.h"
|
||||
|
||||
// MPark.Variant
|
||||
//
|
||||
// Copyright Michael Park, 2015-2017
|
||||
@ -287,6 +301,7 @@ namespace std {
|
||||
|
||||
#define RETURN(...) \
|
||||
noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__) { return __VA_ARGS__; }
|
||||
|
||||
namespace mpark
|
||||
{
|
||||
namespace lib
|
||||
@ -303,6 +318,7 @@ template <typename T, std::size_t N>
|
||||
struct array
|
||||
{
|
||||
constexpr const T& operator[](std::size_t index) const { return data[index]; }
|
||||
|
||||
T data[N == 0 ? 1 : N];
|
||||
};
|
||||
|
||||
@ -338,22 +354,16 @@ inline constexpr T&& forward(remove_reference_t<T>&& t) noexcept
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr remove_reference_t<T>&& move(T&& t) noexcept
|
||||
inline constexpr remove_reference_t<T>&& move(T&& t) noexcept
|
||||
{
|
||||
return static_cast<remove_reference_t<T>&&>(t);
|
||||
}
|
||||
|
||||
#ifdef MPARK_INTEGER_SEQUENCE
|
||||
template <typename T, T... Is>
|
||||
using integer_sequence = std::integer_sequence<T, Is...>;
|
||||
|
||||
template <std::size_t... Is>
|
||||
using index_sequence = std::index_sequence<Is...>;
|
||||
|
||||
template <std::size_t N>
|
||||
using make_index_sequence = std::make_index_sequence<N>;
|
||||
|
||||
template <typename... Ts>
|
||||
using index_sequence_for = std::index_sequence_for<Ts...>;
|
||||
using std::index_sequence;
|
||||
using std::index_sequence_for;
|
||||
using std::integer_sequence;
|
||||
using std::make_index_sequence;
|
||||
#else
|
||||
template <typename T, T... Is>
|
||||
struct integer_sequence
|
||||
@ -475,7 +485,12 @@ template <bool B>
|
||||
using bool_constant = std::integral_constant<bool, B>;
|
||||
|
||||
template <typename...>
|
||||
using void_t = void;
|
||||
struct voider : identity<void>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
using void_t = typename voider<Ts...>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
@ -484,7 +499,7 @@ namespace swappable
|
||||
using std::swap;
|
||||
|
||||
template <typename T>
|
||||
struct is_swappable_impl
|
||||
struct is_swappable
|
||||
{
|
||||
private:
|
||||
template <typename U, typename = decltype(swap(std::declval<U&>(), std::declval<U&>()))>
|
||||
@ -494,12 +509,9 @@ private:
|
||||
inline static std::false_type test(...);
|
||||
|
||||
public:
|
||||
using type = decltype(test<T>(0));
|
||||
static constexpr bool value = decltype(test<T>(0))::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using is_swappable = typename is_swappable_impl<T>::type;
|
||||
|
||||
template <typename T, bool = is_swappable<T>::value>
|
||||
struct is_nothrow_swappable
|
||||
{
|
||||
@ -514,11 +526,8 @@ struct is_nothrow_swappable<T, false> : std::false_type
|
||||
} // namespace swappable
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
using is_swappable = detail::swappable::is_swappable<T>;
|
||||
|
||||
template <typename T>
|
||||
using is_nothrow_swappable = detail::swappable::is_nothrow_swappable<T>;
|
||||
using detail::swappable::is_nothrow_swappable;
|
||||
using detail::swappable::is_swappable;
|
||||
|
||||
// <functional>
|
||||
#ifdef _MSC_VER
|
||||
@ -669,16 +678,13 @@ using remove_all_extents_t = typename remove_all_extents<T>::type;
|
||||
template <std::size_t N>
|
||||
using size_constant = std::integral_constant<std::size_t, N>;
|
||||
|
||||
template <bool... Bs>
|
||||
using bool_sequence = integer_sequence<bool, Bs...>;
|
||||
|
||||
template <std::size_t I, typename T>
|
||||
struct indexed_type : size_constant<I>, identity<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <bool... Bs>
|
||||
using all = std::is_same<bool_sequence<true, Bs...>, bool_sequence<Bs..., true>>;
|
||||
using all = std::is_same<integer_sequence<bool, true, Bs...>, integer_sequence<bool, Bs..., true>>;
|
||||
|
||||
#ifdef MPARK_TYPE_PACK_ELEMENT
|
||||
template <std::size_t I, typename... Ts>
|
||||
@ -712,6 +718,52 @@ template <std::size_t I, typename... Ts>
|
||||
using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
|
||||
#endif
|
||||
|
||||
#ifdef MPARK_TRIVIALITY_TYPE_TRAITS
|
||||
using std::is_trivially_copy_assignable;
|
||||
using std::is_trivially_copy_constructible;
|
||||
using std::is_trivially_move_assignable;
|
||||
using std::is_trivially_move_constructible;
|
||||
#else
|
||||
template <typename T>
|
||||
struct is_trivially_copy_constructible
|
||||
: bool_constant<std::is_copy_constructible<T>::value&& __has_trivial_copy(T)>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_trivially_move_constructible : bool_constant<__is_trivial(T)>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_trivially_copy_assignable
|
||||
: bool_constant<std::is_copy_assignable<T>::value&& __has_trivial_assign(T)>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_trivially_move_assignable : bool_constant<__is_trivial(T)>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename T, bool>
|
||||
struct dependent_type : T
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Is, std::size_t J>
|
||||
struct push_back;
|
||||
|
||||
template <typename Is, std::size_t J>
|
||||
using push_back_t = typename push_back<Is, J>::type;
|
||||
|
||||
template <std::size_t... Is, std::size_t J>
|
||||
struct push_back<index_sequence<Is...>, J>
|
||||
{
|
||||
using type = index_sequence<Is..., J>;
|
||||
};
|
||||
|
||||
} // namespace lib
|
||||
} // namespace mpark
|
||||
|
||||
@ -747,6 +799,7 @@ namespace mpark
|
||||
#define AUTO auto
|
||||
#define AUTO_RETURN(...) \
|
||||
->lib::decay_t<decltype(__VA_ARGS__)> { return __VA_ARGS__; }
|
||||
|
||||
#define AUTO_REFREF auto
|
||||
#define AUTO_REFREF_RETURN(...) \
|
||||
->decltype((__VA_ARGS__)) \
|
||||
@ -758,6 +811,7 @@ namespace mpark
|
||||
#define DECLTYPE_AUTO auto
|
||||
#define DECLTYPE_AUTO_RETURN(...) \
|
||||
->decltype(__VA_ARGS__) { return __VA_ARGS__; }
|
||||
|
||||
#endif
|
||||
|
||||
class bad_variant_access : public std::exception
|
||||
@ -772,6 +826,9 @@ public:
|
||||
throw bad_variant_access{};
|
||||
#else
|
||||
std::terminate();
|
||||
#ifdef MPARK_BUILTIN_UNREACHABLE
|
||||
__builtin_unreachable();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -828,26 +885,16 @@ struct variant_alternative<I, const volatile T> : std::add_cv<variant_alternativ
|
||||
};
|
||||
|
||||
template <std::size_t I, typename... Ts>
|
||||
struct variant_alternative<I, variant<Ts...>> : lib::identity<lib::type_pack_element_t<I, Ts...>>
|
||||
struct variant_alternative<I, variant<Ts...>>
|
||||
{
|
||||
static_assert(I < sizeof...(Ts), "`variant_alternative` index out of range.");
|
||||
static_assert(I < sizeof...(Ts), "Index out of bounds in std::variant_alternative<>");
|
||||
using type = lib::type_pack_element_t<I, Ts...>;
|
||||
};
|
||||
|
||||
constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
inline constexpr bool all()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename... Bs>
|
||||
inline constexpr bool all(bool b, Bs... bs)
|
||||
{
|
||||
return b && all(bs...);
|
||||
}
|
||||
|
||||
constexpr std::size_t not_found = static_cast<std::size_t>(-1);
|
||||
constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
|
||||
|
||||
@ -922,9 +969,9 @@ template <typename T, template <typename> class IsTriviallyAvailable,
|
||||
template <typename> class IsAvailable>
|
||||
inline constexpr Trait trait()
|
||||
{
|
||||
return IsTriviallyAvailable<T>::value ? Trait::TriviallyAvailable : IsAvailable<T>::value ?
|
||||
Trait::Available :
|
||||
Trait::Unavailable;
|
||||
return IsTriviallyAvailable<T>::value ?
|
||||
Trait::TriviallyAvailable :
|
||||
IsAvailable<T>::value ? Trait::Available : Trait::Unavailable;
|
||||
}
|
||||
|
||||
#ifdef MPARK_CPP14_CONSTEXPR
|
||||
@ -965,18 +1012,18 @@ template <typename... Ts>
|
||||
struct traits
|
||||
{
|
||||
static constexpr Trait copy_constructible_trait = common_trait(
|
||||
trait<Ts, std::is_trivially_copy_constructible, std::is_copy_constructible>()...);
|
||||
trait<Ts, lib::is_trivially_copy_constructible, std::is_copy_constructible>()...);
|
||||
|
||||
static constexpr Trait move_constructible_trait = common_trait(
|
||||
trait<Ts, std::is_trivially_move_constructible, std::is_move_constructible>()...);
|
||||
trait<Ts, lib::is_trivially_move_constructible, std::is_move_constructible>()...);
|
||||
|
||||
static constexpr Trait copy_assignable_trait =
|
||||
common_trait(copy_constructible_trait, move_constructible_trait,
|
||||
trait<Ts, std::is_trivially_copy_assignable, std::is_copy_assignable>()...);
|
||||
common_trait(copy_constructible_trait,
|
||||
trait<Ts, lib::is_trivially_copy_assignable, std::is_copy_assignable>()...);
|
||||
|
||||
static constexpr Trait move_assignable_trait =
|
||||
common_trait(move_constructible_trait,
|
||||
trait<Ts, std::is_trivially_move_assignable, std::is_move_assignable>()...);
|
||||
trait<Ts, lib::is_trivially_move_assignable, std::is_move_assignable>()...);
|
||||
|
||||
static constexpr Trait destructible_trait =
|
||||
common_trait(trait<Ts, std::is_trivially_destructible, std::is_destructible>()...);
|
||||
@ -988,15 +1035,15 @@ struct recursive_union
|
||||
{
|
||||
#ifdef MPARK_RETURN_TYPE_DEDUCTION
|
||||
template <typename V>
|
||||
inline static constexpr auto&& get_alt(V&& v, ::std::in_place_index_t<0>)
|
||||
inline static constexpr auto&& get_alt(V&& v, in_place_index_t<0>)
|
||||
{
|
||||
return lib::forward<V>(v).head_;
|
||||
}
|
||||
|
||||
template <typename V, std::size_t I>
|
||||
inline static constexpr auto&& get_alt(V&& v, ::std::in_place_index_t<I>)
|
||||
inline static constexpr auto&& get_alt(V&& v, in_place_index_t<I>)
|
||||
{
|
||||
return get_alt(lib::forward<V>(v).tail_, ::std::in_place_index_t<I - 1>{});
|
||||
return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{});
|
||||
}
|
||||
#else
|
||||
template <std::size_t I, bool Dummy = true>
|
||||
@ -1016,7 +1063,7 @@ struct recursive_union
|
||||
};
|
||||
|
||||
template <typename V, std::size_t I>
|
||||
inline static constexpr AUTO_REFREF get_alt(V&& v, ::std::in_place_index_t<I>)
|
||||
inline static constexpr AUTO_REFREF get_alt(V&& v, in_place_index_t<I>)
|
||||
AUTO_REFREF_RETURN(get_alt_impl<I>{}(lib::forward<V>(v)))
|
||||
#endif
|
||||
};
|
||||
@ -1025,8 +1072,7 @@ struct base
|
||||
{
|
||||
template <std::size_t I, typename V>
|
||||
inline static constexpr AUTO_REFREF get_alt(V&& v)
|
||||
AUTO_REFREF_RETURN(recursive_union::get_alt(lib::forward<V>(v).data_,
|
||||
::std::in_place_index_t<I>{}))
|
||||
AUTO_REFREF_RETURN(recursive_union::get_alt(data(lib::forward<V>(v)), in_place_index_t<I>{}))
|
||||
};
|
||||
|
||||
struct variant
|
||||
@ -1042,7 +1088,6 @@ namespace visitation
|
||||
{
|
||||
struct base
|
||||
{
|
||||
private:
|
||||
template <typename T>
|
||||
inline static constexpr const T& at(const T& elem)
|
||||
{
|
||||
@ -1059,7 +1104,7 @@ private:
|
||||
template <typename F, typename... Fs>
|
||||
inline static constexpr int visit_visitor_return_type_check()
|
||||
{
|
||||
static_assert(all(std::is_same<F, Fs>::value...),
|
||||
static_assert(lib::all<std::is_same<F, Fs>::value...>::value,
|
||||
"`mpark::visit` requires the visitor to have a single "
|
||||
"return type.");
|
||||
return 0;
|
||||
@ -1103,23 +1148,22 @@ private:
|
||||
-> decltype(make_fdiagonal_impl<F, V, Vs...>(
|
||||
lib::make_index_sequence<lib::decay_t<V>::size()>{}))
|
||||
{
|
||||
static_assert(all((lib::decay_t<V>::size() == lib::decay_t<Vs>::size())...),
|
||||
static_assert(lib::all<(lib::decay_t<V>::size() == lib::decay_t<Vs>::size())...>::value,
|
||||
"all of the variants must be the same size.");
|
||||
return make_fdiagonal_impl<F, V, Vs...>(lib::make_index_sequence<lib::decay_t<V>::size()>{});
|
||||
}
|
||||
|
||||
#ifdef MPARK_RETURN_TYPE_DEDUCTION
|
||||
template <typename F, typename... Vs, std::size_t... Is>
|
||||
inline static constexpr auto make_fmatrix_impl(lib::index_sequence<Is...> is)
|
||||
template <typename F, typename... Vs, typename Is>
|
||||
inline static constexpr auto make_fmatrix_impl(Is is)
|
||||
{
|
||||
return make_dispatch<F, Vs...>(is);
|
||||
}
|
||||
|
||||
template <typename F, typename... Vs, std::size_t... Is, std::size_t... Js, typename... Ls>
|
||||
inline static constexpr auto make_fmatrix_impl(lib::index_sequence<Is...>,
|
||||
lib::index_sequence<Js...>, Ls... ls)
|
||||
template <typename F, typename... Vs, typename Is, std::size_t... Js, typename... Ls>
|
||||
inline static constexpr auto make_fmatrix_impl(Is, lib::index_sequence<Js...>, Ls... ls)
|
||||
{
|
||||
return make_farray(make_fmatrix_impl<F, Vs...>(lib::index_sequence<Is..., Js>{}, ls...)...);
|
||||
return make_farray(make_fmatrix_impl<F, Vs...>(lib::push_back_t<Is, Js>{}, ls...)...);
|
||||
}
|
||||
|
||||
template <typename F, typename... Vs>
|
||||
@ -1135,41 +1179,78 @@ private:
|
||||
template <typename...>
|
||||
struct impl;
|
||||
|
||||
template <std::size_t... Is>
|
||||
struct impl<lib::index_sequence<Is...>>
|
||||
template <typename Is>
|
||||
struct impl<Is>
|
||||
{
|
||||
inline constexpr AUTO operator()() const
|
||||
AUTO_RETURN(make_dispatch<F, Vs...>(lib::index_sequence<Is...>{}))
|
||||
inline constexpr AUTO operator()() const AUTO_RETURN(make_dispatch<F, Vs...>(Is{}))
|
||||
};
|
||||
|
||||
template <std::size_t... Is, std::size_t... Js, typename... Ls>
|
||||
struct impl<lib::index_sequence<Is...>, lib::index_sequence<Js...>, Ls...>
|
||||
template <typename Is, std::size_t... Js, typename... Ls>
|
||||
struct impl<Is, lib::index_sequence<Js...>, Ls...>
|
||||
{
|
||||
inline constexpr AUTO operator()() const
|
||||
AUTO_RETURN(make_farray(impl<lib::index_sequence<Is..., Js>, Ls...>{}()...))
|
||||
AUTO_RETURN(make_farray(impl<lib::push_back_t<Is, Js>, Ls...>{}()...))
|
||||
};
|
||||
};
|
||||
|
||||
template <typename F, typename... Vs>
|
||||
inline static constexpr AUTO make_fmatrix()
|
||||
AUTO_RETURN(
|
||||
typename make_fmatrix_impl<F, Vs...>::template impl<
|
||||
lib::index_sequence<>,
|
||||
lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
|
||||
AUTO_RETURN(typename make_fmatrix_impl<F, Vs...>::template impl<
|
||||
lib::index_sequence<>, lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
|
||||
#endif
|
||||
}; // namespace base
|
||||
|
||||
public:
|
||||
template <typename F, typename... Vs>
|
||||
using FDiagonal = decltype(base::make_fdiagonal<F, Vs...>());
|
||||
|
||||
template <typename F, typename... Vs>
|
||||
struct fdiagonal
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4268)
|
||||
#endif
|
||||
static constexpr FDiagonal<F, Vs...> value = base::make_fdiagonal<F, Vs...>();
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename F, typename... Vs>
|
||||
constexpr FDiagonal<F, Vs...> fdiagonal<F, Vs...>::value;
|
||||
|
||||
template <typename F, typename... Vs>
|
||||
using FMatrix = decltype(base::make_fmatrix<F, Vs...>());
|
||||
|
||||
template <typename F, typename... Vs>
|
||||
struct fmatrix
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4268)
|
||||
#endif
|
||||
static constexpr FMatrix<F, Vs...> value = base::make_fmatrix<F, Vs...>();
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename F, typename... Vs>
|
||||
constexpr FMatrix<F, Vs...> fmatrix<F, Vs...>::value;
|
||||
|
||||
struct alt
|
||||
{
|
||||
template <typename Visitor, typename... Vs>
|
||||
inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index, Visitor&& visitor,
|
||||
Vs&&... vs)
|
||||
DECLTYPE_AUTO_RETURN(
|
||||
at(make_fdiagonal<Visitor&&, decltype(as_base(lib::forward<Vs>(vs)))...>(),
|
||||
base::at(fdiagonal<Visitor&&, decltype(as_base(lib::forward<Vs>(vs)))...>::value,
|
||||
index)(lib::forward<Visitor>(visitor), as_base(lib::forward<Vs>(vs))...))
|
||||
|
||||
template <typename Visitor, typename... Vs>
|
||||
inline static constexpr DECLTYPE_AUTO
|
||||
visit_alt(Visitor&& visitor, Vs&&... vs) DECLTYPE_AUTO_RETURN(
|
||||
at(make_fmatrix<Visitor&&, decltype(as_base(lib::forward<Vs>(vs)))...>(),
|
||||
base::at(fmatrix<Visitor&&, decltype(as_base(lib::forward<Vs>(vs)))...>::value,
|
||||
vs.index()...)(lib::forward<Visitor>(visitor), as_base(lib::forward<Vs>(vs))...))
|
||||
};
|
||||
|
||||
@ -1213,12 +1294,12 @@ private:
|
||||
: template <typename Visitor, typename... Vs>
|
||||
inline static constexpr DECLTYPE_AUTO
|
||||
visit_alt_at(std::size_t index, Visitor&& visitor, Vs&&... vs)
|
||||
DECLTYPE_AUTO_RETURN(base::visit_alt_at(index, lib::forward<Visitor>(visitor),
|
||||
DECLTYPE_AUTO_RETURN(alt::visit_alt_at(index, lib::forward<Visitor>(visitor),
|
||||
lib::forward<Vs>(vs).impl_...))
|
||||
|
||||
template <typename Visitor, typename... Vs>
|
||||
inline static constexpr DECLTYPE_AUTO visit_alt(Visitor&& visitor, Vs&&... vs)
|
||||
DECLTYPE_AUTO_RETURN(base::visit_alt(lib::forward<Visitor>(visitor),
|
||||
DECLTYPE_AUTO_RETURN(alt::visit_alt(lib::forward<Visitor>(visitor),
|
||||
lib::forward<Vs>(vs).impl_...))
|
||||
|
||||
template <typename Visitor, typename... Vs>
|
||||
@ -1247,8 +1328,7 @@ struct alt
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
template <typename... Args>
|
||||
inline explicit constexpr alt(::std::in_place_t, Args&&... args)
|
||||
: value(lib::forward<Args>(args)...)
|
||||
inline explicit constexpr alt(in_place_t, Args&&... args) : value(lib::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
@ -1272,15 +1352,16 @@ union recursive_union<DestructibleTrait, Index>
|
||||
{ \
|
||||
public: \
|
||||
inline explicit constexpr recursive_union(valueless_t) noexcept : dummy_{} {} \
|
||||
\
|
||||
template <typename... Args> \
|
||||
inline explicit constexpr recursive_union(::std::in_place_index_t<0>, Args&&... args) \
|
||||
: head_(::std::in_place_t{}, lib::forward<Args>(args)...) \
|
||||
inline explicit constexpr recursive_union(in_place_index_t<0>, Args&&... args) \
|
||||
: head_(in_place_t{}, lib::forward<Args>(args)...) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
template <std::size_t I, typename... Args> \
|
||||
inline explicit constexpr recursive_union(::std::in_place_index_t<I>, Args&&... args) \
|
||||
: tail_(::std::in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) \
|
||||
inline explicit constexpr recursive_union(in_place_index_t<I>, Args&&... args) \
|
||||
: tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
@ -1313,14 +1394,14 @@ template <Trait DestructibleTrait, typename... Ts>
|
||||
class base
|
||||
{
|
||||
public:
|
||||
inline explicit constexpr base(valueless_t tag) noexcept : data_(tag),
|
||||
index_(static_cast<index_t>(-1))
|
||||
inline explicit constexpr base(valueless_t tag) noexcept
|
||||
: data_(tag), index_(static_cast<index_t>(-1))
|
||||
{
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args>
|
||||
inline explicit constexpr base(::std::in_place_index_t<I>, Args&&... args)
|
||||
: data_(::std::in_place_index_t<I>{}, lib::forward<Args>(args)...), index_(I)
|
||||
inline explicit constexpr base(in_place_index_t<I>, Args&&... args)
|
||||
: data_(in_place_index_t<I>{}, lib::forward<Args>(args)...), index_(I)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1335,12 +1416,21 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
using data_t = recursive_union<DestructibleTrait, 0, Ts...>;
|
||||
|
||||
friend inline constexpr base& as_base(base& b) { return b; }
|
||||
friend inline constexpr const base& as_base(const base& b) { return b; }
|
||||
friend inline constexpr base&& as_base(base&& b) { return lib::move(b); }
|
||||
friend inline constexpr const base&& as_base(const base&& b) { return lib::move(b); }
|
||||
|
||||
friend inline constexpr data_t& data(base& b) { return b.data_; }
|
||||
friend inline constexpr const data_t& data(const base& b) { return b.data_; }
|
||||
friend inline constexpr data_t&& data(base&& b) { return lib::move(b).data_; }
|
||||
friend inline constexpr const data_t&& data(const base&& b) { return lib::move(b).data_; }
|
||||
|
||||
inline static constexpr std::size_t size() { return sizeof...(Ts); }
|
||||
recursive_union<DestructibleTrait, 0, Ts...> data_;
|
||||
|
||||
data_t data_;
|
||||
index_t index_;
|
||||
|
||||
friend struct access::base;
|
||||
@ -1404,7 +1494,7 @@ MPARK_VARIANT_DESTRUCTOR(Trait::Available, ~destructor() { destroy(); },
|
||||
inline void destroy() noexcept {
|
||||
if (!this->valueless_by_exception())
|
||||
{
|
||||
visitation::base::visit_alt(dtor{}, *this);
|
||||
visitation::alt::visit_alt(dtor{}, *this);
|
||||
}
|
||||
this->index_ = static_cast<index_t>(-1);
|
||||
});
|
||||
@ -1439,7 +1529,7 @@ protected:
|
||||
inline static T& construct_alt(alt<I, T>& a, Args&&... args)
|
||||
{
|
||||
::new (static_cast<void*>(lib::addressof(a)))
|
||||
alt<I, T>(::std::in_place_t{}, lib::forward<Args>(args)...);
|
||||
alt<I, T>(in_place_t{}, lib::forward<Args>(args)...);
|
||||
return a.value;
|
||||
}
|
||||
|
||||
@ -1449,7 +1539,7 @@ protected:
|
||||
lhs.destroy();
|
||||
if (!rhs.valueless_by_exception())
|
||||
{
|
||||
visitation::base::visit_alt_at(rhs.index(),
|
||||
visitation::alt::visit_alt_at(rhs.index(),
|
||||
#ifdef MPARK_GENERIC_LAMBDAS
|
||||
[](auto& lhs_alt, auto&& rhs_alt) {
|
||||
constructor::construct_alt(
|
||||
@ -1488,12 +1578,10 @@ class move_constructor;
|
||||
MPARK_VARIANT_MOVE_CONSTRUCTOR(Trait::TriviallyAvailable,
|
||||
move_constructor(move_constructor&& that) = default;);
|
||||
|
||||
MPARK_VARIANT_MOVE_CONSTRUCTOR(Trait::Available,
|
||||
move_constructor(move_constructor&& that) noexcept(
|
||||
all(std::is_nothrow_move_constructible<Ts>::value...))
|
||||
: move_constructor(valueless_t{}) {
|
||||
this->generic_construct(*this, lib::move(that));
|
||||
});
|
||||
MPARK_VARIANT_MOVE_CONSTRUCTOR(
|
||||
Trait::Available, move_constructor(move_constructor&& that) noexcept(
|
||||
lib::all<std::is_nothrow_move_constructible<Ts>::value...>::value)
|
||||
: move_constructor(valueless_t{}) { this->generic_construct(*this, lib::move(that)); });
|
||||
|
||||
MPARK_VARIANT_MOVE_CONSTRUCTOR(Trait::Unavailable, move_constructor(move_constructor&&) = delete;);
|
||||
|
||||
@ -1560,15 +1648,14 @@ protected:
|
||||
template <typename ThisAlt, typename ThatAlt>
|
||||
inline void operator()(ThisAlt& this_alt, ThatAlt&& that_alt) const
|
||||
{
|
||||
self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value,
|
||||
std::is_lvalue_reference<That>{});
|
||||
self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value);
|
||||
}
|
||||
assignment* self;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <bool CopyAssign, std::size_t I, typename T, typename Arg>
|
||||
inline void assign_alt(alt<I, T>& a, Arg&& arg, lib::bool_constant<CopyAssign> tag)
|
||||
template <std::size_t I, typename T, typename Arg>
|
||||
inline void assign_alt(alt<I, T>& a, Arg&& arg)
|
||||
{
|
||||
if (this->index() == I)
|
||||
{
|
||||
@ -1585,12 +1672,13 @@ protected:
|
||||
{
|
||||
struct
|
||||
{
|
||||
void operator()(std::true_type) const { this_->emplace<I>(T(lib::forward<Arg>(arg_))); }
|
||||
void operator()(std::false_type) const { this_->emplace<I>(lib::forward<Arg>(arg_)); }
|
||||
void operator()(std::true_type) const { this_->emplace<I>(lib::forward<Arg>(arg_)); }
|
||||
void operator()(std::false_type) const { this_->emplace<I>(T(lib::forward<Arg>(arg_))); }
|
||||
assignment* this_;
|
||||
Arg&& arg_;
|
||||
} impl{this, lib::forward<Arg>(arg)};
|
||||
impl(tag);
|
||||
impl(lib::bool_constant < std::is_nothrow_constructible<T, Arg>::value ||
|
||||
!std::is_nothrow_move_constructible<T>::value > {});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1607,12 +1695,11 @@ protected:
|
||||
}
|
||||
else
|
||||
{
|
||||
visitation::base::visit_alt_at(
|
||||
visitation::alt::visit_alt_at(
|
||||
that.index(),
|
||||
#ifdef MPARK_GENERIC_LAMBDAS
|
||||
[this](auto& this_alt, auto&& that_alt) {
|
||||
this->assign_alt(this_alt, lib::forward<decltype(that_alt)>(that_alt).value,
|
||||
std::is_lvalue_reference<That>{});
|
||||
this->assign_alt(this_alt, lib::forward<decltype(that_alt)>(that_alt).value);
|
||||
}
|
||||
#else
|
||||
assigner<That> { this }
|
||||
@ -1646,10 +1733,10 @@ class move_assignment;
|
||||
MPARK_VARIANT_MOVE_ASSIGNMENT(Trait::TriviallyAvailable,
|
||||
move_assignment& operator=(move_assignment&& that) = default;);
|
||||
|
||||
MPARK_VARIANT_MOVE_ASSIGNMENT(Trait::Available,
|
||||
move_assignment& operator=(move_assignment&& that) noexcept(
|
||||
all((std::is_nothrow_move_constructible<Ts>::value &&
|
||||
std::is_nothrow_move_assignable<Ts>::value)...)) {
|
||||
MPARK_VARIANT_MOVE_ASSIGNMENT(
|
||||
Trait::Available, move_assignment& operator=(move_assignment&& that) noexcept(
|
||||
lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
|
||||
std::is_nothrow_move_assignable<Ts>::value)...>::value) {
|
||||
this->generic_assign(lib::move(that));
|
||||
return *this;
|
||||
});
|
||||
@ -1705,7 +1792,7 @@ public:
|
||||
template <std::size_t I, typename Arg>
|
||||
inline void assign(Arg&& arg)
|
||||
{
|
||||
this->assign_alt(access::base::get_alt<I>(*this), lib::forward<Arg>(arg), std::false_type{});
|
||||
this->assign_alt(access::base::get_alt<I>(*this), lib::forward<Arg>(arg));
|
||||
}
|
||||
|
||||
inline void swap(impl& that)
|
||||
@ -1716,7 +1803,7 @@ public:
|
||||
}
|
||||
else if (this->index() == that.index())
|
||||
{
|
||||
visitation::base::visit_alt_at(this->index(),
|
||||
visitation::alt::visit_alt_at(this->index(),
|
||||
#ifdef MPARK_GENERIC_LAMBDAS
|
||||
[](auto& this_alt, auto& that_alt) {
|
||||
using std::swap;
|
||||
@ -1781,26 +1868,56 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t I, typename T>
|
||||
struct overload_leaf
|
||||
{
|
||||
using F = lib::size_constant<I> (*)(T);
|
||||
operator F() const { return nullptr; }
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
struct overload;
|
||||
|
||||
template <>
|
||||
struct overload<>
|
||||
struct overload_impl
|
||||
{
|
||||
private:
|
||||
template <typename>
|
||||
struct impl;
|
||||
|
||||
template <std::size_t... Is>
|
||||
struct impl<lib::index_sequence<Is...>> : overload_leaf<Is, Ts>...
|
||||
{
|
||||
void operator()() const {}
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct overload<T, Ts...> : overload<Ts...>
|
||||
{
|
||||
using overload<Ts...>::operator();
|
||||
lib::identity<T> operator()(T) const { return {}; }
|
||||
public:
|
||||
using type = impl<lib::index_sequence_for<Ts...>>;
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
using best_match_t = typename lib::invoke_result_t<overload<Ts...>, T&&>::type;
|
||||
template <typename... Ts>
|
||||
using overload = typename overload_impl<Ts...>::type;
|
||||
|
||||
} // detail
|
||||
template <typename T, typename... Ts>
|
||||
using best_match = lib::invoke_result_t<overload<Ts...>, T&&>;
|
||||
|
||||
template <typename T>
|
||||
struct is_in_place_index : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <std::size_t I>
|
||||
struct is_in_place_index<in_place_index_t<I>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_in_place_type : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_in_place_type<in_place_type_t<T>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename... Ts>
|
||||
class variant
|
||||
@ -1820,49 +1937,51 @@ public:
|
||||
template <typename Front = lib::type_pack_element_t<0, Ts...>,
|
||||
lib::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
|
||||
inline constexpr variant() noexcept(std::is_nothrow_default_constructible<Front>::value)
|
||||
: impl_(::std::in_place_index_t<0>{})
|
||||
: impl_(in_place_index_t<0>{})
|
||||
{
|
||||
}
|
||||
|
||||
variant(const variant&) = default;
|
||||
variant(variant&&) = default;
|
||||
|
||||
template <typename Arg,
|
||||
lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value, int> = 0,
|
||||
typename T = detail::best_match_t<Arg, Ts...>,
|
||||
std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
|
||||
template <typename Arg, typename Decayed = lib::decay_t<Arg>,
|
||||
lib::enable_if_t<!std::is_same<Decayed, variant>::value, int> = 0,
|
||||
lib::enable_if_t<!detail::is_in_place_index<Decayed>::value, int> = 0,
|
||||
lib::enable_if_t<!detail::is_in_place_type<Decayed>::value, int> = 0,
|
||||
std::size_t I = detail::best_match<Arg, Ts...>::value,
|
||||
typename T = lib::type_pack_element_t<I, Ts...>,
|
||||
lib::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
|
||||
inline constexpr variant(Arg&& arg) noexcept(std::is_nothrow_constructible<T, Arg>::value)
|
||||
: impl_(::std::in_place_index_t<I>{}, lib::forward<Arg>(arg))
|
||||
: impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg))
|
||||
{
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args, typename T = lib::type_pack_element_t<I, Ts...>,
|
||||
lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
|
||||
inline explicit constexpr variant(::std::in_place_index_t<I>, Args&&... args) noexcept(
|
||||
inline explicit constexpr variant(in_place_index_t<I>, Args&&... args) noexcept(
|
||||
std::is_nothrow_constructible<T, Args...>::value)
|
||||
: impl_(::std::in_place_index_t<I>{}, lib::forward<Args>(args)...)
|
||||
: impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
template <std::size_t I, typename Up, typename... Args,
|
||||
typename T = lib::type_pack_element_t<I, Ts...>,
|
||||
lib::enable_if_t<std::is_constructible<T, std::initializer_list<Up>&, Args...>::value,
|
||||
int> = 0>
|
||||
template <
|
||||
std::size_t I, typename Up, typename... Args, typename T = lib::type_pack_element_t<I, Ts...>,
|
||||
lib::enable_if_t<std::is_constructible<T, std::initializer_list<Up>&, Args...>::value, int> =
|
||||
0>
|
||||
inline explicit constexpr variant(
|
||||
::std::in_place_index_t<I>, std::initializer_list<Up> il,
|
||||
in_place_index_t<I>, std::initializer_list<Up> il,
|
||||
Args&&... args) noexcept(std::is_nothrow_constructible<T, std::initializer_list<Up>&,
|
||||
Args...>::value)
|
||||
: impl_(::std::in_place_index_t<I>{}, il, lib::forward<Args>(args)...)
|
||||
: impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T, typename... Args,
|
||||
std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
|
||||
lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
|
||||
inline explicit constexpr variant(::std::in_place_type_t<T>, Args&&... args) noexcept(
|
||||
inline explicit constexpr variant(in_place_type_t<T>, Args&&... args) noexcept(
|
||||
std::is_nothrow_constructible<T, Args...>::value)
|
||||
: impl_(::std::in_place_index_t<I>{}, lib::forward<Args>(args)...)
|
||||
: impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1871,10 +1990,10 @@ public:
|
||||
lib::enable_if_t<std::is_constructible<T, std::initializer_list<Up>&, Args...>::value,
|
||||
int> = 0>
|
||||
inline explicit constexpr variant(
|
||||
::std::in_place_type_t<T>, std::initializer_list<Up> il,
|
||||
in_place_type_t<T>, std::initializer_list<Up> il,
|
||||
Args&&... args) noexcept(std::is_nothrow_constructible<T, std::initializer_list<Up>&,
|
||||
Args...>::value)
|
||||
: impl_(::std::in_place_index_t<I>{}, il, lib::forward<Args>(args)...)
|
||||
: impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1885,8 +2004,8 @@ public:
|
||||
|
||||
template <
|
||||
typename Arg, lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value, int> = 0,
|
||||
typename T = detail::best_match_t<Arg, Ts...>,
|
||||
std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
|
||||
std::size_t I = detail::best_match<Arg, Ts...>::value,
|
||||
typename T = lib::type_pack_element_t<I, Ts...>,
|
||||
lib::enable_if_t<(std::is_assignable<T&, Arg>::value && std::is_constructible<T, Arg>::value),
|
||||
int> = 0>
|
||||
inline variant& operator=(Arg&& arg) noexcept((std::is_nothrow_assignable<T&, Arg>::value &&
|
||||
@ -1903,10 +2022,10 @@ public:
|
||||
return impl_.template emplace<I>(lib::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <std::size_t I, typename Up, typename... Args,
|
||||
typename T = lib::type_pack_element_t<I, Ts...>,
|
||||
lib::enable_if_t<std::is_constructible<T, std::initializer_list<Up>&, Args...>::value,
|
||||
int> = 0>
|
||||
template <
|
||||
std::size_t I, typename Up, typename... Args, typename T = lib::type_pack_element_t<I, Ts...>,
|
||||
lib::enable_if_t<std::is_constructible<T, std::initializer_list<Up>&, Args...>::value, int> =
|
||||
0>
|
||||
inline T& emplace(std::initializer_list<Up> il, Args&&... args)
|
||||
{
|
||||
return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
|
||||
@ -1935,9 +2054,12 @@ public:
|
||||
}
|
||||
|
||||
inline constexpr std::size_t index() const noexcept { return impl_.index(); }
|
||||
template <bool Dummy = true,
|
||||
lib::enable_if_t<lib::all<Dummy, (std::is_move_constructible<Ts>::value &&
|
||||
lib::is_swappable<Ts>::value)...>::value,
|
||||
|
||||
template <
|
||||
bool Dummy = true,
|
||||
lib::enable_if_t<
|
||||
lib::all<Dummy, (lib::dependent_type<std::is_move_constructible<Ts>, Dummy>::value &&
|
||||
lib::dependent_type<lib::is_swappable<Ts>, Dummy>::value)...>::value,
|
||||
int> = 0>
|
||||
inline void
|
||||
swap(variant& that) noexcept(lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
|
||||
@ -1971,6 +2093,7 @@ template <std::size_t I, typename V>
|
||||
struct generic_get_impl
|
||||
{
|
||||
constexpr generic_get_impl(int) {}
|
||||
|
||||
constexpr AUTO_REFREF operator()(V&& v) const
|
||||
AUTO_REFREF_RETURN(access::variant::get_alt<I>(lib::forward<V>(v)).value)
|
||||
};
|
||||
@ -2190,12 +2313,6 @@ inline constexpr bool operator>=(const variant<Ts...>& lhs, const variant<Ts...>
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Visitor, typename... Vs>
|
||||
inline constexpr DECLTYPE_AUTO visit(Visitor&& visitor, Vs&&... vs) DECLTYPE_AUTO_RETURN(
|
||||
(detail::all(!vs.valueless_by_exception()...) ? (void)0 : throw_bad_variant_access()),
|
||||
detail::visitation::variant::visit_value(lib::forward<Visitor>(visitor),
|
||||
lib::forward<Vs>(vs)...))
|
||||
|
||||
struct monostate
|
||||
{
|
||||
};
|
||||
@ -2230,6 +2347,56 @@ inline constexpr bool operator!=(monostate, monostate) noexcept
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef MPARK_CPP14_CONSTEXPR
|
||||
namespace detail
|
||||
{
|
||||
inline constexpr bool all(std::initializer_list<bool> bs)
|
||||
{
|
||||
for (bool b : bs)
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Visitor, typename... Vs>
|
||||
inline constexpr decltype(auto) visit(Visitor&& visitor, Vs&&... vs)
|
||||
{
|
||||
return (detail::all({!vs.valueless_by_exception()...}) ? (void)0 : throw_bad_variant_access()),
|
||||
detail::visitation::variant::visit_value(lib::forward<Visitor>(visitor),
|
||||
lib::forward<Vs>(vs)...);
|
||||
}
|
||||
#else
|
||||
namespace detail
|
||||
{
|
||||
template <std::size_t N>
|
||||
inline constexpr bool all_impl(const lib::array<bool, N>& bs, std::size_t idx)
|
||||
{
|
||||
return idx >= N || (bs[idx] && all_impl(bs, idx + 1));
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
inline constexpr bool all(const lib::array<bool, N>& bs)
|
||||
{
|
||||
return all_impl(bs, 0);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Visitor, typename... Vs>
|
||||
inline constexpr DECLTYPE_AUTO visit(Visitor&& visitor, Vs&&... vs) DECLTYPE_AUTO_RETURN(
|
||||
(detail::all(lib::array<bool, sizeof...(Vs)>{{!vs.valueless_by_exception()...}}) ?
|
||||
(void)0 :
|
||||
throw_bad_variant_access()),
|
||||
detail::visitation::variant::visit_value(lib::forward<Visitor>(visitor),
|
||||
lib::forward<Vs>(vs)...))
|
||||
#endif
|
||||
|
||||
template <typename... Ts>
|
||||
inline auto swap(variant<Ts...>& lhs, variant<Ts...>& rhs) noexcept(noexcept(lhs.swap(rhs)))
|
||||
-> decltype(lhs.swap(rhs))
|
||||
@ -2342,15 +2509,15 @@ struct hash<mpark::monostate>
|
||||
|
||||
namespace std
|
||||
{
|
||||
using mpark::variant;
|
||||
using mpark::visit;
|
||||
using mpark::holds_alternative;
|
||||
using mpark::bad_variant_access;
|
||||
using mpark::get;
|
||||
using mpark::get_if;
|
||||
using mpark::holds_alternative;
|
||||
using mpark::monostate;
|
||||
using mpark::bad_variant_access;
|
||||
using mpark::variant_size;
|
||||
using mpark::variant;
|
||||
using mpark::variant_alternative;
|
||||
using mpark::variant_alternative_t;
|
||||
using mpark::variant_size;
|
||||
using mpark::visit;
|
||||
} // namespace std
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user