From 9ed19fb9e9bd8ac5852dc034bd29f4dfe2e7e23a Mon Sep 17 00:00:00 2001 From: neargye Date: Thu, 27 Jan 2022 15:34:05 +0200 Subject: [PATCH] move is_flags to customize::enum_range force set the enum-flag true or false --- doc/limitations.md | 6 ++++-- example/enum_flag_example.cpp | 8 +++++--- include/magic_enum.hpp | 23 +++++++++++++---------- test/test_flags.cpp | 2 -- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/doc/limitations.md b/doc/limitations.md index 6ba2435..2d31a4b 100644 --- a/doc/limitations.md +++ b/doc/limitations.md @@ -7,11 +7,13 @@ * 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 enum class Directions { Up = 1 << 1, Down = 1 << 2, Right = 1 << 3, Left = 1 << 4 }; template <> - struct magic_enum::customize::is_flags_enum : std::true_type {}; + struct magic_enum::customize::enum_range { + static constexpr bool is_flags = true; + }; ``` * Enum value must be in range `[MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]`. diff --git a/example/enum_flag_example.cpp b/example/enum_flag_example.cpp index fc29336..318aff0 100644 --- a/example/enum_flag_example.cpp +++ b/example/enum_flag_example.cpp @@ -26,9 +26,11 @@ #include 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. -// template <> -// struct magic_enum::customize::is_flags_enum : std::true_type {}; +// Add specialization `is_flags` to force define that enum are flags. +//template <> +//struct magic_enum::customize::enum_range { +// static constexpr bool is_flags = true; +//}; int main() { // Enum-flags variable to string name. diff --git a/include/magic_enum.hpp b/include/magic_enum.hpp index daf4898..6aea6d8 100644 --- a/include/magic_enum.hpp +++ b/include/magic_enum.hpp @@ -142,9 +142,6 @@ constexpr string_view enum_name(E) noexcept { return {}; } -template -struct is_flags_enum : std::false_type {}; - } // namespace magic_enum::customize namespace detail { @@ -157,6 +154,12 @@ struct supported : std::false_type {}; #endif +template +struct has_is_flags : std::false_type {}; + +template +struct has_is_flags::is_flags)>> : std::bool_constant::is_flags)>>> {}; + struct char_equal_to { constexpr bool operator()(char lhs, char rhs) const noexcept { return lhs == rhs; @@ -472,14 +475,14 @@ template > constexpr bool is_flags_enum() noexcept { static_assert(is_enum_v, "magic_enum::detail::is_flags_enum requires enum type."); -#if defined(MAGIC_ENUM_NO_CHECK_FLAGS) - return customize::is_flags_enum::value; -#else - if constexpr (std::is_same_v) { // bool special case + if constexpr (has_is_flags::value) { + return customize::enum_range::is_flags; + } else if constexpr (std::is_same_v) { // bool special case return false; - } else if constexpr (customize::is_flags_enum::value) { - return true; } else { +#if defined(MAGIC_ENUM_NO_CHECK_FLAGS) + return false; +#else constexpr auto flags_values = values(); constexpr auto default_values = values(); 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; - } #endif + } } template diff --git a/test/test_flags.cpp b/test/test_flags.cpp index 8da3a48..183639a 100644 --- a/test/test_flags.cpp +++ b/test/test_flags.cpp @@ -40,8 +40,6 @@ #include enum class Color { RED = 1, GREEN = 2, BLUE = 4 }; -template <> -struct magic_enum::customize::is_flags_enum : std::true_type {}; enum class Numbers : int { one = 1 << 1,