1
0
Fork 0
mirror of https://github.com/Neargye/magic_enum.git synced 2026-01-09 23:34:23 +00:00

Add prefix trimming (#414)

This commit is contained in:
ZXShady 2025-08-31 21:56:19 +03:00 committed by GitHub
parent d468f23408
commit aaf57737d5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 180 additions and 110 deletions

View file

@ -171,58 +171,55 @@ static_assert([] {
return true;
} (), "magic_enum::customize wchar_t is not compatible with ASCII.");
namespace customize {
template <typename E, typename = void>
struct enum_range;
}
namespace detail {
template<typename E, typename = void>
constexpr inline bool has_is_flags_adl = false;
template<typename E,typename = void>
constexpr inline std::size_t prefix_length_or_zero = 0;
template<typename E>
constexpr inline bool has_is_flags_adl < E, std::void_t<decltype(decltype(adl_magic_enum_define_range(E{}))::is_flags) > > = decltype(adl_magic_enum_define_range(E{}))::is_flags;
template<typename E, typename = void>
constexpr inline auto has_minmax_adl = std::pair<int, int>(MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX);
template<typename E>
constexpr inline auto has_minmax_adl < E, std::void_t<decltype(decltype(adl_magic_enum_define_range(E{}))::max), decltype(decltype(adl_magic_enum_define_range(E{}))::max) >> =
std::pair<int, int>(decltype(adl_magic_enum_define_range(E{}))::min, decltype(adl_magic_enum_define_range(E{}))::max);
constexpr inline auto prefix_length_or_zero<E, std::void_t<decltype(customize::enum_range<E>::prefix_length)>> = std::size_t{ customize::enum_range<E>::prefix_length };
}
namespace customize {
template<auto... Vs>
struct adl_info { static_assert(sizeof...(Vs) && !sizeof...(Vs), "adl_info parameter types must be either 2 ints exactly or 1 bool for the is_flgas"); };
template<int Min, int Max>
struct adl_info<Min, Max> {
static constexpr int min = Min;
static constexpr int max = Max;
template<bool IsFlags = false,int Min = MAGIC_ENUM_RANGE_MIN,int Max = MAGIC_ENUM_RANGE_MAX,std::size_t PrefixLength = 0>
struct adl_info_holder {
constexpr static int max = Max;
constexpr static int min = Min;
constexpr static bool is_flags =IsFlags;
constexpr static std::size_t prefix_length = PrefixLength;
template<int min,int max>
constexpr static adl_info_holder<IsFlags,min,max,PrefixLength> minmax() { return {};}
template<bool is_flag>
constexpr static adl_info_holder<is_flag,Min,Max,PrefixLength> flag() { return {};}
template<std::size_t prefix_len>
constexpr static adl_info_holder<IsFlags,Min,Max,prefix_len> prefix() { return {};}
};
template<bool IsFlags>
struct adl_info<IsFlags> {
static constexpr bool is_flags = IsFlags;
};
adl_info_holder<> adl_info()
{
return {};
}
// Enum value must be in range [MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]. By default MAGIC_ENUM_RANGE_MIN = -128, MAGIC_ENUM_RANGE_MAX = 127.
// If need another range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MIN and MAGIC_ENUM_RANGE_MAX.
// If need another range for specific enum type, add specialization enum_range for necessary enum type.
template <typename E, typename = void>
template <typename E,typename /*= void*/>
struct enum_range {
static constexpr int min = MAGIC_ENUM_RANGE_MIN;
static constexpr int max = MAGIC_ENUM_RANGE_MAX;
};
template <typename E>
struct enum_range < E, decltype(void(adl_magic_enum_define_range(E{}))) > {
static constexpr int min = detail::has_minmax_adl<E>.first;
static constexpr int max = detail::has_minmax_adl<E>.second;
static constexpr bool is_flags = detail::has_is_flags_adl<E>;
static_assert(is_flags || min != MAGIC_ENUM_RANGE_MIN || max != MAGIC_ENUM_RANGE_MAX,
"adl_magic_enum_define_range is declared for this enum but does not define any constants.\n"
"be sure that the member names are static and are not mispelled.");
};
struct enum_range<E, decltype(void(adl_magic_enum_define_range(E{}))) >
: decltype(adl_magic_enum_define_range(E{})) {};
static_assert(MAGIC_ENUM_RANGE_MAX > MAGIC_ENUM_RANGE_MIN, "MAGIC_ENUM_RANGE_MAX must be greater than MAGIC_ENUM_RANGE_MIN.");
@ -310,6 +307,9 @@ class static_str {
MAGIC_ENUM_ASSERT(str.size_ == N);
}
constexpr explicit static_str(const char* const str) noexcept : static_str{ str, std::make_integer_sequence<std::uint16_t, N>{} } {
}
constexpr explicit static_str(string_view str) noexcept : static_str{str.data(), std::make_integer_sequence<std::uint16_t, N>{}} {
MAGIC_ENUM_ASSERT(str.size() == N);
}
@ -658,7 +658,7 @@ constexpr auto enum_name() noexcept {
#else
constexpr auto name = n<V>();
#endif
return static_str<name.size_>{name};
return static_str<name.size_ - prefix_length_or_zero<E>>{name.str_ + prefix_length_or_zero<E>};
} else {
static_assert(always_false_v<E>, "magic_enum::customize invalid.");
}