9#include "plg/config.hpp"
14 constexpr auto ENUM_MIN_VALUE = -128;
15 constexpr auto ENUM_MAX_VALUE = 128;
17 template <std::
size_t N>
20 std::copy(
sv.begin(),
sv.end(), content_.begin());
23 constexpr operator std::string_view()
const noexcept {
24 return { content_.data(),
N };
28 std::array<char, N + 1> content_{};
31 constexpr auto is_pretty(
char ch)
noexcept {
32 return (
ch >=
'a' &&
ch <=
'z') || (
ch >=
'A' &&
ch <=
'Z');
35 constexpr auto pretty_name(std::string_view sv)
noexcept {
36 for (std::size_t n = sv.size() - 1; n > 0; --n) {
37 if (!is_pretty(sv[n])) {
38 sv.remove_prefix(n + 1);
45 template <
typename E, E V>
46 constexpr auto n() noexcept {
47#if PLUGIFY_COMPILER_GCC || PLUGIFY_COMPILER_CLANG
48 return pretty_name({ __PRETTY_FUNCTION__,
sizeof(__PRETTY_FUNCTION__) - 2 });
49#elif PLUGIFY_COMPILER_MSVC
50 return pretty_name({ __FUNCSIG__,
sizeof(__FUNCSIG__) - 17 });
54 template <
typename E, E V>
55 constexpr auto is_valid() {
56 [[maybe_unused]]
constexpr E v =
static_cast<E
>(V);
57 return !n<E, V>().empty();
61 constexpr auto value(std::size_t v) {
62 return static_cast<E
>(ENUM_MIN_VALUE +
static_cast<int>(v));
65 template <std::
size_t N>
66 constexpr auto count_values(
const bool (&valid)[N]) {
67 std::size_t count = 0;
68 for (std::size_t n = 0; n < N; ++n) {
76 template <
typename E, std::size_t... I>
77 constexpr auto values(std::index_sequence<I...>)
noexcept {
78 constexpr bool valid[
sizeof...(I)] = { is_valid<E, value<E>(I)>()... };
79 constexpr auto num_valid = count_values(valid);
80 static_assert(num_valid > 0,
"no support for empty enums");
82 std::array<E, num_valid> values = {};
83 for (std::size_t offset = 0, n = 0; n < num_valid; ++offset) {
85 values[n] = value<E>(offset);
94 constexpr auto values() noexcept {
95 constexpr auto enum_size = ENUM_MAX_VALUE - ENUM_MIN_VALUE + 1;
96 return values<E>(std::make_index_sequence<enum_size>({}));
100 inline constexpr auto values_v = values<E>();
102 template <
typename E, E V>
103 constexpr auto enum_name() {
104 constexpr auto name = n<E, V>();
105 return static_string<name.size()>(name);
108 template <
typename E, E V>
109 inline constexpr auto enum_name_v = enum_name<E, V>();
111 template <
typename E, std::size_t... I>
112 constexpr auto entries(std::index_sequence<I...>)
noexcept {
113 return std::array<std::pair<E, std::string_view>,
sizeof...(I)>{
114 { { values_v<E>[I], enum_name_v<E, values_v<E>[I]> }... }
118 template <
typename E>
119 inline constexpr auto entries_v = entries<E>(std::make_index_sequence<values_v<E>.size()>());
121 template <
typename E>
122 constexpr std::string_view enum_to_string(E value) {
123 for (
const auto& [key, name] : entries_v<E>) {