1
0
Fork 0
mirror of https://github.com/Neargye/magic_enum.git synced 2026-01-09 23:34:23 +00:00
This commit is contained in:
terik23 2019-04-02 00:05:34 +05:00
parent d9ba68f01c
commit 0530e2c5bd
3 changed files with 35 additions and 35 deletions

View file

@ -41,10 +41,10 @@ int main() {
}
// Static storage enum variable to string enum name.
constexpr auto cx = Color::BLUE;
auto cx_name = magic_enum::enum_to_string<cx>();
if (cx_name.has_value()) {
std::cout << cx_name.value() << std::endl; // BLUE
constexpr auto c3 = Color::BLUE;
constexpr auto c3_name = magic_enum::enum_to_string<c3>();
if (c3_name.has_value()) {
std::cout << c3_name.value() << std::endl; // BLUE
}
return 0;

View file

@ -37,23 +37,23 @@
#include <string_view>
#include <optional>
#if !defined(MAGIC_ENUM_MAX_SEARCH_DEPTH)
# define MAGIC_ENUM_MAX_SEARCH_DEPTH 128
#if !defined(MAGIC_ENUM_RANGE)
# define MAGIC_ENUM_RANGE 128
#endif
namespace magic_enum {
static_assert(MAGIC_ENUM_MAX_SEARCH_DEPTH > 0,
"MAGIC_ENUM_MAX_SEARCH_DEPTH must be positive and greater than zero.");
static_assert(MAGIC_ENUM_MAX_SEARCH_DEPTH % 8 == 0,
"MAGIC_ENUM_MAX_SEARCH_DEPTH must be a multiple of 8.");
static_assert(MAGIC_ENUM_MAX_SEARCH_DEPTH < std::numeric_limits<int>::max(),
"MAGIC_ENUM_MAX_SEARCH_DEPTH must be less INT_MAX.");
static_assert(MAGIC_ENUM_RANGE > 0,
"MAGIC_ENUM_RANGE must be positive and greater than zero.");
static_assert(MAGIC_ENUM_RANGE % 8 == 0,
"MAGIC_ENUM_RANGE must be a multiple of 8.");
static_assert(MAGIC_ENUM_RANGE < std::numeric_limits<int>::max(),
"MAGIC_ENUM_RANGE must be less INT_MAX.");
namespace detail {
[[nodiscard]] constexpr bool is_name_char(char c) noexcept {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
[[nodiscard]] constexpr bool is_name_char(char c, bool front) noexcept {
return (!front && c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
}
template <auto V>
@ -72,16 +72,16 @@ template <auto V>
#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 9) || defined(_MSC_VER)
name.remove_suffix(suffix);
for (std::size_t i = name.size(); i > 0; --i) {
if (!is_name_char(name[i - 1])) {
if (!is_name_char(name[i - 1], false)) {
name.remove_prefix(i);
break;
}
}
if (name.front() >= '0' && name.front() <= '9') {
return std::nullopt; // Enum variable does not have name.
} else {
if (name.length() > 0 && is_name_char(name.front(), true)) {
return name;
} else {
return std::nullopt; // Enum variable does not have name.
}
#endif
}
@ -118,10 +118,10 @@ struct enum_to_string_impl_t final {
};
template <typename E>
struct enum_to_string_impl_t<E, MAGIC_ENUM_MAX_SEARCH_DEPTH> final {
struct enum_to_string_impl_t<E, MAGIC_ENUM_RANGE> final {
[[nodiscard]] constexpr std::optional<std::string_view> operator()(int) const noexcept {
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.
return std::nullopt; // Enum variable out of range MAGIC_ENUM_RANGE.
}
};
@ -156,10 +156,10 @@ struct enum_from_string_impl_t final {
};
template <typename E>
struct enum_from_string_impl_t<E, MAGIC_ENUM_MAX_SEARCH_DEPTH> final {
struct enum_from_string_impl_t<E, MAGIC_ENUM_RANGE> 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.
return std::nullopt; // Enum variable out of range MAGIC_ENUM_RANGE.
}
};
@ -169,9 +169,9 @@ struct enum_from_string_impl_t<E, MAGIC_ENUM_MAX_SEARCH_DEPTH> final {
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>>>;
constexpr int min = s ? -MAGIC_ENUM_MAX_SEARCH_DEPTH : 0;
if (static_cast<int>(value) >= MAGIC_ENUM_MAX_SEARCH_DEPTH || static_cast<int>(value) <= -MAGIC_ENUM_MAX_SEARCH_DEPTH) {
return std::nullopt; // Enum variable out of range MAGIC_ENUM_MAX_SEARCH_DEPTH.
constexpr int min = s ? -MAGIC_ENUM_RANGE : 0;
if (static_cast<int>(value) >= MAGIC_ENUM_RANGE || static_cast<int>(value) <= -MAGIC_ENUM_RANGE) {
return std::nullopt; // Enum variable out of range MAGIC_ENUM_RANGE.
}
return detail::enum_to_string_impl_t<std::decay_t<T>, min>{}(static_cast<int>(value));
}
@ -186,7 +186,7 @@ template <auto V, typename = std::enable_if_t<std::is_enum_v<std::decay_t<declty
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;
constexpr int min = s ? -MAGIC_ENUM_RANGE : 0;
return detail::enum_from_string_impl_t<E, min>{}(name);
}

View file

@ -23,7 +23,7 @@
#define CATCH_CONFIG_MAIN
#include <catch.hpp>
#define MAGIC_ENUM_MAX_SEARCH_DEPTH 120
#define MAGIC_ENUM_RANGE 120
#include <magic_enum.hpp>
enum class Color { RED = -12, GREEN = 7, BLUE = 15 };
@ -40,26 +40,26 @@ TEST_CASE("magic_enum::enum_to_string(enum)") {
REQUIRE(magic_enum::enum_to_string(cr).value() == "RED");
REQUIRE(magic_enum::enum_to_string(Color::BLUE).value() == "BLUE");
REQUIRE(magic_enum::enum_to_string(cm[1]).value() == "GREEN");
REQUIRE(!magic_enum::enum_to_string(static_cast<Color>(MAGIC_ENUM_MAX_SEARCH_DEPTH)).has_value());
REQUIRE(!magic_enum::enum_to_string(static_cast<Color>(MAGIC_ENUM_RANGE)).has_value());
Numbers no = Numbers::one;
REQUIRE(magic_enum::enum_to_string(no).value() == "one");
REQUIRE(magic_enum::enum_to_string(Numbers::two).value() == "two");
REQUIRE(magic_enum::enum_to_string(Numbers::three).value() == "three");
REQUIRE(!magic_enum::enum_to_string(static_cast<Numbers>(MAGIC_ENUM_MAX_SEARCH_DEPTH)).has_value());
REQUIRE(!magic_enum::enum_to_string(static_cast<Numbers>(MAGIC_ENUM_RANGE)).has_value());
Directions dr = Directions::Right;
REQUIRE(magic_enum::enum_to_string(Directions::Up).value() == "Up");
REQUIRE(magic_enum::enum_to_string(Directions::Down).value() == "Down");
REQUIRE(magic_enum::enum_to_string(dr).value() == "Right");
REQUIRE(magic_enum::enum_to_string(Directions::Left).value() == "Left");
REQUIRE(!magic_enum::enum_to_string(static_cast<Directions>(MAGIC_ENUM_MAX_SEARCH_DEPTH)).has_value());
REQUIRE(!magic_enum::enum_to_string(static_cast<Directions>(MAGIC_ENUM_RANGE)).has_value());
number nt = number::three;
REQUIRE(magic_enum::enum_to_string(number::one).value() == "one");
REQUIRE(magic_enum::enum_to_string(number::two).value() == "two");
REQUIRE(magic_enum::enum_to_string(nt).value() == "three");
REQUIRE(!magic_enum::enum_to_string(static_cast<number>(MAGIC_ENUM_MAX_SEARCH_DEPTH)).has_value());
REQUIRE(!magic_enum::enum_to_string(static_cast<number>(MAGIC_ENUM_RANGE)).has_value());
}
TEST_CASE("magic_enum::enum_to_string<enum>()") {
@ -68,26 +68,26 @@ TEST_CASE("magic_enum::enum_to_string<enum>()") {
REQUIRE(magic_enum::enum_to_string<cr>().value() == "RED");
REQUIRE(magic_enum::enum_to_string<Color::BLUE>().value() == "BLUE");
REQUIRE(magic_enum::enum_to_string<cm[1]>().value() == "GREEN");
REQUIRE(!magic_enum::enum_to_string<static_cast<Color>(MAGIC_ENUM_MAX_SEARCH_DEPTH)>().has_value());
REQUIRE(!magic_enum::enum_to_string<static_cast<Color>(MAGIC_ENUM_RANGE)>().has_value());
constexpr Numbers no = Numbers::one;
REQUIRE(magic_enum::enum_to_string<no>().value() == "one");
REQUIRE(magic_enum::enum_to_string<Numbers::two>().value() == "two");
REQUIRE(magic_enum::enum_to_string<Numbers::three>().value() == "three");
REQUIRE(!magic_enum::enum_to_string<static_cast<Numbers>(MAGIC_ENUM_MAX_SEARCH_DEPTH)>().has_value());
REQUIRE(!magic_enum::enum_to_string<static_cast<Numbers>(MAGIC_ENUM_RANGE)>().has_value());
constexpr Directions dr = Directions::Right;
REQUIRE(magic_enum::enum_to_string<Directions::Up>().value() == "Up");
REQUIRE(magic_enum::enum_to_string<Directions::Down>().value() == "Down");
REQUIRE(magic_enum::enum_to_string<dr>().value() == "Right");
REQUIRE(magic_enum::enum_to_string<Directions::Left>().value() == "Left");
REQUIRE(!magic_enum::enum_to_string<static_cast<Directions>(MAGIC_ENUM_MAX_SEARCH_DEPTH)>().has_value());
REQUIRE(!magic_enum::enum_to_string<static_cast<Directions>(MAGIC_ENUM_RANGE)>().has_value());
constexpr number nt = number::three;
REQUIRE(magic_enum::enum_to_string<number::one>().value() == "one");
REQUIRE(magic_enum::enum_to_string<number::two>().value() == "two");
REQUIRE(magic_enum::enum_to_string<nt>().value() == "three");
REQUIRE(!magic_enum::enum_to_string<static_cast<number>(MAGIC_ENUM_MAX_SEARCH_DEPTH)>().has_value());
REQUIRE(!magic_enum::enum_to_string<static_cast<number>(MAGIC_ENUM_RANGE)>().has_value());
}
TEST_CASE("magic_enum::enum_from_string(name)") {