11#define FLECS_ENUM_MAX(T) _::to_constant<T, 128>::value
12#define FLECS_ENUM_MAX_COUNT (FLECS_ENUM_MAX(int) + 1)
14#ifndef FLECS_CPP_ENUM_REFLECTION_SUPPORT
15#if !defined(__clang__) && defined(__GNUC__)
16#if __GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ >= 5)
17#define FLECS_CPP_ENUM_REFLECTION_SUPPORT 1
19#define FLECS_CPP_ENUM_REFLECTION_SUPPORT 0
22#define FLECS_CPP_ENUM_REFLECTION_SUPPORT 1
30template <
typename E,
int Value>
32#if defined(__clang__) && __clang_major__ >= 16
34 static constexpr E value = __builtin_bit_cast(E, Value);
36 static constexpr E value =
static_cast<E
>(Value);
40template <
typename E,
int Value>
53 static constexpr E value = FLECS_ENUM_MAX(E);
57#define FLECS_ENUM_LAST(T, Last)\
60 struct enum_last<T> {\
61 static constexpr T value = Last;\
67#if INTPTR_MAX == INT64_MAX
68 #ifdef ECS_TARGET_MSVC
70 #define ECS_SIZE_T_STR "unsigned __int64"
72 #define ECS_SIZE_T_STR "unsigned int"
74 #elif defined(__clang__)
75 #define ECS_SIZE_T_STR "size_t"
77 #ifdef ECS_TARGET_WINDOWS
78 #define ECS_SIZE_T_STR "constexpr size_t; size_t = long long unsigned int"
80 #define ECS_SIZE_T_STR "constexpr size_t; size_t = long unsigned int"
84 #ifdef ECS_TARGET_MSVC
86 #define ECS_SIZE_T_STR "unsigned __int32"
88 #define ECS_SIZE_T_STR "unsigned int"
90 #elif defined(__clang__)
91 #define ECS_SIZE_T_STR "size_t"
93 #ifdef ECS_TARGET_WINDOWS
94 #define ECS_SIZE_T_STR "constexpr size_t; size_t = unsigned int"
96 #define ECS_SIZE_T_STR "constexpr size_t; size_t = unsigned int"
102constexpr size_t enum_type_len() {
103 return ECS_FUNC_TYPE_LEN(, enum_type_len, ECS_FUNC_NAME)
104 - (
sizeof(ECS_SIZE_T_STR) - 1u);
111#if defined(ECS_TARGET_CLANG)
112#if ECS_CLANG_VERSION < 13
113template <
typename E, E C>
117 enum_type_len<E>() + 6 ] >=
'0') &&
119 enum_type_len<E>() + 6 ] <=
'9'));
122template <
typename E, E C>
125 enum_type_len<E>() + 6 ] !=
'(');
128#elif defined(ECS_TARGET_GNU)
129template <
typename E, E C>
132 enum_type_len<E>() + 8 ] !=
'(');
138template <
typename E, E C>
141 enum_type_len<E>() + 1] !=
'(';
145template <
typename E, E C>
147 static constexpr bool value = enum_constant_is_valid<E, C>();
151template <
typename E, E C>
152static const char* enum_constant_to_name() {
153 static const size_t len = ECS_FUNC_TYPE_LEN(
const char*, enum_constant_to_name, ECS_FUNC_NAME);
154 static char result[len + 1] = {};
155 return ecs_cpp_get_constant_name(
156 result, ECS_FUNC_NAME, string::length(ECS_FUNC_NAME),
184 flecs::entity_t
entity(E value)
const {
185 return data.constants[
static_cast<int>(value)].
id;
188 void init(flecs::world_t *
world, flecs::entity_t
id) {
189#if !FLECS_CPP_ENUM_REFLECTION_SUPPORT
190 ecs_abort(ECS_UNSUPPORTED,
"enum reflection requires gcc 7.5 or higher")
194 ecs_cpp_enum_init(
world,
id);
196 data.min = FLECS_ENUM_MAX(
int);
197 init< enum_last<E>::value >(
world);
203 static constexpr int to_int() {
204 return static_cast<int>(Value);
208 static constexpr E from_int() {
213 static constexpr int is_not_0() {
214 return static_cast<int>(Value != from_int<0>());
217 template <E Value, flecs::if_not_t< enum_constant_is_valid<E, Value>() > = 0>
218 static void init_constant(flecs::world_t*) { }
220 template <E Value, flecs::if_t< enum_constant_is_valid<E, Value>() > = 0>
221 static void init_constant(flecs::world_t *
world) {
222 int v = to_int<Value>();
223 const char *name = enum_constant_to_name<E, Value>();
224 data.constants[v].next = data.min;
230 data.constants[v].id = ecs_cpp_enum_constant_register(
231 world, data.id, data.constants[v].id, name, v);
234 template <E Value = FLECS_ENUM_MAX(E) >
235 static void init(flecs::world_t *
world) {
236 init_constant<Value>(
world);
237 if (is_not_0<Value>()) {
238 init<from_int<to_int<Value>() - is_not_0<Value>()>()>(
world);
246template <typename E, if_t< is_enum<E>::value > = 0>
247inline static void init_enum(flecs::world_t *
world, flecs::entity_t
id) {
251template <typename E, if_not_t< is_enum<E>::value > = 0>
252inline static void init_enum(flecs::world_t*, flecs::entity_t) { }
263 bool is_valid(
int value) {
264 return impl_.constants[value].id != 0;
275 int next(
int cur)
const {
276 return impl_.constants[cur].next;
283 flecs::world_t *world_;
#define ecs_abort(error_code,...)
Abort.
constexpr bool enum_constant_is_valid()
Test if value is valid for enumeration.
Enumeration constant data.
Class that scans an enum for constants, extracts names & creates entities.
Convenience type with enum reflection data.
Class that wraps around a flecs::id_t.