1
0
Fork 0
mirror of https://github.com/Neargye/magic_enum.git synced 2026-01-09 23:34:23 +00:00

fix enum_subtype deduction

This commit is contained in:
neargye 2023-06-04 20:45:01 +04:00
parent 1c94e914c2
commit 2274b77c80
3 changed files with 20 additions and 20 deletions

View file

@ -705,7 +705,7 @@ constexpr enum_subtype subtype(std::true_type) noexcept {
return enum_subtype::common;
}
}
return flags_values.size() > 0;
return enum_subtype::flags;
#else
return enum_subtype::common;
#endif
@ -1106,14 +1106,14 @@ template <typename E>
}
// Returns number of enum values.
template <typename E, auto S = detail::subtype_v<E>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
[[nodiscard]] constexpr auto enum_count() noexcept -> detail::enable_if_t<E, std::size_t> {
return detail::count_v<std::decay_t<E>, S>;
}
// Returns enum value at specified index.
// No bounds checking is performed: the behavior is undefined if index >= number of enum values.
template <typename E, auto S = detail::subtype_v<E>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
[[nodiscard]] constexpr auto enum_value(std::size_t index) noexcept -> detail::enable_if_t<E, std::decay_t<E>> {
using D = std::decay_t<E>;
@ -1127,7 +1127,7 @@ template <typename E, auto S = detail::subtype_v<E>>
}
// Returns enum value at specified index.
template <typename E, std::size_t I, auto S = detail::subtype_v<E>>
template <typename E, std::size_t I, detail::enum_subtype S = detail::subtype_v<E>>
[[nodiscard]] constexpr auto enum_value() noexcept -> detail::enable_if_t<E, std::decay_t<E>> {
using D = std::decay_t<E>;
static_assert(I < detail::count_v<D, S>, "magic_enum::enum_value out of range.");
@ -1136,7 +1136,7 @@ template <typename E, std::size_t I, auto S = detail::subtype_v<E>>
}
// Returns std::array with enum values, sorted by enum value.
template <typename E, auto S = detail::subtype_v<E>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
[[nodiscard]] constexpr auto enum_values() noexcept -> detail::enable_if_t<E, detail::values_t<E, S>> {
return detail::values_v<std::decay_t<E>, S>;
}
@ -1155,7 +1155,7 @@ template <typename E>
// Obtains index in enum values from enum value.
// Returns optional with index.
template <typename E, auto S = detail::subtype_v<E>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
[[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_t<E, optional<std::size_t>> {
using D = std::decay_t<E>;
using U = underlying_type_t<D>;
@ -1196,7 +1196,7 @@ template <detail::enum_subtype S, typename E>
}
// Obtains index in enum values from static storage enum variable.
template <auto V, auto S = detail::subtype_v<std::decay_t<decltype(V)>>>
template <auto V, detail::enum_subtype S = detail::subtype_v<std::decay_t<decltype(V)>>>
[[nodiscard]] constexpr auto enum_index() noexcept -> detail::enable_if_t<decltype(V), std::size_t> {
constexpr auto index = enum_index<std::decay_t<decltype(V)>, S>(V);
static_assert(index, "magic_enum::enum_index enum value does not have a index.");
@ -1216,7 +1216,7 @@ template <auto V>
// Returns name from enum value.
// If enum value does not have name or value out of range, returns empty string.
template <typename E, auto S = detail::subtype_v<E>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
[[nodiscard]] constexpr auto enum_name(E value) noexcept -> detail::enable_if_t<E, string_view> {
using D = std::decay_t<E>;
@ -1263,13 +1263,13 @@ template <typename E>
}
// Returns std::array with names, sorted by enum value.
template <typename E, auto S = detail::subtype_v<E>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
[[nodiscard]] constexpr auto enum_names() noexcept -> detail::enable_if_t<E, detail::names_t<E, S>> {
return detail::names_v<std::decay_t<E>, S>;
}
// Returns std::array with pairs (value, name), sorted by enum value.
template <typename E, auto S = detail::subtype_v<E>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
[[nodiscard]] constexpr auto enum_entries() noexcept -> detail::enable_if_t<E, detail::entries_t<E, S>> {
return detail::entries_v<std::decay_t<E>, S>;
}
@ -1279,7 +1279,7 @@ inline constexpr auto case_insensitive = detail::case_insensitive<>{};
// Obtains enum value from integer value.
// Returns optional with enum value.
template <typename E, auto S = detail::subtype_v<E>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
[[nodiscard]] constexpr auto enum_cast(underlying_type_t<E> value) noexcept -> detail::enable_if_t<E, optional<std::decay_t<E>>> {
using D = std::decay_t<E>;
@ -1347,7 +1347,7 @@ template <typename E>
// Obtains enum value from name.
// Returns optional with enum value.
template <typename E, auto S = detail::subtype_v<E>, typename BinaryPredicate = std::equal_to<>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>, typename BinaryPredicate = std::equal_to<>>
[[nodiscard]] constexpr auto enum_cast(string_view value, [[maybe_unused]] BinaryPredicate p = {}) noexcept(detail::is_nothrow_invocable<BinaryPredicate>()) -> detail::enable_if_t<E, optional<std::decay_t<E>>, BinaryPredicate> {
using D = std::decay_t<E>;
@ -1414,7 +1414,7 @@ template <typename E, typename BinaryPredicate = std::equal_to<>>
}
// Checks whether enum contains value with such value.
template <typename E, auto S = detail::subtype_v<E>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
[[nodiscard]] constexpr auto enum_contains(E value) noexcept -> detail::enable_if_t<E, bool> {
using D = std::decay_t<E>;
using U = underlying_type_t<D>;
@ -1441,7 +1441,7 @@ template <typename E>
}
// Checks whether enum contains value with such integer value.
template <typename E, auto S = detail::subtype_v<E>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>>
[[nodiscard]] constexpr auto enum_contains(underlying_type_t<E> value) noexcept -> detail::enable_if_t<E, bool> {
using D = std::decay_t<E>;
@ -1457,7 +1457,7 @@ template <typename E>
}
// Checks whether enum contains enumerator with such name.
template <typename E, auto S = detail::subtype_v<E>, typename BinaryPredicate = std::equal_to<>>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>, typename BinaryPredicate = std::equal_to<>>
[[nodiscard]] constexpr auto enum_contains(string_view value, BinaryPredicate p = {}) noexcept(detail::is_nothrow_invocable<BinaryPredicate>()) -> detail::enable_if_t<E, bool, BinaryPredicate> {
using D = std::decay_t<E>;
@ -1472,7 +1472,7 @@ template <typename E, typename BinaryPredicate = std::equal_to<>>
return static_cast<bool>(enum_flags_cast<D>(value, std::move(p)));
}
template <typename E, auto S = detail::subtype_v<E>, typename F, detail::enable_if_t<E, int> = 0>
template <typename E, detail::enum_subtype S = detail::subtype_v<E>, typename F, detail::enable_if_t<E, int> = 0>
constexpr auto enum_for_each(F&& f) {
using D = std::decay_t<E>;
static_assert(std::is_enum_v<D>, "magic_enum::enum_for_each requires enum type.");

View file

@ -142,7 +142,7 @@ constexpr decltype(auto) constexpr_switch(F&& f, E value, Def&& def) {
} // namespace magic_enum::detail
template <typename Result = detail::default_result_type, typename E, auto S = detail::subtype_v<E>, typename F, typename R = detail::result_t<E, S, Result, F>>
template <typename Result = detail::default_result_type, typename E, detail::enum_subtype S = detail::subtype_v<E>, typename F, typename R = detail::result_t<E, S, Result, F>>
constexpr decltype(auto) enum_switch(F&& f, E value) {
using D = std::decay_t<E>;
static_assert(std::is_enum_v<D>, "magic_enum::enum_switch requires enum type.");
@ -165,7 +165,7 @@ constexpr decltype(auto) enum_switch(F&& f, E value) {
return enum_switch<Result, E, S>(std::forward<F>(f), value);
}
template <typename Result, typename E, auto S = detail::subtype_v<E>, typename F, typename R = detail::result_t<E, S, Result, F>>
template <typename Result, typename E, detail::enum_subtype S = detail::subtype_v<E>, typename F, typename R = detail::result_t<E, S, Result, F>>
constexpr decltype(auto) enum_switch(F&& f, E value, Result&& result) {
using D = std::decay_t<E>;
static_assert(std::is_enum_v<D>, "magic_enum::enum_switch requires enum type.");