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;
164template <typename T, if_t< std::is_trivially_constructible<T>::value > = 0>
170template <
typename T, if_t<
171 ! std::is_default_constructible<T>::value > = 0>
173 flags |= ECS_TYPE_HOOK_CTOR_ILLEGAL;
178template <
typename T, if_t<
179 ! std::is_trivially_constructible<T>::value &&
180 std::is_default_constructible<T>::value > = 0>
186template <typename T, if_t< std::is_trivially_destructible<T>::value > = 0>
192template <
typename T, if_t<
193 std::is_destructible<T>::value &&
194 ! std::is_trivially_destructible<T>::value > = 0>
200template <typename T, if_not_t< std::is_destructible<T>::value > = 0>
202 flecs_static_assert(always_false<T>::value,
203 "component type must be destructible");
204 flags |= ECS_TYPE_HOOK_DTOR_ILLEGAL;
209template <typename T, if_t< std::is_trivially_copyable<T>::value > = 0>
215template <
typename T, if_t<
216 ! std::is_trivially_copyable<T>::value &&
217 ! std::is_copy_assignable<T>::value > = 0>
219 flags |= ECS_TYPE_HOOK_COPY_ILLEGAL;
224template <
typename T, if_t<
225 std::is_copy_assignable<T>::value &&
226 ! std::is_trivially_copyable<T>::value > = 0>
232template <typename T, if_t< std::is_trivially_move_assignable<T>::value > = 0>
238template <typename T, if_not_t< std::is_move_assignable<T>::value > = 0>
240 flags |= ECS_TYPE_HOOK_MOVE_ILLEGAL;
245template <
typename T, if_t<
246 std::is_move_assignable<T>::value &&
247 ! std::is_trivially_move_assignable<T>::value > = 0>
253template <
typename T, if_t<
254 std::is_trivially_copy_constructible<T>::value > = 0>
260template <typename T, if_t< ! std::is_copy_constructible<T>::value > = 0>
262 flags |= ECS_TYPE_HOOK_COPY_CTOR_ILLEGAL;
268template <
typename T, if_t<
269 std::is_copy_constructible<T>::value &&
270 ! std::is_trivially_copy_constructible<T>::value > = 0>
272 return copy_ctor_impl<T>;
276template <
typename T, if_t<
277 std::is_trivially_move_constructible<T>::value > = 0>
283template <typename T, if_not_t< std::is_move_constructible<T>::value > = 0>
285 flags |= ECS_TYPE_HOOK_MOVE_CTOR_ILLEGAL;
290template <
typename T, if_t<
291 std::is_move_constructible<T>::value &&
292 ! std::is_trivially_move_constructible<T>::value > = 0>
294 return move_ctor_impl<T>;
298template <
typename T, if_t<
299 std::is_trivially_move_constructible<T>::value &&
300 std::is_trivially_destructible<T>::value > = 0>
306template <
typename T, if_t<
307 ! std::is_move_constructible<T>::value ||
308 ! std::is_destructible<T>::value > = 0>
309ecs_move_t ctor_move_dtor(ecs_flags32_t &flags) {
310 flags |= ECS_TYPE_HOOK_CTOR_MOVE_DTOR_ILLEGAL;
315template <
typename T, if_t<
316 !(std::is_trivially_move_constructible<T>::value &&
317 std::is_trivially_destructible<T>::value) &&
318 std::is_move_constructible<T>::value &&
319 std::is_destructible<T>::value > = 0>
321 return ctor_move_dtor_impl<T>;
325template <
typename T, if_t<
326 std::is_trivially_move_assignable<T>::value &&
327 std::is_trivially_destructible<T>::value > = 0>
333template <
typename T, if_t<
334 ! std::is_move_assignable<T>::value ||
335 ! std::is_destructible<T>::value > = 0>
337 flags |= ECS_TYPE_HOOK_MOVE_DTOR_ILLEGAL;
342template <
typename T, if_t<
343 !(std::is_trivially_move_assignable<T>::value &&
344 std::is_trivially_destructible<T>::value) &&
345 std::is_move_assignable<T>::value &&
346 std::is_destructible<T>::value > = 0>
348 return move_dtor_impl<T>;
358#if defined(__clang__)
359 #pragma clang diagnostic push
360 #pragma clang diagnostic ignored "-Wfloat-equal"
361#elif defined(__GNUC__) && !defined(__clang__)
362 #pragma GCC diagnostic push
363 #pragma GCC diagnostic ignored "-Wfloat-equal"
367template <
typename T,
typename =
void>
373 std::is_same<decltype(std::declval<const T&>() < std::declval<const T&>()), bool> {};
376template <
typename T,
typename =
void>
382 std::is_same<decltype(std::declval<const T&>() > std::declval<const T&>()), bool> {};
385template <
typename T,
typename =
void>
390struct has_operator_equal<T, void_t<decltype(std::declval<const T&>() == std::declval<const T&>())>> :
391 std::is_same<decltype(std::declval<const T&>() == std::declval<const T&>()), bool> {};
394template <
typename T, if_t<
398int compare_impl(
const void *a,
const void *b,
const ecs_type_info_t *) {
399 const T& lhs = *
static_cast<const T*
>(a);
400 const T& rhs = *
static_cast<const T*
>(b);
401 if (lhs < rhs)
return -1;
402 if (lhs > rhs)
return 1;
408template <
typename T, if_t<
409 has_operator_less<T>::value &&
410 has_operator_equal<T>::value > = 0>
411int compare_impl(
const void *a,
const void *b,
const ecs_type_info_t *) {
412 const T& lhs = *
static_cast<const T*
>(a);
413 const T& rhs = *
static_cast<const T*
>(b);
414 if (lhs == rhs)
return 0;
415 if (lhs < rhs)
return -1;
420template <
typename T, if_t<
421 has_operator_greater<T>::value &&
422 has_operator_equal<T>::value &&
423 !has_operator_less<T>::value > = 0>
424int compare_impl(
const void *a,
const void *b,
const ecs_type_info_t *) {
425 const T& lhs = *
static_cast<const T*
>(a);
426 const T& rhs = *
static_cast<const T*
>(b);
427 if (lhs == rhs)
return 0;
428 if (lhs > rhs)
return 1;
433template <
typename T, if_t<
434 has_operator_less<T>::value &&
435 !has_operator_greater<T>::value &&
436 !has_operator_equal<T>::value > = 0>
437int compare_impl(
const void *a,
const void *b,
const ecs_type_info_t *) {
438 const T& lhs = *
static_cast<const T*
>(a);
439 const T& rhs = *
static_cast<const T*
>(b);
440 if (lhs < rhs)
return -1;
441 if (rhs < lhs)
return 1;
446template <
typename T, if_t<
447 has_operator_greater<T>::value &&
448 !has_operator_less<T>::value &&
449 !has_operator_equal<T>::value > = 0>
450int compare_impl(
const void *a,
const void *b,
const ecs_type_info_t *) {
451 const T& lhs = *
static_cast<const T*
>(a);
452 const T& rhs = *
static_cast<const T*
>(b);
453 if (lhs > rhs)
return 1;
454 if (rhs > lhs)
return -1;
460template <
typename T, if_t<
461 has_operator_less<T>::value ||
462 has_operator_greater<T>::value > = 0>
464 return compare_impl<T>;
467template <
typename T, if_t<
468 !has_operator_less<T>::value &&
469 !has_operator_greater<T>::value > = 0>
475template <
typename T, if_t<
476 has_operator_equal<T>::value > = 0>
477bool equals_impl(
const void *a,
const void *b,
const ecs_type_info_t *) {
478 const T& lhs = *
static_cast<const T*
>(a);
479 const T& rhs = *
static_cast<const T*
>(b);
483template <
typename T, if_t<
484 has_operator_equal<T>::value > = 0>
486 return equals_impl<T>;
489template <
typename T, if_t<
490 !has_operator_equal<T>::value > = 0>
496#if defined(__clang__)
497 #pragma clang diagnostic pop
498#elif defined(__GNUC__) && !defined(__clang__)
499 #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.