From d022583a1a250b13062dc8381b2eb845e749e273 Mon Sep 17 00:00:00 2001 From: neargye Date: Wed, 16 Oct 2019 14:11:15 +0500 Subject: [PATCH] clean-up cast, size check --- include/magic_enum.hpp | 65 +++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/include/magic_enum.hpp b/include/magic_enum.hpp index 0febc40..b7d6eb0 100644 --- a/include/magic_enum.hpp +++ b/include/magic_enum.hpp @@ -65,7 +65,7 @@ namespace magic_enum { // 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 -struct enum_range final { +struct enum_range { static_assert(std::is_enum_v, "magic_enum::enum_range requires enum type."); inline static constexpr int min = MAGIC_ENUM_RANGE_MIN; inline static constexpr int max = MAGIC_ENUM_RANGE_MAX; @@ -83,7 +83,7 @@ static_assert(MAGIC_ENUM_RANGE_MAX > MAGIC_ENUM_RANGE_MIN, "MAGIC_ENUM_RANGE_MAX namespace detail { template -struct supported final +struct supported #if defined(MAGIC_ENUM_SUPPORTED) && MAGIC_ENUM_SUPPORTED || defined(MAGIC_ENUM_NO_CHECK_SUPPORT) : std::true_type {}; #else @@ -94,7 +94,7 @@ template inline constexpr bool is_enum_v = std::is_enum_v && std::is_same_v>; template -struct static_string final { +struct static_string { constexpr static_string(std::string_view str) noexcept : static_string{str, std::make_index_sequence{}} {} constexpr const char* data() const noexcept { return chars.data(); } @@ -111,7 +111,7 @@ struct static_string final { }; template <> -struct static_string<0> final { +struct static_string<0> { constexpr static_string(std::string_view) noexcept {} constexpr const char* data() const noexcept { return nullptr; } @@ -157,20 +157,6 @@ constexpr bool mixed_sign_less(L lhs, R rhs) noexcept { } } -template -constexpr int mixed_sign_min_as_int(L lhs, R rhs) noexcept { - static_assert(std::is_integral_v && std::is_integral_v, "magic_enum::detail::mixed_sign_min_as_int requires integral type."); - - return mixed_sign_less(lhs, rhs) ? static_cast(lhs) : static_cast(rhs); -} - -template -constexpr int mixed_sign_max_as_int(L lhs, R rhs) noexcept { - static_assert(std::is_integral_v && std::is_integral_v, "magic_enum::detail::mixed_sign_max_as_int requires integral type."); - - return mixed_sign_less(lhs, rhs) ? static_cast(rhs) : static_cast(lhs); -} - template constexpr auto n() noexcept { static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); @@ -212,20 +198,38 @@ template inline constexpr auto name_v = n(); template -inline constexpr int reflected_min_v = mixed_sign_max_as_int(enum_range::min, (std::numeric_limits>::min)()); +constexpr int reflected_min() noexcept { + static_assert(is_enum_v, "magic_enum::detail::reflected_min requires enum type."); + constexpr auto lhs = enum_range::min; + static_assert(lhs > (std::numeric_limits::min)(), "magic_enum::enum_range requires min must be greater than INT16_MIN."); + constexpr auto rhs = (std::numeric_limits>::min)(); + + return mixed_sign_less(lhs, rhs) ? rhs : lhs; +} template -inline constexpr int reflected_max_v = mixed_sign_min_as_int(enum_range::max, (std::numeric_limits>::max)()); +constexpr int reflected_max() noexcept { + static_assert(is_enum_v, "magic_enum::detail::reflected_max requires enum type."); + constexpr auto lhs = enum_range::max; + static_assert(lhs < (std::numeric_limits::max)(), "magic_enum::enum_range requires max must be less than INT16_MAX."); + constexpr auto rhs = (std::numeric_limits>::max)(); + + return mixed_sign_less(lhs, rhs) ? lhs : rhs; +} template -constexpr std::size_t reflected_size() { +inline constexpr int reflected_min_v = reflected_min(); + +template +inline constexpr int reflected_max_v = reflected_max(); + +template +constexpr std::size_t reflected_size() noexcept { static_assert(is_enum_v, "magic_enum::detail::reflected_size requires enum type."); - static_assert(reflected_min_v > (std::numeric_limits::min)(), "magic_enum::enum_range requires min must be greater than INT16_MIN."); - static_assert(reflected_max_v < (std::numeric_limits::max)(), "magic_enum::enum_range requires max must be less than INT16_MAX."); static_assert(reflected_max_v > reflected_min_v, "magic_enum::enum_range requires max > min."); constexpr auto size = reflected_max_v - reflected_min_v + 1; static_assert(size > 0, "magic_enum::enum_range requires valid size."); - static_assert(size < (std::numeric_limits::max)(), "magic_enum::enum_range requires valid size."); + static_assert(size < (std::numeric_limits::max)(), "magic_enum::enum_range requires valid size."); return static_cast(size); } @@ -234,12 +238,12 @@ template constexpr auto values(std::integer_sequence) noexcept { static_assert(is_enum_v, "magic_enum::detail::values requires enum type."); constexpr std::array valid{{(n(I + reflected_min_v)>().size() != 0)...}}; - constexpr std::size_t count = ((valid[I] ? 1 : 0) + ...); + constexpr int count = ((valid[I] ? 1 : 0) + ...); std::array values{}; - for (std::size_t i = 0, v = 0; v < count; ++i) { + for (int i = 0, v = 0; v < count; ++i) { if (valid[i]) { - values[v++] = static_cast(static_cast(i) + reflected_min_v); + values[v++] = static_cast(i + reflected_min_v); } } @@ -263,7 +267,7 @@ constexpr std::size_t range_size() noexcept { static_assert(is_enum_v, "magic_enum::detail::range_size requires enum type."); constexpr auto size = max_v - min_v + 1; static_assert(size > 0, "magic_enum::enum_range requires valid size."); - static_assert(size < (std::numeric_limits::max)(), "magic_enum::enum_range requires valid size."); + static_assert(size < (std::numeric_limits::max)(), "magic_enum::enum_range requires valid size."); return static_cast(size); } @@ -360,7 +364,7 @@ struct enum_traits>> { if constexpr (range_size_v != count_v) { return assert(index < count), values[index]; } else { - return assert(index < count), static_cast(static_cast(index) + min_v); + return assert(index < count), static_cast(index + min_v); } } @@ -374,9 +378,6 @@ struct enum_traits>> { private: static_assert(is_enum_v, "magic_enum::enum_traits requires enum type."); - static_assert(enum_range::min > (std::numeric_limits::min)(), "magic_enum::enum_range requires min must be greater than INT16_MIN."); - static_assert(enum_range::max < (std::numeric_limits::max)(), "magic_enum::enum_range requires max must be less than INT16_MAX."); - static_assert(enum_range::max > enum_range::min, "magic_enum::enum_range requires max > min."); static_assert(count > 0, "magic_enum::enum_range requires enum implementation or valid max and min."); using U = underlying_type; inline static constexpr auto indexes = detail::indexes(std::make_integer_sequence>{});