From d2904860b8a234897de78f0391fff1cabe9134b8 Mon Sep 17 00:00:00 2001 From: neargye Date: Sat, 4 Jul 2020 15:13:15 +0500 Subject: [PATCH] wip --- include/magic_enum.hpp | 61 +++++++++++++++++++----------------------- test/test.cpp | 6 +++++ 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/include/magic_enum.hpp b/include/magic_enum.hpp index ad1d968..983f54f 100644 --- a/include/magic_enum.hpp +++ b/include/magic_enum.hpp @@ -299,6 +299,9 @@ constexpr auto values(std::integer_sequence) noexcept { template inline constexpr auto values_v = values(std::make_integer_sequence, reflected_max_v>()>{}); +template > +using values_t = decltype((values_v)); + template inline constexpr std::size_t count_v = values_v.size(); @@ -338,6 +341,9 @@ constexpr auto names(std::index_sequence) noexcept { template inline constexpr auto names_v = names(std::make_index_sequence>{}); +template > +using names_t = decltype((names_v)); + template constexpr auto entries(std::index_sequence) noexcept { static_assert(is_enum_v, "magic_enum::detail::entries requires enum type."); @@ -348,6 +354,9 @@ constexpr auto entries(std::index_sequence) noexcept { template inline constexpr auto entries_v = entries(std::make_index_sequence>{}); +template > +using entries_t = decltype((entries_v)); + template inline constexpr bool is_sparse_v = range_size_v != count_v; @@ -375,8 +384,19 @@ constexpr int endex(E value) noexcept { return undex(static_cast>(value)); } +template +struct enable_if_enum {}; + template -using enable_if_enum_t = std::enable_if_t>, R>; +struct enable_if_enum { + using type = R; + using D = std::decay_t; + static_assert(supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); + static_assert(count_v > 0, "magic_enum requires enum implementation and valid max and min."); +}; + +template +using enable_if_enum_t = typename enable_if_enum>, T, R>::type; template >>> using enum_concept = T; @@ -433,8 +453,9 @@ using underlying_type_t = typename underlying_type::type; // Returns string name of enum type. template -[[nodiscard]] constexpr auto enum_type_name() noexcept -> detail::enable_if_enum_t { +[[nodiscard]] constexpr std::string_view enum_type_name() noexcept { using D = std::decay_t; + static_assert(std::is_enum_v, "Requires enum type."); constexpr std::string_view name = detail::type_name_v; static_assert(name.size() > 0, "Enum type does not have a name."); @@ -445,8 +466,6 @@ template template [[nodiscard]] constexpr auto enum_count() noexcept -> detail::enable_if_enum_t { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); return detail::count_v; } @@ -456,8 +475,6 @@ template template [[nodiscard]] constexpr auto enum_value(std::size_t index) noexcept -> detail::enable_if_enum_t> { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); if constexpr (detail::is_sparse_v) { return assert(index < detail::count_v), detail::values_v[index]; @@ -469,10 +486,8 @@ template // Obtains value enum sequence. // Returns std::array with enum values, sorted by enum value. template -[[nodiscard]] constexpr auto enum_values() noexcept -> detail::enable_if_enum_t>)&> { +[[nodiscard]] constexpr auto enum_values() noexcept -> detail::enable_if_enum_t> { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); return detail::values_v; } @@ -480,9 +495,9 @@ template // Returns string enum name from static storage enum variable. // This version is much lighter on the compile times and is not restricted to the enum_range limitation. template -[[nodiscard]] constexpr auto enum_name() noexcept -> detail::enable_if_enum_t { +[[nodiscard]] constexpr std::string_view enum_name() noexcept { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); + static_assert(std::is_enum_v, "Requires enum type."); constexpr std::string_view name = detail::enum_name_v, V>; static_assert(name.size() > 0, "Enum value does not have a name."); @@ -494,8 +509,6 @@ template template [[nodiscard]] constexpr auto enum_name(E value) noexcept -> detail::enable_if_enum_t { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); if (const auto i = detail::endex(value); i != -1) { return detail::names_v[i]; @@ -507,10 +520,8 @@ template // Obtains string enum name sequence. // Returns std::array with string enum names, sorted by enum value. template -[[nodiscard]] constexpr auto enum_names() noexcept -> detail::enable_if_enum_t>)&> { +[[nodiscard]] constexpr auto enum_names() noexcept -> detail::enable_if_enum_t> { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); return detail::names_v; } @@ -518,10 +529,8 @@ template // Obtains pair (value enum, string enum name) sequence. // Returns std::array with std::pair (value enum, string enum name), sorted by enum value. template -[[nodiscard]] constexpr auto enum_entries() noexcept -> detail::enable_if_enum_t>)&> { +[[nodiscard]] constexpr auto enum_entries() noexcept -> detail::enable_if_enum_t> { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); return detail::entries_v; } @@ -531,8 +540,6 @@ template template [[nodiscard]] constexpr auto enum_cast(std::string_view value, BinaryPredicate p) noexcept(std::is_nothrow_invocable_r_v) -> detail::enable_if_enum_t>> { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); static_assert(std::is_invocable_r_v, "magic_enum::enum_cast requires bool(char, char) invocable predicate."); for (std::size_t i = 0; i < detail::count_v; ++i) { @@ -547,8 +554,6 @@ template template [[nodiscard]] constexpr auto enum_cast(std::string_view value) noexcept -> detail::enable_if_enum_t>> { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); for (std::size_t i = 0; i < detail::count_v; ++i) { if (value == detail::names_v[i]) { @@ -564,8 +569,6 @@ template template [[nodiscard]] constexpr auto enum_cast(underlying_type_t value) noexcept -> detail::enable_if_enum_t>> { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); if (detail::undex(value) != -1) { return static_cast(value); @@ -585,8 +588,6 @@ template template [[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_enum_t> { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); if (const auto i = detail::endex(value); i != -1) { return i; @@ -599,8 +600,6 @@ template template [[nodiscard]] constexpr auto enum_contains(E value) noexcept -> detail::enable_if_enum_t { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); return detail::endex(value) != -1; } @@ -609,8 +608,6 @@ template template [[nodiscard]] constexpr auto enum_contains(underlying_type_t value) noexcept -> detail::enable_if_enum_t { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); return detail::undex(value) != -1; } @@ -619,8 +616,6 @@ template template [[nodiscard]] constexpr auto enum_contains(std::string_view value) noexcept -> detail::enable_if_enum_t { using D = std::decay_t; - static_assert(detail::supported::value, "magic_enum unsupported compiler (https://github.com/Neargye/magic_enum#compiler-compatibility)."); - static_assert(detail::count_v > 0, "magic_enum requires enum implementation and valid max and min."); return enum_cast(value).has_value(); } diff --git a/test/test.cpp b/test/test.cpp index 7222dbf..1c3d87c 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -310,6 +310,8 @@ TEST_CASE("enum_value") { } TEST_CASE("enum_values") { + REQUIRE(std::is_same_v()), const std::array&>); + constexpr auto s1 = enum_values(); REQUIRE(s1 == std::array{{Color::RED, Color::GREEN, Color::BLUE}}); @@ -406,6 +408,8 @@ TEST_CASE("enum_name") { } TEST_CASE("enum_names") { + REQUIRE(std::is_same_v()), const std::array&>); + constexpr auto s1 = enum_names(); REQUIRE(s1 == std::array{{"RED", "GREEN", "BLUE"}}); @@ -420,6 +424,8 @@ TEST_CASE("enum_names") { } TEST_CASE("enum_entries") { + REQUIRE(std::is_same_v()), const std::array, 3>&>); + constexpr auto s1 = enum_entries(); REQUIRE(s1 == std::array, 3>{{{Color::RED, "RED"}, {Color::GREEN, "GREEN"}, {Color::BLUE, "BLUE"}}});