From bc2e94853b26ff588f4268ad20e165dd2b59207b Mon Sep 17 00:00:00 2001 From: neargye Date: Sat, 29 Jun 2024 16:47:56 +0300 Subject: [PATCH] add enum_reflected --- doc/reference.md | 16 ++++++++++++++++ include/magic_enum/magic_enum.hpp | 29 +++++++++++++++++++++++++++++ test/test.cpp | 10 ++++++++++ 3 files changed, 55 insertions(+) diff --git a/doc/reference.md b/doc/reference.md index b6772faa9..bd0d4f6d6 100644 --- a/doc/reference.md +++ b/doc/reference.md @@ -10,6 +10,7 @@ * [`enum_entries` obtains pair (value enum, string enum name) sequence.](#enum_entries) * [`enum_index` obtains index in enum value sequence from enum value.](#enum_index) * [`enum_contains` checks whether enum contains enumerator with such value.](#enum_contains) +* [`enum_reflected` returns true if the enum value is in the range of values that can be reflected..](#enum_reflected) * [`enum_type_name` returns type name of enum.](#enum_type_name) * [`enum_fuse` returns a bijective mix of enum values.](#enum_fuse) * [`enum_switch` allows runtime enum value transformation to constexpr context.](#enum_switch) @@ -316,6 +317,21 @@ constexpr bool enum_contains(string_view value, BinaryPredicate p) noexcept(is_n magic_enum::enum_contains("fda"); // -> false ``` +## `enum_reflected` + +```cpp +template +constexpr bool enum_contains(E value) noexcept; + +template +constexpr bool enum_contains(underlying_type_t value) noexcept; + +template +constexpr bool enum_contains(string_view value) noexcept; +``` + +* Returns true if the enum value is in the range of values that can be reflected. + ## `enum_type_name` ```cpp diff --git a/include/magic_enum/magic_enum.hpp b/include/magic_enum/magic_enum.hpp index 56b723ac0..161f44bbd 100644 --- a/include/magic_enum/magic_enum.hpp +++ b/include/magic_enum/magic_enum.hpp @@ -1414,6 +1414,35 @@ template , typename Bi return static_cast(enum_cast(value, std::move(p))); } +// Returns true if the enum value is in the range of values that can be reflected. +template > +[[nodiscard]] constexpr auto enum_reflected(E value) noexcept -> detail::enable_if_t { + using D = std::decay_t; + + if constexpr (detail::is_reflected_v) { + constexpr auto min = detail::reflected_min(); + constexpr auto max = detail::reflected_max(); + return value >= min && value <= max; + } + return false; +} + +// Returns true if the enum value is in the range of values that can be reflected. +template +[[nodiscard]] constexpr auto enum_reflected(E value) noexcept -> detail::enable_if_t { + using D = std::decay_t; + + return enum_cast(value); +} + +// Returns true if the enum integer value is in the range of values that can be reflected. +template > +[[nodiscard]] constexpr auto enum_reflected(underlying_type_t value) noexcept -> detail::enable_if_t { + using D = std::decay_t; + + return enum_cast(value); +} + template inline constexpr auto as_flags = AsFlags ? detail::enum_subtype::flags : detail::enum_subtype::common; diff --git a/test/test.cpp b/test/test.cpp index 1490fe5d3..2a2420e5e 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1274,3 +1274,13 @@ TEST_CASE("valid_enum") { REQUIRE(magic_enum::detail::is_reflected_v>); REQUIRE(magic_enum::detail::is_reflected_v>); } + +TEST_CASE("enum_reflected") { + REQUIRE(enum_reflected(number::one)); + REQUIRE(enum_reflected(number::three)); + REQUIRE_FALSE(enum_reflected(number::four)); + REQUIRE(enum_reflected(1)); + REQUIRE(enum_reflected(234)); + REQUIRE_FALSE(enum_reflected(400)); + REQUIRE_FALSE(enum_reflected(500)); +}