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>
|
||||
inline constexpr auto enum_name_v = n<E, V>();
|
||||
|
||||
template <typename E, auto V>
|
||||
constexpr bool is_valid() noexcept {
|
||||
template <typename E, E V>
|
||||
constexpr bool valid() noexcept {
|
||||
static_assert(is_enum_v<E>, "nameof::detail::is_valid requires enum type.");
|
||||
|
||||
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 {
|
||||
static_assert(is_enum_v<E>, "nameof::detail::value requires enum type.");
|
||||
|
||||
if constexpr (std::is_same_v<U, bool>) { // bool special case
|
||||
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);
|
||||
}
|
||||
return static_cast<E>(ualue<E, O, IsFlags>(i));
|
||||
}
|
||||
|
||||
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>
|
||||
constexpr auto values(std::index_sequence<I...>) noexcept {
|
||||
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);
|
||||
|
||||
if constexpr (count > 0) {
|
||||
|
|
Loading…
Reference in a new issue