mirror of
https://github.com/Neargye/magic_enum.git
synced 2026-01-09 23:34:23 +00:00
improve enum_from_string, static_assert and doc
This commit is contained in:
parent
935f80ee49
commit
100ca7ba8c
2 changed files with 46 additions and 14 deletions
|
|
@ -58,7 +58,7 @@ namespace detail {
|
|||
|
||||
template <auto V>
|
||||
[[nodiscard]] constexpr std::optional<std::string_view> enum_to_string_impl() noexcept {
|
||||
static_assert(std::is_enum_v<decltype(V)>);
|
||||
static_assert(std::is_enum_v<decltype(V)>, "magic_enum::enum_to_string require enum type.");
|
||||
#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 9)
|
||||
std::string_view name{__PRETTY_FUNCTION__};
|
||||
constexpr auto suffix = sizeof("]") - 1;
|
||||
|
|
@ -89,7 +89,7 @@ template <auto V>
|
|||
template <typename E, int V>
|
||||
struct enum_to_string_impl_t final {
|
||||
[[nodiscard]] constexpr std::optional<std::string_view> operator()(int value) const noexcept {
|
||||
static_assert(std::is_enum_v<E>);
|
||||
static_assert(std::is_enum_v<E>, "magic_enum::enum_to_string require enum type.");
|
||||
if constexpr (V > std::numeric_limits<std::underlying_type_t<E>>::max()) {
|
||||
return std::nullopt; // Enum variable out of range.
|
||||
}
|
||||
|
|
@ -120,14 +120,52 @@ struct enum_to_string_impl_t final {
|
|||
template <typename E>
|
||||
struct enum_to_string_impl_t<E, MAGIC_ENUM_MAX_SEARCH_DEPTH> final {
|
||||
[[nodiscard]] constexpr std::optional<std::string_view> operator()(int) const noexcept {
|
||||
static_assert(std::is_enum_v<E>);
|
||||
static_assert(std::is_enum_v<E>, "magic_enum::enum_to_string require enum type.");
|
||||
return std::nullopt; // Enum variable out of range MAGIC_ENUM_MAX_SEARCH_DEPTH.
|
||||
}
|
||||
};
|
||||
|
||||
template <typename E, int V>
|
||||
struct enum_from_string_impl_t final {
|
||||
[[nodiscard]] constexpr std::optional<E> operator()(std::string_view name) const noexcept {
|
||||
static_assert(std::is_enum_v<E>, "magic_enum::enum_from_string require enum type.");
|
||||
if constexpr (V > std::numeric_limits<std::underlying_type_t<E>>::max()) {
|
||||
return std::nullopt; // Enum variable out of range.
|
||||
}
|
||||
|
||||
if (enum_to_string_impl<static_cast<E>(V)>() == name) {
|
||||
return static_cast<E>(V);
|
||||
} else if (enum_to_string_impl<static_cast<E>(V + 1)>() == name) {
|
||||
return static_cast<E>(V + 1);
|
||||
} else if (enum_to_string_impl<static_cast<E>(V + 2)>() == name) {
|
||||
return static_cast<E>(V + 2);
|
||||
} else if (enum_to_string_impl<static_cast<E>(V + 3)>() == name) {
|
||||
return static_cast<E>(V + 3);
|
||||
} else if (enum_to_string_impl<static_cast<E>(V + 4)>() == name) {
|
||||
return static_cast<E>(V + 4);
|
||||
} else if (enum_to_string_impl<static_cast<E>(V + 5)>() == name) {
|
||||
return static_cast<E>(V + 5);
|
||||
} else if (enum_to_string_impl<static_cast<E>(V + 6)>() == name) {
|
||||
return static_cast<E>(V + 6);
|
||||
} else if (enum_to_string_impl<static_cast<E>(V + 7)>() == name) {
|
||||
return static_cast<E>(V + 7);
|
||||
} else {
|
||||
return enum_from_string_impl_t<E, V + 8>{}(name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename E>
|
||||
struct enum_from_string_impl_t<E, MAGIC_ENUM_MAX_SEARCH_DEPTH> final {
|
||||
[[nodiscard]] constexpr std::optional<E> operator()(std::string_view) const noexcept {
|
||||
static_assert(std::is_enum_v<E>, "magic_enum::enum_from_string require enum type.");
|
||||
return std::nullopt; // Enum variable out of range MAGIC_ENUM_MAX_SEARCH_DEPTH.
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// enum_to_string(value) used to obtain string enum name from enum variable.
|
||||
// enum_to_string(enum) used to obtain string enum name from enum variable.
|
||||
template <typename T, typename = std::enable_if_t<std::is_enum_v<std::decay_t<T>>>>
|
||||
[[nodiscard]] constexpr std::optional<std::string_view> enum_to_string(T value) noexcept {
|
||||
constexpr bool s = std::is_signed_v<std::underlying_type_t<std::decay_t<T>>>;
|
||||
|
|
@ -135,7 +173,7 @@ template <typename T, typename = std::enable_if_t<std::is_enum_v<std::decay_t<T>
|
|||
return detail::enum_to_string_impl_t<std::decay_t<T>, min>{}(static_cast<int>(value));
|
||||
}
|
||||
|
||||
// enum_to_string<value>() used to obtain string enum name from static storage enum variable
|
||||
// enum_to_string<enum>() used to obtain string enum name from static storage enum variable
|
||||
template <auto V, typename = std::enable_if_t<std::is_enum_v<std::decay_t<decltype(V)>>>>
|
||||
[[nodiscard]] constexpr std::optional<std::string_view> enum_to_string() noexcept {
|
||||
return detail::enum_to_string_impl<V>();
|
||||
|
|
@ -146,13 +184,7 @@ template <typename E, typename = std::enable_if_t<std::is_enum_v<E>>>
|
|||
[[nodiscard]] constexpr std::optional<E> enum_from_string(std::string_view name) noexcept {
|
||||
constexpr bool s = std::is_signed_v<std::underlying_type_t<E>>;
|
||||
constexpr int min = s ? -MAGIC_ENUM_MAX_SEARCH_DEPTH : 0;
|
||||
for (int i = min; i < MAGIC_ENUM_MAX_SEARCH_DEPTH; ++i) {
|
||||
if (detail::enum_to_string_impl_t<E, min>{}(i) == name) {
|
||||
return static_cast<E>(i);
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt; // Argument name has not been enum variable name.
|
||||
return detail::enum_from_string_impl_t<E, min>{}(name);
|
||||
}
|
||||
|
||||
} // namespace magic_enum
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ enum Directions { Up = 85, Down = -42, Right = 119, Left = -119 };
|
|||
|
||||
enum number : int { one = 10, two = 20, three = 30 };
|
||||
|
||||
TEST_CASE("magic_enum::enum_to_string(value)") {
|
||||
TEST_CASE("magic_enum::enum_to_string(enum)") {
|
||||
Color cr = Color::RED;
|
||||
Color cm[3] = {Color::RED, Color::GREEN, Color::BLUE};
|
||||
REQUIRE(magic_enum::enum_to_string(cr).value() == "RED");
|
||||
|
|
@ -62,7 +62,7 @@ TEST_CASE("magic_enum::enum_to_string(value)") {
|
|||
REQUIRE(!magic_enum::enum_to_string(static_cast<number>(MAGIC_ENUM_MAX_SEARCH_DEPTH)).has_value());
|
||||
}
|
||||
|
||||
TEST_CASE("magic_enum::enum_to_string<value>()") {
|
||||
TEST_CASE("magic_enum::enum_to_string<enum>()") {
|
||||
constexpr Color cr = Color::RED;
|
||||
constexpr Color cm[3] = {Color::RED, Color::GREEN, Color::BLUE};
|
||||
REQUIRE(magic_enum::enum_to_string<cr>().value() == "RED");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue