19 ECS_INTERNAL_ERROR, NULL);
20 T *arr =
static_cast<T*
>(ptr);
21 for (
int i = 0; i < count; i ++) {
22 FLECS_PLACEMENT_NEW(&arr[i], T);
30 ECS_INTERNAL_ERROR, NULL);
31 T *arr =
static_cast<T*
>(ptr);
32 for (
int i = 0; i < count; i ++) {
39void copy_impl(
void *dst_ptr,
const void *src_ptr, int32_t count,
43 ECS_INTERNAL_ERROR, NULL);
44 T *dst_arr =
static_cast<T*
>(dst_ptr);
45 const T *src_arr =
static_cast<const T*
>(src_ptr);
46 for (
int i = 0; i < count; i ++) {
47 dst_arr[i] = src_arr[i];
53void move_impl(
void *dst_ptr,
void *src_ptr, int32_t count,
57 ECS_INTERNAL_ERROR, NULL);
58 T *dst_arr =
static_cast<T*
>(dst_ptr);
59 T *src_arr =
static_cast<T*
>(src_ptr);
60 for (
int i = 0; i < count; i ++) {
61 dst_arr[i] = FLECS_MOV(src_arr[i]);
67void copy_ctor_impl(
void *dst_ptr,
const void *src_ptr, int32_t count,
71 ECS_INTERNAL_ERROR, NULL);
72 T *dst_arr =
static_cast<T*
>(dst_ptr);
73 const T *src_arr =
static_cast<const T*
>(src_ptr);
74 for (
int i = 0; i < count; i ++) {
75 FLECS_PLACEMENT_NEW(&dst_arr[i], T(src_arr[i]));
81void move_ctor_impl(
void *dst_ptr,
void *src_ptr, int32_t count,
85 ECS_INTERNAL_ERROR, NULL);
86 T *dst_arr =
static_cast<T*
>(dst_ptr);
87 T *src_arr =
static_cast<T*
>(src_ptr);
88 for (
int i = 0; i < count; i ++) {
89 FLECS_PLACEMENT_NEW(&dst_arr[i], T(FLECS_MOV(src_arr[i])));
96void ctor_move_dtor_impl(
void *dst_ptr,
void *src_ptr, int32_t count,
100 ECS_INTERNAL_ERROR, NULL);
101 T *dst_arr =
static_cast<T*
>(dst_ptr);
102 T *src_arr =
static_cast<T*
>(src_ptr);
103 for (
int i = 0; i < count; i ++) {
104 FLECS_PLACEMENT_NEW(&dst_arr[i], T(FLECS_MOV(src_arr[i])));
111template <
typename T, if_not_t<
112 std::is_trivially_move_assignable<T>::value > = 0>
113void move_dtor_impl(
void *dst_ptr,
void *src_ptr, int32_t count,
117 ECS_INTERNAL_ERROR, NULL);
118 T *dst_arr =
static_cast<T*
>(dst_ptr);
119 T *src_arr =
static_cast<T*
>(src_ptr);
120 for (
int i = 0; i < count; i ++) {
122 dst_arr[i] = FLECS_MOV(src_arr[i]);
131template <
typename T, if_t<
132 std::is_trivially_move_assignable<T>::value > = 0>
133void move_dtor_impl(
void *dst_ptr,
void *src_ptr, int32_t count,
137 ECS_INTERNAL_ERROR, NULL);
138 T *dst_arr =
static_cast<T*
>(dst_ptr);
139 T *src_arr =
static_cast<T*
>(src_ptr);
140 for (
int i = 0; i < count; i ++) {
144 dst_arr[i] = FLECS_MOV(src_arr[i]);
156 static constexpr bool value =
157 std::is_default_constructible<actual_type_t<T>>::value;
165 if constexpr (is_trivially_constructible_v<T>) {
167 }
else if constexpr (!is_default_constructible_v<T>) {
168 flags |= ECS_TYPE_HOOK_CTOR_ILLEGAL;
177 if constexpr (is_trivially_destructible_v<T>) {
179 }
else if constexpr (!is_destructible_v<T>) {
180 flecs_static_assert(always_false<T>::value,
181 "component type must be destructible");
182 flags |= ECS_TYPE_HOOK_DTOR_ILLEGAL;
191 if constexpr (is_trivially_copyable_v<T>) {
193 }
else if constexpr (!is_copy_assignable_v<T>) {
194 flags |= ECS_TYPE_HOOK_COPY_ILLEGAL;
203 if constexpr (is_trivially_move_assignable_v<T>) {
205 }
else if constexpr (!is_move_assignable_v<T>) {
206 flags |= ECS_TYPE_HOOK_MOVE_ILLEGAL;
215 if constexpr (is_trivially_copy_constructible_v<T>) {
217 }
else if constexpr (!is_copy_constructible_v<T>) {
218 flags |= ECS_TYPE_HOOK_COPY_CTOR_ILLEGAL;
221 return copy_ctor_impl<T>;
227 if constexpr (is_trivially_move_constructible_v<T>) {
229 }
else if constexpr (!is_move_constructible_v<T>) {
230 flags |= ECS_TYPE_HOOK_MOVE_CTOR_ILLEGAL;
233 return move_ctor_impl<T>;
238ecs_move_t ctor_move_dtor(ecs_flags32_t &flags) {
239 if constexpr (is_trivially_move_constructible_v<T> && is_trivially_destructible_v<T>) {
241 }
else if constexpr (!is_move_constructible_v<T> || !is_destructible_v<T>) {
242 flags |= ECS_TYPE_HOOK_CTOR_MOVE_DTOR_ILLEGAL;
245 return ctor_move_dtor_impl<T>;
251 if constexpr (is_trivially_move_assignable_v<T> && is_trivially_destructible_v<T>) {
253 }
else if constexpr (!is_move_assignable_v<T> || !is_destructible_v<T>) {
254 flags |= ECS_TYPE_HOOK_MOVE_DTOR_ILLEGAL;
257 return move_dtor_impl<T>;
267#if defined(__clang__)
268 #pragma clang diagnostic push
269 #pragma clang diagnostic ignored "-Wfloat-equal"
270#elif defined(__GNUC__) && !defined(__clang__)
271 #pragma GCC diagnostic push
272 #pragma GCC diagnostic ignored "-Wfloat-equal"
276template <
typename T,
typename =
void>
281struct has_operator_less<T, void_t<decltype(std::declval<const T&>() < std::declval<const T&>())>> :
282 std::is_same<decltype(std::declval<const T&>() < std::declval<const T&>()), bool> {};
285template <typename T, typename = void>
286struct has_operator_greater : std::false_type {};
290struct has_operator_greater<T, void_t<decltype(std::declval<const T&>() > std::declval<const T&>())>> :
291 std::is_same<decltype(std::declval<const T&>() > std::declval<const T&>()), bool> {};
294template <
typename T,
typename =
void>
299struct has_operator_equal<T, void_t<decltype(std::declval<const T&>() == std::declval<const T&>())>> :
300 std::is_same<decltype(std::declval<const T&>() == std::declval<const T&>()), bool> {};
304int compare_impl(
const void *a,
const void *b,
const ecs_type_info_t *) {
305 const T& lhs = *
static_cast<const T*
>(a);
306 const T& rhs = *
static_cast<const T*
>(b);
310 if (lhs == rhs)
return 0;
311 if (lhs < rhs)
return -1;
313 }
else if constexpr (has_operator_greater<T>::value && has_operator_equal<T>::value) {
315 if (lhs == rhs)
return 0;
316 if (lhs > rhs)
return 1;
318 }
else if constexpr (has_operator_less<T>::value && has_operator_greater<T>::value) {
320 if (lhs < rhs)
return -1;
321 if (lhs > rhs)
return 1;
323 }
else if constexpr (has_operator_less<T>::value) {
325 if (lhs < rhs)
return -1;
326 if (rhs < lhs)
return 1;
328 }
else if constexpr (has_operator_greater<T>::value) {
330 if (lhs > rhs)
return 1;
331 if (rhs > lhs)
return -1;
343 if constexpr (has_operator_less<T>::value || has_operator_greater<T>::value) {
344 return compare_impl<T>;
352bool equals_impl(
const void *a,
const void *b,
const ecs_type_info_t *) {
353 const T& lhs = *
static_cast<const T*
>(a);
354 const T& rhs = *
static_cast<const T*
>(b);
360 if constexpr (has_operator_equal<T>::value) {
361 return equals_impl<T>;
368#if defined(__clang__)
369 #pragma clang diagnostic pop
370#elif defined(__GNUC__) && !defined(__clang__)
371 #pragma GCC diagnostic pop
#define ecs_assert(condition, error_code,...)
Assert.
int(* ecs_cmp_t)(const void *a_ptr, const void *b_ptr, const ecs_type_info_t *type_info)
Compare hook to compare component instances.
void(* ecs_copy_t)(void *dst_ptr, const void *src_ptr, int32_t count, const ecs_type_info_t *type_info)
Copy is invoked when a component is copied into another component.
bool(* ecs_equals_t)(const void *a_ptr, const void *b_ptr, const ecs_type_info_t *type_info)
Equals operator hook.
void(* ecs_move_t)(void *dst_ptr, void *src_ptr, int32_t count, const ecs_type_info_t *type_info)
Move is invoked when a component is moved to another component.
void(* ecs_xtor_t)(void *ptr, int32_t count, const ecs_type_info_t *type_info)
Constructor/destructor callback.
Type that contains component information (passed to ctors/dtors/...)
ecs_size_t size
Size of type.