Skip to content

Commit

Permalink
🐛 Fails on emscripten 3.1.65 Fix #62
Browse files Browse the repository at this point in the history
Related change: llvm/llvm-project#59036
  • Loading branch information
krzysztof-jusiak committed Aug 29, 2024
1 parent e6f7107 commit 6ac477a
Showing 1 changed file with 30 additions and 13 deletions.
43 changes: 30 additions & 13 deletions reflect
Original file line number Diff line number Diff line change
Expand Up @@ -753,24 +753,44 @@ struct static_vector {
std::array<T, Size> 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<class E, auto N> requires std::is_enum_v<E>
[[nodiscard]] constexpr auto enum_name() {
constexpr auto fn_name = detail::function_name<static_cast<E>(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<static_cast<E>(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<fixed_string<std::remove_cvref_t<decltype(enum_name[0])>, 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<class E, auto Min, auto Max> requires (std::is_enum_v<E> and Max > Min)
inline constexpr auto enum_cases = []<auto... Ns>(std::index_sequence<Ns...>) {
static_vector<std::underlying_type_t<E>, sizeof...(Ns)> cases{};
([&] {
if constexpr (requires { function_name<static_cast<E>(Ns+Min)>(); }) {
const auto fn_name = function_name<static_cast<E>(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<E>(Ns+Min));
}
}
}(), ...);
return cases;
}(std::make_index_sequence<Max-Min+1/*inclusive*/>{});
#if (__clang_major__ > 15) and (__clang_major__ < 19)
#pragma clang diagnostic pop
#endif
#else
template<class E, auto Min, auto Max> requires (std::is_enum_v<E> and Max > Min)
inline constexpr auto enum_cases = []<auto... Ns>(std::index_sequence<Ns...>) {
const auto names = detail::function_name<static_cast<E>(Ns+Min)...>();
const auto begin = detail::enum_name_info::begin;
const auto end = std::size(names) - detail::enum_name_info::end;
detail::static_vector<std::underlying_type_t<E>, sizeof...(Ns)> cases{};
const auto names = function_name<static_cast<E>(Ns+Min)...>();
const auto begin = enum_name_info::begin;
const auto end = std::size(names) - enum_name_info::end;
static_vector<std::underlying_type_t<E>, sizeof...(Ns)> cases{};
std::underlying_type_t<E> index{};
auto valid = true;
for (auto i = begin; i < end; ++i) {
Expand All @@ -786,8 +806,6 @@ inline constexpr auto enum_cases = []<auto... Ns>(std::index_sequence<Ns...>) {
}
return cases;
}(std::make_index_sequence<Max-Min+1/*inclusive*/>{});
#if defined(__clang__) and (__clang_major__ > 15)
#pragma clang diagnostic pop
#endif
} // namespace detail

Expand Down Expand Up @@ -1345,7 +1363,6 @@ static_assert(([] {
B = 1,
};


static_assert([](const auto e) { return requires { enum_name<foobar,"",1,2>(e); }; }(foobar::foo));
static_assert([](const auto e) { return requires { enum_name<mask,"",1,2>(e); }; }(mask::a));
static_assert(not [](const auto e) { return requires { enum_name<foobar,"",1,2>(e); }; }(0));
Expand Down

0 comments on commit 6ac477a

Please sign in to comment.