@@ -161,6 +161,16 @@ constexpr bool isZeroBasedContiguousEnum()
161161#pragma clang diagnostic ignored "-Wenum-constexpr-conversion"
162162#endif
163163
164+ #if COMPILER(CLANG) && __clang_major__ >= 16
165+ template <typename E, auto V, typename = void >
166+ inline constexpr bool isEnumConstexprStaticCastValid = false ;
167+ template <typename E, auto V>
168+ inline constexpr bool isEnumConstexprStaticCastValid<E, V, std::void_t <std::integral_constant<E, static_cast <E>(V)>>> = true ;
169+ #else
170+ template <typename , auto >
171+ inline constexpr bool isEnumConstexprStaticCastValid = true ;
172+ #endif
173+
164174template <typename E>
165175constexpr std::span<const char > enumTypeNameImpl ()
166176{
@@ -224,6 +234,15 @@ constexpr std::span<const char> enumName()
224234 return result;
225235}
226236
237+ template <typename E, auto V>
238+ constexpr std::span<const char > enumName ()
239+ {
240+ if constexpr (isEnumConstexprStaticCastValid<E, V>)
241+ return enumName<static_cast <E>(V)>();
242+ else
243+ return { };
244+ }
245+
227246namespace detail {
228247
229248template <size_t i, size_t end>
@@ -243,7 +262,7 @@ constexpr std::array<std::span<const char>, limit> enumNames()
243262 std::array<std::span<const char >, limit> names;
244263
245264 detail::forConstexpr<0 , limit>([&] (auto i) {
246- names[i] = enumName<static_cast <E>(static_cast <unsigned >(i))>();
265+ names[i] = enumName<E, std:: underlying_type_t <E>(static_cast <unsigned >(i))>();
247266 });
248267 return names;
249268}
0 commit comments