diff --git a/reflect b/reflect index 74e919e..93bb7b5 100644 --- a/reflect +++ b/reflect @@ -753,24 +753,44 @@ struct static_vector { std::array values_{}; std::size_t size_{}; }; -#if defined(__clang__) and (__clang_major__ > 15) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wenum-constexpr-conversion" -#endif template requires std::is_enum_v [[nodiscard]] constexpr auto enum_name() { - constexpr auto fn_name = detail::function_name(N)>(); - constexpr auto name = fn_name.substr(detail::enum_name_info::begin, std::size(fn_name)-detail::enum_name_info::end-detail::enum_name_info::begin); + constexpr auto fn_name = function_name(N)>(); + constexpr auto name = fn_name.substr(enum_name_info::begin, std::size(fn_name)-enum_name_info::end-enum_name_info::begin); constexpr auto enum_name = name.substr(name.find_last_of("::")+1); static_assert(std::size(enum_name) > 0u); return data, std::size(enum_name)>{std::data(enum_name)}>(); } +#if defined(__clang__) +#if (__clang_major__ > 15) and (__clang_major__ < 19) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wenum-constexpr-conversion" +#endif +template requires (std::is_enum_v and Max > Min) +inline constexpr auto enum_cases = [](std::index_sequence) { + static_vector, sizeof...(Ns)> cases{}; + ([&] { + if constexpr (requires { function_name(Ns+Min)>(); }) { + const auto fn_name = function_name(Ns+Min)>(); + const auto name = fn_name.substr(enum_name_info::begin, std::size(fn_name)-enum_name_info::end-enum_name_info::begin); + const auto enum_name = name.substr(name.find_last_of("::")+1); + if (enum_name.find(")") == std::string_view::npos) { + cases.push_back(std::underlying_type_t(Ns+Min)); + } + } + }(), ...); + return cases; +}(std::make_index_sequence{}); +#if (__clang_major__ > 15) and (__clang_major__ < 19) + #pragma clang diagnostic pop +#endif +#else template requires (std::is_enum_v and Max > Min) inline constexpr auto enum_cases = [](std::index_sequence) { - const auto names = detail::function_name(Ns+Min)...>(); - const auto begin = detail::enum_name_info::begin; - const auto end = std::size(names) - detail::enum_name_info::end; - detail::static_vector, sizeof...(Ns)> cases{}; + const auto names = function_name(Ns+Min)...>(); + const auto begin = enum_name_info::begin; + const auto end = std::size(names) - enum_name_info::end; + static_vector, sizeof...(Ns)> cases{}; std::underlying_type_t index{}; auto valid = true; for (auto i = begin; i < end; ++i) { @@ -786,8 +806,6 @@ inline constexpr auto enum_cases = [](std::index_sequence) { } return cases; }(std::make_index_sequence{}); -#if defined(__clang__) and (__clang_major__ > 15) - #pragma clang diagnostic pop #endif } // namespace detail @@ -1345,7 +1363,6 @@ static_assert(([] { B = 1, }; - static_assert([](const auto e) { return requires { enum_name(e); }; }(foobar::foo)); static_assert([](const auto e) { return requires { enum_name(e); }; }(mask::a)); static_assert(not [](const auto e) { return requires { enum_name(e); }; }(0));