fix clang llvm-project#50055(reviews.llvm.org/D130058)
This commit is contained in:
parent
c04b72fc51
commit
c44b65d57d
1 changed files with 26 additions and 13 deletions
|
@ -559,26 +559,39 @@ constexpr auto n() noexcept {
|
||||||
template <typename E, E V>
|
template <typename E, E V>
|
||||||
inline constexpr auto enum_name_v = n<E, V>();
|
inline constexpr auto enum_name_v = n<E, V>();
|
||||||
|
|
||||||
template <typename E, auto V>
|
template <typename E, E V>
|
||||||
constexpr bool is_valid() noexcept {
|
constexpr bool valid() noexcept {
|
||||||
static_assert(is_enum_v<E>, "nameof::detail::is_valid requires enum type.");
|
static_assert(is_enum_v<E>, "nameof::detail::is_valid requires enum type.");
|
||||||
|
|
||||||
return n<E, static_cast<E>(V)>().size() != 0;
|
return n<E, static_cast<E>(V)>().size() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename E, int O, bool IsFlags = false, typename U = std::underlying_type_t<E>>
|
template <typename E, auto V, typename = void>
|
||||||
|
struct is_valid : std::false_type {};
|
||||||
|
|
||||||
|
template <typename E, auto V>
|
||||||
|
struct is_valid<E, V, std::void_t<decltype(valid<E, static_cast<E>(V)>())>> : std::bool_constant<valid<E, static_cast<E>(V)>()> {};
|
||||||
|
|
||||||
|
template <typename E, int O, bool IsFlags, typename U = std::underlying_type_t<E>>
|
||||||
|
constexpr U ualue(std::size_t i) noexcept {
|
||||||
|
static_assert(is_enum_v<E>, "nameof::detail::ualue requires enum type.");
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<U, bool>) { // bool special case
|
||||||
|
static_assert(O == 0, "nameof::detail::ualue requires valid offset.");
|
||||||
|
|
||||||
|
return static_cast<U>(i);
|
||||||
|
} else if constexpr (IsFlags) {
|
||||||
|
return static_cast<U>(U{1} << static_cast<U>(static_cast<int>(i) + O));
|
||||||
|
} else {
|
||||||
|
return static_cast<U>(static_cast<int>(i) + O);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename E, int O, bool IsFlags, typename U = std::underlying_type_t<E>>
|
||||||
constexpr E value(std::size_t i) noexcept {
|
constexpr E value(std::size_t i) noexcept {
|
||||||
static_assert(is_enum_v<E>, "nameof::detail::value requires enum type.");
|
static_assert(is_enum_v<E>, "nameof::detail::value requires enum type.");
|
||||||
|
|
||||||
if constexpr (std::is_same_v<U, bool>) { // bool special case
|
return static_cast<E>(ualue<E, O, IsFlags>(i));
|
||||||
static_assert(O == 0, "nameof::detail::value requires valid offset.");
|
|
||||||
|
|
||||||
return static_cast<E>(i);
|
|
||||||
} else if constexpr (IsFlags) {
|
|
||||||
return static_cast<E>(U{1} << static_cast<U>(static_cast<int>(i) + O));
|
|
||||||
} else {
|
|
||||||
return static_cast<E>(static_cast<int>(i) + O);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename E, bool IsFlags, typename U = std::underlying_type_t<E>>
|
template <typename E, bool IsFlags, typename U = std::underlying_type_t<E>>
|
||||||
|
@ -638,7 +651,7 @@ constexpr std::size_t values_count(const bool (&valid)[N]) noexcept {
|
||||||
template <typename E, bool IsFlags, int Min, std::size_t... I>
|
template <typename E, bool IsFlags, int Min, std::size_t... I>
|
||||||
constexpr auto values(std::index_sequence<I...>) noexcept {
|
constexpr auto values(std::index_sequence<I...>) noexcept {
|
||||||
static_assert(is_enum_v<E>, "nameof::detail::values requires enum type.");
|
static_assert(is_enum_v<E>, "nameof::detail::values requires enum type.");
|
||||||
constexpr bool valid[sizeof...(I)] = {is_valid<E, value<E, Min, IsFlags>(I)>()...};
|
constexpr bool valid[sizeof...(I)] = {is_valid<E, ualue<E, Min, IsFlags>(I)>::value...};
|
||||||
constexpr std::size_t count = values_count(valid);
|
constexpr std::size_t count = values_count(valid);
|
||||||
|
|
||||||
if constexpr (count > 0) {
|
if constexpr (count > 0) {
|
||||||
|
|
Loading…
Reference in a new issue