improve nameof_enum
This commit is contained in:
parent
240b3f4d6a
commit
64499c3763
1 changed files with 27 additions and 24 deletions
|
@ -6,6 +6,7 @@
|
||||||
// |_| \_|\__,_|_| |_| |_|\___|\___/|_| \_____|
|
// |_| \_|\__,_|_| |_| |_|\___|\___/|_| \_____|
|
||||||
// https://github.com/Neargye/nameof
|
// https://github.com/Neargye/nameof
|
||||||
// vesion 0.9.1
|
// vesion 0.9.1
|
||||||
|
// vesion 0.9.2
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
@ -33,6 +34,7 @@
|
||||||
#define NEARGYE_NAMEOF_HPP
|
#define NEARGYE_NAMEOF_HPP
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
@ -380,35 +382,39 @@ constexpr bool mixed_sign_less(L lhs, R rhs) noexcept {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename L, typename R>
|
template <typename E>
|
||||||
constexpr int mixed_sign_min_as_int(L lhs, R rhs) noexcept {
|
constexpr int reflected_min() noexcept {
|
||||||
static_assert(std::is_integral_v<L> && std::is_integral_v<R>, "nameof::detail::mixed_sign_min_as_int requires integral type.");
|
static_assert(is_enum_v<E>, "nameof::detail::reflected_min requires enum type.");
|
||||||
|
constexpr auto lhs = enum_range<E>::min;
|
||||||
|
static_assert(lhs > (std::numeric_limits<std::int16_t>::min)(), "nameof::enum_range requires min must be greater than INT16_MIN.");
|
||||||
|
constexpr auto rhs = (std::numeric_limits<std::underlying_type_t<E>>::min)();
|
||||||
|
|
||||||
return mixed_sign_less(lhs, rhs) ? static_cast<int>(lhs) : static_cast<int>(rhs);
|
return mixed_sign_less(lhs, rhs) ? rhs : lhs;
|
||||||
}
|
|
||||||
|
|
||||||
template <typename L, typename R>
|
|
||||||
constexpr int mixed_sign_max_as_int(L lhs, R rhs) noexcept {
|
|
||||||
static_assert(std::is_integral_v<L> && std::is_integral_v<R>, "nameof::detail::mixed_sign_max_as_int requires integral type.");
|
|
||||||
|
|
||||||
return mixed_sign_less(lhs, rhs) ? static_cast<int>(rhs) : static_cast<int>(lhs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename E>
|
template <typename E>
|
||||||
inline constexpr int reflected_min_v = mixed_sign_max_as_int(enum_range<E>::min, (std::numeric_limits<std::underlying_type_t<E>>::min)());
|
constexpr int reflected_max() noexcept {
|
||||||
|
static_assert(is_enum_v<E>, "nameof::detail::reflected_max requires enum type.");
|
||||||
|
constexpr auto lhs = enum_range<E>::max;
|
||||||
|
static_assert(lhs < (std::numeric_limits<std::int16_t>::max)(), "nameof::enum_range requires max must be less than INT16_MAX.");
|
||||||
|
constexpr auto rhs = (std::numeric_limits<std::underlying_type_t<E>>::max)();
|
||||||
|
|
||||||
|
return mixed_sign_less(lhs, rhs) ? lhs : rhs;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename E>
|
template <typename E>
|
||||||
inline constexpr int reflected_max_v = mixed_sign_min_as_int(enum_range<E>::max, (std::numeric_limits<std::underlying_type_t<E>>::max)());
|
inline constexpr int reflected_min_v = reflected_min<E>();
|
||||||
|
|
||||||
template <typename E>
|
template <typename E>
|
||||||
constexpr std::size_t reflected_size() {
|
inline constexpr int reflected_max_v = reflected_max<E>();
|
||||||
|
|
||||||
|
template <typename E>
|
||||||
|
constexpr std::size_t reflected_size() noexcept {
|
||||||
static_assert(is_enum_v<E>, "nameof::detail::reflected_size requires enum type.");
|
static_assert(is_enum_v<E>, "nameof::detail::reflected_size requires enum type.");
|
||||||
static_assert(reflected_min_v<E> > (std::numeric_limits<std::int16_t>::min)(), "nameof::enum_range requires min must be greater than INT16_MIN.");
|
|
||||||
static_assert(reflected_max_v<E> < (std::numeric_limits<std::int16_t>::max)(), "nameof::enum_range requires max must be less than INT16_MAX.");
|
|
||||||
static_assert(reflected_max_v<E> > reflected_min_v<E>, "nameof::enum_range requires max > min.");
|
static_assert(reflected_max_v<E> > reflected_min_v<E>, "nameof::enum_range requires max > min.");
|
||||||
constexpr auto size = reflected_max_v<E> - reflected_min_v<E> + 1;
|
constexpr auto size = reflected_max_v<E> - reflected_min_v<E> + 1;
|
||||||
static_assert(size > 0, "nameof::enum_range requires valid size.");
|
static_assert(size > 0, "nameof::enum_range requires valid size.");
|
||||||
static_assert(size < (std::numeric_limits<std::int16_t>::max)(), "nameof::enum_range requires valid size.");
|
static_assert(size < (std::numeric_limits<std::uint16_t>::max)(), "nameof::enum_range requires valid size.");
|
||||||
|
|
||||||
return static_cast<std::size_t>(size);
|
return static_cast<std::size_t>(size);
|
||||||
}
|
}
|
||||||
|
@ -417,12 +423,12 @@ template <typename E, int... I>
|
||||||
constexpr auto values(std::integer_sequence<int, I...>) noexcept {
|
constexpr auto values(std::integer_sequence<int, 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 std::array<bool, sizeof...(I)> valid{{(n<E, static_cast<E>(I + reflected_min_v<E>)>().size() != 0)...}};
|
constexpr std::array<bool, sizeof...(I)> valid{{(n<E, static_cast<E>(I + reflected_min_v<E>)>().size() != 0)...}};
|
||||||
constexpr std::size_t count = ((valid[I] ? 1 : 0) + ...);
|
constexpr int count = ((valid[I] ? 1 : 0) + ...);
|
||||||
|
|
||||||
std::array<E, count> values{};
|
std::array<E, count> values{};
|
||||||
for (std::size_t i = 0, v = 0; v < count; ++i) {
|
for (int i = 0, v = 0; v < count; ++i) {
|
||||||
if (valid[i]) {
|
if (valid[i]) {
|
||||||
values[v++] = static_cast<E>(static_cast<int>(i) + reflected_min_v<E>);
|
values[v++] = static_cast<E>(i + reflected_min_v<E>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +452,7 @@ constexpr std::size_t range_size() noexcept {
|
||||||
static_assert(is_enum_v<E>, "nameof::detail::range_size requires enum type.");
|
static_assert(is_enum_v<E>, "nameof::detail::range_size requires enum type.");
|
||||||
constexpr auto size = max_v<E> - min_v<E> + 1;
|
constexpr auto size = max_v<E> - min_v<E> + 1;
|
||||||
static_assert(size > 0, "nameof::enum_range requires valid size.");
|
static_assert(size > 0, "nameof::enum_range requires valid size.");
|
||||||
static_assert(size < (std::numeric_limits<std::int16_t>::max)(), "nameof::enum_range requires valid size.");
|
static_assert(size < (std::numeric_limits<std::uint16_t>::max)(), "nameof::enum_range requires valid size.");
|
||||||
|
|
||||||
return static_cast<std::size_t>(size);
|
return static_cast<std::size_t>(size);
|
||||||
}
|
}
|
||||||
|
@ -499,9 +505,6 @@ constexpr auto strings() noexcept {
|
||||||
template <typename E>
|
template <typename E>
|
||||||
class enum_traits {
|
class enum_traits {
|
||||||
static_assert(is_enum_v<E>, "nameof::enum_traits requires enum type.");
|
static_assert(is_enum_v<E>, "nameof::enum_traits requires enum type.");
|
||||||
static_assert(enum_range<E>::min > (std::numeric_limits<std::int16_t>::min)(), "nameof::enum_range requires min must be greater than INT16_MIN.");
|
|
||||||
static_assert(enum_range<E>::max < (std::numeric_limits<std::int16_t>::max)(), "nameof::enum_range requires max must be less than INT16_MAX.");
|
|
||||||
static_assert(enum_range<E>::max > enum_range<E>::min, "nameof::enum_range requires max > min.");
|
|
||||||
static_assert(count_v<E> > 0, "nameof::enum_range requires enum implementation or valid max and min.");
|
static_assert(count_v<E> > 0, "nameof::enum_range requires enum implementation or valid max and min.");
|
||||||
using U = std::underlying_type_t<E>;
|
using U = std::underlying_type_t<E>;
|
||||||
inline static constexpr auto strings_ = strings<E>();
|
inline static constexpr auto strings_ = strings<E>();
|
||||||
|
|
Loading…
Reference in a new issue