mirror of
https://github.com/Neargye/magic_enum.git
synced 2026-01-10 23:44:29 +00:00
move is_flags to customize::enum_range
force set the enum-flag true or false
This commit is contained in:
parent
a8c9e57fbe
commit
9ed19fb9e9
4 changed files with 22 additions and 17 deletions
|
|
@ -7,11 +7,13 @@
|
||||||
|
|
||||||
* Enum can't reflect if the enum is a forward declaration.
|
* Enum can't reflect if the enum is a forward declaration.
|
||||||
|
|
||||||
* For enum-flags add specialization `is_flags_enum` for necessary enum type. Specialization of `is_flags_enum` must be injected in `namespace magic_enum::customize`.
|
* For enum-flags add `is_flags` to specialization `enum_range` for necessary enum type. Specialization of `enum_range` must be injected in `namespace magic_enum::customize`.
|
||||||
```cpp
|
```cpp
|
||||||
enum class Directions { Up = 1 << 1, Down = 1 << 2, Right = 1 << 3, Left = 1 << 4 };
|
enum class Directions { Up = 1 << 1, Down = 1 << 2, Right = 1 << 3, Left = 1 << 4 };
|
||||||
template <>
|
template <>
|
||||||
struct magic_enum::customize::is_flags_enum<Directions> : std::true_type {};
|
struct magic_enum::customize::enum_range<Directions> {
|
||||||
|
static constexpr bool is_flags = true;
|
||||||
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
* Enum value must be in range `[MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]`.
|
* Enum value must be in range `[MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]`.
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,11 @@
|
||||||
#include <magic_enum.hpp>
|
#include <magic_enum.hpp>
|
||||||
|
|
||||||
enum class AnimalFlags : std::uint64_t { HasClaws = 1 << 10, CanFly = 1 << 20, EatsFish = 1 << 30, Endangered = std::uint64_t{1} << 40 };
|
enum class AnimalFlags : std::uint64_t { HasClaws = 1 << 10, CanFly = 1 << 20, EatsFish = 1 << 30, Endangered = std::uint64_t{1} << 40 };
|
||||||
// Add specialization `is_flags_enum` to force define that enum are flags.
|
// Add specialization `is_flags` to force define that enum are flags.
|
||||||
// template <>
|
//template <>
|
||||||
// struct magic_enum::customize::is_flags_enum<AnimalFlags> : std::true_type {};
|
//struct magic_enum::customize::enum_range<AnimalFlags> {
|
||||||
|
// static constexpr bool is_flags = true;
|
||||||
|
//};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// Enum-flags variable to string name.
|
// Enum-flags variable to string name.
|
||||||
|
|
|
||||||
|
|
@ -142,9 +142,6 @@ constexpr string_view enum_name(E) noexcept {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename E>
|
|
||||||
struct is_flags_enum : std::false_type {};
|
|
||||||
|
|
||||||
} // namespace magic_enum::customize
|
} // namespace magic_enum::customize
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
@ -157,6 +154,12 @@ struct supported
|
||||||
: std::false_type {};
|
: std::false_type {};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct has_is_flags : std::false_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_is_flags<T, std::void_t<decltype(customize::enum_range<T>::is_flags)>> : std::bool_constant<std::is_same_v<bool, std::decay_t<decltype(customize::enum_range<T>::is_flags)>>> {};
|
||||||
|
|
||||||
struct char_equal_to {
|
struct char_equal_to {
|
||||||
constexpr bool operator()(char lhs, char rhs) const noexcept {
|
constexpr bool operator()(char lhs, char rhs) const noexcept {
|
||||||
return lhs == rhs;
|
return lhs == rhs;
|
||||||
|
|
@ -472,14 +475,14 @@ template <typename E, typename U = std::underlying_type_t<E>>
|
||||||
constexpr bool is_flags_enum() noexcept {
|
constexpr bool is_flags_enum() noexcept {
|
||||||
static_assert(is_enum_v<E>, "magic_enum::detail::is_flags_enum requires enum type.");
|
static_assert(is_enum_v<E>, "magic_enum::detail::is_flags_enum requires enum type.");
|
||||||
|
|
||||||
#if defined(MAGIC_ENUM_NO_CHECK_FLAGS)
|
if constexpr (has_is_flags<E>::value) {
|
||||||
return customize::is_flags_enum<E>::value;
|
return customize::enum_range<E>::is_flags;
|
||||||
#else
|
} else if constexpr (std::is_same_v<U, bool>) { // bool special case
|
||||||
if constexpr (std::is_same_v<U, bool>) { // bool special case
|
|
||||||
return false;
|
return false;
|
||||||
} else if constexpr (customize::is_flags_enum<E>::value) {
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
|
#if defined(MAGIC_ENUM_NO_CHECK_FLAGS)
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
constexpr auto flags_values = values<E, true>();
|
constexpr auto flags_values = values<E, true>();
|
||||||
constexpr auto default_values = values<E, false>();
|
constexpr auto default_values = values<E, false>();
|
||||||
if (flags_values.size() == 0 || default_values.size() > flags_values.size()) {
|
if (flags_values.size() == 0 || default_values.size() > flags_values.size()) {
|
||||||
|
|
@ -492,8 +495,8 @@ constexpr bool is_flags_enum() noexcept {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flags_values.size() > 0;
|
return flags_values.size() > 0;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename E>
|
template <typename E>
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,6 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
enum class Color { RED = 1, GREEN = 2, BLUE = 4 };
|
enum class Color { RED = 1, GREEN = 2, BLUE = 4 };
|
||||||
template <>
|
|
||||||
struct magic_enum::customize::is_flags_enum<Color> : std::true_type {};
|
|
||||||
|
|
||||||
enum class Numbers : int {
|
enum class Numbers : int {
|
||||||
one = 1 << 1,
|
one = 1 << 1,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue