mirror of
https://github.com/Neargye/magic_enum.git
synced 2026-01-09 23:34:23 +00:00
fix clang llvm-project#50055(reviews.llvm.org/D130058)
This commit is contained in:
parent
f5d6f707a9
commit
95641a8f78
1 changed files with 29 additions and 11 deletions
|
|
@ -431,26 +431,44 @@ constexpr auto n() noexcept {
|
||||||
template <typename E, E V>
|
template <typename E, E V>
|
||||||
inline constexpr auto enum_name_v = n<E, V>();
|
inline constexpr auto enum_name_v = n<E, V>();
|
||||||
|
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
template <typename E, auto V, typename = void>
|
||||||
|
struct is_valid : std::false_type {};
|
||||||
|
|
||||||
template <typename E, auto V>
|
template <typename E, auto V>
|
||||||
constexpr bool is_valid() noexcept {
|
struct is_valid<E, V, std::void_t<decltype(n<E, static_cast<E>(V)>())>> : std::bool_constant<(n<E, static_cast<E>(V)>().size() != 0)> {};
|
||||||
|
#else
|
||||||
|
template <typename E, auto V>
|
||||||
|
constexpr bool valid() noexcept {
|
||||||
static_assert(is_enum_v<E>, "magic_enum::detail::is_valid requires enum type.");
|
static_assert(is_enum_v<E>, "magic_enum::detail::is_valid requires enum type.");
|
||||||
|
|
||||||
return n<E, static_cast<E>(V)>().size() != 0;
|
return n<E, static_cast<E>(V)>().size() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename E, auto V>
|
||||||
|
struct is_valid : std::bool_constant<valid<E, static_cast<E>(V)>()> {};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename E, int O, bool IsFlags, typename U = std::underlying_type_t<E>>
|
||||||
|
constexpr U ualue(std::size_t i) noexcept {
|
||||||
|
static_assert(is_enum_v<E>, "magic_enum::detail::value requires enum type.");
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<U, bool>) { // bool special case
|
||||||
|
static_assert(O == 0, "magic_enum::detail::value requires valid offset.");
|
||||||
|
|
||||||
|
return static_cast<U>(i);
|
||||||
|
} else if constexpr (IsFlags) {
|
||||||
|
return static_cast<U>(U{1} << static_cast<U>(static_cast<int>(i) + O));
|
||||||
|
} else {
|
||||||
|
return static_cast<U>(static_cast<int>(i) + O);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename E, int O, bool IsFlags, typename U = std::underlying_type_t<E>>
|
template <typename E, int O, bool IsFlags, typename U = std::underlying_type_t<E>>
|
||||||
constexpr E value(std::size_t i) noexcept {
|
constexpr E value(std::size_t i) noexcept {
|
||||||
static_assert(is_enum_v<E>, "magic_enum::detail::value requires enum type.");
|
static_assert(is_enum_v<E>, "magic_enum::detail::value requires enum type.");
|
||||||
|
|
||||||
if constexpr (std::is_same_v<U, bool>) { // bool special case
|
return static_cast<E>(ualue<E, O, IsFlags>(i));
|
||||||
static_assert(O == 0, "magic_enum::detail::value requires valid offset.");
|
|
||||||
|
|
||||||
return static_cast<E>(i);
|
|
||||||
} else if constexpr (IsFlags) {
|
|
||||||
return static_cast<E>(U{1} << static_cast<U>(static_cast<int>(i) + O));
|
|
||||||
} else {
|
|
||||||
return static_cast<E>(static_cast<int>(i) + O);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename E, bool IsFlags, typename U = std::underlying_type_t<E>>
|
template <typename E, bool IsFlags, typename U = std::underlying_type_t<E>>
|
||||||
|
|
@ -510,7 +528,7 @@ constexpr std::size_t values_count(const bool (&valid)[N]) noexcept {
|
||||||
template <typename E, bool IsFlags, int Min, std::size_t... I>
|
template <typename E, bool IsFlags, int Min, std::size_t... I>
|
||||||
constexpr auto values(std::index_sequence<I...>) noexcept {
|
constexpr auto values(std::index_sequence<I...>) noexcept {
|
||||||
static_assert(is_enum_v<E>, "magic_enum::detail::values requires enum type.");
|
static_assert(is_enum_v<E>, "magic_enum::detail::values requires enum type.");
|
||||||
constexpr bool valid[sizeof...(I)] = {is_valid<E, value<E, Min, IsFlags>(I)>()...};
|
constexpr bool valid[sizeof...(I)] = {is_valid<E, ualue<E, Min, IsFlags>(I)>::value...};
|
||||||
constexpr std::size_t count = values_count(valid);
|
constexpr std::size_t count = values_count(valid);
|
||||||
|
|
||||||
if constexpr (count > 0) {
|
if constexpr (count > 0) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue