9 #ifndef EAGINE_REFLECT_ENUMERATORS_HPP
10 #define EAGINE_REFLECT_ENUMERATORS_HPP
12 #include "../selector.hpp"
13 #include "../valid_if/decl.hpp"
19 template <
typename T,
typename Selector>
20 constexpr
auto enumerator_count(type_identity<T>
id, Selector sel) noexcept
21 -> std::enable_if_t<has_enumerator_mapping_v<T, Selector>,
span_size_t> {
22 return span_size_t(enumerator_mapping(
id, sel).size());
26 constexpr
auto enumerator_count(type_identity<T>
id) noexcept {
31 constexpr
auto enumerator_name(T value, type_identity<T>
id = {}) noexcept {
35 template <
typename T,
typename Selector>
37 enumerator_name(T enumerator, type_identity<T>
id, Selector sel) noexcept
38 -> std::enable_if_t<has_enumerator_mapping_v<T, Selector>, decl_name> {
39 for(
const auto& info : enumerator_mapping(
id, sel)) {
40 if(
info.enumerator == enumerator) {
48 constexpr
auto enumerator_value(T value, type_identity<T> = {}) noexcept {
49 return static_cast<std::underlying_type_t<T>
>(value);
52 template <
bool Signed>
53 struct enum_int_value_and_name {
55 std::conditional_t<Signed, std::intmax_t, std::uintmax_t>;
57 constexpr enum_int_value_and_name() noexcept = default;
60 constexpr enum_int_value_and_name(const enumerator_and_name<T>& src) noexcept
62 , value{
static_cast<value_type>(src.enumerator)} {}
68 using signed_enum_value_and_name = enum_int_value_and_name<true>;
69 using unsigned_enum_value_and_name = enum_int_value_and_name<false>;
72 using enum_value_and_name =
73 enum_int_value_and_name<std::is_signed_v<std::underlying_type_t<T>>>;
75 template <
typename T,
typename Selector>
77 enumerator_info(T enumerator, type_identity<T>
id, Selector sel) noexcept
79 has_enumerator_mapping_v<T, Selector>,
80 optionally_valid<enum_value_and_name<T>>> {
81 for(
const auto& info : enumerator_mapping(
id, sel)) {
82 if(
info.enumerator == enumerator) {
83 return {enum_value_and_name<T>{
info},
true};
90 auto enumerator_info(T enumerator, type_identity<T>
id = {}) noexcept {
94 template <
typename T,
typename Selector>
95 inline auto from_value(
96 std::underlying_type_t<T> value,
98 Selector sel) noexcept
99 -> std::enable_if_t<has_enumerator_mapping_v<T, Selector>, optionally_valid<T>> {
100 for(
const auto& info : enumerator_mapping(
id, sel)) {
101 if(enumerator_value(
info.enumerator,
id) == value) {
102 return {
info.enumerator,
true};
108 template <
typename T>
110 from_value(std::underlying_type_t<T> value, type_identity<T>
id = {}) noexcept {
114 template <
typename T,
typename Selector>
117 -> std::enable_if_t<has_enumerator_mapping_v<T, Selector>, optionally_valid<T>> {
118 for(
const auto& info : enumerator_mapping(
id, sel)) {
120 return {
info.enumerator,
true};
126 template <
typename Function,
typename T,
typename Selector>
127 inline auto for_each_enumerator(
130 Selector sel) noexcept
131 -> std::enable_if_t<has_enumerator_mapping_v<T, Selector>> {
132 for(
const auto& info : enumerator_mapping(
id, sel)) {
133 function(enum_value_and_name<T>{
info});
137 template <
typename Function,
typename T>
138 inline auto for_each_enumerator(Function&
function, type_identity<T>
id) noexcept
139 -> std::enable_if_t<has_enumerator_mapping_v<T, default_selector_t>> {
145 #endif // EAGINE_REFLECT_ENUMERATORS_HPP