3#if !defined(__XTD_CORE_INTERNAL__)
4#error "Do not include this file: Internal use only"
8#include "../typeof.hpp"
10#include "../string.hpp"
13#if defined(__XTD_DO_NOT_USE_ENUMERATION_INTROSPECTION__)
14#define __enum_introspection__(namespace_name, enum_t, base_t, ...)
20namespace __enumeration_introspection {
21 constexpr std::string_view trim(std::string_view view) {
22 size_t start = view.find_first_not_of(
' ');
23 if (start == std::string_view::npos)
return "";
24 size_t end = view.find_first_of(
" =", start);
25 if (end == std::string_view::npos)
return view.substr(start);
26 return view.substr(start, end - start);
29 template <
size_t count,
size_t str_size,
class function_t>
30 constexpr void split_trim_apply(
char const(&str)[str_size], function_t func) {
31 std::string_view view(str, str_size - 1);
33 for (
size_t i = 0;
i < count;
i++) {
34 auto new_pos = view.find(
',');
35 func(trim(view.substr(0, new_pos)));
36 if (new_pos != std::string_view::npos) view = view.substr(new_pos + 1);
41 template <
size_t count,
size_t str_size>
42 constexpr size_t compute_name_block_size(
char const(&str)[str_size]) {
44 split_trim_apply<count>(str, [&](std::string_view sv) {total += sv.size();});
48 template <
size_t count,
size_t str_size>
49 constexpr void write_names_and_sizes(
char const(&str)[str_size],
char* destination,
unsigned* offsets) {
50 size_t current_offset = 0;
51 split_trim_apply<count>(str, [&](std::string_view sv) {
52 char const* source = sv.data();
53 size_t size = sv.size();
54 for (
size_t i = 0;
i <
size;
i++)
55 destination[i] = source[i];
56 *offsets++ =
static_cast<unsigned>(current_offset);
58 current_offset +=
size;
60 *offsets =
static_cast<unsigned>(current_offset);
63 constexpr auto get_top_name(std::string_view view) {
64 auto pos = view.find_last_of(
':');
65 if (pos == view.npos)
return view;
66 return view.substr(pos + 1);
69 template <
size_t count>
70 constexpr auto get_top_name(
char const(&str)[count]) {
return get_top_name(std::string_view(str, count - 1));}
72 template <
typename base_t>
73 struct enumeration_maker {
76 enumeration_maker() =
default;
77 enumeration_maker(enumeration_maker
const&) =
default;
78 constexpr enumeration_maker(base_t) : enumeration_maker() {}
79 enumeration_maker& operator =(enumeration_maker
const&) =
default;
81 template <
typename type_t>
82 constexpr enumeration_maker& operator =(type_t
const& v) {
88 constexpr operator base_t()
const {
return value;}
89 template <
typename type_t>
90 constexpr explicit operator type_t()
const {
return type_t(value);}
93 template <
typename base_t>
94 struct value_assigner {
97 constexpr value_assigner& operator, (enumeration_maker<base_t>& other) {
105 class string_block_iterator {
107 unsigned const* indices {};
110 string_block_iterator() =
default;
111 string_block_iterator(string_block_iterator
const&) =
default;
112 constexpr string_block_iterator(
char const* data,
unsigned const* indices) noexcept : data(data), indices(indices) {}
114 constexpr string_block_iterator& operator ++() noexcept {
118 constexpr string_block_iterator operator ++(
int)
noexcept {
119 string_block_iterator previous_state = *
this;
121 return previous_state;
123 constexpr xtd::intptr operator -(string_block_iterator
const& other)
const noexcept {
return indices -
other.indices;}
124 constexpr bool operator ==(string_block_iterator
const& other)
const noexcept {
return indices ==
other.indices;}
125 constexpr bool operator !=(string_block_iterator
const& other)
const noexcept {
return indices !=
other.indices;}
126 constexpr auto operator *() const noexcept -> std::string_view {
127 int off0 = indices[0];
128 int off1 = indices[1];
129 return std::string_view(data + off0, off1 - off0);
133 template <
size_t count,
size_t blk_size>
134 struct string_block {
135 char data[blk_size] {};
136 unsigned offsets[count + 1] {};
137 string_block() =
default;
138 string_block(string_block
const&) =
default;
140 template <
typename function_t>
141 explicit constexpr string_block(function_t&& func) : string_block() {
func(*
this);}
143 template <
typename function_t>
144 constexpr string_block(string_block
const& source, function_t&& func) : string_block() {
func(source, *
this);}
146 using iterator = string_block_iterator;
147 using const_iterator = iterator;
148 constexpr iterator begin() const noexcept {
return iterator(data, offsets);}
149 constexpr iterator
end() const noexcept {
return iterator(data, offsets + count);}
150 constexpr static size_t size() noexcept {
return count;}
151 constexpr static size_t block_size() noexcept {
return blk_size;}
152 constexpr std::string_view operator [](
size_t i)
const noexcept {
153 auto off1 = offsets[
i];
154 auto off2 = offsets[
i + 1];
155 return std::string_view(data + off1, off2 - off1);
159 template <
typename type_t>
160 constexpr std::string_view name_of_type = typeof_<type_t>().name();
162 template <
typename enum_t>
163 struct enum_type_info_base {
164 constexpr static std::string_view qualified_type_name {name_of_type<enum_t>};
165 constexpr static std::string_view type_name {get_top_name(name_of_type<enum_t>)};
166 constexpr static size_t num_states = 0;
167 constexpr static size_t size() noexcept {
return 0;}
170 template <
typename enum_t>
171 struct enum_value_list_base : enum_type_info_base<enum_t> {};
173 template <
typename enum_t>
174 struct enum_name_list_base : enum_type_info_base<enum_t> {
175 using enum_type_info_base<enum_t>::num_states;
176 constexpr static size_t name_block_size = 0;
177 using block_type = string_block<num_states, name_block_size>;
178 block_type name_block;
181 template <
typename enum_t>
182 struct enum_type_info :
public enum_type_info_base<enum_t> {
184 using super = enum_type_info_base<enum_t>;
187 using super::num_states;
188 using super::qualified_type_name;
190 using super::type_name;
193 template <
typename enum_t>
194 struct enum_value_list : enum_type_info<enum_t> {
196 constexpr static enum_value_list_base<enum_t> values {};
197 using super = enum_type_info<enum_t>;
200 using iterator = enum_t
const*;
201 using const_iterator = enum_t
const*;
202 constexpr enum_t
const* begin() const noexcept {
return values.__enumeration_internal_values__;}
203 constexpr enum_t
const*
end() const noexcept {
return values.__enumeration_internal_values__ + super::num_states;}
204 constexpr enum_t
const& operator [](
size_t i)
const noexcept {
return values.__enumeration_internal_values__[
i];}
207 template <
typename enum_t>
208 struct enum_name_list : enum_type_info<enum_t> {
210 constexpr static enum_name_list_base<enum_t> name_info {};
211 using super = enum_type_info<enum_t>;
214 using block_type =
typename enum_name_list_base<enum_t>::block_type;
215 using iterator = string_block_iterator;
216 using const_iterator = iterator;
217 constexpr static block_type
const& get_name_block() noexcept {
return name_info.name_block;}
218 constexpr iterator begin() const noexcept {
return name_info.name_block.begin();}
219 constexpr iterator
end() const noexcept {
return name_info.name_block.end();}
220 constexpr std::string_view operator [](
size_t i)
const noexcept {
return name_info.name_block[
i];}
223 template <
typename enum_t>
224 constexpr size_t num_states = enum_type_info<enum_t>::num_states;
226 template <
typename enum_t>
227 constexpr enum_value_list<enum_t> enum_values {};
229 template <
typename enum_t>
230 constexpr enum_name_list<enum_t> enum_names {};
233#define __enum_introspection_concat__(str1, str2) (#str1 "::" #str2)
235#define __enum_introspection__(namespace_name, enum_t, base_t, ...) \
236 namespace __enumeration_introspection { \
237 template <> struct enum_type_info_base<enum_t> { \
238 using base_type = base_t; \
239 [[maybe_unused]] constexpr static std::string_view qualified_type_name = __enum_introspection_concat__(namespace_name, enum_t); \
240 [[maybe_unused]] constexpr static std::string_view type_name = get_top_name(__enum_introspection_concat__(namespace_name, enum_t)); \
241 constexpr static size_t num_states = []() -> size_t { \
242 enumeration_maker<base_t> __VA_ARGS__; \
243 enumeration_maker<base_t> __enum_introspection_vals[] {__VA_ARGS__}; \
244 return sizeof(__enum_introspection_vals) / sizeof(enumeration_maker<base_t>); \
246 constexpr static size_t size() noexcept {return num_states;} \
248 template <> struct enum_value_list_base<enum_t> : enum_type_info_base<enum_t> { \
249 enum_t __enumeration_internal_values__[enum_type_info_base<enum_t>::num_states]; \
250 constexpr enum_value_list_base() : __enumeration_internal_values__() { \
251 enumeration_maker<base_t> __VA_ARGS__; \
252 value_assigner<base_t> {}, __VA_ARGS__; \
253 enumeration_maker<base_t> __enum_introspection_vals[] {__VA_ARGS__}; \
254 for (size_t i = 0; i < enum_type_info_base<enum_t>::num_states; i++) \
255 this->__enumeration_internal_values__[i] = enum_t(__enum_introspection_vals[i]); \
258 template <> struct enum_name_list_base<enum_t> : enum_type_info_base<enum_t> { \
259 using enum_type_info_base<enum_t>::num_states; \
260 constexpr static size_t name_block_size = compute_name_block_size<num_states>(#__VA_ARGS__); \
261 using block_type = string_block<num_states, name_block_size>; \
262 block_type name_block; \
263 constexpr enum_name_list_base() : name_block([](auto& block) { \
264 write_names_and_sizes<num_states>(#__VA_ARGS__, block.data, block.offsets); \
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
intmax_t intptr
Represent a pointer or a handle.
Definition intptr.hpp:23
delegate< result_t(arguments_t...)> func
Represents a delegate that has variables parameters and returns a value of the type specified by the ...
Definition func.hpp:16
@ start
Starting of a logical operation.
@ other
The operating system is other.