OpenLexocad  27.1
entt.hpp
Go to the documentation of this file.
1 #ifdef min
2 #undef min
3 #endif
4 
5 // #include "core/algorithm.hpp"
6 #ifndef ENTT_CORE_ALGORITHM_HPP
7 #define ENTT_CORE_ALGORITHM_HPP
8 
9 
10 #include <utility>
11 #include <iterator>
12 #include <algorithm>
13 #include <functional>
14 // #include "utility.hpp"
15 #ifndef ENTT_CORE_UTILITY_HPP
16 #define ENTT_CORE_UTILITY_HPP
17 
18 
19 // #include "../config/config.h"
20 #ifndef ENTT_CONFIG_CONFIG_H
21 #define ENTT_CONFIG_CONFIG_H
22 
23 
24 #ifndef ENTT_NOEXCEPT
25 #define ENTT_NOEXCEPT noexcept
26 #endif // ENTT_NOEXCEPT
27 
28 
29 #ifndef ENTT_HS_SUFFIX
30 #define ENTT_HS_SUFFIX _hs
31 #endif // ENTT_HS_SUFFIX
32 
33 
34 #ifndef ENTT_HWS_SUFFIX
35 #define ENTT_HWS_SUFFIX _hws
36 #endif // ENTT_HWS_SUFFIX
37 
38 
39 #ifndef ENTT_NO_ATOMIC
40 #include <atomic>
41 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
42 #else // ENTT_NO_ATOMIC
43 #define ENTT_MAYBE_ATOMIC(Type) Type
44 #endif // ENTT_NO_ATOMIC
45 
46 
47 #ifndef ENTT_DISABLE_ETO
48 #include <type_traits>
49 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
50 #else // ENTT_DISABLE_ETO
51 // sfinae-friendly definition
52 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
53 #endif // ENTT_DISABLE_ETO
54 
55 
56 #ifndef ENTT_ID_TYPE
57 #include <cstdint>
58 #define ENTT_ID_TYPE std::uint32_t
59 #endif // ENTT_ID_TYPE
60 
61 
62 #ifndef ENTT_PAGE_SIZE
63 #define ENTT_PAGE_SIZE 32768
64 #endif // ENTT_PAGE_SIZE
65 
66 
67 #ifndef ENTT_DISABLE_ASSERT
68 #include <cassert>
69 #define ENTT_ASSERT(condition) assert(condition)
70 #else // ENTT_DISABLE_ASSERT
71 #define ENTT_ASSERT(...) ((void)0)
72 #endif // ENTT_DISABLE_ASSERT
73 
74 
75 #endif // ENTT_CONFIG_CONFIG_H
76 
77 
78 
79 namespace entt {
80 
81 
83 struct identity {
90  template<class Type>
91  constexpr Type && operator()(Type &&value) const ENTT_NOEXCEPT {
92  return std::forward<Type>(value);
93  }
94 };
95 
96 
104 template<typename Type, typename Class>
105 constexpr auto overload(Type Class:: *member) ENTT_NOEXCEPT { return member; }
106 
107 
114 template<typename Type>
115 constexpr auto overload(Type *func) ENTT_NOEXCEPT { return func; }
116 
117 
122 template<class... Func>
123 struct overloaded: Func... {
124  using Func::operator()...;
125 };
126 
127 
132 template<class... Type>
133 overloaded(Type...) -> overloaded<Type...>;
134 
135 
140 template<class Func>
141 struct y_combinator {
146  y_combinator(Func recursive):
147  func{std::move(recursive)}
148  {}
149 
156  template <class... Args>
157  decltype(auto) operator()(Args &&... args) const {
158  return func(*this, std::forward<Args>(args)...);
159  }
160 
162  template <class... Args>
163  decltype(auto) operator()(Args &&... args) {
164  return func(*this, std::forward<Args>(args)...);
165  }
166 
167 private:
168  Func func;
169 };
170 
171 
172 }
173 
174 
175 #endif // ENTT_CORE_UTILITY_HPP
176 
177 
178 
179 namespace entt {
180 
181 
190 struct std_sort {
204  template<typename It, typename Compare = std::less<>, typename... Args>
205  void operator()(It first, It last, Compare compare = Compare{}, Args &&... args) const {
206  std::sort(std::forward<Args>(args)..., std::move(first), std::move(last), std::move(compare));
207  }
208 };
209 
210 
224  template<typename It, typename Compare = std::less<>>
225  void operator()(It first, It last, Compare compare = Compare{}) const {
226  if(first < last) {
227  for(auto it = first+1; it < last; ++it) {
228  auto value = std::move(*it);
229  auto pre = it;
230 
231  for(; pre > first && compare(value, *(pre-1)); --pre) {
232  *pre = std::move(*(pre-1));
233  }
234 
235  *pre = std::move(value);
236  }
237  }
238  }
239 };
240 
241 
247 template<std::size_t Bit, std::size_t N>
248 struct radix_sort {
249  static_assert((N % Bit) == 0);
250 
266  template<typename It, typename Getter = identity>
267  void operator()(It first, It last, Getter getter = Getter{}) const {
268  if(first < last) {
269  static constexpr auto mask = (1 << Bit) - 1;
270  static constexpr auto buckets = 1 << Bit;
271  static constexpr auto passes = N / Bit;
272 
273  using value_type = typename std::iterator_traits<It>::value_type;
274  std::vector<value_type> aux(std::distance(first, last));
275 
276  auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) {
277  std::size_t index[buckets]{};
278  std::size_t count[buckets]{};
279 
280  std::for_each(from, to, [&getter, &count, start](const value_type &item) {
281  ++count[(getter(item) >> start) & mask];
282  });
283 
284  std::for_each(std::next(std::begin(index)), std::end(index), [index = std::begin(index), count = std::begin(count)](auto &item) mutable {
285  item = *(index++) + *(count++);
286  });
287 
288  std::for_each(from, to, [&getter, &out, &index, start](value_type &item) {
289  out[index[(getter(item) >> start) & mask]++] = std::move(item);
290  });
291  };
292 
293  for(std::size_t pass = 0; pass < (passes & ~1); pass += 2) {
294  part(first, last, aux.begin(), pass * Bit);
295  part(aux.begin(), aux.end(), first, (pass + 1) * Bit);
296  }
297 
298  if constexpr(passes & 1) {
299  part(first, last, aux.begin(), (passes - 1) * Bit);
300  std::move(aux.begin(), aux.end(), first);
301  }
302  }
303  }
304 };
305 
306 
307 }
308 
309 
310 #endif // ENTT_CORE_ALGORITHM_HPP
311 
312 // #include "core/family.hpp"
313 #ifndef ENTT_CORE_FAMILY_HPP
314 #define ENTT_CORE_FAMILY_HPP
315 
316 
317 #include <type_traits>
318 // #include "../config/config.h"
319 
320 
321 
322 namespace entt {
323 
324 
332 template<typename...>
333 class family {
334  inline static ENTT_MAYBE_ATOMIC(ENTT_ID_TYPE) identifier{};
335 
336 public:
339 
341  template<typename... Type>
342  // at the time I'm writing, clang crashes during compilation if auto is used instead of family_type
343  inline static const family_type type = identifier++;
344 };
345 
346 
347 }
348 
349 
350 #endif // ENTT_CORE_FAMILY_HPP
351 
352 // #include "core/hashed_string.hpp"
353 #ifndef ENTT_CORE_HASHED_STRING_HPP
354 #define ENTT_CORE_HASHED_STRING_HPP
355 
356 
357 #include <cstddef>
358 // #include "../config/config.h"
359 
360 
361 
362 namespace entt {
363 
364 
371 namespace internal {
372 
373 
374 template<typename>
375 struct fnv1a_traits;
376 
377 
378 template<>
379 struct fnv1a_traits<std::uint32_t> {
380  static constexpr std::uint32_t offset = 2166136261;
381  static constexpr std::uint32_t prime = 16777619;
382 };
383 
384 
385 template<>
386 struct fnv1a_traits<std::uint64_t> {
387  static constexpr std::uint64_t offset = 14695981039346656037ull;
388  static constexpr std::uint64_t prime = 1099511628211ull;
389 };
390 
391 
392 }
393 
394 
412 template<typename Char>
414  using traits_type = internal::fnv1a_traits<ENTT_ID_TYPE>;
415 
416  struct const_wrapper {
417  // non-explicit constructor on purpose
418  constexpr const_wrapper(const Char *curr) ENTT_NOEXCEPT: str{curr} {}
419  const Char *str;
420  };
421 
422  // Fowler–Noll–Vo hash function v. 1a - the good
423  static constexpr ENTT_ID_TYPE helper(ENTT_ID_TYPE partial, const Char *curr) ENTT_NOEXCEPT {
424  return curr[0] == 0 ? partial : helper((partial^curr[0])*traits_type::prime, curr+1);
425  }
426 
427 public:
429  using value_type = Char;
432 
448  template<std::size_t N>
449  static constexpr hash_type to_value(const value_type (&str)[N]) ENTT_NOEXCEPT {
450  return helper(traits_type::offset, str);
451  }
452 
458  static hash_type to_value(const_wrapper wrapper) ENTT_NOEXCEPT {
459  return helper(traits_type::offset, wrapper.str);
460  }
461 
468  static hash_type to_value(const value_type *str, std::size_t size) ENTT_NOEXCEPT {
469  ENTT_ID_TYPE partial{traits_type::offset};
470  while(size--) { partial = (partial^(str++)[0])*traits_type::prime; }
471  return partial;
472  }
473 
476  : str{nullptr}, hash{}
477  {}
478 
493  template<std::size_t N>
494  constexpr basic_hashed_string(const value_type (&curr)[N]) ENTT_NOEXCEPT
495  : str{curr}, hash{helper(traits_type::offset, curr)}
496  {}
497 
503  explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
504  : str{wrapper.str}, hash{helper(traits_type::offset, wrapper.str)}
505  {}
506 
511  constexpr const value_type * data() const ENTT_NOEXCEPT {
512  return str;
513  }
514 
519  constexpr hash_type value() const ENTT_NOEXCEPT {
520  return hash;
521  }
522 
527  constexpr operator const value_type *() const ENTT_NOEXCEPT { return str; }
528 
530  constexpr operator hash_type() const ENTT_NOEXCEPT { return hash; }
531 
537  constexpr bool operator==(const basic_hashed_string &other) const ENTT_NOEXCEPT {
538  return hash == other.hash;
539  }
540 
541 private:
542  const value_type *str;
543  hash_type hash;
544 };
545 
546 
557 template<typename Char, std::size_t N>
558 basic_hashed_string(const Char (&str)[N]) ENTT_NOEXCEPT
559 -> basic_hashed_string<Char>;
560 
561 
569 template<typename Char>
571  return !(lhs == rhs);
572 }
573 
574 
577 
578 
581 
582 
583 }
584 
585 
591 constexpr entt::hashed_string operator"" ENTT_HS_SUFFIX(const char *str, std::size_t) ENTT_NOEXCEPT {
592  return entt::hashed_string{str};
593 }
594 
595 
601 constexpr entt::hashed_wstring operator"" ENTT_HWS_SUFFIX(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
602  return entt::hashed_wstring{str};
603 }
604 
605 
606 #endif // ENTT_CORE_HASHED_STRING_HPP
607 
608 // #include "core/ident.hpp"
609 #ifndef ENTT_CORE_IDENT_HPP
610 #define ENTT_CORE_IDENT_HPP
611 
612 
613 #include <tuple>
614 #include <utility>
615 #include <type_traits>
616 // #include "../config/config.h"
617 
618 
619 
620 namespace entt {
621 
622 
650 template<typename... Types>
651 class identifier {
652  using tuple_type = std::tuple<std::decay_t<Types>...>;
653 
654  template<typename Type, std::size_t... Indexes>
655  static constexpr ENTT_ID_TYPE get(std::index_sequence<Indexes...>) ENTT_NOEXCEPT {
656  static_assert(std::disjunction_v<std::is_same<Type, Types>...>);
657  return (0 + ... + (std::is_same_v<Type, std::tuple_element_t<Indexes, tuple_type>> ? ENTT_ID_TYPE(Indexes) : ENTT_ID_TYPE{}));
658  }
659 
660 public:
663 
665  template<typename Type>
666  static constexpr identifier_type type = get<std::decay_t<Type>>(std::index_sequence_for<Types...>{});
667 };
668 
669 
670 }
671 
672 
673 #endif // ENTT_CORE_IDENT_HPP
674 
675 // #include "core/monostate.hpp"
676 #ifndef ENTT_CORE_MONOSTATE_HPP
677 #define ENTT_CORE_MONOSTATE_HPP
678 
679 
680 #include <cassert>
681 // #include "../config/config.h"
682 
683 
684 
685 namespace entt {
686 
687 
699 template<ENTT_ID_TYPE>
700 struct monostate {
706  template<typename Type>
707  void operator=(Type val) const ENTT_NOEXCEPT {
708  value<Type> = val;
709  }
710 
716  template<typename Type>
717  operator Type() const ENTT_NOEXCEPT {
718  return value<Type>;
719  }
720 
721 private:
722  template<typename Type>
723  inline static ENTT_MAYBE_ATOMIC(Type) value{};
724 };
725 
726 
731 template<ENTT_ID_TYPE Value>
733 
734 
735 }
736 
737 
738 #endif // ENTT_CORE_MONOSTATE_HPP
739 
740 // #include "core/type_traits.hpp"
741 #ifndef ENTT_CORE_TYPE_TRAITS_HPP
742 #define ENTT_CORE_TYPE_TRAITS_HPP
743 
744 
745 #include <cstddef>
746 #include <type_traits>
747 // #include "../config/config.h"
748 
749 // #include "../core/hashed_string.hpp"
750 #ifndef ENTT_CORE_HASHED_STRING_HPP
751 #define ENTT_CORE_HASHED_STRING_HPP
752 
753 
754 #include <cstddef>
755 // #include "../config/config.h"
756 #ifndef ENTT_CONFIG_CONFIG_H
757 #define ENTT_CONFIG_CONFIG_H
758 
759 
760 #ifndef ENTT_NOEXCEPT
761 #define ENTT_NOEXCEPT noexcept
762 #endif // ENTT_NOEXCEPT
763 
764 
765 #ifndef ENTT_HS_SUFFIX
766 #define ENTT_HS_SUFFIX _hs
767 #endif // ENTT_HS_SUFFIX
768 
769 
770 #ifndef ENTT_HWS_SUFFIX
771 #define ENTT_HWS_SUFFIX _hws
772 #endif // ENTT_HWS_SUFFIX
773 
774 
775 #ifndef ENTT_NO_ATOMIC
776 #include <atomic>
777 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
778 #else // ENTT_NO_ATOMIC
779 #define ENTT_MAYBE_ATOMIC(Type) Type
780 #endif // ENTT_NO_ATOMIC
781 
782 
783 #ifndef ENTT_DISABLE_ETO
784 #include <type_traits>
785 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
786 #else // ENTT_DISABLE_ETO
787 // sfinae-friendly definition
788 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
789 #endif // ENTT_DISABLE_ETO
790 
791 
792 #ifndef ENTT_ID_TYPE
793 #include <cstdint>
794 #define ENTT_ID_TYPE std::uint32_t
795 #endif // ENTT_ID_TYPE
796 
797 
798 #ifndef ENTT_PAGE_SIZE
799 #define ENTT_PAGE_SIZE 32768
800 #endif // ENTT_PAGE_SIZE
801 
802 
803 #ifndef ENTT_DISABLE_ASSERT
804 #include <cassert>
805 #define ENTT_ASSERT(condition) assert(condition)
806 #else // ENTT_DISABLE_ASSERT
807 #define ENTT_ASSERT(...) ((void)0)
808 #endif // ENTT_DISABLE_ASSERT
809 
810 
811 #endif // ENTT_CONFIG_CONFIG_H
812 
813 
814 
815 namespace entt {
816 
817 
824 namespace internal {
825 
826 
827 template<typename>
828 struct fnv1a_traits;
829 
830 
831 template<>
832 struct fnv1a_traits<std::uint32_t> {
833  static constexpr std::uint32_t offset = 2166136261;
834  static constexpr std::uint32_t prime = 16777619;
835 };
836 
837 
838 template<>
839 struct fnv1a_traits<std::uint64_t> {
840  static constexpr std::uint64_t offset = 14695981039346656037ull;
841  static constexpr std::uint64_t prime = 1099511628211ull;
842 };
843 
844 
845 }
846 
847 
865 template<typename Char>
866 class basic_hashed_string {
867  using traits_type = internal::fnv1a_traits<ENTT_ID_TYPE>;
868 
869  struct const_wrapper {
870  // non-explicit constructor on purpose
871  constexpr const_wrapper(const Char *curr) ENTT_NOEXCEPT: str{curr} {}
872  const Char *str;
873  };
874 
875  // Fowler–Noll–Vo hash function v. 1a - the good
876  static constexpr ENTT_ID_TYPE helper(ENTT_ID_TYPE partial, const Char *curr) ENTT_NOEXCEPT {
877  return curr[0] == 0 ? partial : helper((partial^curr[0])*traits_type::prime, curr+1);
878  }
879 
880 public:
882  using value_type = Char;
884  using hash_type = ENTT_ID_TYPE;
885 
901  template<std::size_t N>
902  static constexpr hash_type to_value(const value_type (&str)[N]) ENTT_NOEXCEPT {
903  return helper(traits_type::offset, str);
904  }
905 
911  static hash_type to_value(const_wrapper wrapper) ENTT_NOEXCEPT {
912  return helper(traits_type::offset, wrapper.str);
913  }
914 
921  static hash_type to_value(const value_type *str, std::size_t size) ENTT_NOEXCEPT {
922  ENTT_ID_TYPE partial{traits_type::offset};
923  while(size--) { partial = (partial^(str++)[0])*traits_type::prime; }
924  return partial;
925  }
926 
929  : str{nullptr}, hash{}
930  {}
931 
946  template<std::size_t N>
947  constexpr basic_hashed_string(const value_type (&curr)[N]) ENTT_NOEXCEPT
948  : str{curr}, hash{helper(traits_type::offset, curr)}
949  {}
950 
956  explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
957  : str{wrapper.str}, hash{helper(traits_type::offset, wrapper.str)}
958  {}
959 
964  constexpr const value_type * data() const ENTT_NOEXCEPT {
965  return str;
966  }
967 
972  constexpr hash_type value() const ENTT_NOEXCEPT {
973  return hash;
974  }
975 
980  constexpr operator const value_type *() const ENTT_NOEXCEPT { return str; }
981 
983  constexpr operator hash_type() const ENTT_NOEXCEPT { return hash; }
984 
990  constexpr bool operator==(const basic_hashed_string &other) const ENTT_NOEXCEPT {
991  return hash == other.hash;
992  }
993 
994 private:
995  const value_type *str;
996  hash_type hash;
997 };
998 
999 
1010 template<typename Char, std::size_t N>
1011 basic_hashed_string(const Char (&str)[N]) ENTT_NOEXCEPT
1012 -> basic_hashed_string<Char>;
1013 
1014 
1022 template<typename Char>
1023 constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
1024  return !(lhs == rhs);
1025 }
1026 
1027 
1029 using hashed_string = basic_hashed_string<char>;
1030 
1031 
1033 using hashed_wstring = basic_hashed_string<wchar_t>;
1034 
1035 
1036 }
1037 
1038 
1044 constexpr entt::hashed_string operator"" ENTT_HS_SUFFIX(const char *str, std::size_t) ENTT_NOEXCEPT {
1045  return entt::hashed_string{str};
1046 }
1047 
1048 
1054 constexpr entt::hashed_wstring operator"" ENTT_HWS_SUFFIX(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
1055  return entt::hashed_wstring{str};
1056 }
1057 
1058 
1059 #endif // ENTT_CORE_HASHED_STRING_HPP
1060 
1061 
1062 
1063 namespace entt {
1064 
1065 
1070 template<std::size_t N>
1071 struct choice_t
1072  // Unfortunately, doxygen cannot parse such a construct.
1074  : choice_t<N-1>
1076 {};
1077 
1078 
1080 template<>
1081 struct choice_t<0> {};
1082 
1083 
1088 template<std::size_t N>
1089 constexpr choice_t<N> choice{};
1090 
1091 
1093 template<typename...>
1094 struct type_list {};
1095 
1096 
1098 template<typename>
1100 
1101 
1106 template<typename... Type>
1107 struct type_list_size<type_list<Type...>>
1108  : std::integral_constant<std::size_t, sizeof...(Type)>
1109 {};
1110 
1111 
1116 template<class List>
1118 
1119 
1121 template<typename...>
1123 
1124 
1126 template<>
1130 };
1131 
1132 
1139 template<typename... Type, typename... Other, typename... List>
1140 struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
1142  using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
1143 };
1144 
1145 
1150 template<typename... Type>
1151 struct type_list_cat<type_list<Type...>> {
1153  using type = type_list<Type...>;
1154 };
1155 
1156 
1161 template<typename... List>
1162 using type_list_cat_t = typename type_list_cat<List...>::type;
1163 
1164 
1166 template<typename>
1168 
1169 
1175 template<typename Type, typename... Other>
1176 struct type_list_unique<type_list<Type, Other...>> {
1178  using type = std::conditional_t<
1179  std::disjunction_v<std::is_same<Type, Other>...>,
1180  typename type_list_unique<type_list<Other...>>::type,
1182  >;
1183 };
1184 
1185 
1187 template<>
1191 };
1192 
1193 
1198 template<typename Type>
1200 
1201 
1207 template<typename Type, typename = std::void_t<>>
1208 struct is_equality_comparable: std::false_type {};
1209 
1210 
1212 template<typename Type>
1213 struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>: std::true_type {};
1214 
1215 
1220 template<class Type>
1222 
1223 
1225 template<typename>
1227 
1228 
1233 template<typename Type>
1234 struct named_type_traits<const Type>
1235  : named_type_traits<Type>
1236 {};
1237 
1238 
1243 template<typename Type>
1245 
1246 
1251 template<class Type>
1253 
1254 
1260 template<typename Type, typename = std::void_t<>>
1261 struct is_named_type: std::false_type {};
1262 
1263 
1265 template<typename Type>
1266 struct is_named_type<Type, std::void_t<named_type_traits_t<std::decay_t<Type>>>>: std::true_type {};
1267 
1268 
1273 template<class Type>
1275 
1276 
1283 #define ENTT_OPAQUE_TYPE(clazz, type)\
1284  enum class clazz: type {};\
1285  constexpr auto to_integer(const clazz id) ENTT_NOEXCEPT {\
1286  return std::underlying_type_t<clazz>(id);\
1287  }\
1288  static_assert(true)
1289 
1290 
1291 }
1292 
1293 
1301 #define ENTT_EXPAND(args) args
1302 
1303 
1321 #define ENTT_NAMED_TYPE(type)\
1322  template<>\
1323  struct entt::named_type_traits<type>\
1324  : std::integral_constant<ENTT_ID_TYPE, entt::basic_hashed_string<std::remove_cv_t<std::remove_pointer_t<std::decay_t<decltype(#type)>>>>{#type}>\
1325  {\
1326  static_assert(std::is_same_v<std::remove_cv_t<type>, type>);\
1327  static_assert(std::is_object_v<type>);\
1328  }
1329 
1330 
1336 #define ENTT_NAMED_STRUCT_ONLY(clazz, body)\
1337  struct clazz body;\
1338  ENTT_NAMED_TYPE(clazz)
1339 
1340 
1347 #define ENTT_NAMED_STRUCT_WITH_NAMESPACE(ns, clazz, body)\
1348  namespace ns { struct clazz body; }\
1349  ENTT_NAMED_TYPE(ns::clazz)
1350 
1351 
1353 #define ENTT_NAMED_STRUCT_OVERLOAD(_1, _2, _3, FUNC, ...) FUNC
1354 
1355 #define ENTT_NAMED_STRUCT(...) ENTT_EXPAND(ENTT_NAMED_STRUCT_OVERLOAD(__VA_ARGS__, ENTT_NAMED_STRUCT_WITH_NAMESPACE, ENTT_NAMED_STRUCT_ONLY,)(__VA_ARGS__))
1356 
1357 
1363 #define ENTT_NAMED_CLASS_ONLY(clazz, body)\
1364  class clazz body;\
1365  ENTT_NAMED_TYPE(clazz)
1366 
1367 
1374 #define ENTT_NAMED_CLASS_WITH_NAMESPACE(ns, clazz, body)\
1375  namespace ns { class clazz body; }\
1376  ENTT_NAMED_TYPE(ns::clazz)
1377 
1378 
1380 #define ENTT_NAMED_CLASS_MACRO(_1, _2, _3, FUNC, ...) FUNC
1381 
1382 #define ENTT_NAMED_CLASS(...) ENTT_EXPAND(ENTT_NAMED_CLASS_MACRO(__VA_ARGS__, ENTT_NAMED_CLASS_WITH_NAMESPACE, ENTT_NAMED_CLASS_ONLY,)(__VA_ARGS__))
1383 
1384 
1385 #endif // ENTT_CORE_TYPE_TRAITS_HPP
1386 
1387 // #include "core/utility.hpp"
1388 
1389 // #include "entity/actor.hpp"
1390 #ifndef ENTT_ENTITY_ACTOR_HPP
1391 #define ENTT_ENTITY_ACTOR_HPP
1392 
1393 
1394 #include <cassert>
1395 #include <utility>
1396 #include <type_traits>
1397 // #include "../config/config.h"
1398 #ifndef ENTT_CONFIG_CONFIG_H
1399 #define ENTT_CONFIG_CONFIG_H
1400 
1401 
1402 #ifndef ENTT_NOEXCEPT
1403 #define ENTT_NOEXCEPT noexcept
1404 #endif // ENTT_NOEXCEPT
1405 
1406 
1407 #ifndef ENTT_HS_SUFFIX
1408 #define ENTT_HS_SUFFIX _hs
1409 #endif // ENTT_HS_SUFFIX
1410 
1411 
1412 #ifndef ENTT_HWS_SUFFIX
1413 #define ENTT_HWS_SUFFIX _hws
1414 #endif // ENTT_HWS_SUFFIX
1415 
1416 
1417 #ifndef ENTT_NO_ATOMIC
1418 #include <atomic>
1419 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
1420 #else // ENTT_NO_ATOMIC
1421 #define ENTT_MAYBE_ATOMIC(Type) Type
1422 #endif // ENTT_NO_ATOMIC
1423 
1424 
1425 #ifndef ENTT_DISABLE_ETO
1426 #include <type_traits>
1427 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
1428 #else // ENTT_DISABLE_ETO
1429 // sfinae-friendly definition
1430 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
1431 #endif // ENTT_DISABLE_ETO
1432 
1433 
1434 #ifndef ENTT_ID_TYPE
1435 #include <cstdint>
1436 #define ENTT_ID_TYPE std::uint32_t
1437 #endif // ENTT_ID_TYPE
1438 
1439 
1440 #ifndef ENTT_PAGE_SIZE
1441 #define ENTT_PAGE_SIZE 32768
1442 #endif // ENTT_PAGE_SIZE
1443 
1444 
1445 #ifndef ENTT_DISABLE_ASSERT
1446 #include <cassert>
1447 #define ENTT_ASSERT(condition) assert(condition)
1448 #else // ENTT_DISABLE_ASSERT
1449 #define ENTT_ASSERT(...) ((void)0)
1450 #endif // ENTT_DISABLE_ASSERT
1451 
1452 
1453 #endif // ENTT_CONFIG_CONFIG_H
1454 
1455 // #include "registry.hpp"
1456 #ifndef ENTT_ENTITY_REGISTRY_HPP
1457 #define ENTT_ENTITY_REGISTRY_HPP
1458 
1459 
1460 #include <tuple>
1461 #include <vector>
1462 #include <memory>
1463 #include <utility>
1464 #include <cstddef>
1465 #include <iterator>
1466 #include <algorithm>
1467 #include <type_traits>
1468 // #include "../config/config.h"
1469 
1470 // #include "../core/family.hpp"
1471 #ifndef ENTT_CORE_FAMILY_HPP
1472 #define ENTT_CORE_FAMILY_HPP
1473 
1474 
1475 #include <type_traits>
1476 // #include "../config/config.h"
1477 #ifndef ENTT_CONFIG_CONFIG_H
1478 #define ENTT_CONFIG_CONFIG_H
1479 
1480 
1481 #ifndef ENTT_NOEXCEPT
1482 #define ENTT_NOEXCEPT noexcept
1483 #endif // ENTT_NOEXCEPT
1484 
1485 
1486 #ifndef ENTT_HS_SUFFIX
1487 #define ENTT_HS_SUFFIX _hs
1488 #endif // ENTT_HS_SUFFIX
1489 
1490 
1491 #ifndef ENTT_HWS_SUFFIX
1492 #define ENTT_HWS_SUFFIX _hws
1493 #endif // ENTT_HWS_SUFFIX
1494 
1495 
1496 #ifndef ENTT_NO_ATOMIC
1497 #include <atomic>
1498 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
1499 #else // ENTT_NO_ATOMIC
1500 #define ENTT_MAYBE_ATOMIC(Type) Type
1501 #endif // ENTT_NO_ATOMIC
1502 
1503 
1504 #ifndef ENTT_DISABLE_ETO
1505 #include <type_traits>
1506 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
1507 #else // ENTT_DISABLE_ETO
1508 // sfinae-friendly definition
1509 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
1510 #endif // ENTT_DISABLE_ETO
1511 
1512 
1513 #ifndef ENTT_ID_TYPE
1514 #include <cstdint>
1515 #define ENTT_ID_TYPE std::uint32_t
1516 #endif // ENTT_ID_TYPE
1517 
1518 
1519 #ifndef ENTT_PAGE_SIZE
1520 #define ENTT_PAGE_SIZE 32768
1521 #endif // ENTT_PAGE_SIZE
1522 
1523 
1524 #ifndef ENTT_DISABLE_ASSERT
1525 #include <cassert>
1526 #define ENTT_ASSERT(condition) assert(condition)
1527 #else // ENTT_DISABLE_ASSERT
1528 #define ENTT_ASSERT(...) ((void)0)
1529 #endif // ENTT_DISABLE_ASSERT
1530 
1531 
1532 #endif // ENTT_CONFIG_CONFIG_H
1533 
1534 
1535 
1536 namespace entt {
1537 
1538 
1546 template<typename...>
1547 class family {
1548  inline static ENTT_MAYBE_ATOMIC(ENTT_ID_TYPE) identifier{};
1549 
1550 public:
1552  using family_type = ENTT_ID_TYPE;
1553 
1555  template<typename... Type>
1556  // at the time I'm writing, clang crashes during compilation if auto is used instead of family_type
1557  inline static const family_type type = identifier++;
1558 };
1559 
1560 
1561 }
1562 
1563 
1564 #endif // ENTT_CORE_FAMILY_HPP
1565 
1566 // #include "../core/algorithm.hpp"
1567 #ifndef ENTT_CORE_ALGORITHM_HPP
1568 #define ENTT_CORE_ALGORITHM_HPP
1569 
1570 
1571 #include <utility>
1572 #include <iterator>
1573 #include <algorithm>
1574 #include <functional>
1575 // #include "utility.hpp"
1576 #ifndef ENTT_CORE_UTILITY_HPP
1577 #define ENTT_CORE_UTILITY_HPP
1578 
1579 
1580 // #include "../config/config.h"
1581 
1582 
1583 
1584 namespace entt {
1585 
1586 
1588 struct identity {
1595  template<class Type>
1596  constexpr Type && operator()(Type &&value) const ENTT_NOEXCEPT {
1597  return std::forward<Type>(value);
1598  }
1599 };
1600 
1601 
1609 template<typename Type, typename Class>
1610 constexpr auto overload(Type Class:: *member) ENTT_NOEXCEPT { return member; }
1611 
1612 
1619 template<typename Type>
1620 constexpr auto overload(Type *func) ENTT_NOEXCEPT { return func; }
1621 
1622 
1627 template<class... Func>
1628 struct overloaded: Func... {
1629  using Func::operator()...;
1630 };
1631 
1632 
1637 template<class... Type>
1638 overloaded(Type...) -> overloaded<Type...>;
1639 
1640 
1645 template<class Func>
1646 struct y_combinator {
1651  y_combinator(Func recursive):
1652  func{std::move(recursive)}
1653  {}
1654 
1661  template <class... Args>
1662  decltype(auto) operator()(Args &&... args) const {
1663  return func(*this, std::forward<Args>(args)...);
1664  }
1665 
1667  template <class... Args>
1668  decltype(auto) operator()(Args &&... args) {
1669  return func(*this, std::forward<Args>(args)...);
1670  }
1671 
1672 private:
1673  Func func;
1674 };
1675 
1676 
1677 }
1678 
1679 
1680 #endif // ENTT_CORE_UTILITY_HPP
1681 
1682 
1683 
1684 namespace entt {
1685 
1686 
1695 struct std_sort {
1709  template<typename It, typename Compare = std::less<>, typename... Args>
1710  void operator()(It first, It last, Compare compare = Compare{}, Args &&... args) const {
1711  std::sort(std::forward<Args>(args)..., std::move(first), std::move(last), std::move(compare));
1712  }
1713 };
1714 
1715 
1717 struct insertion_sort {
1729  template<typename It, typename Compare = std::less<>>
1730  void operator()(It first, It last, Compare compare = Compare{}) const {
1731  if(first < last) {
1732  for(auto it = first+1; it < last; ++it) {
1733  auto value = std::move(*it);
1734  auto pre = it;
1735 
1736  for(; pre > first && compare(value, *(pre-1)); --pre) {
1737  *pre = std::move(*(pre-1));
1738  }
1739 
1740  *pre = std::move(value);
1741  }
1742  }
1743  }
1744 };
1745 
1746 
1752 template<std::size_t Bit, std::size_t N>
1753 struct radix_sort {
1754  static_assert((N % Bit) == 0);
1755 
1771  template<typename It, typename Getter = identity>
1772  void operator()(It first, It last, Getter getter = Getter{}) const {
1773  if(first < last) {
1774  static constexpr auto mask = (1 << Bit) - 1;
1775  static constexpr auto buckets = 1 << Bit;
1776  static constexpr auto passes = N / Bit;
1777 
1778  using value_type = typename std::iterator_traits<It>::value_type;
1779  std::vector<value_type> aux(std::distance(first, last));
1780 
1781  auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) {
1782  std::size_t index[buckets]{};
1783  std::size_t count[buckets]{};
1784 
1785  std::for_each(from, to, [&getter, &count, start](const value_type &item) {
1786  ++count[(getter(item) >> start) & mask];
1787  });
1788 
1789  std::for_each(std::next(std::begin(index)), std::end(index), [index = std::begin(index), count = std::begin(count)](auto &item) mutable {
1790  item = *(index++) + *(count++);
1791  });
1792 
1793  std::for_each(from, to, [&getter, &out, &index, start](value_type &item) {
1794  out[index[(getter(item) >> start) & mask]++] = std::move(item);
1795  });
1796  };
1797 
1798  for(std::size_t pass = 0; pass < (passes & ~1); pass += 2) {
1799  part(first, last, aux.begin(), pass * Bit);
1800  part(aux.begin(), aux.end(), first, (pass + 1) * Bit);
1801  }
1802 
1803  if constexpr(passes & 1) {
1804  part(first, last, aux.begin(), (passes - 1) * Bit);
1805  std::move(aux.begin(), aux.end(), first);
1806  }
1807  }
1808  }
1809 };
1810 
1811 
1812 }
1813 
1814 
1815 #endif // ENTT_CORE_ALGORITHM_HPP
1816 
1817 // #include "../core/type_traits.hpp"
1818 #ifndef ENTT_CORE_TYPE_TRAITS_HPP
1819 #define ENTT_CORE_TYPE_TRAITS_HPP
1820 
1821 
1822 #include <cstddef>
1823 #include <type_traits>
1824 // #include "../config/config.h"
1825 
1826 // #include "../core/hashed_string.hpp"
1827 #ifndef ENTT_CORE_HASHED_STRING_HPP
1828 #define ENTT_CORE_HASHED_STRING_HPP
1829 
1830 
1831 #include <cstddef>
1832 // #include "../config/config.h"
1833 #ifndef ENTT_CONFIG_CONFIG_H
1834 #define ENTT_CONFIG_CONFIG_H
1835 
1836 
1837 #ifndef ENTT_NOEXCEPT
1838 #define ENTT_NOEXCEPT noexcept
1839 #endif // ENTT_NOEXCEPT
1840 
1841 
1842 #ifndef ENTT_HS_SUFFIX
1843 #define ENTT_HS_SUFFIX _hs
1844 #endif // ENTT_HS_SUFFIX
1845 
1846 
1847 #ifndef ENTT_HWS_SUFFIX
1848 #define ENTT_HWS_SUFFIX _hws
1849 #endif // ENTT_HWS_SUFFIX
1850 
1851 
1852 #ifndef ENTT_NO_ATOMIC
1853 #include <atomic>
1854 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
1855 #else // ENTT_NO_ATOMIC
1856 #define ENTT_MAYBE_ATOMIC(Type) Type
1857 #endif // ENTT_NO_ATOMIC
1858 
1859 
1860 #ifndef ENTT_DISABLE_ETO
1861 #include <type_traits>
1862 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
1863 #else // ENTT_DISABLE_ETO
1864 // sfinae-friendly definition
1865 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
1866 #endif // ENTT_DISABLE_ETO
1867 
1868 
1869 #ifndef ENTT_ID_TYPE
1870 #include <cstdint>
1871 #define ENTT_ID_TYPE std::uint32_t
1872 #endif // ENTT_ID_TYPE
1873 
1874 
1875 #ifndef ENTT_PAGE_SIZE
1876 #define ENTT_PAGE_SIZE 32768
1877 #endif // ENTT_PAGE_SIZE
1878 
1879 
1880 #ifndef ENTT_DISABLE_ASSERT
1881 #include <cassert>
1882 #define ENTT_ASSERT(condition) assert(condition)
1883 #else // ENTT_DISABLE_ASSERT
1884 #define ENTT_ASSERT(...) ((void)0)
1885 #endif // ENTT_DISABLE_ASSERT
1886 
1887 
1888 #endif // ENTT_CONFIG_CONFIG_H
1889 
1890 
1891 
1892 namespace entt {
1893 
1894 
1901 namespace internal {
1902 
1903 
1904 template<typename>
1905 struct fnv1a_traits;
1906 
1907 
1908 template<>
1909 struct fnv1a_traits<std::uint32_t> {
1910  static constexpr std::uint32_t offset = 2166136261;
1911  static constexpr std::uint32_t prime = 16777619;
1912 };
1913 
1914 
1915 template<>
1916 struct fnv1a_traits<std::uint64_t> {
1917  static constexpr std::uint64_t offset = 14695981039346656037ull;
1918  static constexpr std::uint64_t prime = 1099511628211ull;
1919 };
1920 
1921 
1922 }
1923 
1924 
1942 template<typename Char>
1943 class basic_hashed_string {
1944  using traits_type = internal::fnv1a_traits<ENTT_ID_TYPE>;
1945 
1946  struct const_wrapper {
1947  // non-explicit constructor on purpose
1948  constexpr const_wrapper(const Char *curr) ENTT_NOEXCEPT: str{curr} {}
1949  const Char *str;
1950  };
1951 
1952  // Fowler–Noll–Vo hash function v. 1a - the good
1953  static constexpr ENTT_ID_TYPE helper(ENTT_ID_TYPE partial, const Char *curr) ENTT_NOEXCEPT {
1954  return curr[0] == 0 ? partial : helper((partial^curr[0])*traits_type::prime, curr+1);
1955  }
1956 
1957 public:
1959  using value_type = Char;
1961  using hash_type = ENTT_ID_TYPE;
1962 
1978  template<std::size_t N>
1979  static constexpr hash_type to_value(const value_type (&str)[N]) ENTT_NOEXCEPT {
1980  return helper(traits_type::offset, str);
1981  }
1982 
1988  static hash_type to_value(const_wrapper wrapper) ENTT_NOEXCEPT {
1989  return helper(traits_type::offset, wrapper.str);
1990  }
1991 
1998  static hash_type to_value(const value_type *str, std::size_t size) ENTT_NOEXCEPT {
1999  ENTT_ID_TYPE partial{traits_type::offset};
2000  while(size--) { partial = (partial^(str++)[0])*traits_type::prime; }
2001  return partial;
2002  }
2003 
2006  : str{nullptr}, hash{}
2007  {}
2008 
2023  template<std::size_t N>
2024  constexpr basic_hashed_string(const value_type (&curr)[N]) ENTT_NOEXCEPT
2025  : str{curr}, hash{helper(traits_type::offset, curr)}
2026  {}
2027 
2033  explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
2034  : str{wrapper.str}, hash{helper(traits_type::offset, wrapper.str)}
2035  {}
2036 
2041  constexpr const value_type * data() const ENTT_NOEXCEPT {
2042  return str;
2043  }
2044 
2049  constexpr hash_type value() const ENTT_NOEXCEPT {
2050  return hash;
2051  }
2052 
2057  constexpr operator const value_type *() const ENTT_NOEXCEPT { return str; }
2058 
2060  constexpr operator hash_type() const ENTT_NOEXCEPT { return hash; }
2061 
2067  constexpr bool operator==(const basic_hashed_string &other) const ENTT_NOEXCEPT {
2068  return hash == other.hash;
2069  }
2070 
2071 private:
2072  const value_type *str;
2073  hash_type hash;
2074 };
2075 
2076 
2087 template<typename Char, std::size_t N>
2088 basic_hashed_string(const Char (&str)[N]) ENTT_NOEXCEPT
2089 -> basic_hashed_string<Char>;
2090 
2091 
2099 template<typename Char>
2100 constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
2101  return !(lhs == rhs);
2102 }
2103 
2104 
2106 using hashed_string = basic_hashed_string<char>;
2107 
2108 
2110 using hashed_wstring = basic_hashed_string<wchar_t>;
2111 
2112 
2113 }
2114 
2115 
2121 constexpr entt::hashed_string operator"" ENTT_HS_SUFFIX(const char *str, std::size_t) ENTT_NOEXCEPT {
2122  return entt::hashed_string{str};
2123 }
2124 
2125 
2131 constexpr entt::hashed_wstring operator"" ENTT_HWS_SUFFIX(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
2132  return entt::hashed_wstring{str};
2133 }
2134 
2135 
2136 #endif // ENTT_CORE_HASHED_STRING_HPP
2137 
2138 
2139 
2140 namespace entt {
2141 
2142 
2147 template<std::size_t N>
2148 struct choice_t
2149  // Unfortunately, doxygen cannot parse such a construct.
2151  : choice_t<N-1>
2153 {};
2154 
2155 
2157 template<>
2158 struct choice_t<0> {};
2159 
2160 
2165 template<std::size_t N>
2166 constexpr choice_t<N> choice{};
2167 
2168 
2170 template<typename...>
2171 struct type_list {};
2172 
2173 
2175 template<typename>
2176 struct type_list_size;
2177 
2178 
2183 template<typename... Type>
2184 struct type_list_size<type_list<Type...>>
2185  : std::integral_constant<std::size_t, sizeof...(Type)>
2186 {};
2187 
2188 
2193 template<class List>
2194 constexpr auto type_list_size_v = type_list_size<List>::value;
2195 
2196 
2198 template<typename...>
2199 struct type_list_cat;
2200 
2201 
2203 template<>
2204 struct type_list_cat<> {
2206  using type = type_list<>;
2207 };
2208 
2209 
2216 template<typename... Type, typename... Other, typename... List>
2217 struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
2219  using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
2220 };
2221 
2222 
2227 template<typename... Type>
2228 struct type_list_cat<type_list<Type...>> {
2230  using type = type_list<Type...>;
2231 };
2232 
2233 
2238 template<typename... List>
2239 using type_list_cat_t = typename type_list_cat<List...>::type;
2240 
2241 
2243 template<typename>
2244 struct type_list_unique;
2245 
2246 
2252 template<typename Type, typename... Other>
2253 struct type_list_unique<type_list<Type, Other...>> {
2255  using type = std::conditional_t<
2256  std::disjunction_v<std::is_same<Type, Other>...>,
2257  typename type_list_unique<type_list<Other...>>::type,
2258  type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>
2259  >;
2260 };
2261 
2262 
2264 template<>
2265 struct type_list_unique<type_list<>> {
2267  using type = type_list<>;
2268 };
2269 
2270 
2275 template<typename Type>
2276 using type_list_unique_t = typename type_list_unique<Type>::type;
2277 
2278 
2284 template<typename Type, typename = std::void_t<>>
2285 struct is_equality_comparable: std::false_type {};
2286 
2287 
2289 template<typename Type>
2290 struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>: std::true_type {};
2291 
2292 
2297 template<class Type>
2298 constexpr auto is_equality_comparable_v = is_equality_comparable<Type>::value;
2299 
2300 
2302 template<typename>
2303 struct named_type_traits;
2304 
2305 
2310 template<typename Type>
2311 struct named_type_traits<const Type>
2312  : named_type_traits<Type>
2313 {};
2314 
2315 
2320 template<typename Type>
2321 using named_type_traits_t = typename named_type_traits<Type>::type;
2322 
2323 
2328 template<class Type>
2329 constexpr auto named_type_traits_v = named_type_traits<Type>::value;
2330 
2331 
2337 template<typename Type, typename = std::void_t<>>
2338 struct is_named_type: std::false_type {};
2339 
2340 
2342 template<typename Type>
2343 struct is_named_type<Type, std::void_t<named_type_traits_t<std::decay_t<Type>>>>: std::true_type {};
2344 
2345 
2350 template<class Type>
2351 constexpr auto is_named_type_v = is_named_type<Type>::value;
2352 
2353 
2360 #define ENTT_OPAQUE_TYPE(clazz, type)\
2361  enum class clazz: type {};\
2362  constexpr auto to_integer(const clazz id) ENTT_NOEXCEPT {\
2363  return std::underlying_type_t<clazz>(id);\
2364  }\
2365  static_assert(true)
2366 
2367 
2368 }
2369 
2370 
2378 #define ENTT_EXPAND(args) args
2379 
2380 
2398 #define ENTT_NAMED_TYPE(type)\
2399  template<>\
2400  struct entt::named_type_traits<type>\
2401  : std::integral_constant<ENTT_ID_TYPE, entt::basic_hashed_string<std::remove_cv_t<std::remove_pointer_t<std::decay_t<decltype(#type)>>>>{#type}>\
2402  {\
2403  static_assert(std::is_same_v<std::remove_cv_t<type>, type>);\
2404  static_assert(std::is_object_v<type>);\
2405  }
2406 
2407 
2413 #define ENTT_NAMED_STRUCT_ONLY(clazz, body)\
2414  struct clazz body;\
2415  ENTT_NAMED_TYPE(clazz)
2416 
2417 
2424 #define ENTT_NAMED_STRUCT_WITH_NAMESPACE(ns, clazz, body)\
2425  namespace ns { struct clazz body; }\
2426  ENTT_NAMED_TYPE(ns::clazz)
2427 
2428 
2430 #define ENTT_NAMED_STRUCT_OVERLOAD(_1, _2, _3, FUNC, ...) FUNC
2431 
2432 #define ENTT_NAMED_STRUCT(...) ENTT_EXPAND(ENTT_NAMED_STRUCT_OVERLOAD(__VA_ARGS__, ENTT_NAMED_STRUCT_WITH_NAMESPACE, ENTT_NAMED_STRUCT_ONLY,)(__VA_ARGS__))
2433 
2434 
2440 #define ENTT_NAMED_CLASS_ONLY(clazz, body)\
2441  class clazz body;\
2442  ENTT_NAMED_TYPE(clazz)
2443 
2444 
2451 #define ENTT_NAMED_CLASS_WITH_NAMESPACE(ns, clazz, body)\
2452  namespace ns { class clazz body; }\
2453  ENTT_NAMED_TYPE(ns::clazz)
2454 
2455 
2457 #define ENTT_NAMED_CLASS_MACRO(_1, _2, _3, FUNC, ...) FUNC
2458 
2459 #define ENTT_NAMED_CLASS(...) ENTT_EXPAND(ENTT_NAMED_CLASS_MACRO(__VA_ARGS__, ENTT_NAMED_CLASS_WITH_NAMESPACE, ENTT_NAMED_CLASS_ONLY,)(__VA_ARGS__))
2460 
2461 
2462 #endif // ENTT_CORE_TYPE_TRAITS_HPP
2463 
2464 // #include "../signal/delegate.hpp"
2465 #ifndef ENTT_SIGNAL_DELEGATE_HPP
2466 #define ENTT_SIGNAL_DELEGATE_HPP
2467 
2468 
2469 #include <tuple>
2470 #include <cstring>
2471 #include <utility>
2472 #include <algorithm>
2473 #include <functional>
2474 #include <type_traits>
2475 // #include "../config/config.h"
2476 #ifndef ENTT_CONFIG_CONFIG_H
2477 #define ENTT_CONFIG_CONFIG_H
2478 
2479 
2480 #ifndef ENTT_NOEXCEPT
2481 #define ENTT_NOEXCEPT noexcept
2482 #endif // ENTT_NOEXCEPT
2483 
2484 
2485 #ifndef ENTT_HS_SUFFIX
2486 #define ENTT_HS_SUFFIX _hs
2487 #endif // ENTT_HS_SUFFIX
2488 
2489 
2490 #ifndef ENTT_HWS_SUFFIX
2491 #define ENTT_HWS_SUFFIX _hws
2492 #endif // ENTT_HWS_SUFFIX
2493 
2494 
2495 #ifndef ENTT_NO_ATOMIC
2496 #include <atomic>
2497 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
2498 #else // ENTT_NO_ATOMIC
2499 #define ENTT_MAYBE_ATOMIC(Type) Type
2500 #endif // ENTT_NO_ATOMIC
2501 
2502 
2503 #ifndef ENTT_DISABLE_ETO
2504 #include <type_traits>
2505 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
2506 #else // ENTT_DISABLE_ETO
2507 // sfinae-friendly definition
2508 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
2509 #endif // ENTT_DISABLE_ETO
2510 
2511 
2512 #ifndef ENTT_ID_TYPE
2513 #include <cstdint>
2514 #define ENTT_ID_TYPE std::uint32_t
2515 #endif // ENTT_ID_TYPE
2516 
2517 
2518 #ifndef ENTT_PAGE_SIZE
2519 #define ENTT_PAGE_SIZE 32768
2520 #endif // ENTT_PAGE_SIZE
2521 
2522 
2523 #ifndef ENTT_DISABLE_ASSERT
2524 #include <cassert>
2525 #define ENTT_ASSERT(condition) assert(condition)
2526 #else // ENTT_DISABLE_ASSERT
2527 #define ENTT_ASSERT(...) ((void)0)
2528 #endif // ENTT_DISABLE_ASSERT
2529 
2530 
2531 #endif // ENTT_CONFIG_CONFIG_H
2532 
2533 
2534 
2535 namespace entt {
2536 
2537 
2544 namespace internal {
2545 
2546 
2547 template<typename Ret, typename... Args>
2548 auto to_function_pointer(Ret(*)(Args...)) -> Ret(*)(Args...);
2549 
2550 
2551 template<typename Ret, typename... Args, typename Type, typename Payload, typename = std::enable_if_t<std::is_convertible_v<const Payload *, const Type *>>>
2552 auto to_function_pointer(Ret(*)(Type &, Args...), const Payload *) -> Ret(*)(Args...);
2553 
2554 
2555 template<typename Ret, typename... Args, typename Type, typename Payload, typename = std::enable_if_t<std::is_convertible_v<const Payload *, const Type *>>>
2556 auto to_function_pointer(Ret(*)(Type *, Args...), const Payload *) -> Ret(*)(Args...);
2557 
2558 
2559 template<typename Class, typename Ret, typename... Args>
2560 auto to_function_pointer(Ret(Class:: *)(Args...), const Class *) -> Ret(*)(Args...);
2561 
2562 
2563 template<typename Class, typename Ret, typename... Args>
2564 auto to_function_pointer(Ret(Class:: *)(Args...) const, const Class *) -> Ret(*)(Args...);
2565 
2566 
2567 template<typename Class, typename Type>
2568 auto to_function_pointer(Type Class:: *, const Class *) -> Type(*)();
2569 
2570 
2571 template<typename... Type>
2572 using to_function_pointer_t = decltype(internal::to_function_pointer(std::declval<Type>()...));
2573 
2574 
2575 template<typename Ret, typename... Args>
2576 constexpr auto index_sequence_for(Ret(*)(Args...)) {
2577  return std::index_sequence_for<Args...>{};
2578 }
2579 
2580 
2581 }
2582 
2583 
2591 template<auto>
2592 struct connect_arg_t {};
2593 
2594 
2596 template<auto Func>
2598 
2599 
2606 template<typename>
2607 class delegate;
2608 
2609 
2623 template<typename Ret, typename... Args>
2624 class delegate<Ret(Args...)> {
2625  using proto_fn_type = Ret(const void *, std::tuple<Args &&...>);
2626 
2627  template<auto Function, std::size_t... Index>
2628  void connect(std::index_sequence<Index...>) ENTT_NOEXCEPT {
2629  static_assert(std::is_invocable_r_v<Ret, decltype(Function), std::tuple_element_t<Index, std::tuple<Args...>>...>);
2630  data = nullptr;
2631 
2632  fn = [](const void *, std::tuple<Args &&...> args) -> Ret {
2633  // Ret(...) makes void(...) eat the return values to avoid errors
2634  return Ret(std::invoke(Function, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
2635  };
2636  }
2637 
2638  template<auto Candidate, typename Type, std::size_t... Index>
2639  void connect(Type &value_or_instance, std::index_sequence<Index...>) ENTT_NOEXCEPT {
2640  static_assert(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, std::tuple_element_t<Index, std::tuple<Args...>>...>);
2641  data = &value_or_instance;
2642 
2643  fn = [](const void *payload, std::tuple<Args &&...> args) -> Ret {
2644  Type *curr = static_cast<Type *>(const_cast<std::conditional_t<std::is_const_v<Type>, const void *, void *>>(payload));
2645  // Ret(...) makes void(...) eat the return values to avoid errors
2646  return Ret(std::invoke(Candidate, *curr, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
2647  };
2648  }
2649 
2650  template<auto Candidate, typename Type, std::size_t... Index>
2651  void connect(Type *value_or_instance, std::index_sequence<Index...>) ENTT_NOEXCEPT {
2652  static_assert(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, std::tuple_element_t<Index, std::tuple<Args...>>...>);
2653  data = value_or_instance;
2654 
2655  fn = [](const void *payload, std::tuple<Args &&...> args) -> Ret {
2656  Type *curr = static_cast<Type *>(const_cast<std::conditional_t<std::is_const_v<Type>, const void *, void *>>(payload));
2657  // Ret(...) makes void(...) eat the return values to avoid errors
2658  return Ret(std::invoke(Candidate, curr, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
2659  };
2660  }
2661 
2662 public:
2664  using function_type = Ret(Args...);
2665 
2668  : fn{nullptr}, data{nullptr}
2669  {}
2670 
2675  template<auto Function>
2677  : delegate{}
2678  {
2679  connect<Function>();
2680  }
2681 
2689  template<auto Candidate, typename Type>
2691  : delegate{}
2692  {
2693  connect<Candidate>(value_or_instance);
2694  }
2695 
2703  template<auto Candidate, typename Type>
2705  : delegate{}
2706  {
2707  connect<Candidate>(value_or_instance);
2708  }
2709 
2714  template<auto Function>
2716  connect<Function>(internal::index_sequence_for(internal::to_function_pointer_t<decltype(Function)>{}));
2717  }
2718 
2734  template<auto Candidate, typename Type>
2735  void connect(Type &value_or_instance) ENTT_NOEXCEPT {
2736  connect<Candidate>(value_or_instance, internal::index_sequence_for(internal::to_function_pointer_t<decltype(Candidate), Type *>{}));
2737  }
2738 
2754  template<auto Candidate, typename Type>
2755  void connect(Type *value_or_instance) ENTT_NOEXCEPT {
2756  connect<Candidate>(value_or_instance, internal::index_sequence_for(internal::to_function_pointer_t<decltype(Candidate), Type *>{}));
2757  }
2758 
2765  fn = nullptr;
2766  data = nullptr;
2767  }
2768 
2773  const void * instance() const ENTT_NOEXCEPT {
2774  return data;
2775  }
2776 
2791  Ret operator()(Args... args) const {
2792  ENTT_ASSERT(fn);
2793  return fn(data, std::forward_as_tuple(std::forward<Args>(args)...));
2794  }
2795 
2800  explicit operator bool() const ENTT_NOEXCEPT {
2801  // no need to test also data
2802  return fn;
2803  }
2804 
2810  bool operator==(const delegate<Ret(Args...)> &other) const ENTT_NOEXCEPT {
2811  return fn == other.fn && data == other.data;
2812  }
2813 
2814 private:
2815  proto_fn_type *fn;
2816  const void *data;
2817 };
2818 
2819 
2828 template<typename Ret, typename... Args>
2829 bool operator!=(const delegate<Ret(Args...)> &lhs, const delegate<Ret(Args...)> &rhs) ENTT_NOEXCEPT {
2830  return !(lhs == rhs);
2831 }
2832 
2833 
2842 template<auto Function>
2843 delegate(connect_arg_t<Function>) ENTT_NOEXCEPT
2844 -> delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Function)>>>;
2845 
2846 
2856 template<auto Candidate, typename Type>
2857 delegate(connect_arg_t<Candidate>, Type &) ENTT_NOEXCEPT
2858 -> delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Candidate), Type *>>>;
2859 
2860 
2870 template<auto Candidate, typename Type>
2871 delegate(connect_arg_t<Candidate>, Type *) ENTT_NOEXCEPT
2872 -> delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Candidate), Type *>>>;
2873 
2874 
2875 }
2876 
2877 
2878 #endif // ENTT_SIGNAL_DELEGATE_HPP
2879 
2880 // #include "../signal/sigh.hpp"
2881 #ifndef ENTT_SIGNAL_SIGH_HPP
2882 #define ENTT_SIGNAL_SIGH_HPP
2883 
2884 
2885 #include <vector>
2886 #include <utility>
2887 #include <iterator>
2888 #include <algorithm>
2889 #include <functional>
2890 #include <type_traits>
2891 // #include "../config/config.h"
2892 
2893 // #include "delegate.hpp"
2894 
2895 // #include "fwd.hpp"
2896 #ifndef ENTT_SIGNAL_FWD_HPP
2897 #define ENTT_SIGNAL_FWD_HPP
2898 
2899 
2900 namespace entt {
2901 
2902 
2904 template<typename>
2905 class delegate;
2906 
2908 template<typename>
2909 class sink;
2910 
2912 template<typename>
2913 class sigh;
2914 
2915 
2916 }
2917 
2918 
2919 #endif // ENTT_SIGNAL_FWD_HPP
2920 
2921 
2922 
2923 namespace entt {
2924 
2925 
2934 template<typename Function>
2935 class sink;
2936 
2937 
2946 template<typename Function>
2947 class sigh;
2948 
2949 
2965 template<typename Ret, typename... Args>
2966 class sigh<Ret(Args...)> {
2968  friend class sink<Ret(Args...)>;
2969 
2970 public:
2972  using size_type = std::size_t;
2974  using sink_type = entt::sink<Ret(Args...)>;
2975 
2980  template<typename Class>
2981  using instance_type = Class *;
2982 
2988  return calls.size();
2989  }
2990 
2995  bool empty() const ENTT_NOEXCEPT {
2996  return calls.empty();
2997  }
2998 
3006  void publish(Args... args) const {
3007  std::for_each(calls.cbegin(), calls.cend(), [&args...](auto &&call) {
3008  call(args...);
3009  });
3010  }
3011 
3026  template<typename Func>
3027  void collect(Func func, Args... args) const {
3028  for(auto &&call: calls) {
3029  if constexpr(std::is_void_v<Ret>) {
3030  if constexpr(std::is_invocable_r_v<bool, Func>) {
3031  call(args...);
3032  if(func()) { break; }
3033  } else {
3034  call(args...);
3035  func();
3036  }
3037  } else {
3038  if constexpr(std::is_invocable_r_v<bool, Func, Ret>) {
3039  if(func(call(args...))) { break; }
3040  } else {
3041  func(call(args...));
3042  }
3043  }
3044  }
3045  }
3046 
3047 private:
3048  std::vector<delegate<Ret(Args...)>> calls;
3049 };
3050 
3051 
3059 class connection {
3061  template<typename>
3062  friend class sink;
3063 
3064  connection(delegate<void(void *)> fn, void *ref)
3065  : disconnect{fn}, signal{ref}
3066  {}
3067 
3068 public:
3070  connection() = default;
3071 
3073  connection(const connection &) = default;
3074 
3080  : connection{}
3081  {
3082  std::swap(disconnect, other.disconnect);
3083  std::swap(signal, other.signal);
3084  }
3085 
3087  connection & operator=(const connection &) = default;
3088 
3095  if(this != &other) {
3096  auto tmp{std::move(other)};
3097  disconnect = tmp.disconnect;
3098  signal = tmp.signal;
3099  }
3100 
3101  return *this;
3102  }
3103 
3108  explicit operator bool() const ENTT_NOEXCEPT {
3109  return static_cast<bool>(disconnect);
3110  }
3111 
3113  void release() {
3114  if(disconnect) {
3115  disconnect(signal);
3116  disconnect.reset();
3117  }
3118  }
3119 
3120 private:
3121  delegate<void(void *)> disconnect;
3122  void *signal{};
3123 };
3124 
3125 
3136  using connection::operator bool;
3137  using connection::release;
3138 
3140  scoped_connection() = default;
3141 
3147  : connection{conn}
3148  {}
3149 
3151  scoped_connection(const scoped_connection &) = delete;
3152 
3154  scoped_connection(scoped_connection &&) = default;
3155 
3159  }
3160 
3165  scoped_connection & operator=(const scoped_connection &) = delete;
3166 
3172 
3179  static_cast<connection &>(*this) = other;
3180  return *this;
3181  }
3182 
3189  static_cast<connection &>(*this) = std::move(other);
3190  return *this;
3191  }
3192 };
3193 
3194 
3209 template<typename Ret, typename... Args>
3210 class sink<Ret(Args...)> {
3211  using signal_type = sigh<Ret(Args...)>;
3212  using difference_type = typename std::iterator_traits<typename decltype(signal_type::calls)::iterator>::difference_type;
3213 
3214  template<auto Candidate, typename Type>
3215  static void release(Type value_or_instance, void *signal) {
3216  sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>(value_or_instance);
3217  }
3218 
3219  template<auto Function>
3220  static void release(void *signal) {
3221  sink{*static_cast<signal_type *>(signal)}.disconnect<Function>();
3222  }
3223 
3224 public:
3229  sink(sigh<Ret(Args...)> &ref) ENTT_NOEXCEPT
3230  : offset{},
3231  signal{&ref}
3232  {}
3233 
3238  bool empty() const ENTT_NOEXCEPT {
3239  return signal->calls.empty();
3240  }
3241 
3247  template<auto Function>
3249  delegate<Ret(Args...)> call{};
3250  call.template connect<Function>();
3251 
3252  const auto &calls = signal->calls;
3253  const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
3254 
3255  sink other{*this};
3256  other.offset = std::distance(it, calls.cend());
3257  return other;
3258  }
3259 
3268  template<auto Candidate, typename Type>
3269  sink before(Type &value_or_instance) {
3270  delegate<Ret(Args...)> call{};
3271  call.template connect<Candidate>(value_or_instance);
3272 
3273  const auto &calls = signal->calls;
3274  const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
3275 
3276  sink other{*this};
3277  other.offset = std::distance(it, calls.cend());
3278  return other;
3279  }
3280 
3289  template<auto Candidate, typename Type>
3290  sink before(Type *value_or_instance) {
3291  delegate<Ret(Args...)> call{};
3292  call.template connect<Candidate>(value_or_instance);
3293 
3294  const auto &calls = signal->calls;
3295  const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
3296 
3297  sink other{*this};
3298  other.offset = std::distance(it, calls.cend());
3299  return other;
3300  }
3301 
3309  template<typename Type>
3310  sink before(Type &value_or_instance) {
3311  return before(&value_or_instance);
3312  }
3313 
3321  template<typename Type>
3322  sink before(Type *value_or_instance) {
3323  sink other{*this};
3324 
3325  if(value_or_instance) {
3326  const auto &calls = signal->calls;
3327  const auto it = std::find_if(calls.cbegin(), calls.cend(), [value_or_instance](const auto &delegate) {
3328  return delegate.instance() == value_or_instance;
3329  });
3330 
3331  other.offset = std::distance(it, calls.cend());
3332  }
3333 
3334  return other;
3335  }
3336 
3342  sink other{*this};
3343  other.offset = signal->calls.size();
3344  return other;
3345  }
3346 
3356  template<auto Function>
3358  disconnect<Function>();
3359 
3360  delegate<Ret(Args...)> call{};
3361  call.template connect<Function>();
3362  signal->calls.insert(signal->calls.end() - offset, std::move(call));
3363 
3364  delegate<void(void *)> conn{};
3365  conn.template connect<&release<Function>>();
3366  return { std::move(conn), signal };
3367  }
3368 
3386  template<auto Candidate, typename Type>
3387  connection connect(Type &value_or_instance) {
3388  disconnect<Candidate>(value_or_instance);
3389 
3390  delegate<Ret(Args...)> call{};
3391  call.template connect<Candidate>(value_or_instance);
3392  signal->calls.insert(signal->calls.end() - offset, std::move(call));
3393 
3394  delegate<void(void *)> conn{};
3395  conn.template connect<&release<Candidate, Type &>>(value_or_instance);
3396  return { std::move(conn), signal };
3397  }
3398 
3416  template<auto Candidate, typename Type>
3417  connection connect(Type *value_or_instance) {
3418  disconnect<Candidate>(value_or_instance);
3419 
3420  delegate<Ret(Args...)> call{};
3421  call.template connect<Candidate>(value_or_instance);
3422  signal->calls.insert(signal->calls.end() - offset, std::move(call));
3423 
3424  delegate<void(void *)> conn{};
3425  conn.template connect<&release<Candidate, Type *>>(value_or_instance);
3426  return { std::move(conn), signal };
3427  }
3428 
3433  template<auto Function>
3434  void disconnect() {
3435  auto &calls = signal->calls;
3436  delegate<Ret(Args...)> call{};
3437  call.template connect<Function>();
3438  calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
3439  }
3440 
3448  template<auto Candidate, typename Type>
3449  void disconnect(Type &value_or_instance) {
3450  auto &calls = signal->calls;
3451  delegate<Ret(Args...)> call{};
3452  call.template connect<Candidate>(value_or_instance);
3453  calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
3454  }
3455 
3463  template<auto Candidate, typename Type>
3464  void disconnect(Type *value_or_instance) {
3465  auto &calls = signal->calls;
3466  delegate<Ret(Args...)> call{};
3467  call.template connect<Candidate>(value_or_instance);
3468  calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
3469  }
3470 
3477  template<typename Type>
3478  void disconnect(Type &value_or_instance) {
3479  disconnect(&value_or_instance);
3480  }
3481 
3488  template<typename Type>
3489  void disconnect(Type *value_or_instance) {
3490  if(value_or_instance) {
3491  auto &calls = signal->calls;
3492  calls.erase(std::remove_if(calls.begin(), calls.end(), [value_or_instance](const auto &delegate) {
3493  return delegate.instance() == value_or_instance;
3494  }), calls.end());
3495  }
3496  }
3497 
3499  void disconnect() {
3500  signal->calls.clear();
3501  }
3502 
3503 private:
3504  difference_type offset;
3505  signal_type *signal;
3506 };
3507 
3508 
3518 template<typename Ret, typename... Args>
3519 sink(sigh<Ret(Args...)> &) ENTT_NOEXCEPT -> sink<Ret(Args...)>;
3520 
3521 
3522 }
3523 
3524 
3525 #endif // ENTT_SIGNAL_SIGH_HPP
3526 
3527 // #include "runtime_view.hpp"
3528 #ifndef ENTT_ENTITY_RUNTIME_VIEW_HPP
3529 #define ENTT_ENTITY_RUNTIME_VIEW_HPP
3530 
3531 
3532 #include <iterator>
3533 #include <cassert>
3534 #include <vector>
3535 #include <utility>
3536 #include <algorithm>
3537 #include <type_traits>
3538 // #include "../config/config.h"
3539 
3540 // #include "sparse_set.hpp"
3541 #ifndef ENTT_ENTITY_SPARSE_SET_HPP
3542 #define ENTT_ENTITY_SPARSE_SET_HPP
3543 
3544 
3545 #include <algorithm>
3546 #include <iterator>
3547 #include <utility>
3548 #include <vector>
3549 #include <memory>
3550 #include <cstddef>
3551 #include <numeric>
3552 #include <type_traits>
3553 // #include "../config/config.h"
3554 
3555 // #include "../core/algorithm.hpp"
3556 
3557 // #include "entity.hpp"
3558 #ifndef ENTT_ENTITY_ENTITY_HPP
3559 #define ENTT_ENTITY_ENTITY_HPP
3560 
3561 
3562 #include <cstdint>
3563 #include <type_traits>
3564 // #include "../config/config.h"
3565 
3566 
3567 
3568 namespace entt {
3569 
3570 
3577 template<typename>
3579 
3580 
3589 template<>
3590 struct entt_traits<std::uint16_t> {
3592  using entity_type = std::uint16_t;
3594  using version_type = std::uint8_t;
3596  using difference_type = std::int32_t;
3597 
3599  static constexpr std::uint16_t entity_mask = 0xFFF;
3601  static constexpr std::uint16_t version_mask = 0xF;
3603  static constexpr auto entity_shift = 12;
3604 };
3605 
3606 
3615 template<>
3616 struct entt_traits<std::uint32_t> {
3618  using entity_type = std::uint32_t;
3620  using version_type = std::uint16_t;
3622  using difference_type = std::int64_t;
3623 
3625  static constexpr std::uint32_t entity_mask = 0xFFFFF;
3627  static constexpr std::uint32_t version_mask = 0xFFF;
3629  static constexpr auto entity_shift = 20;
3630 };
3631 
3632 
3641 template<>
3642 struct entt_traits<std::uint64_t> {
3644  using entity_type = std::uint64_t;
3646  using version_type = std::uint32_t;
3648  using difference_type = std::int64_t;
3649 
3651  static constexpr std::uint64_t entity_mask = 0xFFFFFFFF;
3653  static constexpr std::uint64_t version_mask = 0xFFFFFFFF;
3655  static constexpr auto entity_shift = 32;
3656 };
3657 
3658 
3665 namespace internal {
3666 
3667 
3668 class null {
3669  template<typename Entity>
3670  using traits_type = entt_traits<std::underlying_type_t<Entity>>;
3671 
3672 public:
3673  template<typename Entity>
3674  constexpr operator Entity() const ENTT_NOEXCEPT {
3675  return Entity{traits_type<Entity>::entity_mask};
3676  }
3677 
3678  constexpr bool operator==(null) const ENTT_NOEXCEPT {
3679  return true;
3680  }
3681 
3682  constexpr bool operator!=(null) const ENTT_NOEXCEPT {
3683  return false;
3684  }
3685 
3686  template<typename Entity>
3687  constexpr bool operator==(const Entity entity) const ENTT_NOEXCEPT {
3688  return (to_integer(entity) & traits_type<Entity>::entity_mask) == to_integer(static_cast<Entity>(*this));
3689  }
3690 
3691  template<typename Entity>
3692  constexpr bool operator!=(const Entity entity) const ENTT_NOEXCEPT {
3693  return !(entity == *this);
3694  }
3695 };
3696 
3697 
3698 template<typename Entity>
3699 constexpr bool operator==(const Entity entity, null other) ENTT_NOEXCEPT {
3700  return other == entity;
3701 }
3702 
3703 
3704 template<typename Entity>
3705 constexpr bool operator!=(const Entity entity, null other) ENTT_NOEXCEPT {
3706  return other != entity;
3707 }
3708 
3709 
3710 }
3711 
3712 
3726 constexpr auto null = internal::null{};
3727 
3728 
3729 }
3730 
3731 
3732 #endif // ENTT_ENTITY_ENTITY_HPP
3733 
3734 // #include "fwd.hpp"
3735 #ifndef ENTT_ENTITY_FWD_HPP
3736 #define ENTT_ENTITY_FWD_HPP
3737 
3738 
3739 // #include "../config/config.h"
3740 
3741 // #include "../core/type_traits.hpp"
3742 
3743 
3744 
3745 namespace entt {
3746 
3748 template <typename>
3750 
3752 template<typename...>
3754 
3756 template<typename>
3758 
3760 template<typename...>
3762 
3764 template<typename>
3766 
3768 template <typename>
3770 
3772 template<typename>
3774 
3776 template<typename>
3778 
3780 template<typename>
3782 
3785 
3787 ENTT_OPAQUE_TYPE(component, ENTT_ID_TYPE);
3788 
3791 
3794 
3797 
3800 
3803 
3806 
3811 template<typename... Types>
3812 using view = basic_view<entity, Types...>;
3813 
3816 
3821 template<typename... Types>
3822 using group = basic_group<entity, Types...>;
3823 
3824 
3825 }
3826 
3827 
3828 #endif // ENTT_ENTITY_FWD_HPP
3829 
3830 
3831 
3832 namespace entt {
3833 
3834 
3862 template<typename Entity>
3863 class sparse_set {
3865 
3866  static_assert(ENTT_PAGE_SIZE && ((ENTT_PAGE_SIZE & (ENTT_PAGE_SIZE - 1)) == 0));
3867  static constexpr auto entt_per_page = ENTT_PAGE_SIZE / sizeof(typename traits_type::entity_type);
3868 
3869  class iterator {
3870  friend class sparse_set<Entity>;
3871 
3872  using direct_type = const std::vector<Entity>;
3873  using index_type = typename traits_type::difference_type;
3874 
3875  iterator(direct_type *ref, const index_type idx) ENTT_NOEXCEPT
3876  : direct{ref}, index{idx}
3877  {}
3878 
3879  public:
3880  using difference_type = index_type;
3881  using value_type = Entity;
3882  using pointer = const value_type *;
3883  using reference = const value_type &;
3884  using iterator_category = std::random_access_iterator_tag;
3885 
3886  iterator() ENTT_NOEXCEPT = default;
3887 
3888  iterator & operator++() ENTT_NOEXCEPT {
3889  return --index, *this;
3890  }
3891 
3892  iterator operator++(int) ENTT_NOEXCEPT {
3893  iterator orig = *this;
3894  return ++(*this), orig;
3895  }
3896 
3897  iterator & operator--() ENTT_NOEXCEPT {
3898  return ++index, *this;
3899  }
3900 
3901  iterator operator--(int) ENTT_NOEXCEPT {
3902  iterator orig = *this;
3903  return --(*this), orig;
3904  }
3905 
3906  iterator & operator+=(const difference_type value) ENTT_NOEXCEPT {
3907  index -= value;
3908  return *this;
3909  }
3910 
3911  iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
3912  return iterator{direct, index-value};
3913  }
3914 
3915  iterator & operator-=(const difference_type value) ENTT_NOEXCEPT {
3916  return (*this += -value);
3917  }
3918 
3919  iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
3920  return (*this + -value);
3921  }
3922 
3923  difference_type operator-(const iterator &other) const ENTT_NOEXCEPT {
3924  return other.index - index;
3925  }
3926 
3927  reference operator[](const difference_type value) const ENTT_NOEXCEPT {
3928  const auto pos = size_type(index-value-1);
3929  return (*direct)[pos];
3930  }
3931 
3932  bool operator==(const iterator &other) const ENTT_NOEXCEPT {
3933  return other.index == index;
3934  }
3935 
3936  bool operator!=(const iterator &other) const ENTT_NOEXCEPT {
3937  return !(*this == other);
3938  }
3939 
3940  bool operator<(const iterator &other) const ENTT_NOEXCEPT {
3941  return index > other.index;
3942  }
3943 
3944  bool operator>(const iterator &other) const ENTT_NOEXCEPT {
3945  return index < other.index;
3946  }
3947 
3948  bool operator<=(const iterator &other) const ENTT_NOEXCEPT {
3949  return !(*this > other);
3950  }
3951 
3952  bool operator>=(const iterator &other) const ENTT_NOEXCEPT {
3953  return !(*this < other);
3954  }
3955 
3956  pointer operator->() const ENTT_NOEXCEPT {
3957  const auto pos = size_type(index-1);
3958  return &(*direct)[pos];
3959  }
3960 
3961  reference operator*() const ENTT_NOEXCEPT {
3962  return *operator->();
3963  }
3964 
3965  private:
3966  direct_type *direct;
3967  index_type index;
3968  };
3969 
3970  void assure(const std::size_t page) {
3971  if(!(page < reverse.size())) {
3972  reverse.resize(page+1);
3973  }
3974 
3975  if(!reverse[page]) {
3976  reverse[page] = std::make_unique<entity_type[]>(entt_per_page);
3977  // null is safe in all cases for our purposes
3978  std::fill_n(reverse[page].get(), entt_per_page, null);
3979  }
3980  }
3981 
3982  auto map(const Entity entt) const ENTT_NOEXCEPT {
3983  const auto identifier = to_integer(entt) & traits_type::entity_mask;
3984  const auto page = size_type(identifier / entt_per_page);
3985  const auto offset = size_type(identifier & (entt_per_page - 1));
3986  return std::make_pair(page, offset);
3987  }
3988 
3989 public:
3991  using entity_type = Entity;
3993  using size_type = std::size_t;
3995  using iterator_type = iterator;
3996 
3998  sparse_set() = default;
3999 
4004  sparse_set(const sparse_set &other)
4005  : reverse{},
4006  direct{other.direct}
4007  {
4008  for(size_type pos{}, last = other.reverse.size(); pos < last; ++pos) {
4009  if(other.reverse[pos]) {
4010  assure(pos);
4011  std::copy_n(other.reverse[pos].get(), entt_per_page, reverse[pos].get());
4012  }
4013  }
4014  }
4015 
4017  sparse_set(sparse_set &&) = default;
4018 
4020  virtual ~sparse_set() ENTT_NOEXCEPT = default;
4021 
4027  sparse_set & operator=(const sparse_set &other) {
4028  if(&other != this) {
4029  auto tmp{other};
4030  *this = std::move(tmp);
4031  }
4032 
4033  return *this;
4034  }
4035 
4037  sparse_set & operator=(sparse_set &&) = default;
4038 
4047  void reserve(const size_type cap) {
4048  direct.reserve(cap);
4049  }
4050 
4057  return direct.capacity();
4058  }
4059 
4061  void shrink_to_fit() {
4062  // conservative approach
4063  if(direct.empty()) {
4064  reverse.clear();
4065  }
4066 
4067  reverse.shrink_to_fit();
4068  direct.shrink_to_fit();
4069  }
4070 
4082  return reverse.size() * entt_per_page;
4083  }
4084 
4096  return direct.size();
4097  }
4098 
4103  bool empty() const ENTT_NOEXCEPT {
4104  return direct.empty();
4105  }
4106 
4122  const entity_type * data() const ENTT_NOEXCEPT {
4123  return direct.data();
4124  }
4125 
4140  const typename traits_type::difference_type pos = direct.size();
4141  return iterator_type{&direct, pos};
4142  }
4143 
4159  return iterator_type{&direct, {}};
4160  }
4161 
4169  return has(entt) ? --(end() - index(entt)) : end();
4170  }
4171 
4177  bool has(const entity_type entt) const ENTT_NOEXCEPT {
4178  auto [page, offset] = map(entt);
4179  // testing against null permits to avoid accessing the direct vector
4180  return (page < reverse.size() && reverse[page] && reverse[page][offset] != null);
4181  }
4182 
4196  ENTT_ASSERT(has(entt));
4197  auto [page, offset] = map(entt);
4198  return size_type(reverse[page][offset]);
4199  }
4200 
4213  ENTT_ASSERT(!has(entt));
4214  auto [page, offset] = map(entt);
4215  assure(page);
4216  reverse[page][offset] = entity_type(direct.size());
4217  direct.push_back(entt);
4218  }
4219 
4233  template<typename It>
4234  void batch(It first, It last) {
4235  std::for_each(first, last, [this, next = direct.size()](const auto entt) mutable {
4236  ENTT_ASSERT(!has(entt));
4237  auto [page, offset] = map(entt);
4238  assure(page);
4239  reverse[page][offset] = entity_type(next++);
4240  });
4241 
4242  direct.insert(direct.end(), first, last);
4243  }
4244 
4256  void destroy(const entity_type entt) {
4257  ENTT_ASSERT(has(entt));
4258  auto [from_page, from_offset] = map(entt);
4259  auto [to_page, to_offset] = map(direct.back());
4260  direct[size_type(reverse[from_page][from_offset])] = entity_type(direct.back());
4261  reverse[to_page][to_offset] = reverse[from_page][from_offset];
4262  reverse[from_page][from_offset] = null;
4263  direct.pop_back();
4264  }
4265 
4281  virtual void swap(const entity_type lhs, const entity_type rhs) ENTT_NOEXCEPT {
4282  auto [src_page, src_offset] = map(lhs);
4283  auto [dst_page, dst_offset] = map(rhs);
4284  auto &from = reverse[src_page][src_offset];
4285  auto &to = reverse[dst_page][dst_offset];
4286  std::swap(direct[size_type(from)], direct[size_type(to)]);
4287  std::swap(from, to);
4288  }
4289 
4329  template<typename Compare, typename Sort = std_sort, typename... Args>
4330  void sort(iterator_type first, iterator_type last, Compare compare, Sort algo = Sort{}, Args &&... args) {
4331  ENTT_ASSERT(!(last < first));
4332  ENTT_ASSERT(!(last > end()));
4333 
4334  const auto length = std::distance(first, last);
4335  const auto skip = std::distance(last, end());
4336  const auto to = direct.rend() - skip;
4337  const auto from = to - length;
4338 
4339  algo(from, to, std::move(compare), std::forward<Args>(args)...);
4340 
4341  for(size_type pos = skip, end = skip+length; pos < end; ++pos) {
4342  auto [page, offset] = map(direct[pos]);
4343  reverse[page][offset] = entity_type(pos);
4344  }
4345  }
4346 
4374  template<typename Apply, typename Compare, typename Sort = std_sort, typename... Args>
4375  void arrange(iterator_type first, iterator_type last, Apply apply, Compare compare, Sort algo = Sort{}, Args &&... args) {
4376  ENTT_ASSERT(!(last < first));
4377  ENTT_ASSERT(!(last > end()));
4378 
4379  const auto length = std::distance(first, last);
4380  const auto skip = std::distance(last, end());
4381  const auto to = direct.rend() - skip;
4382  const auto from = to - length;
4383 
4384  algo(from, to, std::move(compare), std::forward<Args>(args)...);
4385 
4386  for(size_type pos = skip, end = skip+length; pos < end; ++pos) {
4387  auto curr = pos;
4388  auto next = index(direct[curr]);
4389 
4390  while(curr != next) {
4391  apply(direct[curr], direct[next]);
4392  auto [page, offset] = map(direct[curr]);
4393  reverse[page][offset] = entity_type(curr);
4394 
4395  curr = next;
4396  next = index(direct[curr]);
4397  }
4398  }
4399  }
4400 
4421  void respect(const sparse_set &other) ENTT_NOEXCEPT {
4422  const auto to = other.end();
4423  auto from = other.begin();
4424 
4425  size_type pos = direct.size() - 1;
4426 
4427  while(pos && from != to) {
4428  if(has(*from)) {
4429  if(*from != direct[pos]) {
4430  swap(direct[pos], *from);
4431  }
4432 
4433  --pos;
4434  }
4435 
4436  ++from;
4437  }
4438  }
4439 
4443  void reset() {
4444  reverse.clear();
4445  direct.clear();
4446  }
4447 
4448 private:
4449  std::vector<std::unique_ptr<entity_type[]>> reverse;
4450  std::vector<entity_type> direct;
4451 };
4452 
4453 
4454 }
4455 
4456 
4457 #endif // ENTT_ENTITY_SPARSE_SET_HPP
4458 
4459 // #include "entity.hpp"
4460 
4461 // #include "fwd.hpp"
4462 
4463 
4464 
4465 namespace entt {
4466 
4467 
4506 template<typename Entity>
4507 class basic_runtime_view {
4509  friend class basic_registry<Entity>;
4510 
4511  using underlying_iterator_type = typename sparse_set<Entity>::iterator_type;
4512 
4513  class iterator {
4514  friend class basic_runtime_view<Entity>;
4515 
4516  iterator(underlying_iterator_type first, underlying_iterator_type last, const sparse_set<Entity> * const *others, const sparse_set<Entity> * const *length) ENTT_NOEXCEPT
4517  : begin{first},
4518  end{last},
4519  from{others},
4520  to{length}
4521  {
4522  if(begin != end && !valid()) {
4523  ++(*this);
4524  }
4525  }
4526 
4527  bool valid() const ENTT_NOEXCEPT {
4528  return std::all_of(from, to, [entt = *begin](const auto *view) {
4529  return view->has(entt);
4530  });
4531  }
4532 
4533  public:
4534  using difference_type = typename underlying_iterator_type::difference_type;
4535  using value_type = typename underlying_iterator_type::value_type;
4536  using pointer = typename underlying_iterator_type::pointer;
4537  using reference = typename underlying_iterator_type::reference;
4538  using iterator_category = std::forward_iterator_tag;
4539 
4540  iterator() ENTT_NOEXCEPT = default;
4541 
4542  iterator & operator++() ENTT_NOEXCEPT {
4543  return (++begin != end && !valid()) ? ++(*this) : *this;
4544  }
4545 
4546  iterator operator++(int) ENTT_NOEXCEPT {
4547  iterator orig = *this;
4548  return ++(*this), orig;
4549  }
4550 
4551  bool operator==(const iterator &other) const ENTT_NOEXCEPT {
4552  return other.begin == begin;
4553  }
4554 
4555  bool operator!=(const iterator &other) const ENTT_NOEXCEPT {
4556  return !(*this == other);
4557  }
4558 
4559  pointer operator->() const ENTT_NOEXCEPT {
4560  return begin.operator->();
4561  }
4562 
4563  reference operator*() const ENTT_NOEXCEPT {
4564  return *operator->();
4565  }
4566 
4567  private:
4568  underlying_iterator_type begin;
4569  underlying_iterator_type end;
4570  const sparse_set<Entity> * const *from;
4571  const sparse_set<Entity> * const *to;
4572  };
4573 
4574  basic_runtime_view(std::vector<const sparse_set<Entity> *> others) ENTT_NOEXCEPT
4575  : pools{std::move(others)}
4576  {
4577  const auto it = std::min_element(pools.begin(), pools.end(), [](const auto *lhs, const auto *rhs) {
4578  return (!lhs && rhs) || (lhs && rhs && lhs->size() < rhs->size());
4579  });
4580 
4581  // brings the best candidate (if any) on front of the vector
4582  std::rotate(pools.begin(), it, pools.end());
4583  }
4584 
4585  bool valid() const ENTT_NOEXCEPT {
4586  return !pools.empty() && pools.front();
4587  }
4588 
4589 public:
4591  using entity_type = Entity;
4593  using size_type = std::size_t;
4595  using iterator_type = iterator;
4596 
4602  return valid() ? pools.front()->size() : size_type{};
4603  }
4604 
4609  bool empty() const ENTT_NOEXCEPT {
4610  return !valid() || pools.front()->empty();
4611  }
4612 
4628  iterator_type it{};
4629 
4630  if(valid()) {
4631  const auto &pool = *pools.front();
4632  const auto * const *data = pools.data();
4633  it = { pool.begin(), pool.end(), data + 1, data + pools.size() };
4634  }
4635 
4636  return it;
4637  }
4638 
4655  iterator_type it{};
4656 
4657  if(valid()) {
4658  const auto &pool = *pools.front();
4659  it = { pool.end(), pool.end(), nullptr, nullptr };
4660  }
4661 
4662  return it;
4663  }
4664 
4671  return valid() && std::all_of(pools.cbegin(), pools.cend(), [entt](const auto *view) {
4672  return view->find(entt) != view->end();
4673  });
4674  }
4675 
4691  template<typename Func>
4692  void each(Func func) const {
4693  std::for_each(begin(), end(), func);
4694  }
4695 
4696 private:
4697  std::vector<const sparse_set<Entity> *> pools;
4698 };
4699 
4700 
4701 }
4702 
4703 
4704 #endif // ENTT_ENTITY_RUNTIME_VIEW_HPP
4705 
4706 // #include "sparse_set.hpp"
4707 
4708 // #include "snapshot.hpp"
4709 #ifndef ENTT_ENTITY_SNAPSHOT_HPP
4710 #define ENTT_ENTITY_SNAPSHOT_HPP
4711 
4712 
4713 #include <array>
4714 #include <cstddef>
4715 #include <utility>
4716 #include <iterator>
4717 #include <type_traits>
4718 #include <unordered_map>
4719 // #include "../config/config.h"
4720 
4721 // #include "entity.hpp"
4722 
4723 // #include "fwd.hpp"
4724 
4725 
4726 
4727 namespace entt {
4728 
4729 
4740 template<typename Entity>
4741 class basic_snapshot {
4743  friend class basic_registry<Entity>;
4744 
4745  using follow_fn_type = Entity(const basic_registry<Entity> &, const Entity);
4747 
4748  basic_snapshot(const basic_registry<Entity> *source, Entity init, follow_fn_type *fn) ENTT_NOEXCEPT
4749  : reg{source},
4750  seed{init},
4751  follow{fn}
4752  {}
4753 
4754  template<typename Component, typename Archive, typename It>
4755  void get(Archive &archive, std::size_t sz, It first, It last) const {
4756  archive(typename traits_type::entity_type(sz));
4757 
4758  while(first != last) {
4759  const auto entt = *(first++);
4760 
4761  if(reg->template has<Component>(entt)) {
4762  if constexpr(std::is_empty_v<Component>) {
4763  archive(entt);
4764  } else {
4765  archive(entt, reg->template get<Component>(entt));
4766  }
4767  }
4768  }
4769  }
4770 
4771  template<typename... Component, typename Archive, typename It, std::size_t... Indexes>
4772  void component(Archive &archive, It first, It last, std::index_sequence<Indexes...>) const {
4773  std::array<std::size_t, sizeof...(Indexes)> size{};
4774  auto begin = first;
4775 
4776  while(begin != last) {
4777  const auto entt = *(begin++);
4778  ((reg->template has<Component>(entt) ? ++size[Indexes] : size[Indexes]), ...);
4779  }
4780 
4781  (get<Component>(archive, size[Indexes], first, last), ...);
4782  }
4783 
4784 public:
4786  basic_snapshot(basic_snapshot &&) = default;
4787 
4789  basic_snapshot & operator=(basic_snapshot &&) = default;
4790 
4801  template<typename Archive>
4802  const basic_snapshot & entities(Archive &archive) const {
4803  archive(typename traits_type::entity_type(reg->alive()));
4804  reg->each([&archive](const auto entt) { archive(entt); });
4805  return *this;
4806  }
4807 
4818  template<typename Archive>
4819  const basic_snapshot & destroyed(Archive &archive) const {
4820  auto size = reg->size() - reg->alive();
4821  archive(typename traits_type::entity_type(size));
4822 
4823  if(size) {
4824  auto curr = seed;
4825  archive(curr);
4826 
4827  for(--size; size; --size) {
4828  curr = follow(*reg, curr);
4829  archive(curr);
4830  }
4831  }
4832 
4833  return *this;
4834  }
4835 
4847  template<typename... Component, typename Archive>
4848  const basic_snapshot & component(Archive &archive) const {
4849  (component<Component>(archive, reg->template data<Component>(), reg->template data<Component>() + reg->template size<Component>()), ...);
4850  return *this;
4851  }
4852 
4867  template<typename... Component, typename Archive, typename It>
4868  const basic_snapshot & component(Archive &archive, It first, It last) const {
4869  component<Component...>(archive, first, last, std::index_sequence_for<Component...>{});
4870  return *this;
4871  }
4872 
4873 private:
4874  const basic_registry<Entity> *reg;
4875  const Entity seed;
4876  follow_fn_type *follow;
4877 };
4878 
4879 
4890 template<typename Entity>
4891 class basic_snapshot_loader {
4893  friend class basic_registry<Entity>;
4894 
4895  using force_fn_type = void(basic_registry<Entity> &, const Entity, const bool);
4897 
4898  basic_snapshot_loader(basic_registry<Entity> *source, force_fn_type *fn) ENTT_NOEXCEPT
4899  : reg{source},
4900  force{fn}
4901  {
4902  // to restore a snapshot as a whole requires a clean registry
4903  ENTT_ASSERT(reg->empty());
4904  }
4905 
4906  template<typename Archive>
4907  void assure(Archive &archive, bool discard) const {
4908  typename traits_type::entity_type length{};
4909  archive(length);
4910 
4911  while(length--) {
4912  Entity entt{};
4913  archive(entt);
4914  force(*reg, entt, discard);
4915  }
4916  }
4917 
4918  template<typename Type, typename Archive, typename... Args>
4919  void assign(Archive &archive, Args... args) const {
4920  typename traits_type::entity_type length{};
4921  archive(length);
4922 
4923  while(length--) {
4924  static constexpr auto discard = false;
4925  Entity entt{};
4926 
4927  if constexpr(std::is_empty_v<Type>) {
4928  archive(entt);
4929  force(*reg, entt, discard);
4930  reg->template assign<Type>(args..., entt);
4931  } else {
4932  Type instance{};
4933  archive(entt, instance);
4934  force(*reg, entt, discard);
4935  reg->template assign<Type>(args..., entt, std::as_const(instance));
4936  }
4937  }
4938  }
4939 
4940 public:
4942  basic_snapshot_loader(basic_snapshot_loader &&) = default;
4943 
4945  basic_snapshot_loader & operator=(basic_snapshot_loader &&) = default;
4946 
4957  template<typename Archive>
4958  const basic_snapshot_loader & entities(Archive &archive) const {
4959  static constexpr auto discard = false;
4960  assure(archive, discard);
4961  return *this;
4962  }
4963 
4974  template<typename Archive>
4975  const basic_snapshot_loader & destroyed(Archive &archive) const {
4976  static constexpr auto discard = true;
4977  assure(archive, discard);
4978  return *this;
4979  }
4980 
4994  template<typename... Component, typename Archive>
4995  const basic_snapshot_loader & component(Archive &archive) const {
4996  (assign<Component>(archive), ...);
4997  return *this;
4998  }
4999 
5010  const basic_snapshot_loader & orphans() const {
5011  reg->orphans([this](const auto entt) {
5012  reg->destroy(entt);
5013  });
5014 
5015  return *this;
5016  }
5017 
5018 private:
5020  force_fn_type *force;
5021 };
5022 
5023 
5040 template<typename Entity>
5041 class basic_continuous_loader {
5042  using traits_type = entt_traits<std::underlying_type_t<Entity>>;
5043 
5044  void destroy(Entity entt) {
5045  const auto it = remloc.find(entt);
5046 
5047  if(it == remloc.cend()) {
5048  const auto local = reg->create();
5049  remloc.emplace(entt, std::make_pair(local, true));
5050  reg->destroy(local);
5051  }
5052  }
5053 
5054  void restore(Entity entt) {
5055  const auto it = remloc.find(entt);
5056 
5057  if(it == remloc.cend()) {
5058  const auto local = reg->create();
5059  remloc.emplace(entt, std::make_pair(local, true));
5060  } else {
5061  remloc[entt].first = reg->valid(remloc[entt].first) ? remloc[entt].first : reg->create();
5062  // set the dirty flag
5063  remloc[entt].second = true;
5064  }
5065  }
5066 
5067  template<typename Container>
5068  auto update(int, Container &container)
5069  -> decltype(typename Container::mapped_type{}, void()) {
5070  // map like container
5071  Container other;
5072 
5073  for(auto &&pair: container) {
5074  using first_type = std::remove_const_t<typename std::decay_t<decltype(pair)>::first_type>;
5075  using second_type = typename std::decay_t<decltype(pair)>::second_type;
5076 
5077  if constexpr(std::is_same_v<first_type, Entity> && std::is_same_v<second_type, Entity>) {
5078  other.emplace(map(pair.first), map(pair.second));
5079  } else if constexpr(std::is_same_v<first_type, Entity>) {
5080  other.emplace(map(pair.first), std::move(pair.second));
5081  } else {
5082  static_assert(std::is_same_v<second_type, Entity>);
5083  other.emplace(std::move(pair.first), map(pair.second));
5084  }
5085  }
5086 
5087  std::swap(container, other);
5088  }
5089 
5090  template<typename Container>
5091  auto update(char, Container &container)
5092  -> decltype(typename Container::value_type{}, void()) {
5093  // vector like container
5094  static_assert(std::is_same_v<typename Container::value_type, Entity>);
5095 
5096  for(auto &&entt: container) {
5097  entt = map(entt);
5098  }
5099  }
5100 
5101  template<typename Other, typename Type, typename Member>
5102  void update(Other &instance, Member Type:: *member) {
5103  if constexpr(!std::is_same_v<Other, Type>) {
5104  return;
5105  } else if constexpr(std::is_same_v<Member, Entity>) {
5106  instance.*member = map(instance.*member);
5107  } else {
5108  // maybe a container? let's try...
5109  update(0, instance.*member);
5110  }
5111  }
5112 
5113  template<typename Archive>
5114  void assure(Archive &archive, void(basic_continuous_loader:: *member)(Entity)) {
5115  typename traits_type::entity_type length{};
5116  archive(length);
5117 
5118  while(length--) {
5119  Entity entt{};
5120  archive(entt);
5121  (this->*member)(entt);
5122  }
5123  }
5124 
5125  template<typename Component>
5126  void reset() {
5127  for(auto &&ref: remloc) {
5128  const auto local = ref.second.first;
5129 
5130  if(reg->valid(local)) {
5131  reg->template reset<Component>(local);
5132  }
5133  }
5134  }
5135 
5136  template<typename Other, typename Archive, typename... Type, typename... Member>
5137  void assign(Archive &archive, [[maybe_unused]] Member Type:: *... member) {
5138  typename traits_type::entity_type length{};
5139  archive(length);
5140 
5141  while(length--) {
5142  Entity entt{};
5143 
5144  if constexpr(std::is_empty_v<Other>) {
5145  archive(entt);
5146  restore(entt);
5147  reg->template assign_or_replace<Other>(map(entt));
5148  } else {
5149  Other instance{};
5150  archive(entt, instance);
5151  (update(instance, member), ...);
5152  restore(entt);
5153  reg->template assign_or_replace<Other>(map(entt), std::as_const(instance));
5154  }
5155  }
5156  }
5157 
5158 public:
5160  using entity_type = Entity;
5161 
5167  : reg{&source}
5168  {}
5169 
5172 
5175 
5186  template<typename Archive>
5187  basic_continuous_loader & entities(Archive &archive) {
5188  assure(archive, &basic_continuous_loader::restore);
5189  return *this;
5190  }
5191 
5202  template<typename Archive>
5203  basic_continuous_loader & destroyed(Archive &archive) {
5204  assure(archive, &basic_continuous_loader::destroy);
5205  return *this;
5206  }
5207 
5227  template<typename... Component, typename Archive, typename... Type, typename... Member>
5228  basic_continuous_loader & component(Archive &archive, Member Type:: *... member) {
5229  (reset<Component>(), ...);
5230  (assign<Component>(archive, member...), ...);
5231  return *this;
5232  }
5233 
5243  auto it = remloc.begin();
5244 
5245  while(it != remloc.cend()) {
5246  const auto local = it->second.first;
5247  bool &dirty = it->second.second;
5248 
5249  if(dirty) {
5250  dirty = false;
5251  ++it;
5252  } else {
5253  if(reg->valid(local)) {
5254  reg->destroy(local);
5255  }
5256 
5257  it = remloc.erase(it);
5258  }
5259  }
5260 
5261  return *this;
5262  }
5263 
5275  reg->orphans([this](const auto entt) {
5276  reg->destroy(entt);
5277  });
5278 
5279  return *this;
5280  }
5281 
5288  return (remloc.find(entt) != remloc.cend());
5289  }
5290 
5297  const auto it = remloc.find(entt);
5298  entity_type other = null;
5299 
5300  if(it != remloc.cend()) {
5301  other = it->second.first;
5302  }
5303 
5304  return other;
5305  }
5306 
5307 private:
5308  std::unordered_map<entity_type, std::pair<entity_type, bool>> remloc;
5310 };
5311 
5312 
5313 }
5314 
5315 
5316 #endif // ENTT_ENTITY_SNAPSHOT_HPP
5317 
5318 // #include "storage.hpp"
5319 #ifndef ENTT_ENTITY_STORAGE_HPP
5320 #define ENTT_ENTITY_STORAGE_HPP
5321 
5322 
5323 #include <algorithm>
5324 #include <iterator>
5325 #include <numeric>
5326 #include <utility>
5327 #include <vector>
5328 #include <cstddef>
5329 #include <type_traits>
5330 // #include "../config/config.h"
5331 
5332 // #include "../core/algorithm.hpp"
5333 
5334 // #include "sparse_set.hpp"
5335 
5336 // #include "entity.hpp"
5337 
5338 
5339 
5340 namespace entt {
5341 
5342 
5372 template<typename Entity, typename Type, typename = std::void_t<>>
5373 class basic_storage: public sparse_set<Entity> {
5376 
5377  template<bool Const>
5378  class iterator {
5379  friend class basic_storage<Entity, Type>;
5380 
5381  using instance_type = std::conditional_t<Const, const std::vector<Type>, std::vector<Type>>;
5382  using index_type = typename traits_type::difference_type;
5383 
5384  iterator(instance_type *ref, const index_type idx) ENTT_NOEXCEPT
5385  : instances{ref}, index{idx}
5386  {}
5387 
5388  public:
5389  using difference_type = index_type;
5390  using value_type = Type;
5391  using pointer = std::conditional_t<Const, const value_type *, value_type *>;
5392  using reference = std::conditional_t<Const, const value_type &, value_type &>;
5393  using iterator_category = std::random_access_iterator_tag;
5394 
5395  iterator() ENTT_NOEXCEPT = default;
5396 
5397  iterator & operator++() ENTT_NOEXCEPT {
5398  return --index, *this;
5399  }
5400 
5401  iterator operator++(int) ENTT_NOEXCEPT {
5402  iterator orig = *this;
5403  return ++(*this), orig;
5404  }
5405 
5406  iterator & operator--() ENTT_NOEXCEPT {
5407  return ++index, *this;
5408  }
5409 
5410  iterator operator--(int) ENTT_NOEXCEPT {
5411  iterator orig = *this;
5412  return --(*this), orig;
5413  }
5414 
5415  iterator & operator+=(const difference_type value) ENTT_NOEXCEPT {
5416  index -= value;
5417  return *this;
5418  }
5419 
5420  iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
5421  return iterator{instances, index-value};
5422  }
5423 
5424  iterator & operator-=(const difference_type value) ENTT_NOEXCEPT {
5425  return (*this += -value);
5426  }
5427 
5428  iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
5429  return (*this + -value);
5430  }
5431 
5432  difference_type operator-(const iterator &other) const ENTT_NOEXCEPT {
5433  return other.index - index;
5434  }
5435 
5436  reference operator[](const difference_type value) const ENTT_NOEXCEPT {
5437  const auto pos = size_type(index-value-1);
5438  return (*instances)[pos];
5439  }
5440 
5441  bool operator==(const iterator &other) const ENTT_NOEXCEPT {
5442  return other.index == index;
5443  }
5444 
5445  bool operator!=(const iterator &other) const ENTT_NOEXCEPT {
5446  return !(*this == other);
5447  }
5448 
5449  bool operator<(const iterator &other) const ENTT_NOEXCEPT {
5450  return index > other.index;
5451  }
5452 
5453  bool operator>(const iterator &other) const ENTT_NOEXCEPT {
5454  return index < other.index;
5455  }
5456 
5457  bool operator<=(const iterator &other) const ENTT_NOEXCEPT {
5458  return !(*this > other);
5459  }
5460 
5461  bool operator>=(const iterator &other) const ENTT_NOEXCEPT {
5462  return !(*this < other);
5463  }
5464 
5465  pointer operator->() const ENTT_NOEXCEPT {
5466  const auto pos = size_type(index-1);
5467  return &(*instances)[pos];
5468  }
5469 
5470  reference operator*() const ENTT_NOEXCEPT {
5471  return *operator->();
5472  }
5473 
5474  private:
5475  instance_type *instances;
5476  index_type index;
5477  };
5478 
5479 public:
5481  using object_type = Type;
5483  using entity_type = Entity;
5485  using size_type = std::size_t;
5487  using iterator_type = iterator<false>;
5489  using const_iterator_type = iterator<true>;
5490 
5499  void reserve(const size_type cap) {
5501  instances.reserve(cap);
5502  }
5503 
5505  void shrink_to_fit() {
5507  instances.shrink_to_fit();
5508  }
5509 
5525  const object_type * raw() const ENTT_NOEXCEPT {
5526  return instances.data();
5527  }
5528 
5531  return const_cast<object_type *>(std::as_const(*this).raw());
5532  }
5533 
5547  const typename traits_type::difference_type pos = underlying_type::size();
5548  return const_iterator_type{&instances, pos};
5549  }
5550 
5553  return cbegin();
5554  }
5555 
5558  const typename traits_type::difference_type pos = underlying_type::size();
5559  return iterator_type{&instances, pos};
5560  }
5561 
5577  return const_iterator_type{&instances, {}};
5578  }
5579 
5582  return cend();
5583  }
5584 
5587  return iterator_type{&instances, {}};
5588  }
5589 
5603  return instances[underlying_type::index(entt)];
5604  }
5605 
5608  return const_cast<object_type &>(std::as_const(*this).get(entt));
5609  }
5610 
5617  return underlying_type::has(entt) ? (instances.data() + underlying_type::index(entt)) : nullptr;
5618  }
5619 
5622  return const_cast<object_type *>(std::as_const(*this).try_get(entt));
5623  }
5624 
5643  template<typename... Args>
5644  object_type & construct(const entity_type entt, Args &&... args) {
5645  if constexpr(std::is_aggregate_v<object_type>) {
5646  instances.emplace_back(Type{std::forward<Args>(args)...});
5647  } else {
5648  instances.emplace_back(std::forward<Args>(args)...);
5649  }
5650 
5651  // entity goes after component in case constructor throws
5653  return instances.back();
5654  }
5655 
5677  template<typename It, typename... Args>
5678  iterator_type batch(It first, It last, Args &&... args) {
5679  if constexpr(sizeof...(Args) == 0) {
5680  instances.resize(instances.size() + std::distance(first, last));
5681  } else {
5682  instances.resize(instances.size() + std::distance(first, last), Type{std::forward<Args>(args)...});
5683  }
5684 
5685  // entity goes after component in case constructor throws
5686  underlying_type::batch(first, last);
5687  return begin();
5688  }
5689 
5701  void destroy(const entity_type entt) {
5702  auto other = std::move(instances.back());
5703  instances[underlying_type::index(entt)] = std::move(other);
5704  instances.pop_back();
5706  }
5707 
5720  void swap(const entity_type lhs, const entity_type rhs) ENTT_NOEXCEPT override {
5721  std::swap(instances[underlying_type::index(lhs)], instances[underlying_type::index(rhs)]);
5722  underlying_type::swap(lhs, rhs);
5723  }
5724 
5770  template<typename Compare, typename Sort = std_sort, typename... Args>
5771  void sort(iterator_type first, iterator_type last, Compare compare, Sort algo = Sort{}, Args &&... args) {
5772  ENTT_ASSERT(!(last < first));
5773  ENTT_ASSERT(!(last > end()));
5774 
5775  const auto from = underlying_type::begin() + std::distance(begin(), first);
5776  const auto to = from + std::distance(first, last);
5777 
5778  const auto apply = [this](const auto lhs, const auto rhs) {
5779  std::swap(instances[underlying_type::index(lhs)], instances[underlying_type::index(rhs)]);
5780  };
5781 
5782  if constexpr(std::is_invocable_v<Compare, const object_type &, const object_type &>) {
5783  underlying_type::arrange(from, to, std::move(apply), [this, compare = std::move(compare)](const auto lhs, const auto rhs) {
5784  return compare(std::as_const(instances[underlying_type::index(lhs)]), std::as_const(instances[underlying_type::index(rhs)]));
5785  }, std::move(algo), std::forward<Args>(args)...);
5786  } else {
5787  underlying_type::arrange(from, to, std::move(apply), std::move(compare), std::move(algo), std::forward<Args>(args)...);
5788  }
5789  }
5790 
5792  void reset() {
5794  instances.clear();
5795  }
5796 
5797 private:
5798  std::vector<object_type> instances;
5799 };
5800 
5801 
5803 template<typename Entity, typename Type>
5804 class basic_storage<Entity, Type, std::enable_if_t<ENTT_ENABLE_ETO(Type)>>: public sparse_set<Entity> {
5807 
5808  class iterator {
5809  friend class basic_storage<Entity, Type>;
5810 
5811  using index_type = typename traits_type::difference_type;
5812 
5813  iterator(const index_type idx) ENTT_NOEXCEPT
5814  : index{idx}
5815  {}
5816 
5817  public:
5818  using difference_type = index_type;
5819  using value_type = Type;
5820  using pointer = const value_type *;
5821  using reference = value_type;
5822  using iterator_category = std::input_iterator_tag;
5823 
5824  iterator() ENTT_NOEXCEPT = default;
5825 
5826  iterator & operator++() ENTT_NOEXCEPT {
5827  return --index, *this;
5828  }
5829 
5830  iterator operator++(int) ENTT_NOEXCEPT {
5831  iterator orig = *this;
5832  return ++(*this), orig;
5833  }
5834 
5835  iterator & operator--() ENTT_NOEXCEPT {
5836  return ++index, *this;
5837  }
5838 
5839  iterator operator--(int) ENTT_NOEXCEPT {
5840  iterator orig = *this;
5841  return --(*this), orig;
5842  }
5843 
5844  iterator & operator+=(const difference_type value) ENTT_NOEXCEPT {
5845  index -= value;
5846  return *this;
5847  }
5848 
5849  iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
5850  return iterator{index-value};
5851  }
5852 
5853  iterator & operator-=(const difference_type value) ENTT_NOEXCEPT {
5854  return (*this += -value);
5855  }
5856 
5857  iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
5858  return (*this + -value);
5859  }
5860 
5861  difference_type operator-(const iterator &other) const ENTT_NOEXCEPT {
5862  return other.index - index;
5863  }
5864 
5865  reference operator[](const difference_type) const ENTT_NOEXCEPT {
5866  return {};
5867  }
5868 
5869  bool operator==(const iterator &other) const ENTT_NOEXCEPT {
5870  return other.index == index;
5871  }
5872 
5873  bool operator!=(const iterator &other) const ENTT_NOEXCEPT {
5874  return !(*this == other);
5875  }
5876 
5877  bool operator<(const iterator &other) const ENTT_NOEXCEPT {
5878  return index > other.index;
5879  }
5880 
5881  bool operator>(const iterator &other) const ENTT_NOEXCEPT {
5882  return index < other.index;
5883  }
5884 
5885  bool operator<=(const iterator &other) const ENTT_NOEXCEPT {
5886  return !(*this > other);
5887  }
5888 
5889  bool operator>=(const iterator &other) const ENTT_NOEXCEPT {
5890  return !(*this < other);
5891  }
5892 
5893  pointer operator->() const ENTT_NOEXCEPT {
5894  return nullptr;
5895  }
5896 
5897  reference operator*() const ENTT_NOEXCEPT {
5898  return {};
5899  }
5900 
5901  private:
5902  index_type index;
5903  };
5904 
5905 public:
5907  using object_type = Type;
5909  using entity_type = Entity;
5911  using size_type = std::size_t;
5913  using iterator_type = iterator;
5914 
5928  const typename traits_type::difference_type pos = underlying_type::size();
5929  return iterator_type{pos};
5930  }
5931 
5934  return cbegin();
5935  }
5936 
5952  return iterator_type{};
5953  }
5954 
5957  return cend();
5958  }
5959 
5976  object_type get([[maybe_unused]] const entity_type entt) const ENTT_NOEXCEPT {
5978  return {};
5979  }
5980 
5998  template<typename It>
5999  iterator_type batch(It first, It last, const object_type & = {}) {
6000  underlying_type::batch(first, last);
6001  return begin();
6002  }
6003 
6005  template<typename Compare, typename Sort = std_sort, typename... Args>
6006  void sort(iterator_type first, iterator_type last, Compare compare, Sort algo = Sort{}, Args &&... args) {
6007  ENTT_ASSERT(!(last < first));
6008  ENTT_ASSERT(!(last > end()));
6009 
6010  const auto from = underlying_type::begin() + std::distance(begin(), first);
6011  const auto to = from + std::distance(first, last);
6012 
6013  underlying_type::sort(from, to, std::move(compare), std::move(algo), std::forward<Args>(args)...);
6014  }
6015 };
6016 
6018 template<typename Entity, typename Type>
6019 struct storage: basic_storage<Entity, Type> {};
6020 
6021 
6022 }
6023 
6024 
6025 #endif // ENTT_ENTITY_STORAGE_HPP
6026 
6027 // #include "utility.hpp"
6028 #ifndef ENTT_ENTITY_UTILITY_HPP
6029 #define ENTT_ENTITY_UTILITY_HPP
6030 
6031 
6032 // #include "../core/type_traits.hpp"
6033 
6034 
6035 
6036 namespace entt {
6037 
6038 
6043 template<typename... Type>
6044 struct exclude_t: type_list<Type...> {};
6045 
6046 
6051 template<typename... Type>
6052 constexpr exclude_t<Type...> exclude{};
6053 
6054 
6059 template<typename... Type>
6060 struct get_t: type_list<Type...>{};
6061 
6062 
6067 template<typename... Type>
6068 constexpr get_t<Type...> get{};
6069 
6070 
6071 }
6072 
6073 
6074 #endif // ENTT_ENTITY_UTILITY_HPP
6075 
6076 // #include "entity.hpp"
6077 
6078 // #include "group.hpp"
6079 #ifndef ENTT_ENTITY_GROUP_HPP
6080 #define ENTT_ENTITY_GROUP_HPP
6081 
6082 
6083 #include <tuple>
6084 #include <utility>
6085 #include <type_traits>
6086 // #include "../config/config.h"
6087 
6088 // #include "../core/type_traits.hpp"
6089 
6090 // #include "sparse_set.hpp"
6091 
6092 // #include "storage.hpp"
6093 
6094 // #include "utility.hpp"
6095 
6096 // #include "fwd.hpp"
6097 
6098 
6099 
6100 namespace entt {
6101 
6102 
6109 template<typename...>
6110 class basic_group;
6111 
6112 
6152 template<typename Entity, typename... Exclude, typename... Get>
6153 class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>> {
6155  friend class basic_registry<Entity>;
6156 
6157  template<typename Component>
6158  using pool_type = std::conditional_t<std::is_const_v<Component>, const storage<Entity, std::remove_const_t<Component>>, storage<Entity, Component>>;
6159 
6160  // we could use pool_type<Type> *..., but vs complains about it and refuses to compile for unknown reasons (most likely a bug)
6161  basic_group(sparse_set<Entity> *ref, storage<Entity, std::remove_const_t<Get>> *... gpool) ENTT_NOEXCEPT
6162  : handler{ref},
6163  pools{gpool...}
6164  {}
6165 
6166  template<typename Func, typename... Weak>
6167  void traverse(Func func, type_list<Weak...>) const {
6168  for(const auto entt: *handler) {
6169  if constexpr(std::is_invocable_v<Func, decltype(get<Weak>({}))...>) {
6170  func(std::get<pool_type<Weak> *>(pools)->get(entt)...);
6171  } else {
6172  func(entt, std::get<pool_type<Weak> *>(pools)->get(entt)...);
6173  }
6174  }
6175  }
6176 
6177 public:
6179  using entity_type = Entity;
6181  using size_type = std::size_t;
6184 
6190  template<typename Component>
6192  return std::get<pool_type<Component> *>(pools)->size();
6193  }
6194 
6200  return handler->size();
6201  }
6202 
6209  return handler->capacity();
6210  }
6211 
6213  void shrink_to_fit() {
6214  handler->shrink_to_fit();
6215  }
6216 
6224  template<typename... Component>
6225  bool empty() const ENTT_NOEXCEPT {
6226  if constexpr(sizeof...(Component) == 0) {
6227  return handler->empty();
6228  } else {
6229  return (std::get<pool_type<Component> *>(pools)->empty() && ...);
6230  }
6231  }
6232 
6247  template<typename Component>
6248  Component * raw() const ENTT_NOEXCEPT {
6249  return std::get<pool_type<Component> *>(pools)->raw();
6250  }
6251 
6266  template<typename Component>
6267  const entity_type * data() const ENTT_NOEXCEPT {
6268  return std::get<pool_type<Component> *>(pools)->data();
6269  }
6270 
6283  const entity_type * data() const ENTT_NOEXCEPT {
6284  return handler->data();
6285  }
6286 
6302  return handler->begin();
6303  }
6304 
6321  return handler->end();
6322  }
6323 
6331  const auto it = handler->find(entt);
6332  return it != end() && *it == entt ? it : end();
6333  }
6334 
6341  return begin()[pos];
6342  }
6343 
6350  return find(entt) != end();
6351  }
6352 
6370  template<typename... Component>
6371  decltype(auto) get([[maybe_unused]] const entity_type entt) const ENTT_NOEXCEPT {
6372  ENTT_ASSERT(contains(entt));
6373 
6374  if constexpr(sizeof...(Component) == 1) {
6375  return (std::get<pool_type<Component> *>(pools)->get(entt), ...);
6376  } else {
6377  return std::tuple<decltype(get<Component>({}))...>{get<Component>(entt)...};
6378  }
6379  }
6380 
6404  template<typename Func>
6405  void each(Func func) const {
6406  traverse(std::move(func), type_list<Get...>{});
6407  }
6408 
6429  template<typename Func>
6430  void less(Func func) const {
6431  using get_type_list = type_list_cat_t<std::conditional_t<ENTT_ENABLE_ETO(Get), type_list<>, type_list<Get>>...>;
6432  traverse(std::move(func), get_type_list{});
6433  }
6434 
6476  template<typename... Component, typename Compare, typename Sort = std_sort, typename... Args>
6477  void sort(Compare compare, Sort algo = Sort{}, Args &&... args) {
6478  if constexpr(sizeof...(Component) == 0) {
6479  static_assert(std::is_invocable_v<Compare, const entity_type, const entity_type>);
6480  handler->sort(handler->begin(), handler->end(), std::move(compare), std::move(algo), std::forward<Args>(args)...);
6481  } else if constexpr(sizeof...(Component) == 1) {
6482  handler->sort(handler->begin(), handler->end(), [this, compare = std::move(compare)](const entity_type lhs, const entity_type rhs) {
6483  return compare((std::get<pool_type<Component> *>(pools)->get(lhs), ...), (std::get<pool_type<Component> *>(pools)->get(rhs), ...));
6484  }, std::move(algo), std::forward<Args>(args)...);
6485  } else {
6486  handler->sort(handler->begin(), handler->end(), [this, compare = std::move(compare)](const entity_type lhs, const entity_type rhs) {
6487  return compare(std::tuple<decltype(get<Component>({}))...>{std::get<pool_type<Component> *>(pools)->get(lhs)...}, std::tuple<decltype(get<Component>({}))...>{std::get<pool_type<Component> *>(pools)->get(rhs)...});
6488  }, std::move(algo), std::forward<Args>(args)...);
6489  }
6490  }
6491 
6508  template<typename Component>
6509  void sort() const {
6510  handler->respect(*std::get<pool_type<Component> *>(pools));
6511  }
6512 
6513 private:
6514  sparse_set<entity_type> *handler;
6515  const std::tuple<pool_type<Get> *...> pools;
6516 };
6517 
6518 
6566 template<typename Entity, typename... Exclude, typename... Get, typename... Owned>
6567 class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>, Owned...> {
6569  friend class basic_registry<Entity>;
6570 
6571  template<typename Component>
6572  using pool_type = std::conditional_t<std::is_const_v<Component>, const storage<Entity, std::remove_const_t<Component>>, storage<Entity, Component>>;
6573 
6574  template<typename Component>
6575  using component_iterator_type = decltype(std::declval<pool_type<Component>>().begin());
6576 
6577  // we could use pool_type<Type> *..., but vs complains about it and refuses to compile for unknown reasons (most likely a bug)
6578  basic_group(const std::size_t *ref, const std::size_t *extent, storage<Entity, std::remove_const_t<Owned>> *... opool, storage<Entity, std::remove_const_t<Get>> *... gpool) ENTT_NOEXCEPT
6579  : pools{opool..., gpool...},
6580  length{extent},
6581  super{ref}
6582  {}
6583 
6584  template<typename Func, typename... Strong, typename... Weak>
6585  void traverse(Func func, type_list<Strong...>, type_list<Weak...>) const {
6586  [[maybe_unused]] auto it = std::make_tuple((std::get<pool_type<Strong> *>(pools)->end() - *length)...);
6587  [[maybe_unused]] auto data = std::get<0>(pools)->sparse_set<entity_type>::end() - *length;
6588 
6589  for(auto next = *length; next; --next) {
6590  if constexpr(std::is_invocable_v<Func, decltype(get<Strong>({}))..., decltype(get<Weak>({}))...>) {
6591  if constexpr(sizeof...(Weak) == 0) {
6592  func(*(std::get<component_iterator_type<Strong>>(it)++)...);
6593  } else {
6594  const auto entt = *(data++);
6595  func(*(std::get<component_iterator_type<Strong>>(it)++)..., std::get<pool_type<Weak> *>(pools)->get(entt)...);
6596  }
6597  } else {
6598  const auto entt = *(data++);
6599  func(entt, *(std::get<component_iterator_type<Strong>>(it)++)..., std::get<pool_type<Weak> *>(pools)->get(entt)...);
6600  }
6601  }
6602  }
6603 
6604 public:
6606  using entity_type = Entity;
6608  using size_type = std::size_t;
6611 
6617  template<typename Component>
6619  return std::get<pool_type<Component> *>(pools)->size();
6620  }
6621 
6627  return *length;
6628  }
6629 
6637  template<typename... Component>
6638  bool empty() const ENTT_NOEXCEPT {
6639  if constexpr(sizeof...(Component) == 0) {
6640  return !*length;
6641  } else {
6642  return (std::get<pool_type<Component> *>(pools)->empty() && ...);
6643  }
6644  }
6645 
6663  template<typename Component>
6664  Component * raw() const ENTT_NOEXCEPT {
6665  return std::get<pool_type<Component> *>(pools)->raw();
6666  }
6667 
6685  template<typename Component>
6686  const entity_type * data() const ENTT_NOEXCEPT {
6687  return std::get<pool_type<Component> *>(pools)->data();
6688  }
6689 
6702  const entity_type * data() const ENTT_NOEXCEPT {
6703  return std::get<0>(pools)->data();
6704  }
6705 
6721  return std::get<0>(pools)->sparse_set<entity_type>::end() - *length;
6722  }
6723 
6740  return std::get<0>(pools)->sparse_set<entity_type>::end();
6741  }
6742 
6750  const auto it = std::get<0>(pools)->find(entt);
6751  return it != end() && it >= begin() && *it == entt ? it : end();
6752  }
6753 
6760  return begin()[pos];
6761  }
6762 
6769  return find(entt) != end();
6770  }
6771 
6789  template<typename... Component>
6790  decltype(auto) get([[maybe_unused]] const entity_type entt) const ENTT_NOEXCEPT {
6791  ENTT_ASSERT(contains(entt));
6792 
6793  if constexpr(sizeof...(Component) == 1) {
6794  return (std::get<pool_type<Component> *>(pools)->get(entt), ...);
6795  } else {
6796  return std::tuple<decltype(get<Component>({}))...>{get<Component>(entt)...};
6797  }
6798  }
6799 
6823  template<typename Func>
6824  void each(Func func) const {
6825  traverse(std::move(func), type_list<Owned...>{}, type_list<Get...>{});
6826  }
6827 
6848  template<typename Func>
6849  void less(Func func) const {
6850  using owned_type_list = type_list_cat_t<std::conditional_t<ENTT_ENABLE_ETO(Owned), type_list<>, type_list<Owned>>...>;
6851  using get_type_list = type_list_cat_t<std::conditional_t<ENTT_ENABLE_ETO(Get), type_list<>, type_list<Get>>...>;
6852  traverse(std::move(func), owned_type_list{}, get_type_list{});
6853  }
6854 
6859  bool sortable() const ENTT_NOEXCEPT {
6860  constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
6861  return *super == size;
6862  }
6863 
6906  template<typename... Component, typename Compare, typename Sort = std_sort, typename... Args>
6907  void sort(Compare compare, Sort algo = Sort{}, Args &&... args) {
6908  ENTT_ASSERT(sortable());
6909  auto *cpool = std::get<0>(pools);
6910 
6911  if constexpr(sizeof...(Component) == 0) {
6912  static_assert(std::is_invocable_v<Compare, const entity_type, const entity_type>);
6913  cpool->sort(cpool->end()-*length, cpool->end(), std::move(compare), std::move(algo), std::forward<Args>(args)...);
6914  } else if constexpr(sizeof...(Component) == 1) {
6915  cpool->sort(cpool->end()-*length, cpool->end(), [this, compare = std::move(compare)](const entity_type lhs, const entity_type rhs) {
6916  return compare((std::get<pool_type<Component> *>(pools)->get(lhs), ...), (std::get<pool_type<Component> *>(pools)->get(rhs), ...));
6917  }, std::move(algo), std::forward<Args>(args)...);
6918  } else {
6919  cpool->sort(cpool->end()-*length, cpool->end(), [this, compare = std::move(compare)](const entity_type lhs, const entity_type rhs) {
6920  return compare(std::tuple<decltype(get<Component>({}))...>{std::get<pool_type<Component> *>(pools)->get(lhs)...}, std::tuple<decltype(get<Component>({}))...>{std::get<pool_type<Component> *>(pools)->get(rhs)...});
6921  }, std::move(algo), std::forward<Args>(args)...);
6922  }
6923 
6924  [this](auto *head, auto *... other) {
6925  for(auto next = *length; next; --next) {
6926  const auto pos = next - 1;
6927  [[maybe_unused]] const auto entt = head->data()[pos];
6928  (other->swap(other->data()[pos], entt), ...);
6929  }
6930  }(std::get<pool_type<Owned> *>(pools)...);
6931  }
6932 
6933 private:
6934  const std::tuple<pool_type<Owned> *..., pool_type<Get> *...> pools;
6935  const size_type *length;
6936  const size_type *super;
6937 };
6938 
6939 
6940 }
6941 
6942 
6943 #endif // ENTT_ENTITY_GROUP_HPP
6944 
6945 // #include "view.hpp"
6946 #ifndef ENTT_ENTITY_VIEW_HPP
6947 #define ENTT_ENTITY_VIEW_HPP
6948 
6949 
6950 #include <iterator>
6951 #include <array>
6952 #include <tuple>
6953 #include <utility>
6954 #include <algorithm>
6955 #include <type_traits>
6956 // #include "../config/config.h"
6957 
6958 // #include "../core/type_traits.hpp"
6959 
6960 // #include "sparse_set.hpp"
6961 
6962 // #include "storage.hpp"
6963 
6964 // #include "utility.hpp"
6965 
6966 // #include "entity.hpp"
6967 
6968 // #include "fwd.hpp"
6969 
6970 
6971 
6972 namespace entt {
6973 
6974 
6981 template<typename...>
6982 class basic_view;
6983 
6984 
7022 template<typename Entity, typename... Exclude, typename... Component>
7023 class basic_view<Entity, exclude_t<Exclude...>, Component...> {
7025  friend class basic_registry<Entity>;
7026 
7027  template<typename Comp>
7028  using pool_type = std::conditional_t<std::is_const_v<Comp>, const storage<Entity, std::remove_const_t<Comp>>, storage<Entity, Comp>>;
7029 
7030  template<typename Comp>
7031  using component_iterator_type = decltype(std::declval<pool_type<Comp>>().begin());
7032 
7033  using underlying_iterator_type = typename sparse_set<Entity>::iterator_type;
7034  using unchecked_type = std::array<const sparse_set<Entity> *, (sizeof...(Component) - 1)>;
7035  using filter_type = std::array<const sparse_set<Entity> *, sizeof...(Exclude)>;
7036 
7037  class iterator {
7038  friend class basic_view<Entity, exclude_t<Exclude...>, Component...>;
7039 
7040  iterator(underlying_iterator_type first, underlying_iterator_type last, unchecked_type other, filter_type ignore) ENTT_NOEXCEPT
7041  : begin{first},
7042  end{last},
7043  unchecked{other},
7044  filter{ignore}
7045  {
7046  if(begin != end && !valid()) {
7047  ++(*this);
7048  }
7049  }
7050 
7051  bool valid() const ENTT_NOEXCEPT {
7052  return std::all_of(unchecked.cbegin(), unchecked.cend(), [this](const sparse_set<Entity> *view) { return view->has(*begin); })
7053  && std::none_of(filter.cbegin(), filter.cend(), [this](const sparse_set<Entity> *view) { return view->has(*begin); });
7054  }
7055 
7056  public:
7057  using difference_type = typename underlying_iterator_type::difference_type;
7058  using value_type = typename underlying_iterator_type::value_type;
7059  using pointer = typename underlying_iterator_type::pointer;
7060  using reference = typename underlying_iterator_type::reference;
7061  using iterator_category = std::forward_iterator_tag;
7062 
7063  iterator() ENTT_NOEXCEPT = default;
7064 
7065  iterator & operator++() ENTT_NOEXCEPT {
7066  return (++begin != end && !valid()) ? ++(*this) : *this;
7067  }
7068 
7069  iterator operator++(int) ENTT_NOEXCEPT {
7070  iterator orig = *this;
7071  return ++(*this), orig;
7072  }
7073 
7074  bool operator==(const iterator &other) const ENTT_NOEXCEPT {
7075  return other.begin == begin;
7076  }
7077 
7078  bool operator!=(const iterator &other) const ENTT_NOEXCEPT {
7079  return !(*this == other);
7080  }
7081 
7082  pointer operator->() const ENTT_NOEXCEPT {
7083  return begin.operator->();
7084  }
7085 
7086  reference operator*() const ENTT_NOEXCEPT {
7087  return *operator->();
7088  }
7089 
7090  private:
7091  underlying_iterator_type begin;
7092  underlying_iterator_type end;
7093  unchecked_type unchecked;
7094  filter_type filter;
7095  };
7096 
7097  // we could use pool_type<Component> *..., but vs complains about it and refuses to compile for unknown reasons (likely a bug)
7098  basic_view(storage<Entity, std::remove_const_t<Component>> *... component, storage<Entity, std::remove_const_t<Exclude>> *... epool) ENTT_NOEXCEPT
7099  : pools{component...},
7100  filter{epool...}
7101  {}
7102 
7103  const sparse_set<Entity> * candidate() const ENTT_NOEXCEPT {
7104  return std::min({ static_cast<const sparse_set<Entity> *>(std::get<pool_type<Component> *>(pools))... }, [](const auto *lhs, const auto *rhs) {
7105  return lhs->size() < rhs->size();
7106  });
7107  }
7108 
7109  unchecked_type unchecked(const sparse_set<Entity> *view) const ENTT_NOEXCEPT {
7110  std::size_t pos{};
7111  unchecked_type other{};
7112  ((std::get<pool_type<Component> *>(pools) == view ? nullptr : (other[pos++] = std::get<pool_type<Component> *>(pools))), ...);
7113  return other;
7114  }
7115 
7116  template<typename Comp, typename Other>
7117  decltype(auto) get([[maybe_unused]] component_iterator_type<Comp> it, [[maybe_unused]] pool_type<Other> *cpool, [[maybe_unused]] const Entity entt) const ENTT_NOEXCEPT {
7118  if constexpr(std::is_same_v<Comp, Other>) {
7119  return *it;
7120  } else {
7121  return cpool->get(entt);
7122  }
7123  }
7124 
7125  template<typename Comp, typename Func, typename... Other, typename... Type>
7126  void traverse(Func func, type_list<Other...>, type_list<Type...>) const {
7127  const auto end = std::get<pool_type<Comp> *>(pools)->sparse_set<Entity>::end();
7128  auto begin = std::get<pool_type<Comp> *>(pools)->sparse_set<Entity>::begin();
7129 
7130  if constexpr(std::disjunction_v<std::is_same<Comp, Type>...>) {
7131  std::for_each(begin, end, [this, raw = std::get<pool_type<Comp> *>(pools)->begin(), &func](const auto entity) mutable {
7132  auto curr = raw++;
7133 
7134  if((std::get<pool_type<Other> *>(pools)->has(entity) && ...) && (!std::get<pool_type<Exclude> *>(filter)->has(entity) && ...)) {
7135  if constexpr(std::is_invocable_v<Func, decltype(get<Type>({}))...>) {
7136  func(get<Comp, Type>(curr, std::get<pool_type<Type> *>(pools), entity)...);
7137  } else {
7138  func(entity, get<Comp, Type>(curr, std::get<pool_type<Type> *>(pools), entity)...);
7139  }
7140  }
7141  });
7142  } else {
7143  std::for_each(begin, end, [this, &func](const auto entity) {
7144  if((std::get<pool_type<Other> *>(pools)->has(entity) && ...) && (!std::get<pool_type<Exclude> *>(filter)->has(entity) && ...)) {
7145  if constexpr(std::is_invocable_v<Func, decltype(get<Type>({}))...>) {
7146  func(std::get<pool_type<Type> *>(pools)->get(entity)...);
7147  } else {
7148  func(entity, std::get<pool_type<Type> *>(pools)->get(entity)...);
7149  }
7150  }
7151  });
7152  }
7153  }
7154 
7155 public:
7157  using entity_type = Entity;
7159  using size_type = std::size_t;
7161  using iterator_type = iterator;
7162 
7171  template<typename Comp>
7173  return std::get<pool_type<Comp> *>(pools)->size();
7174  }
7175 
7181  return std::min({ std::get<pool_type<Component> *>(pools)->size()... });
7182  }
7183 
7196  template<typename... Comp>
7197  bool empty() const ENTT_NOEXCEPT {
7198  if constexpr(sizeof...(Comp) == 0) {
7199  return (std::get<pool_type<Component> *>(pools)->empty() || ...);
7200  } else {
7201  return (std::get<pool_type<Comp> *>(pools)->empty() && ...);
7202  }
7203  }
7204 
7219  template<typename Comp>
7220  Comp * raw() const ENTT_NOEXCEPT {
7221  return std::get<pool_type<Comp> *>(pools)->raw();
7222  }
7223 
7238  template<typename Comp>
7239  const entity_type * data() const ENTT_NOEXCEPT {
7240  return std::get<pool_type<Comp> *>(pools)->data();
7241  }
7242 
7258  const auto *view = candidate();
7259  const filter_type ignore{std::get<pool_type<Exclude> *>(filter)...};
7260  return iterator_type{view->begin(), view->end(), unchecked(view), ignore};
7261  }
7262 
7279  const auto *view = candidate();
7280  const filter_type ignore{std::get<pool_type<Exclude> *>(filter)...};
7281  return iterator_type{view->end(), view->end(), unchecked(view), ignore};
7282  }
7283 
7291  const auto *view = candidate();
7292  const filter_type ignore{std::get<pool_type<Exclude> *>(filter)...};
7293  iterator_type it{view->find(entt), view->end(), unchecked(view), ignore};
7294  return (it != end() && *it == entt) ? it : end();
7295  }
7296 
7303  return find(entt) != end();
7304  }
7305 
7323  template<typename... Comp>
7324  decltype(auto) get([[maybe_unused]] const entity_type entt) const ENTT_NOEXCEPT {
7325  ENTT_ASSERT(contains(entt));
7326 
7327  if constexpr(sizeof...(Comp) == 0) {
7328  static_assert(sizeof...(Component) == 1);
7329  return (std::get<pool_type<Component> *>(pools)->get(entt), ...);
7330  } else if constexpr(sizeof...(Comp) == 1) {
7331  return (std::get<pool_type<Comp> *>(pools)->get(entt), ...);
7332  } else {
7333  return std::tuple<decltype(get<Comp>({}))...>{get<Comp>(entt)...};
7334  }
7335  }
7336 
7360  template<typename Func>
7361  void each(Func func) const {
7362  const auto *view = candidate();
7363  ((std::get<pool_type<Component> *>(pools) == view ? each<Component>(std::move(func)) : void()), ...);
7364  }
7365 
7396  template<typename Comp, typename Func>
7397  void each(Func func) const {
7399  traverse<Comp>(std::move(func), other_type{}, type_list<Component...>{});
7400  }
7401 
7422  template<typename Func>
7423  void less(Func func) const {
7424  const auto *view = candidate();
7425  ((std::get<pool_type<Component> *>(pools) == view ? less<Component>(std::move(func)) : void()), ...);
7426  }
7427 
7455  template<typename Comp, typename Func>
7456  void less(Func func) const {
7458  using non_empty_type = type_list_cat_t<std::conditional_t<ENTT_ENABLE_ETO(Component), type_list<>, type_list<Component>>...>;
7459  traverse<Comp>(std::move(func), other_type{}, non_empty_type{});
7460  }
7461 
7462 private:
7463  const std::tuple<pool_type<Component> *...> pools;
7464  const std::tuple<pool_type<Exclude> *...> filter;
7465 };
7466 
7467 
7501 template<typename Entity, typename Component>
7502 class basic_view<Entity, exclude_t<>, Component> {
7504  friend class basic_registry<Entity>;
7505 
7506  using pool_type = std::conditional_t<std::is_const_v<Component>, const storage<Entity, std::remove_const_t<Component>>, storage<Entity, Component>>;
7507 
7508  basic_view(pool_type *ref) ENTT_NOEXCEPT
7509  : pool{ref}
7510  {}
7511 
7512 public:
7514  using raw_type = Component;
7516  using entity_type = Entity;
7518  using size_type = std::size_t;
7521 
7527  return pool->size();
7528  }
7529 
7534  bool empty() const ENTT_NOEXCEPT {
7535  return pool->empty();
7536  }
7537 
7551  return pool->raw();
7552  }
7553 
7566  const entity_type * data() const ENTT_NOEXCEPT {
7567  return pool->data();
7568  }
7569 
7585  return pool->sparse_set<Entity>::begin();
7586  }
7587 
7604  return pool->sparse_set<Entity>::end();
7605  }
7606 
7614  const auto it = pool->find(entt);
7615  return it != end() && *it == entt ? it : end();
7616  }
7617 
7624  return begin()[pos];
7625  }
7626 
7633  return find(entt) != end();
7634  }
7635 
7651  template<typename Comp = Component>
7652  decltype(auto) get(const entity_type entt) const ENTT_NOEXCEPT {
7653  static_assert(std::is_same_v<Comp, Component>);
7654  ENTT_ASSERT(contains(entt));
7655  return pool->get(entt);
7656  }
7657 
7681  template<typename Func>
7682  void each(Func func) const {
7683  if constexpr(std::is_invocable_v<Func, decltype(get({}))>) {
7684  std::for_each(pool->begin(), pool->end(), std::move(func));
7685  } else {
7686  std::for_each(pool->sparse_set<Entity>::begin(), pool->sparse_set<Entity>::end(), [&func, raw = pool->begin()](const auto entt) mutable {
7687  func(entt, *(raw++));
7688  });
7689  }
7690  }
7691 
7720  template<typename Func>
7721  void less(Func func) const {
7722  if constexpr(ENTT_ENABLE_ETO(Component)) {
7723  if constexpr(std::is_invocable_v<Func>) {
7724  for(auto pos = pool->size(); pos; --pos) {
7725  func();
7726  }
7727  } else {
7728  std::for_each(pool->sparse_set<Entity>::begin(), pool->sparse_set<Entity>::end(), std::move(func));
7729  }
7730  } else {
7731  each(std::move(func));
7732  }
7733  }
7734 
7735 private:
7736  pool_type *pool;
7737 };
7738 
7739 
7740 }
7741 
7742 
7743 #endif // ENTT_ENTITY_VIEW_HPP
7744 
7745 // #include "fwd.hpp"
7746 
7747 
7748 
7749 namespace entt {
7750 
7751 
7762 template<typename Entity>
7763 class basic_registry {
7764  using context_family = family<struct internal_registry_context_family>;
7765  using component_family = family<struct internal_registry_component_family>;
7766  using traits_type = entt_traits<std::underlying_type_t<Entity>>;
7767 
7768  template<typename Component>
7769  struct pool_handler: storage<Entity, Component> {
7770  std::size_t super{};
7771 
7772  template<typename... Args>
7773  pool_handler(Args &&... args)
7774  : storage<Entity, Component>{std::forward<Args>(args)...},
7775  super{}
7776  {}
7777 
7778  auto on_construct() ENTT_NOEXCEPT {
7779  return sink{construction};
7780  }
7781 
7782  auto on_replace() ENTT_NOEXCEPT {
7783  return sink{update};
7784  }
7785 
7786  auto on_destroy() ENTT_NOEXCEPT {
7787  return sink{destruction};
7788  }
7789 
7790  template<typename... Args>
7791  decltype(auto) assign(basic_registry &owner, const Entity entt, Args &&... args) {
7792  if constexpr(ENTT_ENABLE_ETO(Component)) {
7794  construction.publish(entt, owner, Component{});
7795  return Component{std::forward<Args>(args)...};
7796  } else {
7797  auto &component = storage<Entity, Component>::construct(entt, std::forward<Args>(args)...);
7798  construction.publish(entt, owner, component);
7799  return component;
7800  }
7801  }
7802 
7803  template<typename It, typename... Args>
7804  auto batch(basic_registry &owner, It first, It last, Args &&... args) {
7805  auto it = storage<Entity, Component>::batch(first, last, std::forward<Args>(args)...);
7806 
7807  if(!construction.empty()) {
7808  std::for_each(first, last, [this, &owner, it](const auto entt) mutable {
7809  construction.publish(entt, owner, *(it++));
7810  });
7811  }
7812 
7813  return it;
7814  }
7815 
7816  void remove(basic_registry &owner, const Entity entt) {
7817  destruction.publish(entt, owner);
7819  }
7820 
7821  template<typename... Args>
7822  decltype(auto) replace(basic_registry &owner, const Entity entt, Args &&... args) {
7823  if constexpr(ENTT_ENABLE_ETO(Component)) {
7825  update.publish(entt, owner, Component{});
7826  return Component{std::forward<Args>(args)...};
7827  } else {
7828  Component component{std::forward<Args>(args)...};
7829  update.publish(entt, owner, component);
7830  return (storage<Entity, Component>::get(entt) = std::move(component));
7831  }
7832  }
7833 
7834  private:
7835  using reference_type = std::conditional_t<ENTT_ENABLE_ETO(Component), const Component &, Component &>;
7836  sigh<void(const Entity, basic_registry &, reference_type)> construction{};
7837  sigh<void(const Entity, basic_registry &, reference_type)> update{};
7838  sigh<void(const Entity, basic_registry &)> destruction{};
7839  };
7840 
7841  template<typename Component>
7842  using pool_type = pool_handler<std::decay_t<Component>>;
7843 
7844  template<typename...>
7845  struct group_handler;
7846 
7847  template<typename... Exclude, typename... Get>
7848  struct group_handler<exclude_t<Exclude...>, get_t<Get...>> {
7849  const std::tuple<pool_type<Get> *..., pool_type<Exclude> *...> cpools{};
7850  sparse_set<Entity> set{};
7851 
7852  template<typename Component>
7853  void maybe_valid_if(const Entity entt) {
7854  if constexpr(std::disjunction_v<std::is_same<Get, Component>...>) {
7855  if(((std::is_same_v<Component, Get> || std::get<pool_type<Get> *>(cpools)->has(entt)) && ...)
7856  && (!std::get<pool_type<Exclude> *>(cpools)->has(entt) && ...)
7857  && !set.has(entt))
7858  {
7859  set.construct(entt);
7860  }
7861  } else if constexpr(std::disjunction_v<std::is_same<Exclude, Component>...>) {
7862  if((std::get<pool_type<Get> *>(cpools)->has(entt) && ...)
7863  && ((std::is_same_v<Exclude, Component> || !std::get<pool_type<Exclude> *>(cpools)->has(entt)) && ...)
7864  && !set.has(entt))
7865  {
7866  set.construct(entt);
7867  }
7868  }
7869  }
7870 
7871  void discard_if(const Entity entt) {
7872  if(set.has(entt)) {
7873  set.destroy(entt);
7874  }
7875  }
7876  };
7877 
7878  template<typename... Exclude, typename... Get, typename... Owned>
7879  struct group_handler<exclude_t<Exclude...>, get_t<Get...>, Owned...> {
7880  const std::tuple<pool_type<Owned> *..., pool_type<Get> *..., pool_type<Exclude> *...> cpools{};
7881  std::size_t owned{};
7882 
7883  template<typename Component>
7884  void maybe_valid_if(const Entity entt) {
7885  if constexpr(std::disjunction_v<std::is_same<Owned, Component>..., std::is_same<Get, Component>...>) {
7886  if(((std::is_same_v<Component, Owned> || std::get<pool_type<Owned> *>(cpools)->has(entt)) && ...)
7887  && ((std::is_same_v<Component, Get> || std::get<pool_type<Get> *>(cpools)->has(entt)) && ...)
7888  && (!std::get<pool_type<Exclude> *>(cpools)->has(entt) && ...)
7889  && !(std::get<0>(cpools)->index(entt) < owned))
7890  {
7891  const auto pos = owned++;
7892  (std::get<pool_type<Owned> *>(cpools)->swap(std::get<pool_type<Owned> *>(cpools)->data()[pos], entt), ...);
7893  }
7894  } else if constexpr(std::disjunction_v<std::is_same<Exclude, Component>...>) {
7895  if((std::get<pool_type<Owned> *>(cpools)->has(entt) && ...)
7896  && (std::get<pool_type<Get> *>(cpools)->has(entt) && ...)
7897  && ((std::is_same_v<Exclude, Component> || !std::get<pool_type<Exclude> *>(cpools)->has(entt)) && ...)
7898  && !(std::get<0>(cpools)->index(entt) < owned))
7899  {
7900  const auto pos = owned++;
7901  (std::get<pool_type<Owned> *>(cpools)->swap(std::get<pool_type<Owned> *>(cpools)->data()[pos], entt), ...);
7902  }
7903  }
7904  }
7905 
7906  void discard_if(const Entity entt) {
7907  if(std::get<0>(cpools)->has(entt) && std::get<0>(cpools)->index(entt) < owned) {
7908  const auto pos = --owned;
7909  (std::get<pool_type<Owned> *>(cpools)->swap(std::get<pool_type<Owned> *>(cpools)->data()[pos], entt), ...);
7910  }
7911  }
7912  };
7913 
7914  struct pool_data {
7915  std::unique_ptr<sparse_set<Entity>> pool;
7916  void(* remove)(sparse_set<Entity> &, basic_registry &, const Entity);
7917  std::unique_ptr<sparse_set<Entity>>(* clone)(const sparse_set<Entity> &);
7918  void(* stomp)(const sparse_set<Entity> &, const Entity, basic_registry &, const Entity);
7919  ENTT_ID_TYPE runtime_type;
7920  };
7921 
7922  struct group_data {
7923  std::size_t extent[3];
7924  std::unique_ptr<void, void(*)(void *)> group;
7925  bool(* owned)(const component) ENTT_NOEXCEPT;
7926  bool(* get)(const component) ENTT_NOEXCEPT;
7927  bool(* exclude)(const component) ENTT_NOEXCEPT;
7928  };
7929 
7930  struct ctx_variable {
7931  std::unique_ptr<void, void(*)(void *)> value;
7932  ENTT_ID_TYPE runtime_type;
7933  };
7934 
7935  template<typename Type, typename Family>
7936  static ENTT_ID_TYPE runtime_type() ENTT_NOEXCEPT {
7937  if constexpr(is_named_type_v<Type>) {
7938  return named_type_traits_v<Type>;
7939  } else {
7940  return Family::template type<std::decay_t<Type>>;
7941  }
7942  }
7943 
7944  auto generate() {
7945  Entity entt;
7946 
7947  if(destroyed == null) {
7948  entt = entities.emplace_back(entity_type(entities.size()));
7949  // traits_type::entity_mask is reserved to allow for null identifiers
7950  ENTT_ASSERT(to_integer(entt) < traits_type::entity_mask);
7951  } else {
7952  const auto curr = to_integer(destroyed);
7953  const auto version = to_integer(entities[curr]) & (traits_type::version_mask << traits_type::entity_shift);
7954  destroyed = entity_type{to_integer(entities[curr]) & traits_type::entity_mask};
7955  entt = entity_type{curr | version};
7956  entities[curr] = entt;
7957  }
7958 
7959  return entt;
7960  }
7961 
7962  void release(const Entity entity) {
7963  // lengthens the implicit list of destroyed entities
7964  const auto entt = to_integer(entity) & traits_type::entity_mask;
7965  const auto version = ((to_integer(entity) >> traits_type::entity_shift) + 1) << traits_type::entity_shift;
7966  const auto node = to_integer(destroyed) | version;
7967  entities[entt] = Entity{node};
7968  destroyed = Entity{entt};
7969  }
7970 
7971  template<typename Component>
7972  const pool_type<Component> * assure() const {
7973  const auto ctype = to_integer(type<Component>());
7974  pool_data *pdata = nullptr;
7975 
7976  if constexpr(is_named_type_v<Component>) {
7977  const auto it = std::find_if(pools.begin()+skip_family_pools, pools.end(), [ctype](const auto &candidate) {
7978  return candidate.runtime_type == ctype;
7979  });
7980 
7981  pdata = (it == pools.cend() ? &pools.emplace_back() : &(*it));
7982  } else {
7983  if(!(ctype < skip_family_pools)) {
7984  pools.reserve(pools.size()+ctype-skip_family_pools+1);
7985 
7986  while(!(ctype < skip_family_pools)) {
7987  pools.emplace(pools.begin()+(skip_family_pools++), pool_data{});
7988  }
7989  }
7990 
7991  pdata = &pools[ctype];
7992  }
7993 
7994  if(!pdata->pool) {
7995  pdata->runtime_type = ctype;
7996  pdata->pool = std::make_unique<pool_type<Component>>();
7997 
7998  pdata->remove = [](sparse_set<Entity> &cpool, basic_registry &owner, const Entity entt) {
7999  static_cast<pool_type<Component> &>(cpool).remove(owner, entt);
8000  };
8001 
8002  if constexpr(std::is_copy_constructible_v<std::decay_t<Component>>) {
8003  pdata->clone = [](const sparse_set<Entity> &cpool) -> std::unique_ptr<sparse_set<Entity>> {
8004  return std::make_unique<pool_type<Component>>(static_cast<const pool_type<Component> &>(cpool));
8005  };
8006 
8007  pdata->stomp = [](const sparse_set<Entity> &cpool, const Entity from, basic_registry &other, const Entity to) {
8008  other.assign_or_replace<Component>(to, static_cast<const pool_type<Component> &>(cpool).get(from));
8009  };
8010  } else {
8011  pdata->clone = nullptr;
8012  pdata->stomp = nullptr;
8013  }
8014  }
8015 
8016  return static_cast<pool_type<Component> *>(pdata->pool.get());
8017  }
8018 
8019  template<typename Component>
8020  pool_type<Component> * assure() {
8021  return const_cast<pool_type<Component> *>(std::as_const(*this).template assure<Component>());
8022  }
8023 
8024 public:
8026  using entity_type = Entity;
8028  using version_type = typename traits_type::version_type;
8030  using size_type = std::size_t;
8031 
8033  basic_registry() ENTT_NOEXCEPT = default;
8034 
8036  basic_registry(basic_registry &&) = default;
8037 
8039  basic_registry & operator=(basic_registry &&) = default;
8040 
8050  template<typename Component>
8051  static component type() ENTT_NOEXCEPT {
8052  return component{runtime_type<Component, component_family>()};
8053  }
8054 
8059  template<typename... Component>
8060  void prepare() {
8061  (assure<Component>(), ...);
8062  }
8063 
8069  template<typename Component>
8071  return assure<Component>()->size();
8072  }
8073 
8079  return entities.size();
8080  }
8081 
8087  auto sz = entities.size();
8088  auto curr = destroyed;
8089 
8090  for(; curr != null; --sz) {
8091  curr = entities[to_integer(curr) & traits_type::entity_mask];
8092  }
8093 
8094  return sz;
8095  }
8096 
8110  template<typename... Component>
8111  void reserve(const size_type cap) {
8112  if constexpr(sizeof...(Component) == 0) {
8113  entities.reserve(cap);
8114  } else {
8115  (assure<Component>()->reserve(cap), ...);
8116  }
8117  }
8118 
8124  template<typename Component>
8126  return assure<Component>()->capacity();
8127  }
8128 
8135  return entities.capacity();
8136  }
8137 
8143  template<typename... Component>
8144  void shrink_to_fit() {
8145  (assure<Component>()->shrink_to_fit(), ...);
8146  }
8147 
8159  template<typename... Component>
8160  bool empty() const ENTT_NOEXCEPT {
8161  if constexpr(sizeof...(Component) == 0) {
8162  return !alive();
8163  } else {
8164  return (assure<Component>()->empty() && ...);
8165  }
8166  }
8167 
8185  template<typename Component>
8186  const Component * raw() const ENTT_NOEXCEPT {
8187  return assure<Component>()->raw();
8188  }
8189 
8191  template<typename Component>
8192  Component * raw() ENTT_NOEXCEPT {
8193  return const_cast<Component *>(std::as_const(*this).template raw<Component>());
8194  }
8195 
8209  template<typename Component>
8210  const entity_type * data() const ENTT_NOEXCEPT {
8211  return assure<Component>()->data();
8212  }
8213 
8220  const auto pos = size_type(to_integer(entity) & traits_type::entity_mask);
8221  return (pos < entities.size() && entities[pos] == entity);
8222  }
8223 
8230  return entity_type{to_integer(entity) & traits_type::entity_mask};
8231  }
8232 
8239  return version_type(to_integer(entity) >> traits_type::entity_shift);
8240  }
8241 
8256  const auto pos = size_type(to_integer(entity) & traits_type::entity_mask);
8257  ENTT_ASSERT(pos < entities.size());
8258  return version_type(to_integer(entities[pos]) >> traits_type::entity_shift);
8259  }
8260 
8283  template<typename... Component>
8284  auto create() {
8285  if constexpr(sizeof...(Component) == 0) {
8286  return generate();
8287  } else {
8288  const entity_type entt = generate();
8289  return std::tuple<entity_type, decltype(assign<Component>({}))...>{entt, assign<Component>(entt)...};
8290  }
8291  }
8292 
8309  template<typename... Component, typename It>
8310  auto create(It first, It last) {
8311  std::generate(first, last, [this]() { return generate(); });
8312 
8313  if constexpr(sizeof...(Component) > 0) {
8314  // the reverse iterators guarantee the ordering between entities and components (hint: the pools return begin())
8315  return std::make_tuple(assure<Component>()->batch(*this, std::make_reverse_iterator(last), std::make_reverse_iterator(first))...);
8316  }
8317  }
8318 
8338  template<typename... Component, typename... Exclude>
8340  const auto entt = create();
8341  stomp<Component...>(entt, src, other, exclude<Exclude...>);
8342  return entt;
8343  }
8344 
8367  template<typename... Component, typename It, typename... Exclude>
8368  void create(It first, It last, entity_type src, const basic_registry &other, exclude_t<Exclude...> = {}) {
8369  create(first, last);
8370 
8371  if constexpr(sizeof...(Component) == 0) {
8372  stomp<Component...>(first, last, src, other, exclude<Exclude...>);
8373  } else {
8374  static_assert(sizeof...(Exclude) == 0);
8375  (assure<Component>()->batch(*this, std::make_reverse_iterator(last), std::make_reverse_iterator(first), other.get<Component>(src)), ...);
8376  }
8377  }
8378 
8403 
8404  for(auto pos = pools.size(); pos; --pos) {
8405  if(auto &pdata = pools[pos-1]; pdata.pool && pdata.pool->has(entity)) {
8406  pdata.remove(*pdata.pool, *this, entity);
8407  }
8408  }
8409 
8410  // just a way to protect users from listeners that attach components
8412  release(entity);
8413  }
8414 
8424  template<typename It>
8425  void destroy(It first, It last) {
8426  // useless this-> used to suppress a warning with clang
8427  std::for_each(first, last, [this](const auto entity) { this->destroy(entity); });
8428  }
8429 
8450  template<typename Component, typename... Args>
8451  decltype(auto) assign(const entity_type entity, [[maybe_unused]] Args &&... args) {
8453  return assure<Component>()->assign(*this, entity, std::forward<Args>(args)...);
8454  }
8455 
8469  template<typename Component>
8470  void remove(const entity_type entity) {
8472  assure<Component>()->remove(*this, entity);
8473  }
8474 
8487  template<typename... Component>
8488  bool has(const entity_type entity) const ENTT_NOEXCEPT {
8490  return (assure<Component>()->has(entity) && ...);
8491  }
8492 
8507  template<typename... Component>
8508  decltype(auto) get([[maybe_unused]] const entity_type entity) const {
8510 
8511  if constexpr(sizeof...(Component) == 1) {
8512  return (assure<Component>()->get(entity), ...);
8513  } else {
8514  return std::tuple<decltype(get<Component>({}))...>{get<Component>(entity)...};
8515  }
8516  }
8517 
8519  template<typename... Component>
8520  decltype(auto) get([[maybe_unused]] const entity_type entity) ENTT_NOEXCEPT {
8522 
8523  if constexpr(sizeof...(Component) == 1) {
8524  return (assure<Component>()->get(entity), ...);
8525  } else {
8526  return std::tuple<decltype(get<Component>({}))...>{get<Component>(entity)...};
8527  }
8528  }
8529 
8554  template<typename Component, typename... Args>
8555  decltype(auto) get_or_assign(const entity_type entity, Args &&... args) ENTT_NOEXCEPT {
8557  auto *cpool = assure<Component>();
8558  return cpool->has(entity) ? cpool->get(entity) : cpool->assign(*this, entity, std::forward<Args>(args)...);
8559  }
8560 
8573  template<typename... Component>
8574  auto try_get([[maybe_unused]] const entity_type entity) const ENTT_NOEXCEPT {
8576 
8577  if constexpr(sizeof...(Component) == 1) {
8578  return (assure<Component>()->try_get(entity), ...);
8579  } else {
8580  return std::tuple<decltype(try_get<Component>({}))...>{try_get<Component>(entity)...};
8581  }
8582  }
8583 
8585  template<typename... Component>
8586  auto try_get([[maybe_unused]] const entity_type entity) ENTT_NOEXCEPT {
8587  if constexpr(sizeof...(Component) == 1) {
8588  return (assure<Component>()->try_get(entity), ...);
8589  } else {
8590  return std::tuple<decltype(try_get<Component>({}))...>{try_get<Component>(entity)...};
8591  }
8592  }
8593 
8614  template<typename Component, typename... Args>
8615  decltype(auto) replace(const entity_type entity, Args &&... args) {
8617  return assure<Component>()->replace(*this, entity, std::forward<Args>(args)...);
8618  }
8619 
8642  template<typename Component, typename... Args>
8643  decltype(auto) assign_or_replace(const entity_type entity, Args &&... args) {
8645  auto *cpool = assure<Component>();
8646  return cpool->has(entity) ? cpool->replace(*this, entity, std::forward<Args>(args)...) : cpool->assign(*this, entity, std::forward<Args>(args)...);
8647  }
8648 
8676  template<typename Component>
8678  return assure<Component>()->on_construct();
8679  }
8680 
8707  template<typename Component>
8709  return assure<Component>()->on_replace();
8710  }
8711 
8739  template<typename Component>
8741  return assure<Component>()->on_destroy();
8742  }
8743 
8791  template<typename Component, typename Compare, typename Sort = std_sort, typename... Args>
8792  void sort(Compare compare, Sort algo = Sort{}, Args &&... args) {
8793  auto *cpool = assure<Component>();
8794  ENTT_ASSERT(!cpool->super);
8795  cpool->sort(cpool->begin(), cpool->end(), std::move(compare), std::move(algo), std::forward<Args>(args)...);
8796  }
8797 
8833  template<typename To, typename From>
8834  void sort() {
8835  auto *cpool = assure<To>();
8836  ENTT_ASSERT(!cpool->super);
8837  cpool->respect(*assure<From>());
8838  }
8839 
8854  template<typename Component>
8855  void reset(const entity_type entity) {
8857 
8858  if(auto *cpool = assure<Component>(); cpool->has(entity)) {
8859  cpool->remove(*this, entity);
8860  }
8861  }
8862 
8871  template<typename Component>
8872  void reset() {
8873  if(auto *cpool = assure<Component>(); cpool->on_destroy().empty()) {
8874  // no group set, otherwise the signal wouldn't be empty
8875  cpool->reset();
8876  } else {
8877  for(const auto entity: static_cast<const sparse_set<entity_type> &>(*cpool)) {
8878  cpool->remove(*this, entity);
8879  }
8880  }
8881  }
8882 
8891  void reset() {
8892  each([this](const auto entity) {
8893  // useless this-> used to suppress a warning with clang
8894  this->destroy(entity);
8895  });
8896  }
8897 
8915  template<typename Func>
8916  void each(Func func) const {
8917  static_assert(std::is_invocable_v<Func, entity_type>);
8918 
8919  if(destroyed == null) {
8920  for(auto pos = entities.size(); pos; --pos) {
8921  func(entities[pos-1]);
8922  }
8923  } else {
8924  for(auto pos = entities.size(); pos; --pos) {
8925  const auto curr = entity_type(pos - 1);
8926  const auto entity = entities[to_integer(curr)];
8927  const auto entt = entity_type{to_integer(entity) & traits_type::entity_mask};
8928 
8929  if(curr == entt) {
8930  func(entity);
8931  }
8932  }
8933  }
8934  }
8935 
8941  bool orphan(const entity_type entity) const {
8943  bool orphan = true;
8944 
8945  for(std::size_t pos{}, last = pools.size(); pos < last && orphan; ++pos) {
8946  const auto &pdata = pools[pos];
8947  orphan = !(pdata.pool && pdata.pool->has(entity));
8948  }
8949 
8950  return orphan;
8951  }
8952 
8969  template<typename Func>
8970  void orphans(Func func) const {
8971  static_assert(std::is_invocable_v<Func, entity_type>);
8972 
8973  each([this, &func](const auto entity) {
8974  if(orphan(entity)) {
8975  func(entity);
8976  }
8977  });
8978  }
8979 
9012  template<typename... Component, typename... Exclude>
9013  entt::basic_view<Entity, exclude_t<Exclude...>, Component...> view(exclude_t<Exclude...> = {}) {
9014  static_assert(sizeof...(Component) > 0);
9015  return { assure<Component>()..., assure<Exclude>()... };
9016  }
9017 
9019  template<typename... Component, typename... Exclude>
9020  entt::basic_view<Entity, exclude_t<Exclude...>, Component...> view(exclude_t<Exclude...> = {}) const {
9021  static_assert(std::conjunction_v<std::is_const<Component>...>);
9022  return const_cast<basic_registry *>(this)->view<Component...>(exclude<Exclude...>);
9023  }
9024 
9031  template<typename... Component>
9032  bool sortable() const ENTT_NOEXCEPT {
9033  return !(assure<Component>()->super || ...);
9034  }
9035 
9063  template<typename... Owned, typename... Get, typename... Exclude>
9064  entt::basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>, Owned...> group(get_t<Get...>, exclude_t<Exclude...> = {}) {
9065  static_assert(sizeof...(Owned) + sizeof...(Get) > 0);
9066  static_assert(sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude) > 1);
9067 
9068  using handler_type = group_handler<exclude_t<Exclude...>, get_t<Get...>, Owned...>;
9069 
9070  [[maybe_unused]] constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
9071  const auto cpools = std::make_tuple(assure<Owned>()..., assure<Get>()..., assure<Exclude>()...);
9072  const std::size_t extent[3]{sizeof...(Owned), sizeof...(Get), sizeof...(Exclude)};
9073  handler_type *handler = nullptr;
9074 
9075  if(auto it = std::find_if(groups.cbegin(), groups.cend(), [&extent](const auto &gdata) {
9076  return std::equal(std::begin(extent), std::end(extent), std::begin(gdata.extent))
9077  && (gdata.owned(type<Owned>()) && ...)
9078  && (gdata.get(type<Get>()) && ...)
9079  && (gdata.exclude(type<Exclude>()) && ...);
9080  }); it != groups.cend())
9081  {
9082  handler = static_cast<handler_type *>(it->group.get());
9083  }
9084 
9085  if(!handler) {
9086  const void *maybe_valid_if = nullptr;
9087  const void *discard_if = nullptr;
9088 
9089  group_data gdata{
9090  { sizeof...(Owned), sizeof...(Get), sizeof...(Exclude) },
9091  decltype(group_data::group){new handler_type{cpools}, [](void *gptr) { delete static_cast<handler_type *>(gptr); }},
9092  [](const component ctype) ENTT_NOEXCEPT { return ((ctype == type<Owned>()) || ...); },
9093  [](const component ctype) ENTT_NOEXCEPT { return ((ctype == type<Get>()) || ...); },
9094  [](const component ctype) ENTT_NOEXCEPT { return ((ctype == type<Exclude>()) || ...); }
9095  };
9096 
9097  if constexpr(sizeof...(Owned) == 0) {
9098  handler = static_cast<handler_type *>(groups.emplace_back(std::move(gdata)).group.get());
9099  } else {
9100  ENTT_ASSERT(std::all_of(groups.cbegin(), groups.cend(), [&extent](const auto &curr) {
9101  const std::size_t diff[3]{ (0u + ... + curr.owned(type<Owned>())), (0u + ... + curr.get(type<Get>())), (0u + ... + curr.exclude(type<Exclude>())) };
9102  return !diff[0] || ((std::equal(std::begin(diff), std::end(diff), extent) || std::equal(std::begin(diff), std::end(diff), curr.extent)));
9103  }));
9104 
9105  const auto next = std::find_if_not(groups.cbegin(), groups.cend(), [&size](const auto &curr) {
9106  const std::size_t diff = (0u + ... + curr.owned(type<Owned>()));
9107  return !diff || (size > (curr.extent[0] + curr.extent[1] + curr.extent[2]));
9108  });
9109 
9110  const auto prev = std::find_if(std::make_reverse_iterator(next), groups.crend(), [](const auto &curr) {
9111  return (0u + ... + curr.owned(type<Owned>()));
9112  });
9113 
9114  maybe_valid_if = (next == groups.cend() ? maybe_valid_if : next->group.get());
9115  discard_if = (prev == groups.crend() ? discard_if : prev->group.get());
9116  handler = static_cast<handler_type *>(groups.insert(next, std::move(gdata))->group.get());
9117  }
9118 
9119  ((std::get<pool_type<Owned> *>(cpools)->super = std::max(std::get<pool_type<Owned> *>(cpools)->super, size)), ...);
9120 
9121  (std::get<pool_type<Owned> *>(cpools)->on_construct().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<Owned>>(*handler), ...);
9122  (std::get<pool_type<Get> *>(cpools)->on_construct().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<Get>>(*handler), ...);
9123  (std::get<pool_type<Exclude> *>(cpools)->on_destroy().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<Exclude>>(*handler), ...);
9124 
9125  (std::get<pool_type<Owned> *>(cpools)->on_destroy().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...);
9126  (std::get<pool_type<Get> *>(cpools)->on_destroy().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...);
9127  (std::get<pool_type<Exclude> *>(cpools)->on_construct().before(discard_if).template connect<&handler_type::discard_if>(*handler), ...);
9128 
9129  const auto *cpool = std::min({
9130  static_cast<sparse_set<Entity> *>(std::get<pool_type<Owned> *>(cpools))...,
9131  static_cast<sparse_set<Entity> *>(std::get<pool_type<Get> *>(cpools))...
9132  }, [](const auto *lhs, const auto *rhs) {
9133  return lhs->size() < rhs->size();
9134  });
9135 
9136  // we cannot iterate backwards because we want to leave behind valid entities in case of owned types
9137  std::for_each(cpool->data(), cpool->data() + cpool->size(), [cpools, handler](const auto entity) {
9138  if((std::get<pool_type<Owned> *>(cpools)->has(entity) && ...)
9139  && (std::get<pool_type<Get> *>(cpools)->has(entity) && ...)
9140  && !(std::get<pool_type<Exclude> *>(cpools)->has(entity) || ...))
9141  {
9142  if constexpr(sizeof...(Owned) == 0) {
9143  handler->set.construct(entity);
9144  } else {
9145  if(!(std::get<0>(cpools)->index(entity) < handler->owned)) {
9146  const auto pos = handler->owned++;
9147  (std::get<pool_type<Owned> *>(cpools)->swap(std::get<pool_type<Owned> *>(cpools)->data()[pos], entity), ...);
9148  }
9149  }
9150  }
9151  });
9152  }
9153 
9154  if constexpr(sizeof...(Owned) == 0) {
9155  return { &handler->set, std::get<pool_type<Get> *>(cpools)... };
9156  } else {
9157  return { &std::get<0>(cpools)->super, &handler->owned, std::get<pool_type<Owned> *>(cpools)... , std::get<pool_type<Get> *>(cpools)... };
9158  }
9159  }
9160 
9171  template<typename... Owned, typename... Get, typename... Exclude>
9172  entt::basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>, Owned...> group(get_t<Get...>, exclude_t<Exclude...> = {}) const {
9173  static_assert(std::conjunction_v<std::is_const<Owned>..., std::is_const<Get>...>);
9174  return const_cast<basic_registry *>(this)->group<Owned...>(entt::get<Get...>, exclude<Exclude...>);
9175  }
9176 
9186  template<typename... Owned, typename... Exclude>
9187  entt::basic_group<Entity, exclude_t<Exclude...>, get_t<>, Owned...> group(exclude_t<Exclude...> = {}) {
9188  return group<Owned...>(entt::get<>, exclude<Exclude...>);
9189  }
9190 
9200  template<typename... Owned, typename... Exclude>
9201  entt::basic_group<Entity, exclude_t<Exclude...>, get_t<>, Owned...> group(exclude_t<Exclude...> = {}) const {
9202  static_assert(std::conjunction_v<std::is_const<Owned>...>);
9203  return const_cast<basic_registry *>(this)->group<Owned...>(exclude<Exclude...>);
9204  }
9205 
9226  template<typename It>
9228  std::vector<const sparse_set<Entity> *> selected(std::distance(first, last));
9229 
9230  std::transform(first, last, selected.begin(), [this](const component ctype) {
9231  auto it = std::find_if(pools.begin(), pools.end(), [ctype = to_integer(ctype)](const auto &pdata) {
9232  return pdata.pool && pdata.runtime_type == ctype;
9233  });
9234 
9235  return it != pools.cend() && it->pool ? it->pool.get() : nullptr;
9236  });
9237 
9238  return { std::move(selected) };
9239  }
9240 
9274  template<typename... Component, typename... Exclude>
9276  static_assert(std::conjunction_v<std::is_copy_constructible<Component>...>);
9277  basic_registry other;
9278 
9279  other.pools.resize(pools.size());
9280 
9281  for(auto pos = pools.size(); pos; --pos) {
9282  const auto &pdata = pools[pos-1];
9283  ENTT_ASSERT(!sizeof...(Component) || !pdata.pool || pdata.clone);
9284 
9285  if(pdata.pool && pdata.clone
9286  && (!sizeof...(Component) || ... || (pdata.runtime_type == to_integer(type<Component>())))
9287  && ((pdata.runtime_type != to_integer(type<Exclude>())) && ...))
9288  {
9289  auto &curr = other.pools[pos-1];
9290  curr.remove = pdata.remove;
9291  curr.clone = pdata.clone;
9292  curr.stomp = pdata.stomp;
9293  curr.pool = pdata.clone ? pdata.clone(*pdata.pool) : nullptr;
9294  curr.runtime_type = pdata.runtime_type;
9295  }
9296  }
9297 
9298  other.skip_family_pools = skip_family_pools;
9299  other.destroyed = destroyed;
9300  other.entities = entities;
9301 
9302  other.pools.erase(std::remove_if(other.pools.begin()+skip_family_pools, other.pools.end(), [](const auto &pdata) {
9303  return !pdata.pool;
9304  }), other.pools.end());
9305 
9306  return other;
9307  }
9308 
9339  template<typename... Component, typename... Exclude>
9340  void stomp(const entity_type dst, const entity_type src, const basic_registry &other, exclude_t<Exclude...> = {}) {
9341  const entity_type entt[1]{dst};
9342  stomp<Component...>(std::begin(entt), std::end(entt), src, other, exclude<Exclude...>);
9343  }
9344 
9358  template<typename... Component, typename It, typename... Exclude>
9359  void stomp(It first, It last, const entity_type src, const basic_registry &other, exclude_t<Exclude...> = {}) {
9360  static_assert(sizeof...(Component) == 0 || sizeof...(Exclude) == 0);
9361 
9362  for(auto pos = other.pools.size(); pos; --pos) {
9363  const auto &pdata = other.pools[pos-1];
9364  ENTT_ASSERT(!sizeof...(Component) || !pdata.pool || pdata.stomp);
9365 
9366  if(pdata.pool && pdata.stomp
9367  && (!sizeof...(Component) || ... || (pdata.runtime_type == to_integer(type<Component>())))
9368  && ((pdata.runtime_type != to_integer(type<Exclude>())) && ...)
9369  && pdata.pool->has(src))
9370  {
9371  std::for_each(first, last, [this, &pdata, src](const auto entity) {
9372  pdata.stomp(*pdata.pool, src, *this, entity);
9373  });
9374  }
9375  }
9376  }
9377 
9389  using follow_fn_type = entity_type(const basic_registry &, const entity_type);
9390 
9391  const auto head = to_integer(destroyed);
9392  const entity_type seed = (destroyed == null) ? destroyed : entity_type{head | (to_integer(entities[head]) & (traits_type::version_mask << traits_type::entity_shift))};
9393 
9394  follow_fn_type *follow = [](const basic_registry &reg, const entity_type entity) -> entity_type {
9395  const auto &others = reg.entities;
9396  const auto entt = to_integer(entity) & traits_type::entity_mask;
9397  const auto curr = to_integer(others[entt]) & traits_type::entity_mask;
9398  return entity_type{curr | (to_integer(others[curr]) & (traits_type::version_mask << traits_type::entity_shift))};
9399  };
9400 
9401  return { this, seed, follow };
9402  }
9403 
9420  using force_fn_type = void(basic_registry &, const entity_type, const bool);
9421 
9422  force_fn_type *force = [](basic_registry &reg, const entity_type entity, const bool discard) {
9423  const auto entt = to_integer(entity) & traits_type::entity_mask;
9424  auto &others = reg.entities;
9425 
9426  if(!(entt < others.size())) {
9427  auto curr = others.size();
9428  others.resize(entt + 1);
9429 
9430  std::generate(others.data() + curr, others.data() + entt, [curr]() mutable {
9431  return entity_type(curr++);
9432  });
9433  }
9434 
9435  others[entt] = entity;
9436 
9437  if(discard) {
9438  reg.destroy(entity);
9439  const auto version = to_integer(entity) & (traits_type::version_mask << traits_type::entity_shift);
9440  others[entt] = entity_type{(to_integer(others[entt]) & traits_type::entity_mask) | version};
9441  }
9442  };
9443 
9444  reset();
9445  entities.clear();
9446  destroyed = null;
9447 
9448  return { this, force };
9449  }
9450 
9462  template<typename Type, typename... Args>
9463  Type & set(Args &&... args) {
9464  const auto ctype = runtime_type<Type, context_family>();
9465  auto it = std::find_if(vars.begin(), vars.end(), [ctype](const auto &candidate) {
9466  return candidate.runtime_type == ctype;
9467  });
9468 
9469  if(it == vars.cend()) {
9470  vars.push_back({
9471  decltype(ctx_variable::value){new Type{std::forward<Args>(args)...}, [](void *ptr) { delete static_cast<Type *>(ptr); }},
9472  ctype
9473  });
9474 
9475  it = std::prev(vars.end());
9476  } else {
9477  it->value.reset(new Type{std::forward<Args>(args)...});
9478  }
9479 
9480  return *static_cast<Type *>(it->value.get());
9481  }
9482 
9487  template<typename Type>
9488  void unset() {
9489  vars.erase(std::remove_if(vars.begin(), vars.end(), [](auto &var) {
9490  return var.runtime_type == runtime_type<Type, context_family>();
9491  }), vars.end());
9492  }
9493 
9505  template<typename Type, typename... Args>
9506  Type & ctx_or_set(Args &&... args) {
9507  auto *value = try_ctx<Type>();
9508  return value ? *value : set<Type>(std::forward<Args>(args)...);
9509  }
9510 
9517  template<typename Type>
9518  const Type * try_ctx() const ENTT_NOEXCEPT {
9519  const auto it = std::find_if(vars.begin(), vars.end(), [](const auto &var) {
9520  return var.runtime_type == runtime_type<Type, context_family>();
9521  });
9522 
9523  return (it == vars.cend()) ? nullptr : static_cast<const Type *>(it->value.get());
9524  }
9525 
9527  template<typename Type>
9529  return const_cast<Type *>(std::as_const(*this).template try_ctx<Type>());
9530  }
9531 
9544  template<typename Type>
9545  const Type & ctx() const ENTT_NOEXCEPT {
9546  const auto *instance = try_ctx<Type>();
9547  ENTT_ASSERT(instance);
9548  return *instance;
9549  }
9550 
9552  template<typename Type>
9553  Type & ctx() ENTT_NOEXCEPT {
9554  return const_cast<Type &>(std::as_const(*this).template ctx<Type>());
9555  }
9556 
9557 private:
9558  mutable std::size_t skip_family_pools{};
9559  mutable std::vector<pool_data> pools{};
9560  std::vector<group_data> groups{};
9561  std::vector<ctx_variable> vars{};
9562  std::vector<entity_type> entities{};
9563  entity_type destroyed{null};
9564 };
9565 
9566 
9567 }
9568 
9569 
9570 #endif // ENTT_ENTITY_REGISTRY_HPP
9571 
9572 // #include "entity.hpp"
9573 
9574 // #include "fwd.hpp"
9575 
9576 
9577 
9578 namespace entt {
9579 
9580 
9591 template<typename Entity>
9592 struct basic_actor {
9596  using entity_type = Entity;
9597 
9599  : entt{entt::null}, reg{nullptr}
9600  {}
9601 
9607  : entt{ref.create()}, reg{&ref}
9608  {}
9609 
9616  : entt{entity}, reg{&ref}
9617  {
9618  ENTT_ASSERT(ref.valid(entity));
9619  }
9620 
9622  virtual ~basic_actor() {
9623  if(*this) {
9624  reg->destroy(entt);
9625  }
9626  }
9627 
9638  : entt{other.entt}, reg{other.reg}
9639  {
9640  other.entt = null;
9641  }
9642 
9654  if(this != &other) {
9655  auto tmp{std::move(other)};
9656  std::swap(reg, tmp.reg);
9657  std::swap(entt, tmp.entt);
9658  }
9659 
9660  return *this;
9661  }
9662 
9677  template<typename Component, typename... Args>
9678  decltype(auto) assign(Args &&... args) {
9679  return reg->template assign_or_replace<Component>(entt, std::forward<Args>(args)...);
9680  }
9681 
9686  template<typename Component>
9687  void remove() {
9688  reg->template remove<Component>(entt);
9689  }
9690 
9696  template<typename... Component>
9697  bool has() const ENTT_NOEXCEPT {
9698  return (reg->template has<Component>(entt) && ...);
9699  }
9700 
9706  template<typename... Component>
9707  decltype(auto) get() const ENTT_NOEXCEPT {
9708  return std::as_const(*reg).template get<Component...>(entt);
9709  }
9710 
9712  template<typename... Component>
9713  decltype(auto) get() ENTT_NOEXCEPT {
9714  return reg->template get<Component...>(entt);
9715  }
9716 
9722  template<typename... Component>
9723  auto try_get() const ENTT_NOEXCEPT {
9724  return std::as_const(*reg).template try_get<Component...>(entt);
9725  }
9726 
9728  template<typename... Component>
9730  return reg->template try_get<Component...>(entt);
9731  }
9732 
9738  return *reg;
9739  }
9740 
9743  return const_cast<registry_type &>(std::as_const(*this).backend());
9744  }
9745 
9751  return entt;
9752  }
9753 
9758  explicit operator bool() const ENTT_NOEXCEPT {
9759  return reg && reg->valid(entt);
9760  }
9761 
9762 private:
9763  entity_type entt;
9764  registry_type *reg;
9765 };
9766 
9767 
9768 }
9769 
9770 
9771 #endif // ENTT_ENTITY_ACTOR_HPP
9772 
9773 // #include "entity/entity.hpp"
9774 
9775 // #include "entity/group.hpp"
9776 
9777 // #include "entity/helper.hpp"
9778 #ifndef ENTT_ENTITY_HELPER_HPP
9779 #define ENTT_ENTITY_HELPER_HPP
9780 
9781 
9782 #include <type_traits>
9783 // #include "../config/config.h"
9784 
9785 // #include "../signal/sigh.hpp"
9786 
9787 // #include "registry.hpp"
9788 
9789 
9790 
9791 namespace entt {
9792 
9793 
9799 template<bool Const, typename Entity>
9800 struct as_view {
9802  using registry_type = std::conditional_t<Const, const entt::basic_registry<Entity>, entt::basic_registry<Entity>>;
9803 
9808  as_view(registry_type &source) ENTT_NOEXCEPT: reg{source} {}
9809 
9816  template<typename Exclude, typename... Component>
9817  operator entt::basic_view<Entity, Exclude, Component...>() const {
9818  return reg.template view<Component...>(Exclude{});
9819  }
9820 
9821 private:
9822  registry_type &reg;
9823 };
9824 
9825 
9834 template<typename Entity>
9835 as_view(basic_registry<Entity> &) ENTT_NOEXCEPT -> as_view<false, Entity>;
9836 
9837 
9839 template<typename Entity>
9840 as_view(const basic_registry<Entity> &) ENTT_NOEXCEPT -> as_view<true, Entity>;
9841 
9842 
9848 template<bool Const, typename Entity>
9849 struct as_group {
9851  using registry_type = std::conditional_t<Const, const entt::basic_registry<Entity>, entt::basic_registry<Entity>>;
9852 
9857  as_group(registry_type &source) ENTT_NOEXCEPT: reg{source} {}
9858 
9866  template<typename Exclude, typename Get, typename... Owned>
9867  operator entt::basic_group<Entity, Exclude, Get, Owned...>() const {
9868  return reg.template group<Owned...>(Get{}, Exclude{});
9869  }
9870 
9871 private:
9872  registry_type &reg;
9873 };
9874 
9875 
9884 template<typename Entity>
9885 as_group(basic_registry<Entity> &) ENTT_NOEXCEPT -> as_group<false, Entity>;
9886 
9887 
9889 template<typename Entity>
9890 as_group(const basic_registry<Entity> &) ENTT_NOEXCEPT -> as_group<true, Entity>;
9891 
9892 
9912 template<ENTT_ID_TYPE Value>
9913 using tag = std::integral_constant<ENTT_ID_TYPE, Value>;
9914 
9915 
9916 }
9917 
9918 
9919 #endif // ENTT_ENTITY_HELPER_HPP
9920 
9921 // #include "entity/observer.hpp"
9922 #ifndef ENTT_ENTITY_OBSERVER_HPP
9923 #define ENTT_ENTITY_OBSERVER_HPP
9924 
9925 
9926 #include <limits>
9927 #include <cstddef>
9928 #include <cstdint>
9929 #include <utility>
9930 #include <algorithm>
9931 #include <type_traits>
9932 // #include "../config/config.h"
9933 
9934 // #include "../core/type_traits.hpp"
9935 
9936 // #include "registry.hpp"
9937 
9938 // #include "storage.hpp"
9939 
9940 // #include "entity.hpp"
9941 
9942 // #include "fwd.hpp"
9943 
9944 
9945 
9946 namespace entt {
9947 
9948 
9950 template<typename...>
9951 struct matcher {};
9952 
9953 
9960 template<typename...>
9962 
9963 
9972 template<>
9980  template<typename... AllOf, typename... NoneOf>
9981  static constexpr auto group(exclude_t<NoneOf...> = {}) ENTT_NOEXCEPT {
9982  return basic_collector<matcher<type_list<>, type_list<>, type_list<NoneOf...>, AllOf...>>{};
9983  }
9984 
9990  template<typename AnyOf>
9991  static constexpr auto replace() ENTT_NOEXCEPT {
9993  }
9994 };
9995 
10004 template<typename... Reject, typename... Require, typename... Rule, typename... Other>
10005 struct basic_collector<matcher<type_list<Reject...>, type_list<Require...>, Rule...>, Other...> {
10007  using current_type = matcher<type_list<Reject...>, type_list<Require...>, Rule...>;
10008 
10015  template<typename... AllOf, typename... NoneOf>
10016  static constexpr auto group(exclude_t<NoneOf...> = {}) ENTT_NOEXCEPT {
10017  return basic_collector<matcher<type_list<>, type_list<>, type_list<NoneOf...>, AllOf...>, current_type, Other...>{};
10018  }
10019 
10025  template<typename AnyOf>
10026  static constexpr auto replace() ENTT_NOEXCEPT {
10027  return basic_collector<matcher<type_list<>, type_list<>, AnyOf>, current_type, Other...>{};
10028  }
10029 
10036  template<typename... AllOf, typename... NoneOf>
10037  static constexpr auto where(exclude_t<NoneOf...> = {}) ENTT_NOEXCEPT {
10038  using extended_type = matcher<type_list<Reject..., NoneOf...>, type_list<Require..., AllOf...>, Rule...>;
10039  return basic_collector<extended_type, Other...>{};
10040  }
10041 };
10042 
10043 
10046 
10047 
10097 template<typename Entity>
10098 class basic_observer {
10099  using payload_type = std::uint32_t;
10100 
10101  template<typename>
10102  struct matcher_handler;
10103 
10104  template<typename... Reject, typename... Require, typename AnyOf>
10105  struct matcher_handler<matcher<type_list<Reject...>, type_list<Require...>, AnyOf>> {
10106  template<std::size_t Index>
10107  static void maybe_valid_if(basic_observer &obs, const Entity entt, const basic_registry<Entity> &reg) {
10108  if(reg.template has<Require...>(entt) && !(reg.template has<Reject>(entt) || ...)) {
10109  auto *comp = obs.view.try_get(entt);
10110  (comp ? *comp : obs.view.construct(entt)) |= (1 << Index);
10111  }
10112  }
10113 
10114  template<std::size_t Index>
10115  static void discard_if(basic_observer &obs, const Entity entt) {
10116  if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) {
10117  obs.view.destroy(entt);
10118  }
10119  }
10120 
10121  template<std::size_t Index>
10122  static void connect(basic_observer &obs, basic_registry<Entity> &reg) {
10123  (reg.template on_destroy<Require>().template connect<&discard_if<Index>>(obs), ...);
10124  (reg.template on_construct<Reject>().template connect<&discard_if<Index>>(obs), ...);
10125  reg.template on_replace<AnyOf>().template connect<&maybe_valid_if<Index>>(obs);
10126  reg.template on_destroy<AnyOf>().template connect<&discard_if<Index>>(obs);
10127  }
10128 
10129  static void disconnect(basic_observer &obs, basic_registry<Entity> &reg) {
10130  (reg.template on_destroy<Require>().disconnect(obs), ...);
10131  (reg.template on_construct<Reject>().disconnect(obs), ...);
10132  reg.template on_replace<AnyOf>().disconnect(obs);
10133  reg.template on_destroy<AnyOf>().disconnect(obs);
10134  }
10135  };
10136 
10137  template<typename... Reject, typename... Require, typename... NoneOf, typename... AllOf>
10138  struct matcher_handler<matcher<type_list<Reject...>, type_list<Require...>, type_list<NoneOf...>, AllOf...>> {
10139  template<std::size_t Index>
10140  static void maybe_valid_if(basic_observer &obs, const Entity entt, const basic_registry<Entity> &reg) {
10141  if(reg.template has<AllOf..., Require...>(entt) && !(reg.template has<NoneOf>(entt) || ...) && !(reg.template has<Reject>(entt) || ...)) {
10142  auto *comp = obs.view.try_get(entt);
10143  (comp ? *comp : obs.view.construct(entt)) |= (1 << Index);
10144  }
10145  }
10146 
10147  template<std::size_t Index>
10148  static void discard_if(basic_observer &obs, const Entity entt) {
10149  if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) {
10150  obs.view.destroy(entt);
10151  }
10152  }
10153 
10154  template<std::size_t Index>
10155  static void connect(basic_observer &obs, basic_registry<Entity> &reg) {
10156  (reg.template on_destroy<Require>().template connect<&discard_if<Index>>(obs), ...);
10157  (reg.template on_construct<Reject>().template connect<&discard_if<Index>>(obs), ...);
10158  (reg.template on_construct<AllOf>().template connect<&maybe_valid_if<Index>>(obs), ...);
10159  (reg.template on_destroy<NoneOf>().template connect<&maybe_valid_if<Index>>(obs), ...);
10160  (reg.template on_destroy<AllOf>().template connect<&discard_if<Index>>(obs), ...);
10161  (reg.template on_construct<NoneOf>().template connect<&discard_if<Index>>(obs), ...);
10162  }
10163 
10164  static void disconnect(basic_observer &obs, basic_registry<Entity> &reg) {
10165  (reg.template on_destroy<Require>().disconnect(obs), ...);
10166  (reg.template on_construct<Reject>().disconnect(obs), ...);
10167  (reg.template on_construct<AllOf>().disconnect(obs), ...);
10168  (reg.template on_destroy<NoneOf>().disconnect(obs), ...);
10169  (reg.template on_destroy<AllOf>().disconnect(obs), ...);
10170  (reg.template on_construct<NoneOf>().disconnect(obs), ...);
10171  }
10172  };
10173 
10174  template<typename... Matcher>
10175  static void disconnect(basic_observer &obs, basic_registry<Entity> &reg) {
10176  (matcher_handler<Matcher>::disconnect(obs, reg), ...);
10177  }
10178 
10179  template<typename... Matcher, std::size_t... Index>
10180  void connect(basic_registry<Entity> &reg, std::index_sequence<Index...>) {
10181  static_assert(sizeof...(Matcher) < std::numeric_limits<payload_type>::digits);
10182  (matcher_handler<Matcher>::template connect<Index>(*this, reg), ...);
10183  release = &basic_observer::disconnect<Matcher...>;
10184  }
10185 
10186 public:
10188  using entity_type = Entity;
10190  using size_type = std::size_t;
10193 
10196  : target{}, release{}, view{}
10197  {}
10198 
10200  basic_observer(const basic_observer &) = delete;
10202  basic_observer(basic_observer &&) = delete;
10203 
10209  template<typename... Matcher>
10211  : target{&reg},
10212  release{},
10213  view{}
10214  {
10215  connect<Matcher...>(reg, std::index_sequence_for<Matcher...>{});
10216  }
10217 
10219  ~basic_observer() = default;
10220 
10225  basic_observer & operator=(const basic_observer &) = delete;
10226 
10231  basic_observer & operator=(basic_observer &&) = delete;
10232 
10238  template<typename... Matcher>
10240  disconnect();
10241  connect<Matcher...>(reg, std::index_sequence_for<Matcher...>{});
10242  target = &reg;
10243  view.reset();
10244  }
10245 
10247  void disconnect() {
10248  if(release) {
10249  release(*this, *target);
10250  release = nullptr;
10251  }
10252  }
10253 
10259  return view.size();
10260  }
10261 
10266  bool empty() const ENTT_NOEXCEPT {
10267  return view.empty();
10268  }
10269 
10282  const entity_type * data() const ENTT_NOEXCEPT {
10283  return view.data();
10284  }
10285 
10295  return view.sparse_set<entity_type>::begin();
10296  }
10297 
10309  return view.sparse_set<entity_type>::end();
10310  }
10311 
10313  void clear() {
10314  view.reset();
10315  }
10316 
10331  template<typename Func>
10332  void each(Func func) const {
10333  static_assert(std::is_invocable_v<Func, entity_type>);
10334  std::for_each(begin(), end(), std::move(func));
10335  }
10336 
10351  template<typename Func>
10352  void each(Func func) {
10353  std::as_const(*this).each(std::move(func));
10354  clear();
10355  }
10356 
10357 private:
10359  void(* release)(basic_observer &, basic_registry<entity_type> &);
10361 };
10362 
10363 
10364 }
10365 
10366 
10367 #endif // ENTT_ENTITY_OBSERVER_HPP
10368 
10369 // #include "entity/registry.hpp"
10370 
10371 // #include "entity/runtime_view.hpp"
10372 
10373 // #include "entity/snapshot.hpp"
10374 
10375 // #include "entity/sparse_set.hpp"
10376 
10377 // #include "entity/storage.hpp"
10378 
10379 // #include "entity/utility.hpp"
10380 
10381 // #include "entity/view.hpp"
10382 
10383 // #include "locator/locator.hpp"
10384 #ifndef ENTT_LOCATOR_LOCATOR_HPP
10385 #define ENTT_LOCATOR_LOCATOR_HPP
10386 
10387 
10388 #include <memory>
10389 #include <utility>
10390 // #include "../config/config.h"
10391 #ifndef ENTT_CONFIG_CONFIG_H
10392 #define ENTT_CONFIG_CONFIG_H
10393 
10394 
10395 #ifndef ENTT_NOEXCEPT
10396 #define ENTT_NOEXCEPT noexcept
10397 #endif // ENTT_NOEXCEPT
10398 
10399 
10400 #ifndef ENTT_HS_SUFFIX
10401 #define ENTT_HS_SUFFIX _hs
10402 #endif // ENTT_HS_SUFFIX
10403 
10404 
10405 #ifndef ENTT_HWS_SUFFIX
10406 #define ENTT_HWS_SUFFIX _hws
10407 #endif // ENTT_HWS_SUFFIX
10408 
10409 
10410 #ifndef ENTT_NO_ATOMIC
10411 #include <atomic>
10412 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
10413 #else // ENTT_NO_ATOMIC
10414 #define ENTT_MAYBE_ATOMIC(Type) Type
10415 #endif // ENTT_NO_ATOMIC
10416 
10417 
10418 #ifndef ENTT_DISABLE_ETO
10419 #include <type_traits>
10420 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
10421 #else // ENTT_DISABLE_ETO
10422 // sfinae-friendly definition
10423 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
10424 #endif // ENTT_DISABLE_ETO
10425 
10426 
10427 #ifndef ENTT_ID_TYPE
10428 #include <cstdint>
10429 #define ENTT_ID_TYPE std::uint32_t
10430 #endif // ENTT_ID_TYPE
10431 
10432 
10433 #ifndef ENTT_PAGE_SIZE
10434 #define ENTT_PAGE_SIZE 32768
10435 #endif // ENTT_PAGE_SIZE
10436 
10437 
10438 #ifndef ENTT_DISABLE_ASSERT
10439 #include <cassert>
10440 #define ENTT_ASSERT(condition) assert(condition)
10441 #else // ENTT_DISABLE_ASSERT
10442 #define ENTT_ASSERT(...) ((void)0)
10443 #endif // ENTT_DISABLE_ASSERT
10444 
10445 
10446 #endif // ENTT_CONFIG_CONFIG_H
10447 
10448 
10449 
10450 namespace entt {
10451 
10452 
10464 template<typename Service>
10467  using service_type = Service;
10468 
10470  service_locator() = delete;
10472  ~service_locator() = delete;
10473 
10478  static bool empty() ENTT_NOEXCEPT {
10479  return !static_cast<bool>(service);
10480  }
10481 
10492  static std::weak_ptr<Service> get() ENTT_NOEXCEPT {
10493  return service;
10494  }
10495 
10510  static Service & ref() ENTT_NOEXCEPT {
10511  return *service;
10512  }
10513 
10520  template<typename Impl = Service, typename... Args>
10521  static void set(Args &&... args) {
10522  service = std::make_shared<Impl>(std::forward<Args>(args)...);
10523  }
10524 
10529  static void set(std::shared_ptr<Service> ptr) {
10530  ENTT_ASSERT(static_cast<bool>(ptr));
10531  service = std::move(ptr);
10532  }
10533 
10539  static void reset() {
10540  service.reset();
10541  }
10542 
10543 private:
10544  inline static std::shared_ptr<Service> service = nullptr;
10545 };
10546 
10547 
10548 }
10549 
10550 
10551 #endif // ENTT_LOCATOR_LOCATOR_HPP
10552 
10553 // #include "meta/factory.hpp"
10554 #ifndef ENTT_META_FACTORY_HPP
10555 #define ENTT_META_FACTORY_HPP
10556 
10557 
10558 #include <tuple>
10559 #include <array>
10560 #include <cstddef>
10561 #include <utility>
10562 #include <functional>
10563 #include <type_traits>
10564 // #include "../config/config.h"
10565 #ifndef ENTT_CONFIG_CONFIG_H
10566 #define ENTT_CONFIG_CONFIG_H
10567 
10568 
10569 #ifndef ENTT_NOEXCEPT
10570 #define ENTT_NOEXCEPT noexcept
10571 #endif // ENTT_NOEXCEPT
10572 
10573 
10574 #ifndef ENTT_HS_SUFFIX
10575 #define ENTT_HS_SUFFIX _hs
10576 #endif // ENTT_HS_SUFFIX
10577 
10578 
10579 #ifndef ENTT_HWS_SUFFIX
10580 #define ENTT_HWS_SUFFIX _hws
10581 #endif // ENTT_HWS_SUFFIX
10582 
10583 
10584 #ifndef ENTT_NO_ATOMIC
10585 #include <atomic>
10586 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
10587 #else // ENTT_NO_ATOMIC
10588 #define ENTT_MAYBE_ATOMIC(Type) Type
10589 #endif // ENTT_NO_ATOMIC
10590 
10591 
10592 #ifndef ENTT_DISABLE_ETO
10593 #include <type_traits>
10594 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
10595 #else // ENTT_DISABLE_ETO
10596 // sfinae-friendly definition
10597 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
10598 #endif // ENTT_DISABLE_ETO
10599 
10600 
10601 #ifndef ENTT_ID_TYPE
10602 #include <cstdint>
10603 #define ENTT_ID_TYPE std::uint32_t
10604 #endif // ENTT_ID_TYPE
10605 
10606 
10607 #ifndef ENTT_PAGE_SIZE
10608 #define ENTT_PAGE_SIZE 32768
10609 #endif // ENTT_PAGE_SIZE
10610 
10611 
10612 #ifndef ENTT_DISABLE_ASSERT
10613 #include <cassert>
10614 #define ENTT_ASSERT(condition) assert(condition)
10615 #else // ENTT_DISABLE_ASSERT
10616 #define ENTT_ASSERT(...) ((void)0)
10617 #endif // ENTT_DISABLE_ASSERT
10618 
10619 
10620 #endif // ENTT_CONFIG_CONFIG_H
10621 
10622 // #include "../core/type_traits.hpp"
10623 #ifndef ENTT_CORE_TYPE_TRAITS_HPP
10624 #define ENTT_CORE_TYPE_TRAITS_HPP
10625 
10626 
10627 #include <cstddef>
10628 #include <type_traits>
10629 // #include "../config/config.h"
10630 #ifndef ENTT_CONFIG_CONFIG_H
10631 #define ENTT_CONFIG_CONFIG_H
10632 
10633 
10634 #ifndef ENTT_NOEXCEPT
10635 #define ENTT_NOEXCEPT noexcept
10636 #endif // ENTT_NOEXCEPT
10637 
10638 
10639 #ifndef ENTT_HS_SUFFIX
10640 #define ENTT_HS_SUFFIX _hs
10641 #endif // ENTT_HS_SUFFIX
10642 
10643 
10644 #ifndef ENTT_HWS_SUFFIX
10645 #define ENTT_HWS_SUFFIX _hws
10646 #endif // ENTT_HWS_SUFFIX
10647 
10648 
10649 #ifndef ENTT_NO_ATOMIC
10650 #include <atomic>
10651 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
10652 #else // ENTT_NO_ATOMIC
10653 #define ENTT_MAYBE_ATOMIC(Type) Type
10654 #endif // ENTT_NO_ATOMIC
10655 
10656 
10657 #ifndef ENTT_DISABLE_ETO
10658 #include <type_traits>
10659 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
10660 #else // ENTT_DISABLE_ETO
10661 // sfinae-friendly definition
10662 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
10663 #endif // ENTT_DISABLE_ETO
10664 
10665 
10666 #ifndef ENTT_ID_TYPE
10667 #include <cstdint>
10668 #define ENTT_ID_TYPE std::uint32_t
10669 #endif // ENTT_ID_TYPE
10670 
10671 
10672 #ifndef ENTT_PAGE_SIZE
10673 #define ENTT_PAGE_SIZE 32768
10674 #endif // ENTT_PAGE_SIZE
10675 
10676 
10677 #ifndef ENTT_DISABLE_ASSERT
10678 #include <cassert>
10679 #define ENTT_ASSERT(condition) assert(condition)
10680 #else // ENTT_DISABLE_ASSERT
10681 #define ENTT_ASSERT(...) ((void)0)
10682 #endif // ENTT_DISABLE_ASSERT
10683 
10684 
10685 #endif // ENTT_CONFIG_CONFIG_H
10686 
10687 // #include "../core/hashed_string.hpp"
10688 #ifndef ENTT_CORE_HASHED_STRING_HPP
10689 #define ENTT_CORE_HASHED_STRING_HPP
10690 
10691 
10692 #include <cstddef>
10693 // #include "../config/config.h"
10694 #ifndef ENTT_CONFIG_CONFIG_H
10695 #define ENTT_CONFIG_CONFIG_H
10696 
10697 
10698 #ifndef ENTT_NOEXCEPT
10699 #define ENTT_NOEXCEPT noexcept
10700 #endif // ENTT_NOEXCEPT
10701 
10702 
10703 #ifndef ENTT_HS_SUFFIX
10704 #define ENTT_HS_SUFFIX _hs
10705 #endif // ENTT_HS_SUFFIX
10706 
10707 
10708 #ifndef ENTT_HWS_SUFFIX
10709 #define ENTT_HWS_SUFFIX _hws
10710 #endif // ENTT_HWS_SUFFIX
10711 
10712 
10713 #ifndef ENTT_NO_ATOMIC
10714 #include <atomic>
10715 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
10716 #else // ENTT_NO_ATOMIC
10717 #define ENTT_MAYBE_ATOMIC(Type) Type
10718 #endif // ENTT_NO_ATOMIC
10719 
10720 
10721 #ifndef ENTT_DISABLE_ETO
10722 #include <type_traits>
10723 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
10724 #else // ENTT_DISABLE_ETO
10725 // sfinae-friendly definition
10726 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
10727 #endif // ENTT_DISABLE_ETO
10728 
10729 
10730 #ifndef ENTT_ID_TYPE
10731 #include <cstdint>
10732 #define ENTT_ID_TYPE std::uint32_t
10733 #endif // ENTT_ID_TYPE
10734 
10735 
10736 #ifndef ENTT_PAGE_SIZE
10737 #define ENTT_PAGE_SIZE 32768
10738 #endif // ENTT_PAGE_SIZE
10739 
10740 
10741 #ifndef ENTT_DISABLE_ASSERT
10742 #include <cassert>
10743 #define ENTT_ASSERT(condition) assert(condition)
10744 #else // ENTT_DISABLE_ASSERT
10745 #define ENTT_ASSERT(...) ((void)0)
10746 #endif // ENTT_DISABLE_ASSERT
10747 
10748 
10749 #endif // ENTT_CONFIG_CONFIG_H
10750 
10751 
10752 
10753 namespace entt {
10754 
10755 
10762 namespace internal {
10763 
10764 
10765 template<typename>
10766 struct fnv1a_traits;
10767 
10768 
10769 template<>
10770 struct fnv1a_traits<std::uint32_t> {
10771  static constexpr std::uint32_t offset = 2166136261;
10772  static constexpr std::uint32_t prime = 16777619;
10773 };
10774 
10775 
10776 template<>
10777 struct fnv1a_traits<std::uint64_t> {
10778  static constexpr std::uint64_t offset = 14695981039346656037ull;
10779  static constexpr std::uint64_t prime = 1099511628211ull;
10780 };
10781 
10782 
10783 }
10784 
10785 
10803 template<typename Char>
10804 class basic_hashed_string {
10805  using traits_type = internal::fnv1a_traits<ENTT_ID_TYPE>;
10806 
10807  struct const_wrapper {
10808  // non-explicit constructor on purpose
10809  constexpr const_wrapper(const Char *curr) ENTT_NOEXCEPT: str{curr} {}
10810  const Char *str;
10811  };
10812 
10813  // Fowler–Noll–Vo hash function v. 1a - the good
10814  static constexpr ENTT_ID_TYPE helper(ENTT_ID_TYPE partial, const Char *curr) ENTT_NOEXCEPT {
10815  return curr[0] == 0 ? partial : helper((partial^curr[0])*traits_type::prime, curr+1);
10816  }
10817 
10818 public:
10820  using value_type = Char;
10822  using hash_type = ENTT_ID_TYPE;
10823 
10839  template<std::size_t N>
10840  static constexpr hash_type to_value(const value_type (&str)[N]) ENTT_NOEXCEPT {
10841  return helper(traits_type::offset, str);
10842  }
10843 
10849  static hash_type to_value(const_wrapper wrapper) ENTT_NOEXCEPT {
10850  return helper(traits_type::offset, wrapper.str);
10851  }
10852 
10859  static hash_type to_value(const value_type *str, std::size_t size) ENTT_NOEXCEPT {
10860  ENTT_ID_TYPE partial{traits_type::offset};
10861  while(size--) { partial = (partial^(str++)[0])*traits_type::prime; }
10862  return partial;
10863  }
10864 
10867  : str{nullptr}, hash{}
10868  {}
10869 
10884  template<std::size_t N>
10885  constexpr basic_hashed_string(const value_type (&curr)[N]) ENTT_NOEXCEPT
10886  : str{curr}, hash{helper(traits_type::offset, curr)}
10887  {}
10888 
10894  explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
10895  : str{wrapper.str}, hash{helper(traits_type::offset, wrapper.str)}
10896  {}
10897 
10902  constexpr const value_type * data() const ENTT_NOEXCEPT {
10903  return str;
10904  }
10905 
10910  constexpr hash_type value() const ENTT_NOEXCEPT {
10911  return hash;
10912  }
10913 
10918  constexpr operator const value_type *() const ENTT_NOEXCEPT { return str; }
10919 
10921  constexpr operator hash_type() const ENTT_NOEXCEPT { return hash; }
10922 
10928  constexpr bool operator==(const basic_hashed_string &other) const ENTT_NOEXCEPT {
10929  return hash == other.hash;
10930  }
10931 
10932 private:
10933  const value_type *str;
10934  hash_type hash;
10935 };
10936 
10937 
10948 template<typename Char, std::size_t N>
10949 basic_hashed_string(const Char (&str)[N]) ENTT_NOEXCEPT
10950 -> basic_hashed_string<Char>;
10951 
10952 
10960 template<typename Char>
10961 constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
10962  return !(lhs == rhs);
10963 }
10964 
10965 
10967 using hashed_string = basic_hashed_string<char>;
10968 
10969 
10971 using hashed_wstring = basic_hashed_string<wchar_t>;
10972 
10973 
10974 }
10975 
10976 
10982 constexpr entt::hashed_string operator"" ENTT_HS_SUFFIX(const char *str, std::size_t) ENTT_NOEXCEPT {
10983  return entt::hashed_string{str};
10984 }
10985 
10986 
10992 constexpr entt::hashed_wstring operator"" ENTT_HWS_SUFFIX(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
10993  return entt::hashed_wstring{str};
10994 }
10995 
10996 
10997 #endif // ENTT_CORE_HASHED_STRING_HPP
10998 
10999 
11000 
11001 namespace entt {
11002 
11003 
11008 template<std::size_t N>
11009 struct choice_t
11010  // Unfortunately, doxygen cannot parse such a construct.
11012  : choice_t<N-1>
11014 {};
11015 
11016 
11018 template<>
11019 struct choice_t<0> {};
11020 
11021 
11026 template<std::size_t N>
11027 constexpr choice_t<N> choice{};
11028 
11029 
11031 template<typename...>
11032 struct type_list {};
11033 
11034 
11036 template<typename>
11037 struct type_list_size;
11038 
11039 
11044 template<typename... Type>
11045 struct type_list_size<type_list<Type...>>
11046  : std::integral_constant<std::size_t, sizeof...(Type)>
11047 {};
11048 
11049 
11054 template<class List>
11055 constexpr auto type_list_size_v = type_list_size<List>::value;
11056 
11057 
11059 template<typename...>
11060 struct type_list_cat;
11061 
11062 
11064 template<>
11065 struct type_list_cat<> {
11067  using type = type_list<>;
11068 };
11069 
11070 
11077 template<typename... Type, typename... Other, typename... List>
11078 struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
11080  using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
11081 };
11082 
11083 
11088 template<typename... Type>
11089 struct type_list_cat<type_list<Type...>> {
11091  using type = type_list<Type...>;
11092 };
11093 
11094 
11099 template<typename... List>
11100 using type_list_cat_t = typename type_list_cat<List...>::type;
11101 
11102 
11104 template<typename>
11105 struct type_list_unique;
11106 
11107 
11113 template<typename Type, typename... Other>
11114 struct type_list_unique<type_list<Type, Other...>> {
11116  using type = std::conditional_t<
11117  std::disjunction_v<std::is_same<Type, Other>...>,
11118  typename type_list_unique<type_list<Other...>>::type,
11119  type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>
11120  >;
11121 };
11122 
11123 
11125 template<>
11126 struct type_list_unique<type_list<>> {
11128  using type = type_list<>;
11129 };
11130 
11131 
11136 template<typename Type>
11137 using type_list_unique_t = typename type_list_unique<Type>::type;
11138 
11139 
11145 template<typename Type, typename = std::void_t<>>
11146 struct is_equality_comparable: std::false_type {};
11147 
11148 
11150 template<typename Type>
11151 struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>: std::true_type {};
11152 
11153 
11158 template<class Type>
11159 constexpr auto is_equality_comparable_v = is_equality_comparable<Type>::value;
11160 
11161 
11163 template<typename>
11164 struct named_type_traits;
11165 
11166 
11171 template<typename Type>
11172 struct named_type_traits<const Type>
11173  : named_type_traits<Type>
11174 {};
11175 
11176 
11181 template<typename Type>
11182 using named_type_traits_t = typename named_type_traits<Type>::type;
11183 
11184 
11189 template<class Type>
11190 constexpr auto named_type_traits_v = named_type_traits<Type>::value;
11191 
11192 
11198 template<typename Type, typename = std::void_t<>>
11199 struct is_named_type: std::false_type {};
11200 
11201 
11203 template<typename Type>
11204 struct is_named_type<Type, std::void_t<named_type_traits_t<std::decay_t<Type>>>>: std::true_type {};
11205 
11206 
11211 template<class Type>
11212 constexpr auto is_named_type_v = is_named_type<Type>::value;
11213 
11214 
11221 #define ENTT_OPAQUE_TYPE(clazz, type)\
11222  enum class clazz: type {};\
11223  constexpr auto to_integer(const clazz id) ENTT_NOEXCEPT {\
11224  return std::underlying_type_t<clazz>(id);\
11225  }\
11226  static_assert(true)
11227 
11228 
11229 }
11230 
11231 
11239 #define ENTT_EXPAND(args) args
11240 
11241 
11259 #define ENTT_NAMED_TYPE(type)\
11260  template<>\
11261  struct entt::named_type_traits<type>\
11262  : std::integral_constant<ENTT_ID_TYPE, entt::basic_hashed_string<std::remove_cv_t<std::remove_pointer_t<std::decay_t<decltype(#type)>>>>{#type}>\
11263  {\
11264  static_assert(std::is_same_v<std::remove_cv_t<type>, type>);\
11265  static_assert(std::is_object_v<type>);\
11266  }
11267 
11268 
11274 #define ENTT_NAMED_STRUCT_ONLY(clazz, body)\
11275  struct clazz body;\
11276  ENTT_NAMED_TYPE(clazz)
11277 
11278 
11285 #define ENTT_NAMED_STRUCT_WITH_NAMESPACE(ns, clazz, body)\
11286  namespace ns { struct clazz body; }\
11287  ENTT_NAMED_TYPE(ns::clazz)
11288 
11289 
11291 #define ENTT_NAMED_STRUCT_OVERLOAD(_1, _2, _3, FUNC, ...) FUNC
11292 
11293 #define ENTT_NAMED_STRUCT(...) ENTT_EXPAND(ENTT_NAMED_STRUCT_OVERLOAD(__VA_ARGS__, ENTT_NAMED_STRUCT_WITH_NAMESPACE, ENTT_NAMED_STRUCT_ONLY,)(__VA_ARGS__))
11294 
11295 
11301 #define ENTT_NAMED_CLASS_ONLY(clazz, body)\
11302  class clazz body;\
11303  ENTT_NAMED_TYPE(clazz)
11304 
11305 
11312 #define ENTT_NAMED_CLASS_WITH_NAMESPACE(ns, clazz, body)\
11313  namespace ns { class clazz body; }\
11314  ENTT_NAMED_TYPE(ns::clazz)
11315 
11316 
11318 #define ENTT_NAMED_CLASS_MACRO(_1, _2, _3, FUNC, ...) FUNC
11319 
11320 #define ENTT_NAMED_CLASS(...) ENTT_EXPAND(ENTT_NAMED_CLASS_MACRO(__VA_ARGS__, ENTT_NAMED_CLASS_WITH_NAMESPACE, ENTT_NAMED_CLASS_ONLY,)(__VA_ARGS__))
11321 
11322 
11323 #endif // ENTT_CORE_TYPE_TRAITS_HPP
11324 
11325 // #include "policy.hpp"
11326 #ifndef ENTT_META_POLICY_HPP
11327 #define ENTT_META_POLICY_HPP
11328 
11329 
11330 namespace entt {
11331 
11332 
11334 struct as_alias_t {};
11335 
11336 
11339 
11340 
11342 struct as_is_t {};
11343 
11344 
11346 struct as_void_t {};
11347 
11348 
11349 }
11350 
11351 
11352 #endif // ENTT_META_POLICY_HPP
11353 
11354 // #include "meta.hpp"
11355 #ifndef ENTT_META_META_HPP
11356 #define ENTT_META_META_HPP
11357 
11358 
11359 #include <array>
11360 #include <memory>
11361 #include <cstddef>
11362 #include <utility>
11363 #include <type_traits>
11364 // #include "../config/config.h"
11365 
11366 // #include "../core/type_traits.hpp"
11367 
11368 // #include "../core/utility.hpp"
11369 #ifndef ENTT_CORE_UTILITY_HPP
11370 #define ENTT_CORE_UTILITY_HPP
11371 
11372 
11373 // #include "../config/config.h"
11374 
11375 
11376 
11377 namespace entt {
11378 
11379 
11381 struct identity {
11388  template<class Type>
11389  constexpr Type && operator()(Type &&value) const ENTT_NOEXCEPT {
11390  return std::forward<Type>(value);
11391  }
11392 };
11393 
11394 
11402 template<typename Type, typename Class>
11403 constexpr auto overload(Type Class:: *member) ENTT_NOEXCEPT { return member; }
11404 
11405 
11412 template<typename Type>
11413 constexpr auto overload(Type *func) ENTT_NOEXCEPT { return func; }
11414 
11415 
11420 template<class... Func>
11421 struct overloaded: Func... {
11422  using Func::operator()...;
11423 };
11424 
11425 
11430 template<class... Type>
11431 overloaded(Type...) -> overloaded<Type...>;
11432 
11433 
11438 template<class Func>
11439 struct y_combinator {
11444  y_combinator(Func recursive):
11445  func{std::move(recursive)}
11446  {}
11447 
11454  template <class... Args>
11455  decltype(auto) operator()(Args &&... args) const {
11456  return func(*this, std::forward<Args>(args)...);
11457  }
11458 
11460  template <class... Args>
11461  decltype(auto) operator()(Args &&... args) {
11462  return func(*this, std::forward<Args>(args)...);
11463  }
11464 
11465 private:
11466  Func func;
11467 };
11468 
11469 
11470 }
11471 
11472 
11473 #endif // ENTT_CORE_UTILITY_HPP
11474 
11475 
11476 
11477 namespace entt {
11478 
11479 
11480 class meta_any;
11481 class meta_handle;
11482 class meta_type;
11483 
11484 
11491 namespace internal {
11492 
11493 
11494 struct meta_type_node;
11495 
11496 
11497 struct meta_prop_node {
11498  meta_prop_node * next;
11499  meta_any(* const key)();
11500  meta_any(* const value)();
11501 };
11502 
11503 
11504 struct meta_base_node {
11505  meta_type_node * const parent;
11506  meta_base_node * next;
11507  meta_type_node *(* const type)() ENTT_NOEXCEPT;
11508  void *(* const cast)(void *) ENTT_NOEXCEPT;
11509 };
11510 
11511 
11512 struct meta_conv_node {
11513  meta_type_node * const parent;
11514  meta_conv_node * next;
11515  meta_type_node *(* const type)() ENTT_NOEXCEPT;
11516  meta_any(* const conv)(const void *);
11517 };
11518 
11519 
11520 struct meta_ctor_node {
11521  using size_type = std::size_t;
11522  meta_type_node * const parent;
11523  meta_ctor_node * next;
11524  meta_prop_node * prop;
11525  const size_type size;
11526  meta_type_node *(* const arg)(size_type) ENTT_NOEXCEPT;
11527  meta_any(* const invoke)(meta_any * const);
11528 };
11529 
11530 
11531 struct meta_dtor_node {
11532  meta_type_node * const parent;
11533  bool(* const invoke)(meta_handle);
11534 };
11535 
11536 
11537 struct meta_data_node {
11538  ENTT_ID_TYPE identifier;
11539  meta_type_node * const parent;
11540  meta_data_node * next;
11541  meta_prop_node * prop;
11542  const bool is_const;
11543  const bool is_static;
11544  meta_type_node *(* const type)() ENTT_NOEXCEPT;
11545  bool(* const set)(meta_handle, meta_any, meta_any);
11546  meta_any(* const get)(meta_handle, meta_any);
11547 };
11548 
11549 
11550 struct meta_func_node {
11551  using size_type = std::size_t;
11552  ENTT_ID_TYPE identifier;
11553  meta_type_node * const parent;
11554  meta_func_node * next;
11555  meta_prop_node * prop;
11556  const size_type size;
11557  const bool is_const;
11558  const bool is_static;
11559  meta_type_node *(* const ret)() ENTT_NOEXCEPT;
11560  meta_type_node *(* const arg)(size_type) ENTT_NOEXCEPT;
11561  meta_any(* const invoke)(meta_handle, meta_any *);
11562 };
11563 
11564 
11565 struct meta_type_node {
11566  using size_type = std::size_t;
11567  ENTT_ID_TYPE identifier;
11568  meta_type_node * next;
11569  meta_prop_node * prop;
11570  const bool is_void;
11571  const bool is_integral;
11572  const bool is_floating_point;
11573  const bool is_array;
11574  const bool is_enum;
11575  const bool is_union;
11576  const bool is_class;
11577  const bool is_pointer;
11578  const bool is_function_pointer;
11579  const bool is_member_object_pointer;
11580  const bool is_member_function_pointer;
11581  const size_type extent;
11582  bool(* const compare)(const void *, const void *);
11583  meta_type_node *(* const remove_pointer)() ENTT_NOEXCEPT;
11584  meta_type_node *(* const remove_extent)() ENTT_NOEXCEPT;
11585  meta_base_node *base{nullptr};
11586  meta_conv_node *conv{nullptr};
11587  meta_ctor_node *ctor{nullptr};
11588  meta_dtor_node *dtor{nullptr};
11589  meta_data_node *data{nullptr};
11590  meta_func_node *func{nullptr};
11591 };
11592 
11593 
11594 template<typename Type, typename Op, typename Node>
11595 void iterate(Op op, Node *curr) ENTT_NOEXCEPT {
11596  while(curr) {
11597  op(Type{curr});
11598  curr = curr->next;
11599  }
11600 }
11601 
11602 
11603 template<auto Member, typename Type, typename Op>
11604 void iterate(Op op, const meta_type_node *node) ENTT_NOEXCEPT {
11605  if(node) {
11606  auto *curr = node->base;
11607  iterate<Type>(op, node->*Member);
11608 
11609  while(curr) {
11610  iterate<Member, Type>(op, curr->type());
11611  curr = curr->next;
11612  }
11613  }
11614 }
11615 
11616 
11617 template<typename Op, typename Node>
11618 auto find_if(Op op, Node *curr) ENTT_NOEXCEPT {
11619  while(curr && !op(curr)) {
11620  curr = curr->next;
11621  }
11622 
11623  return curr;
11624 }
11625 
11626 
11627 template<auto Member, typename Op>
11628 auto find_if(Op op, const meta_type_node *node) ENTT_NOEXCEPT
11629 -> decltype(find_if(op, node->*Member)) {
11630  decltype(find_if(op, node->*Member)) ret = nullptr;
11631 
11632  if(node) {
11633  ret = find_if(op, node->*Member);
11634  auto *curr = node->base;
11635 
11636  while(curr && !ret) {
11637  ret = find_if<Member>(op, curr->type());
11638  curr = curr->next;
11639  }
11640  }
11641 
11642  return ret;
11643 }
11644 
11645 
11646 template<typename Type>
11647 static bool compare(const void *lhs, const void *rhs) {
11648  if constexpr(!std::is_function_v<Type> && is_equality_comparable_v<Type>) {
11649  return *static_cast<const Type *>(lhs) == *static_cast<const Type *>(rhs);
11650  } else {
11651  return lhs == rhs;
11652  }
11653 }
11654 
11655 
11656 template<typename...>
11657 struct meta_node;
11658 
11659 
11660 template<>
11661 struct meta_node<> {
11662  inline static meta_type_node *local = nullptr;
11663  inline static meta_type_node **global = &local;
11664 };
11665 
11666 
11667 template<typename Type>
11668 struct meta_node<Type> {
11669  static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>);
11670 
11671  static void reset() ENTT_NOEXCEPT {
11672  auto * const node = resolve();
11673  auto **it = meta_node<>::global;
11674 
11675  while(*it && *it != node) {
11676  it = &(*it)->next;
11677  }
11678 
11679  if(*it) {
11680  *it = (*it)->next;
11681  }
11682 
11683  const auto unregister_all = y_combinator{
11684  [](auto &&self, auto **curr, auto... member) {
11685  while(*curr) {
11686  auto *prev = *curr;
11687  (self(&(prev->*member)), ...);
11688  *curr = prev->next;
11689  prev->next = nullptr;
11690  }
11691  }
11692  };
11693 
11694  unregister_all(&node->prop);
11695  unregister_all(&node->base);
11696  unregister_all(&node->conv);
11697  unregister_all(&node->ctor, &internal::meta_ctor_node::prop);
11698  unregister_all(&node->data, &internal::meta_data_node::prop);
11699  unregister_all(&node->func, &internal::meta_func_node::prop);
11700 
11701  node->identifier = {};
11702  node->dtor = nullptr;
11703  node->next = nullptr;
11704  }
11705 
11706  static meta_type_node * resolve() ENTT_NOEXCEPT {
11707  static meta_type_node node{
11708  {},
11709  nullptr,
11710  nullptr,
11711  std::is_void_v<Type>,
11712  std::is_integral_v<Type>,
11713  std::is_floating_point_v<Type>,
11714  std::is_array_v<Type>,
11715  std::is_enum_v<Type>,
11716  std::is_union_v<Type>,
11717  std::is_class_v<Type>,
11718  std::is_pointer_v<Type>,
11719  std::is_pointer_v<Type> && std::is_function_v<std::remove_pointer_t<Type>>,
11720  std::is_member_object_pointer_v<Type>,
11721  std::is_member_function_pointer_v<Type>,
11722  std::extent_v<Type>,
11723  &compare<Type>, // workaround for an issue with VS2017
11724  []() ENTT_NOEXCEPT -> meta_type_node * {
11725  return meta_node<std::remove_const_t<std::remove_pointer_t<Type>>>::resolve();
11726  },
11727  []() ENTT_NOEXCEPT -> meta_type_node * {
11728  return meta_node<std::remove_const_t<std::remove_extent_t<Type>>>::resolve();
11729  }
11730  };
11731 
11732  if constexpr(is_named_type_v<Type>) {
11733  auto *candidate = internal::find_if([](auto *curr) {
11734  return curr->identifier == named_type_traits_v<Type>;
11735  }, *meta_node<>::global);
11736 
11737  return candidate ? candidate : &node;
11738  } else {
11739  return &node;
11740  }
11741  }
11742 };
11743 
11744 
11745 template<typename... Type>
11746 struct meta_info: meta_node<std::remove_cv_t<std::remove_reference_t<Type>>...> {};
11747 
11748 
11749 }
11750 
11751 
11773 class meta_any {
11775  friend class meta_handle;
11776 
11777  using storage_type = std::aligned_storage_t<sizeof(void *), alignof(void *)>;
11778  using copy_fn_type = void *(storage_type &, const void *);
11779  using destroy_fn_type = void(void *);
11780  using steal_fn_type = void *(storage_type &, void *, destroy_fn_type *);
11781 
11782  template<typename Type>
11783  static Type * release(Type *instance) {
11784  const auto * const node = internal::meta_info<Type>::resolve();
11785  [[maybe_unused]] const bool destroyed = (!node->dtor || node->dtor->invoke(*instance));
11786  ENTT_ASSERT(destroyed);
11787  return instance;
11788  }
11789 
11790  template<typename Type, typename = std::void_t<>>
11791  struct type_traits {
11792  template<typename... Args>
11793  static void * instance(storage_type &storage, Args &&... args) {
11794  auto instance = std::make_unique<Type>(std::forward<Args>(args)...);
11795  new (&storage) Type *{instance.get()};
11796  return instance.release();
11797  }
11798 
11799  static void destroy(void *instance) {
11800  delete release<Type>(static_cast<Type *>(instance));
11801  }
11802 
11803  static void * copy(storage_type &storage, const void *other) {
11804  auto instance = std::make_unique<Type>(*static_cast<const Type *>(other));
11805  new (&storage) Type *{instance.get()};
11806  return instance.release();
11807  }
11808 
11809  static void * steal(storage_type &to, void *from, destroy_fn_type *) {
11810  auto * const instance = static_cast<Type *>(from);
11811  new (&to) Type *{instance};
11812  return instance;
11813  }
11814  };
11815 
11816  template<typename Type>
11817  struct type_traits<Type, std::enable_if_t<sizeof(Type) <= sizeof(void *) && std::is_nothrow_move_constructible_v<Type>>> {
11818  template<typename... Args>
11819  static void * instance(storage_type &storage, Args &&... args) {
11820  return new (&storage) Type{std::forward<Args>(args)...};
11821  }
11822 
11823  static void destroy(void *instance) {
11824  release<Type>(static_cast<Type *>(instance))->~Type();
11825  }
11826 
11827  static void * copy(storage_type &storage, const void *instance) {
11828  return new (&storage) Type{*static_cast<const Type *>(instance)};
11829  }
11830 
11831  static void * steal(storage_type &to, void *from, destroy_fn_type *destroy_fn) {
11832  void * const instance = new (&to) Type{std::move(*static_cast<Type *>(from))};
11833  destroy_fn(from);
11834  return instance;
11835  }
11836  };
11837 
11838 public:
11841  : storage{},
11842  instance{nullptr},
11843  node{nullptr},
11844  destroy_fn{nullptr},
11845  copy_fn{nullptr},
11846  steal_fn{nullptr}
11847  {}
11848 
11855  template<typename Type, typename... Args>
11856  explicit meta_any(std::in_place_type_t<Type>, [[maybe_unused]] Args &&... args)
11857  : meta_any{}
11858  {
11860 
11861  if constexpr(!std::is_void_v<Type>) {
11862  using traits_type = type_traits<std::remove_cv_t<std::remove_reference_t<Type>>>;
11863  static_assert(std::is_copy_constructible_v<Type>);
11864 
11865  instance = traits_type::instance(storage, std::forward<Args>(args)...);
11866  destroy_fn = &traits_type::destroy;
11867  copy_fn = &traits_type::copy;
11868  steal_fn = &traits_type::steal;
11869  }
11870  }
11871 
11877  template<typename Type>
11878  explicit meta_any(std::reference_wrapper<Type> type)
11879  : meta_any{}
11880  {
11882  instance = &type.get();
11883  }
11884 
11889  inline meta_any(meta_handle handle) ENTT_NOEXCEPT;
11890 
11896  template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, meta_any>>>
11897  meta_any(Type &&type)
11898  : meta_any{std::in_place_type<std::remove_cv_t<std::remove_reference_t<Type>>>, std::forward<Type>(type)}
11899  {}
11900 
11905  meta_any(const meta_any &other)
11906  : meta_any{}
11907  {
11908  node = other.node;
11909  instance = other.copy_fn ? other.copy_fn(storage, other.instance) : other.instance;
11910  destroy_fn = other.destroy_fn;
11911  copy_fn = other.copy_fn;
11912  steal_fn = other.steal_fn;
11913  }
11914 
11925  : meta_any{}
11926  {
11927  swap(*this, other);
11928  }
11929 
11932  if(destroy_fn) {
11933  destroy_fn(instance);
11934  }
11935  }
11936 
11943  template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, meta_any>>>
11944  meta_any & operator=(Type &&type) {
11945  return (*this = meta_any{std::forward<Type>(type)});
11946  }
11947 
11953  meta_any & operator=(const meta_any &other) {
11954  return (*this = meta_any{other});
11955  }
11956 
11963  meta_any any{std::move(other)};
11964  swap(any, *this);
11965  return *this;
11966  }
11967 
11972  inline meta_type type() const ENTT_NOEXCEPT;
11973 
11978  const void * data() const ENTT_NOEXCEPT {
11979  return instance;
11980  }
11981 
11983  void * data() ENTT_NOEXCEPT {
11984  return const_cast<void *>(std::as_const(*this).data());
11985  }
11986 
11992  template<typename Type>
11993  const Type * try_cast() const ENTT_NOEXCEPT {
11994  const auto * const type = internal::meta_info<Type>::resolve();
11995  void *ret = nullptr;
11996 
11997  if(node == type) {
11998  ret = instance;
11999  } else {
12000  const auto *base = internal::find_if<&internal::meta_type_node::base>([type](auto *candidate) {
12001  return candidate->type() == type;
12002  }, node);
12003 
12004  ret = base ? base->cast(instance) : nullptr;
12005  }
12006 
12007  return static_cast<const Type *>(ret);
12008  }
12009 
12011  template<typename Type>
12013  return const_cast<Type *>(std::as_const(*this).try_cast<Type>());
12014  }
12015 
12030  template<typename Type>
12031  const Type & cast() const ENTT_NOEXCEPT {
12032  auto * const actual = try_cast<Type>();
12033  ENTT_ASSERT(actual);
12034  return *actual;
12035  }
12036 
12038  template<typename Type>
12039  Type & cast() ENTT_NOEXCEPT {
12040  return const_cast<Type &>(std::as_const(*this).cast<Type>());
12041  }
12042 
12049  template<typename Type>
12050  meta_any convert() const {
12051  meta_any any{};
12052 
12053  if(const auto * const type = internal::meta_info<Type>::resolve(); node == type) {
12054  any = *static_cast<const Type *>(instance);
12055  } else {
12056  const auto * const conv = internal::find_if<&internal::meta_type_node::conv>([type](auto *other) {
12057  return other->type() == type;
12058  }, node);
12059 
12060  if(conv) {
12061  any = conv->conv(instance);
12062  }
12063  }
12064 
12065  return any;
12066  }
12067 
12073  template<typename Type>
12074  bool convert() {
12075  bool valid = (node == internal::meta_info<Type>::resolve());
12076 
12077  if(!valid) {
12078  if(auto any = std::as_const(*this).convert<Type>(); any) {
12079  swap(any, *this);
12080  valid = true;
12081  }
12082  }
12083 
12084  return valid;
12085  }
12086 
12094  template<typename Type, typename... Args>
12095  void emplace(Args &&... args) {
12096  *this = meta_any{std::in_place_type_t<Type>{}, std::forward<Args>(args)...};
12097  }
12098 
12103  explicit operator bool() const ENTT_NOEXCEPT {
12104  return node;
12105  }
12106 
12113  bool operator==(const meta_any &other) const ENTT_NOEXCEPT {
12114  return node == other.node && (!node || node->compare(instance, other.instance));
12115  }
12116 
12122  friend void swap(meta_any &lhs, meta_any &rhs) ENTT_NOEXCEPT {
12123  if(lhs.steal_fn && rhs.steal_fn) {
12124  storage_type buffer;
12125  auto * const temp = lhs.steal_fn(buffer, lhs.instance, lhs.destroy_fn);
12126  lhs.instance = rhs.steal_fn(lhs.storage, rhs.instance, rhs.destroy_fn);
12127  rhs.instance = lhs.steal_fn(rhs.storage, temp, lhs.destroy_fn);
12128  } else if(lhs.steal_fn) {
12129  lhs.instance = lhs.steal_fn(rhs.storage, lhs.instance, lhs.destroy_fn);
12130  std::swap(rhs.instance, lhs.instance);
12131  } else if(rhs.steal_fn) {
12132  rhs.instance = rhs.steal_fn(lhs.storage, rhs.instance, rhs.destroy_fn);
12133  std::swap(rhs.instance, lhs.instance);
12134  } else {
12135  std::swap(lhs.instance, rhs.instance);
12136  }
12137 
12138  std::swap(lhs.node, rhs.node);
12139  std::swap(lhs.destroy_fn, rhs.destroy_fn);
12140  std::swap(lhs.copy_fn, rhs.copy_fn);
12141  std::swap(lhs.steal_fn, rhs.steal_fn);
12142  }
12143 
12144 private:
12145  storage_type storage;
12146  void *instance;
12147  const internal::meta_type_node *node;
12148  destroy_fn_type *destroy_fn;
12149  copy_fn_type *copy_fn;
12150  steal_fn_type *steal_fn;
12151 };
12152 
12153 
12164  friend class meta_any;
12165 
12166 public:
12169  : node{nullptr},
12170  instance{nullptr}
12171  {}
12172 
12178  : node{any.node},
12179  instance{any.instance}
12180  {}
12181 
12187  template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, meta_handle>>>
12190  instance{&obj}
12191  {}
12192 
12194  inline meta_type type() const ENTT_NOEXCEPT;
12195 
12197  const void * data() const ENTT_NOEXCEPT {
12198  return instance;
12199  }
12200 
12202  void * data() ENTT_NOEXCEPT {
12203  return const_cast<void *>(std::as_const(*this).data());
12204  }
12205 
12210  explicit operator bool() const ENTT_NOEXCEPT {
12211  return instance;
12212  }
12213 
12214 private:
12215  const internal::meta_type_node *node;
12216  void *instance;
12217 };
12218 
12219 
12226 inline bool operator!=(const meta_any &lhs, const meta_any &rhs) ENTT_NOEXCEPT {
12227  return !(lhs == rhs);
12228 }
12229 
12230 
12232 struct meta_prop {
12237  meta_prop(const internal::meta_prop_node *curr = nullptr) ENTT_NOEXCEPT
12238  : node{curr}
12239  {}
12240 
12246  return node->key();
12247  }
12248 
12254  return node->value();
12255  }
12256 
12261  explicit operator bool() const ENTT_NOEXCEPT {
12262  return node;
12263  }
12264 
12271  bool operator==(const meta_prop &other) const ENTT_NOEXCEPT {
12272  return node == other.node;
12273  }
12274 
12275 private:
12276  const internal::meta_prop_node *node;
12277 };
12278 
12279 
12286 inline bool operator!=(const meta_prop &lhs, const meta_prop &rhs) ENTT_NOEXCEPT {
12287  return !(lhs == rhs);
12288 }
12289 
12290 
12292 struct meta_base {
12294  meta_base(const internal::meta_base_node *curr = nullptr) ENTT_NOEXCEPT
12295  : node{curr}
12296  {}
12297 
12302  inline meta_type parent() const ENTT_NOEXCEPT;
12303 
12305  inline meta_type type() const ENTT_NOEXCEPT;
12306 
12312  void * cast(void *instance) const ENTT_NOEXCEPT {
12313  return node->cast(instance);
12314  }
12315 
12320  explicit operator bool() const ENTT_NOEXCEPT {
12321  return node;
12322  }
12323 
12325  bool operator==(const meta_base &other) const ENTT_NOEXCEPT {
12326  return node == other.node;
12327  }
12328 
12329 private:
12330  const internal::meta_base_node *node;
12331 };
12332 
12333 
12335 inline bool operator!=(const meta_base &lhs, const meta_base &rhs) ENTT_NOEXCEPT {
12336  return !(lhs == rhs);
12337 }
12338 
12339 
12341 struct meta_conv {
12343  meta_conv(const internal::meta_conv_node *curr = nullptr) ENTT_NOEXCEPT
12344  : node{curr}
12345  {}
12346 
12348  inline meta_type parent() const ENTT_NOEXCEPT;
12349 
12351  inline meta_type type() const ENTT_NOEXCEPT;
12352 
12358  meta_any convert(const void *instance) const ENTT_NOEXCEPT {
12359  return node->conv(instance);
12360  }
12361 
12366  explicit operator bool() const ENTT_NOEXCEPT {
12367  return node;
12368  }
12369 
12371  bool operator==(const meta_conv &other) const ENTT_NOEXCEPT {
12372  return node == other.node;
12373  }
12374 
12375 private:
12376  const internal::meta_conv_node *node;
12377 };
12378 
12379 
12381 inline bool operator!=(const meta_conv &lhs, const meta_conv &rhs) ENTT_NOEXCEPT {
12382  return !(lhs == rhs);
12383 }
12384 
12385 
12387 struct meta_ctor {
12389  using size_type = typename internal::meta_ctor_node::size_type;
12390 
12392  meta_ctor(const internal::meta_ctor_node *curr = nullptr) ENTT_NOEXCEPT
12393  : node{curr}
12394  {}
12395 
12397  inline meta_type parent() const ENTT_NOEXCEPT;
12398 
12403  size_type size() const ENTT_NOEXCEPT {
12404  return node->size;
12405  }
12406 
12412  meta_type arg(size_type index) const ENTT_NOEXCEPT;
12413 
12425  template<typename... Args>
12426  meta_any invoke(Args &&... args) const {
12427  std::array<meta_any, sizeof...(Args)> arguments{{std::forward<Args>(args)...}};
12428  meta_any any{};
12429 
12430  if(sizeof...(Args) == size()) {
12431  any = node->invoke(arguments.data());
12432  }
12433 
12434  return any;
12435  }
12436 
12442  template<typename Op>
12443  std::enable_if_t<std::is_invocable_v<Op, meta_prop>, void>
12444  prop(Op op) const ENTT_NOEXCEPT {
12445  internal::iterate<meta_prop>(std::move(op), node->prop);
12446  }
12447 
12454  return internal::find_if([key = std::move(key)](auto *candidate) {
12455  return candidate->key() == key;
12456  }, node->prop);
12457  }
12458 
12463  explicit operator bool() const ENTT_NOEXCEPT {
12464  return node;
12465  }
12466 
12468  bool operator==(const meta_ctor &other) const ENTT_NOEXCEPT {
12469  return node == other.node;
12470  }
12471 
12472 private:
12473  const internal::meta_ctor_node *node;
12474 };
12475 
12476 
12478 inline bool operator!=(const meta_ctor &lhs, const meta_ctor &rhs) ENTT_NOEXCEPT {
12479  return !(lhs == rhs);
12480 }
12481 
12482 
12484 struct meta_dtor {
12486  meta_dtor(const internal::meta_dtor_node *curr = nullptr) ENTT_NOEXCEPT
12487  : node{curr}
12488  {}
12489 
12491  inline meta_type parent() const ENTT_NOEXCEPT;
12492 
12503  bool invoke(meta_handle handle) const {
12504  return node->invoke(handle);
12505  }
12506 
12511  explicit operator bool() const ENTT_NOEXCEPT {
12512  return node;
12513  }
12514 
12516  bool operator==(const meta_dtor &other) const ENTT_NOEXCEPT {
12517  return node == other.node;
12518  }
12519 
12520 private:
12521  const internal::meta_dtor_node *node;
12522 };
12523 
12524 
12526 inline bool operator!=(const meta_dtor &lhs, const meta_dtor &rhs) ENTT_NOEXCEPT {
12527  return !(lhs == rhs);
12528 }
12529 
12530 
12532 struct meta_data {
12534  meta_data(const internal::meta_data_node *curr = nullptr) ENTT_NOEXCEPT
12535  : node{curr}
12536  {}
12537 
12540  return node->identifier;
12541  }
12542 
12544  inline meta_type parent() const ENTT_NOEXCEPT;
12545 
12550  bool is_const() const ENTT_NOEXCEPT {
12551  return node->is_const;
12552  }
12553 
12562  bool is_static() const ENTT_NOEXCEPT {
12563  return node->is_static;
12564  }
12565 
12567  inline meta_type type() const ENTT_NOEXCEPT;
12568 
12583  template<typename Type>
12584  bool set(meta_handle handle, Type &&value) const {
12585  return node->set(handle, meta_any{}, std::forward<Type>(value));
12586  }
12587 
12603  template<typename Type>
12604  bool set(meta_handle handle, std::size_t index, Type &&value) const {
12605  ENTT_ASSERT(index < node->type()->extent);
12606  return node->set(handle, index, std::forward<Type>(value));
12607  }
12608 
12619  return node->get(handle, meta_any{});
12620  }
12621 
12632  meta_any get(meta_handle handle, std::size_t index) const ENTT_NOEXCEPT {
12633  ENTT_ASSERT(index < node->type()->extent);
12634  return node->get(handle, index);
12635  }
12636 
12642  template<typename Op>
12643  std::enable_if_t<std::is_invocable_v<Op, meta_prop>, void>
12644  prop(Op op) const ENTT_NOEXCEPT {
12645  internal::iterate<meta_prop>(std::move(op), node->prop);
12646  }
12647 
12654  return internal::find_if([key = std::move(key)](auto *candidate) {
12655  return candidate->key() == key;
12656  }, node->prop);
12657  }
12658 
12663  explicit operator bool() const ENTT_NOEXCEPT {
12664  return node;
12665  }
12666 
12668  bool operator==(const meta_data &other) const ENTT_NOEXCEPT {
12669  return node == other.node;
12670  }
12671 
12672 private:
12673  const internal::meta_data_node *node;
12674 };
12675 
12676 
12678 inline bool operator!=(const meta_data &lhs, const meta_data &rhs) ENTT_NOEXCEPT {
12679  return !(lhs == rhs);
12680 }
12681 
12682 
12684 struct meta_func {
12686  using size_type = typename internal::meta_func_node::size_type;
12687 
12689  meta_func(const internal::meta_func_node *curr = nullptr) ENTT_NOEXCEPT
12690  : node{curr}
12691  {}
12692 
12695  return node->identifier;
12696  }
12697 
12699  inline meta_type parent() const ENTT_NOEXCEPT;
12700 
12705  size_type size() const ENTT_NOEXCEPT {
12706  return node->size;
12707  }
12708 
12713  bool is_const() const ENTT_NOEXCEPT {
12714  return node->is_const;
12715  }
12716 
12725  bool is_static() const ENTT_NOEXCEPT {
12726  return node->is_static;
12727  }
12728 
12733  inline meta_type ret() const ENTT_NOEXCEPT;
12734 
12740  inline meta_type arg(size_type index) const ENTT_NOEXCEPT;
12741 
12757  template<typename... Args>
12758  meta_any invoke(meta_handle handle, Args &&... args) const {
12759  // makes aliasing on the values and passes forward references if any
12760  std::array<meta_any, sizeof...(Args)> arguments{{meta_handle{args}...}};
12761  meta_any any{};
12762 
12763  if(sizeof...(Args) == size()) {
12764  any = node->invoke(handle, arguments.data());
12765  }
12766 
12767  return any;
12768  }
12769 
12775  template<typename Op>
12776  std::enable_if_t<std::is_invocable_v<Op, meta_prop>, void>
12777  prop(Op op) const ENTT_NOEXCEPT {
12778  internal::iterate<meta_prop>(std::move(op), node->prop);
12779  }
12780 
12787  return internal::find_if([key = std::move(key)](auto *candidate) {
12788  return candidate->key() == key;
12789  }, node->prop);
12790  }
12791 
12796  explicit operator bool() const ENTT_NOEXCEPT {
12797  return node;
12798  }
12799 
12801  bool operator==(const meta_func &other) const ENTT_NOEXCEPT {
12802  return node == other.node;
12803  }
12804 
12805 private:
12806  const internal::meta_func_node *node;
12807 };
12808 
12809 
12811 inline bool operator!=(const meta_func &lhs, const meta_func &rhs) ENTT_NOEXCEPT {
12812  return !(lhs == rhs);
12813 }
12814 
12815 
12817 class meta_type {
12818  template<typename... Args, std::size_t... Indexes>
12819  auto ctor(std::index_sequence<Indexes...>) const ENTT_NOEXCEPT {
12820  return internal::find_if([](auto *candidate) {
12821  return candidate->size == sizeof...(Args) && ([](auto *from, auto *to) {
12822  return (from == to) || internal::find_if<&internal::meta_type_node::base>([to](auto *curr) { return curr->type() == to; }, from)
12823  || internal::find_if<&internal::meta_type_node::conv>([to](auto *curr) { return curr->type() == to; }, from);
12824  }(internal::meta_info<Args>::resolve(), candidate->arg(Indexes)) && ...);
12825  }, node->ctor);
12826  }
12827 
12828 public:
12830  using size_type = typename internal::meta_type_node::size_type;
12831 
12833  meta_type(const internal::meta_type_node *curr = nullptr) ENTT_NOEXCEPT
12834  : node{curr}
12835  {}
12836 
12842  return node->identifier;
12843  }
12844 
12849  bool is_void() const ENTT_NOEXCEPT {
12850  return node->is_void;
12851  }
12852 
12859  return node->is_integral;
12860  }
12861 
12869  return node->is_floating_point;
12870  }
12871 
12877  bool is_array() const ENTT_NOEXCEPT {
12878  return node->is_array;
12879  }
12880 
12885  bool is_enum() const ENTT_NOEXCEPT {
12886  return node->is_enum;
12887  }
12888 
12893  bool is_union() const ENTT_NOEXCEPT {
12894  return node->is_union;
12895  }
12896 
12901  bool is_class() const ENTT_NOEXCEPT {
12902  return node->is_class;
12903  }
12904 
12909  bool is_pointer() const ENTT_NOEXCEPT {
12910  return node->is_pointer;
12911  }
12912 
12920  return node->is_function_pointer;
12921  }
12922 
12930  return node->is_member_object_pointer;
12931  }
12932 
12940  return node->is_member_function_pointer;
12941  }
12942 
12950  return node->extent;
12951  }
12952 
12959  return node->remove_pointer();
12960  }
12961 
12968  return node->remove_extent();
12969  }
12970 
12979  template<typename Op>
12980  std::enable_if_t<std::is_invocable_v<Op, meta_base>, void>
12981  base(Op op) const ENTT_NOEXCEPT {
12982  internal::iterate<&internal::meta_type_node::base, meta_base>(std::move(op), node);
12983  }
12984 
12994  return internal::find_if<&internal::meta_type_node::base>([identifier](auto *candidate) {
12995  return candidate->type()->identifier == identifier;
12996  }, node);
12997  }
12998 
13008  template<typename Op>
13009  void conv(Op op) const ENTT_NOEXCEPT {
13010  internal::iterate<&internal::meta_type_node::conv, meta_conv>(std::move(op), node);
13011  }
13012 
13023  template<typename Type>
13025  return internal::find_if<&internal::meta_type_node::conv>([type = internal::meta_info<Type>::resolve()](auto *candidate) {
13026  return candidate->type() == type;
13027  }, node);
13028  }
13029 
13035  template<typename Op>
13036  void ctor(Op op) const ENTT_NOEXCEPT {
13037  internal::iterate<meta_ctor>(std::move(op), node->ctor);
13038  }
13039 
13045  template<typename... Args>
13047  return ctor<Args...>(std::index_sequence_for<Args...>{});
13048  }
13049 
13055  return node->dtor;
13056  }
13057 
13067  template<typename Op>
13068  std::enable_if_t<std::is_invocable_v<Op, meta_data>, void>
13069  data(Op op) const ENTT_NOEXCEPT {
13070  internal::iterate<&internal::meta_type_node::data, meta_data>(std::move(op), node);
13071  }
13072 
13084  return internal::find_if<&internal::meta_type_node::data>([identifier](auto *candidate) {
13085  return candidate->identifier == identifier;
13086  }, node);
13087  }
13088 
13099  template<typename Op>
13100  std::enable_if_t<std::is_invocable_v<Op, meta_func>, void>
13101  func(Op op) const ENTT_NOEXCEPT {
13102  internal::iterate<&internal::meta_type_node::func, meta_func>(std::move(op), node);
13103  }
13104 
13116  return internal::find_if<&internal::meta_type_node::func>([identifier](auto *candidate) {
13117  return candidate->identifier == identifier;
13118  }, node);
13119  }
13120 
13132  template<typename... Args>
13133  meta_any construct(Args &&... args) const {
13134  std::array<meta_any, sizeof...(Args)> arguments{{std::forward<Args>(args)...}};
13135  meta_any any{};
13136 
13137  internal::find_if<&internal::meta_type_node::ctor>([data = arguments.data(), &any](auto *curr) -> bool {
13138  if(curr->size == sizeof...(args)) {
13139  any = curr->invoke(data);
13140  }
13141 
13142  return static_cast<bool>(any);
13143  }, node);
13144 
13145  return any;
13146  }
13147 
13161  return (handle.type() == node) && (!node->dtor || node->dtor->invoke(handle));
13162  }
13163 
13173  template<typename Op>
13174  std::enable_if_t<std::is_invocable_v<Op, meta_prop>, void>
13175  prop(Op op) const ENTT_NOEXCEPT {
13176  internal::iterate<&internal::meta_type_node::prop, meta_prop>(std::move(op), node);
13177  }
13178 
13190  return internal::find_if<&internal::meta_type_node::prop>([key = std::move(key)](auto *candidate) {
13191  return candidate->key() == key;
13192  }, node);
13193  }
13194 
13199  explicit operator bool() const ENTT_NOEXCEPT {
13200  return node;
13201  }
13202 
13204  bool operator==(const meta_type &other) const ENTT_NOEXCEPT {
13205  return node == other.node;
13206  }
13207 
13208 private:
13209  const internal::meta_type_node *node;
13210 };
13211 
13212 
13214 struct meta_ctx {
13219  static void bind(meta_ctx other) ENTT_NOEXCEPT {
13220  internal::meta_info<>::global = other.ctx;
13221  }
13222 
13223 private:
13224  internal::meta_type_node **ctx{&internal::meta_info<>::local};
13225 };
13226 
13227 
13229 inline bool operator!=(const meta_type &lhs, const meta_type &rhs) ENTT_NOEXCEPT {
13230  return !(lhs == rhs);
13231 }
13232 
13233 
13235  : meta_any{}
13236 {
13237  node = handle.node;
13238  instance = handle.instance;
13239 }
13240 
13241 
13243  return node;
13244 }
13245 
13246 
13248  return node;
13249 }
13250 
13251 
13253  return node->parent;
13254 }
13255 
13256 
13258  return node->type();
13259 }
13260 
13261 
13263  return node->parent;
13264 }
13265 
13266 
13268  return node->type();
13269 }
13270 
13271 
13273  return node->parent;
13274 }
13275 
13276 
13278  return index < size() ? node->arg(index) : nullptr;
13279 }
13280 
13281 
13283  return node->parent;
13284 }
13285 
13286 
13288  return node->parent;
13289 }
13290 
13291 
13293  return node->type();
13294 }
13295 
13296 
13298  return node->parent;
13299 }
13300 
13301 
13303  return node->ret();
13304 }
13305 
13306 
13308  return index < size() ? node->arg(index) : nullptr;
13309 }
13310 
13311 
13312 }
13313 
13314 
13315 #endif // ENTT_META_META_HPP
13316 
13317 
13318 
13319 namespace entt {
13320 
13321 
13328 namespace internal {
13329 
13330 
13331 template<typename>
13332 struct meta_function_helper;
13333 
13334 
13335 template<typename Ret, typename... Args>
13336 struct meta_function_helper<Ret(Args...)> {
13337  using return_type = std::remove_cv_t<std::remove_reference_t<Ret>>;
13338  using args_type = std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...>;
13339 
13340  static constexpr std::index_sequence_for<Args...> index_sequence{};
13341  static constexpr auto is_const = false;
13342 
13343  static auto arg(typename internal::meta_func_node::size_type index) ENTT_NOEXCEPT {
13344  return std::array<meta_type_node *, sizeof...(Args)>{{meta_info<Args>::resolve()...}}[index];
13345  }
13346 };
13347 
13348 
13349 template<typename Ret, typename... Args>
13350 struct meta_function_helper<Ret(Args...) const>: meta_function_helper<Ret(Args...)> {
13351  static constexpr auto is_const = true;
13352 };
13353 
13354 
13355 template<typename Ret, typename... Args, typename Class>
13356 constexpr meta_function_helper<Ret(Args...)>
13357 to_meta_function_helper(Ret(Class:: *)(Args...));
13358 
13359 
13360 template<typename Ret, typename... Args, typename Class>
13361 constexpr meta_function_helper<Ret(Args...) const>
13362 to_meta_function_helper(Ret(Class:: *)(Args...) const);
13363 
13364 
13365 template<typename Ret, typename... Args>
13366 constexpr meta_function_helper<Ret(Args...)>
13367 to_meta_function_helper(Ret(*)(Args...));
13368 
13369 
13370 constexpr void to_meta_function_helper(...);
13371 
13372 
13373 template<typename Candidate>
13374 using meta_function_helper_t = decltype(to_meta_function_helper(std::declval<Candidate>()));
13375 
13376 
13377 template<typename Type, typename... Args, std::size_t... Indexes>
13378 meta_any construct(meta_any * const args, std::index_sequence<Indexes...>) {
13379  [[maybe_unused]] auto direct = std::make_tuple((args+Indexes)->try_cast<Args>()...);
13380  meta_any any{};
13381 
13382  if(((std::get<Indexes>(direct) || (args+Indexes)->convert<Args>()) && ...)) {
13383  any = Type{(std::get<Indexes>(direct) ? *std::get<Indexes>(direct) : (args+Indexes)->cast<Args>())...};
13384  }
13385 
13386  return any;
13387 }
13388 
13389 
13390 template<bool Const, typename Type, auto Data>
13391 bool setter([[maybe_unused]] meta_handle handle, [[maybe_unused]] meta_any index, [[maybe_unused]] meta_any value) {
13392  bool accepted = false;
13393 
13394  if constexpr(!Const) {
13395  if constexpr(std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>> || std::is_member_function_pointer_v<decltype(Data)>) {
13396  using helper_type = meta_function_helper_t<decltype(Data)>;
13397  using data_type = std::tuple_element_t<!std::is_member_function_pointer_v<decltype(Data)>, typename helper_type::args_type>;
13398  static_assert(std::is_invocable_v<decltype(Data), Type &, data_type>);
13399  auto * const clazz = meta_any{handle}.try_cast<Type>();
13400  auto * const direct = value.try_cast<data_type>();
13401 
13402  if(clazz && (direct || value.convert<data_type>())) {
13403  std::invoke(Data, *clazz, direct ? *direct : value.cast<data_type>());
13404  accepted = true;
13405  }
13406  } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
13407  using data_type = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<Type>().*Data)>>;
13408  static_assert(std::is_invocable_v<decltype(Data), Type *>);
13409  auto * const clazz = meta_any{handle}.try_cast<Type>();
13410 
13411  if constexpr(std::is_array_v<data_type>) {
13412  using underlying_type = std::remove_extent_t<data_type>;
13413  auto * const direct = value.try_cast<underlying_type>();
13414  auto * const idx = index.try_cast<std::size_t>();
13415 
13416  if(clazz && idx && (direct || value.convert<underlying_type>())) {
13417  std::invoke(Data, clazz)[*idx] = direct ? *direct : value.cast<underlying_type>();
13418  accepted = true;
13419  }
13420  } else {
13421  auto * const direct = value.try_cast<data_type>();
13422 
13423  if(clazz && (direct || value.convert<data_type>())) {
13424  std::invoke(Data, clazz) = (direct ? *direct : value.cast<data_type>());
13425  accepted = true;
13426  }
13427  }
13428  } else {
13429  static_assert(std::is_pointer_v<decltype(Data)>);
13430  using data_type = std::remove_cv_t<std::remove_reference_t<decltype(*Data)>>;
13431 
13432  if constexpr(std::is_array_v<data_type>) {
13433  using underlying_type = std::remove_extent_t<data_type>;
13434  auto * const direct = value.try_cast<underlying_type>();
13435  auto * const idx = index.try_cast<std::size_t>();
13436 
13437  if(idx && (direct || value.convert<underlying_type>())) {
13438  (*Data)[*idx] = (direct ? *direct : value.cast<underlying_type>());
13439  accepted = true;
13440  }
13441  } else {
13442  auto * const direct = value.try_cast<data_type>();
13443 
13444  if(direct || value.convert<data_type>()) {
13445  *Data = (direct ? *direct : value.cast<data_type>());
13446  accepted = true;
13447  }
13448  }
13449  }
13450  }
13451 
13452  return accepted;
13453 }
13454 
13455 
13456 template<typename Type, auto Data, typename Policy>
13457 meta_any getter([[maybe_unused]] meta_handle handle, [[maybe_unused]] meta_any index) {
13458  auto dispatch = [](auto &&value) {
13459  if constexpr(std::is_same_v<Policy, as_void_t>) {
13460  return meta_any{std::in_place_type<void>};
13461  } else if constexpr(std::is_same_v<Policy, as_alias_t>) {
13462  return meta_any{std::ref(std::forward<decltype(value)>(value))};
13463  } else {
13464  static_assert(std::is_same_v<Policy, as_is_t>);
13465  return meta_any{std::forward<decltype(value)>(value)};
13466  }
13467  };
13468 
13469  if constexpr(std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>> || std::is_member_function_pointer_v<decltype(Data)>) {
13470  static_assert(std::is_invocable_v<decltype(Data), Type &>);
13471  auto * const clazz = meta_any{handle}.try_cast<Type>();
13472  return clazz ? dispatch(std::invoke(Data, *clazz)) : meta_any{};
13473  } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
13474  using data_type = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<Type>().*Data)>>;
13475  static_assert(std::is_invocable_v<decltype(Data), Type *>);
13476  auto * const clazz = meta_any{handle}.try_cast<Type>();
13477 
13478  if constexpr(std::is_array_v<data_type>) {
13479  auto * const idx = index.try_cast<std::size_t>();
13480  return (clazz && idx) ? dispatch(std::invoke(Data, clazz)[*idx]) : meta_any{};
13481  } else {
13482  return clazz ? dispatch(std::invoke(Data, clazz)) : meta_any{};
13483  }
13484  } else {
13485  static_assert(std::is_pointer_v<std::decay_t<decltype(Data)>>);
13486 
13487  if constexpr(std::is_array_v<std::remove_pointer_t<decltype(Data)>>) {
13488  auto * const idx = index.try_cast<std::size_t>();
13489  return idx ? dispatch((*Data)[*idx]) : meta_any{};
13490  } else {
13491  return dispatch(*Data);
13492  }
13493  }
13494 }
13495 
13496 
13497 template<typename Type, auto Candidate, typename Policy, std::size_t... Indexes>
13498 meta_any invoke([[maybe_unused]] meta_handle handle, meta_any *args, std::index_sequence<Indexes...>) {
13499  using helper_type = meta_function_helper_t<decltype(Candidate)>;
13500 
13501  auto dispatch = [](auto *... params) {
13502  if constexpr(std::is_void_v<typename helper_type::return_type> || std::is_same_v<Policy, as_void_t>) {
13503  std::invoke(Candidate, *params...);
13504  return meta_any{std::in_place_type<void>};
13505  } else if constexpr(std::is_same_v<Policy, as_alias_t>) {
13506  return meta_any{std::ref(std::invoke(Candidate, *params...))};
13507  } else {
13508  static_assert(std::is_same_v<Policy, as_is_t>);
13509  return meta_any{std::invoke(Candidate, *params...)};
13510  }
13511  };
13512 
13513  [[maybe_unused]] const auto direct = std::make_tuple([](meta_any *any, auto *instance) {
13514  using arg_type = std::remove_reference_t<decltype(*instance)>;
13515 
13516  if(!instance && any->convert<arg_type>()) {
13517  instance = any->try_cast<arg_type>();
13518  }
13519 
13520  return instance;
13521  }(args+Indexes, (args+Indexes)->try_cast<std::tuple_element_t<Indexes, typename helper_type::args_type>>())...);
13522 
13523  if constexpr(std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Candidate)>>>) {
13524  return (std::get<Indexes>(direct) && ...) ? dispatch(std::get<Indexes>(direct)...) : meta_any{};
13525  } else {
13526  auto * const clazz = meta_any{handle}.try_cast<Type>();
13527  return (clazz && (std::get<Indexes>(direct) && ...)) ? dispatch(clazz, std::get<Indexes>(direct)...) : meta_any{};
13528  }
13529 }
13530 
13531 
13532 }
13533 
13534 
13541 template<typename, typename...>
13543 
13544 
13555 template<typename Type>
13557  template<typename Node>
13558  bool duplicate(const Node *candidate, const Node *node) ENTT_NOEXCEPT {
13559  return node && (node == candidate || duplicate(candidate, node->next));
13560  }
13561 
13562  template<typename Node>
13563  bool duplicate(const ENTT_ID_TYPE identifier, const Node *node) ENTT_NOEXCEPT {
13564  return node && (node->identifier == identifier || duplicate(identifier, node->next));
13565  }
13566 
13567  auto record(const ENTT_ID_TYPE identifier) ENTT_NOEXCEPT {
13568  auto * const node = internal::meta_info<Type>::resolve();
13569 
13570  ENTT_ASSERT(!duplicate(identifier, *internal::meta_info<>::global));
13571  ENTT_ASSERT(!duplicate(node, *internal::meta_info<>::global));
13572  node->identifier = identifier;
13573  node->next = *internal::meta_info<>::global;
13574  *internal::meta_info<>::global = node;
13575 
13576  return extended_meta_factory<Type>{&node->prop};
13577  }
13578 
13579 public:
13589  static_assert(!is_named_type_v<Type>);
13590  return record(identifier);
13591  }
13592 
13601  static_assert(is_named_type_v<Type>);
13602  return record(named_type_traits_t<Type>::value);
13603  }
13604 
13613  template<typename Base>
13615  static_assert(std::is_base_of_v<Base, Type>);
13616  auto * const type = internal::meta_info<Type>::resolve();
13617 
13618  static internal::meta_base_node node{
13619  type,
13620  nullptr,
13622  [](void *instance) ENTT_NOEXCEPT -> void * {
13623  return static_cast<Base *>(static_cast<Type *>(instance));
13624  }
13625  };
13626 
13627  ENTT_ASSERT(!duplicate(&node, type->base));
13628  node.next = type->base;
13629  type->base = &node;
13630 
13631  return meta_factory<Type>{};
13632  }
13633 
13643  template<typename To>
13645  static_assert(std::is_convertible_v<Type, To>);
13646  auto * const type = internal::meta_info<Type>::resolve();
13647 
13648  static internal::meta_conv_node node{
13649  type,
13650  nullptr,
13652  [](const void *instance) -> meta_any {
13653  return static_cast<To>(*static_cast<const Type *>(instance));
13654  }
13655  };
13656 
13657  ENTT_ASSERT(!duplicate(&node, type->conv));
13658  node.next = type->conv;
13659  type->conv = &node;
13660 
13661  return meta_factory<Type>{};
13662  }
13663 
13676  template<auto Candidate>
13678  using conv_type = std::invoke_result_t<decltype(Candidate), Type &>;
13679  auto * const type = internal::meta_info<Type>::resolve();
13680 
13681  static internal::meta_conv_node node{
13682  type,
13683  nullptr,
13685  [](const void *instance) -> meta_any {
13686  return std::invoke(Candidate, *static_cast<const Type *>(instance));
13687  }
13688  };
13689 
13690  ENTT_ASSERT(!duplicate(&node, type->conv));
13691  node.next = type->conv;
13692  type->conv = &node;
13693 
13694  return meta_factory<Type>{};
13695  }
13696 
13710  template<auto Func, typename Policy = as_is_t>
13712  using helper_type = internal::meta_function_helper_t<decltype(Func)>;
13713  static_assert(std::is_same_v<typename helper_type::return_type, Type>);
13714  auto * const type = internal::meta_info<Type>::resolve();
13715 
13716  static internal::meta_ctor_node node{
13717  type,
13718  nullptr,
13719  nullptr,
13720  helper_type::index_sequence.size(),
13721  &helper_type::arg,
13722  [](meta_any * const any) {
13723  return internal::invoke<Type, Func, Policy>({}, any, helper_type::index_sequence);
13724  }
13725  };
13726 
13727  ENTT_ASSERT(!duplicate(&node, type->ctor));
13728  node.next = type->ctor;
13729  type->ctor = &node;
13730 
13731  return extended_meta_factory<Type, std::integral_constant<decltype(Func), Func>>{&node.prop};
13732  }
13733 
13744  template<typename... Args>
13746  using helper_type = internal::meta_function_helper_t<Type(*)(Args...)>;
13747  auto * const type = internal::meta_info<Type>::resolve();
13748 
13749  static internal::meta_ctor_node node{
13750  type,
13751  nullptr,
13752  nullptr,
13753  helper_type::index_sequence.size(),
13754  &helper_type::arg,
13755  [](meta_any * const any) {
13756  return internal::construct<Type, std::remove_cv_t<std::remove_reference_t<Args>>...>(any, helper_type::index_sequence);
13757  }
13758  };
13759 
13760  ENTT_ASSERT(!duplicate(&node, type->ctor));
13761  node.next = type->ctor;
13762  type->ctor = &node;
13763 
13764  return extended_meta_factory<Type, Type(Args...)>{&node.prop};
13765  }
13766 
13783  template<auto Func>
13785  static_assert(std::is_invocable_v<decltype(Func), Type &>);
13786  auto * const type = internal::meta_info<Type>::resolve();
13787 
13788  static internal::meta_dtor_node node{
13789  type,
13790  [](meta_handle handle) {
13791  const auto valid = (handle.type() == internal::meta_info<Type>::resolve());
13792 
13793  if(valid) {
13794  std::invoke(Func, *meta_any{handle}.try_cast<Type>());
13795  }
13796 
13797  return valid;
13798  }
13799  };
13800 
13801  ENTT_ASSERT(!type->dtor);
13802  type->dtor = &node;
13803 
13804  return meta_factory<Type>{};
13805  }
13806 
13820  template<auto Data, typename Policy = as_is_t>
13822  auto * const type = internal::meta_info<Type>::resolve();
13823  internal::meta_data_node *curr = nullptr;
13824 
13825  if constexpr(std::is_same_v<Type, decltype(Data)>) {
13826  static_assert(std::is_same_v<Policy, as_is_t>);
13827 
13828  static internal::meta_data_node node{
13829  {},
13830  type,
13831  nullptr,
13832  nullptr,
13833  true,
13834  true,
13836  [](meta_handle, meta_any, meta_any) { return false; },
13837  [](meta_handle, meta_any) -> meta_any { return Data; }
13838  };
13839 
13840  curr = &node;
13841  } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
13842  using data_type = std::remove_reference_t<decltype(std::declval<Type>().*Data)>;
13843 
13844  static internal::meta_data_node node{
13845  {},
13846  type,
13847  nullptr,
13848  nullptr,
13849  std::is_const_v<data_type>,
13850  !std::is_member_object_pointer_v<decltype(Data)>,
13852  &internal::setter<std::is_const_v<data_type>, Type, Data>,
13853  &internal::getter<Type, Data, Policy>
13854  };
13855 
13856  curr = &node;
13857  } else {
13858  static_assert(std::is_pointer_v<std::decay_t<decltype(Data)>>);
13859  using data_type = std::remove_pointer_t<std::decay_t<decltype(Data)>>;
13860 
13861  static internal::meta_data_node node{
13862  {},
13863  type,
13864  nullptr,
13865  nullptr,
13866  std::is_const_v<data_type>,
13867  !std::is_member_object_pointer_v<decltype(Data)>,
13869  &internal::setter<std::is_const_v<data_type>, Type, Data>,
13870  &internal::getter<Type, Data, Policy>
13871  };
13872 
13873  curr = &node;
13874  }
13875 
13876  ENTT_ASSERT(!duplicate(identifier, type->data));
13877  ENTT_ASSERT(!duplicate(curr, type->data));
13878  curr->identifier = identifier;
13879  curr->next = type->data;
13880  type->data = curr;
13881 
13882  return extended_meta_factory<Type, std::integral_constant<decltype(Data), Data>>{&curr->prop};
13883  }
13884 
13905  template<auto Setter, auto Getter, typename Policy = as_is_t>
13907  using underlying_type = std::invoke_result_t<decltype(Getter), Type &>;
13908  static_assert(std::is_invocable_v<decltype(Setter), Type &, underlying_type>);
13909  auto * const type = internal::meta_info<Type>::resolve();
13910 
13911  static internal::meta_data_node node{
13912  {},
13913  type,
13914  nullptr,
13915  nullptr,
13916  false,
13917  false,
13919  &internal::setter<false, Type, Setter>,
13920  &internal::getter<Type, Getter, Policy>
13921  };
13922 
13923  ENTT_ASSERT(!duplicate(identifier, type->data));
13924  ENTT_ASSERT(!duplicate(&node, type->data));
13925  node.identifier = identifier;
13926  node.next = type->data;
13927  type->data = &node;
13928 
13929  return extended_meta_factory<Type, std::integral_constant<decltype(Setter), Setter>, std::integral_constant<decltype(Getter), Getter>>{&node.prop};
13930  }
13931 
13945  template<auto Candidate, typename Policy = as_is_t>
13947  using helper_type = internal::meta_function_helper_t<decltype(Candidate)>;
13948  auto * const type = internal::meta_info<Type>::resolve();
13949 
13950  static internal::meta_func_node node{
13951  {},
13952  type,
13953  nullptr,
13954  nullptr,
13955  helper_type::index_sequence.size(),
13956  helper_type::is_const,
13957  !std::is_member_function_pointer_v<decltype(Candidate)>,
13958  &internal::meta_info<std::conditional_t<std::is_same_v<Policy, as_void_t>, void, typename helper_type::return_type>>::resolve,
13959  &helper_type::arg,
13960  [](meta_handle handle, meta_any *any) {
13961  return internal::invoke<Type, Candidate, Policy>(handle, any, helper_type::index_sequence);
13962  }
13963  };
13964 
13965  ENTT_ASSERT(!duplicate(identifier, type->func));
13966  ENTT_ASSERT(!duplicate(&node, type->func));
13967  node.identifier = identifier;
13968  node.next = type->func;
13969  type->func = &node;
13970 
13971  return extended_meta_factory<Type, std::integral_constant<decltype(Candidate), Candidate>>{&node.prop};
13972  }
13973 
13983  internal::meta_info<Type>::reset();
13984  }
13985 };
13986 
13987 
13993 template<typename Type, typename... Spec>
13994 class extended_meta_factory: public meta_factory<Type> {
13995  bool duplicate(const meta_any &key, const internal::meta_prop_node *node) ENTT_NOEXCEPT {
13996  return node && (node->key() == key || duplicate(key, node->next));
13997  }
13998 
13999  template<std::size_t Step = 0, std::size_t... Index, typename... Property, typename... Other>
14000  void unpack(std::index_sequence<Index...>, std::tuple<Property...> property, Other &&... other) {
14001  unroll<Step>(choice<3>, std::move(std::get<Index>(property))..., std::forward<Other>(other)...);
14002  }
14003 
14004  template<std::size_t Step = 0, typename... Property, typename... Other>
14005  void unroll(choice_t<3>, std::tuple<Property...> property, Other &&... other) {
14006  unpack<Step>(std::index_sequence_for<Property...>{}, std::move(property), std::forward<Other>(other)...);
14007  }
14008 
14009  template<std::size_t Step = 0, typename... Property, typename... Other>
14010  void unroll(choice_t<2>, std::pair<Property...> property, Other &&... other) {
14011  assign<Step>(std::move(property.first), std::move(property.second));
14012  unroll<Step+1>(choice<3>, std::forward<Other>(other)...);
14013  }
14014 
14015  template<std::size_t Step = 0, typename Property, typename... Other>
14016  std::enable_if_t<!std::is_invocable_v<Property>>
14017  unroll(choice_t<1>, Property &&property, Other &&... other) {
14018  assign<Step>(std::forward<Property>(property));
14019  unroll<Step+1>(choice<3>, std::forward<Other>(other)...);
14020  }
14021 
14022  template<std::size_t Step = 0, typename Func, typename... Other>
14023  void unroll(choice_t<0>, Func &&invocable, Other &&... other) {
14024  unroll<Step>(choice<3>, std::forward<Func>(invocable)(), std::forward<Other>(other)...);
14025  }
14026 
14027  template<std::size_t>
14028  void unroll(choice_t<0>) {}
14029 
14030  template<std::size_t = 0, typename Key, typename... Value>
14031  void assign(Key &&key, Value &&... value) {
14032  static auto property{std::make_tuple(std::forward<Key>(key), std::forward<Value>(value)...)};
14033 
14034  static internal::meta_prop_node node{
14035  nullptr,
14036  []() -> meta_any {
14037  return std::get<0>(property);
14038  },
14039  []() -> meta_any {
14040  if constexpr(sizeof...(Value) == 0) {
14041  return {};
14042  } else {
14043  return std::get<1>(property);
14044  }
14045  }
14046  };
14047 
14048  ENTT_ASSERT(!duplicate(node.key(), *curr));
14049  node.next = *curr;
14050  *curr = &node;
14051  }
14052 
14053 public:
14058  extended_meta_factory(entt::internal::meta_prop_node **target)
14059  : curr{target}
14060  {}
14061 
14073  template<typename PropertyOrKey, typename... Value>
14074  auto prop(PropertyOrKey &&property_or_key, Value &&... value) && {
14075  if constexpr(sizeof...(Value) == 0) {
14076  unroll(choice<3>, std::forward<PropertyOrKey>(property_or_key));
14077  } else {
14078  assign(std::forward<PropertyOrKey>(property_or_key), std::forward<Value>(value)...);
14079  }
14080 
14081  return extended_meta_factory<Type, Spec..., PropertyOrKey, Value...>{curr};
14082  }
14083 
14094  template <typename... Property>
14095  auto props(Property... property) && {
14096  unroll(choice<3>, std::forward<Property>(property)...);
14097  return extended_meta_factory<Type, Spec..., Property...>{curr};
14098  }
14099 
14100 private:
14101  entt::internal::meta_prop_node **curr{nullptr};
14102 };
14103 
14104 
14116 template<typename Type>
14118  return meta_factory<Type>{};
14119 }
14120 
14121 
14127 template<typename Type>
14130 }
14131 
14132 
14139  return internal::find_if([identifier](auto *node) {
14140  return node->identifier == identifier;
14141  }, *internal::meta_info<>::global);
14142 }
14143 
14144 
14150 template<typename Op>
14151 inline std::enable_if_t<std::is_invocable_v<Op, meta_type>, void>
14153  internal::iterate<meta_type>(std::move(op), *internal::meta_info<>::global);
14154 }
14155 
14156 
14157 }
14158 
14159 
14160 #endif // ENTT_META_FACTORY_HPP
14161 
14162 // #include "meta/meta.hpp"
14163 
14164 // #include "meta/policy.hpp"
14165 
14166 // #include "process/process.hpp"
14167 #ifndef ENTT_PROCESS_PROCESS_HPP
14168 #define ENTT_PROCESS_PROCESS_HPP
14169 
14170 
14171 #include <utility>
14172 #include <type_traits>
14173 // #include "../config/config.h"
14174 #ifndef ENTT_CONFIG_CONFIG_H
14175 #define ENTT_CONFIG_CONFIG_H
14176 
14177 
14178 #ifndef ENTT_NOEXCEPT
14179 #define ENTT_NOEXCEPT noexcept
14180 #endif // ENTT_NOEXCEPT
14181 
14182 
14183 #ifndef ENTT_HS_SUFFIX
14184 #define ENTT_HS_SUFFIX _hs
14185 #endif // ENTT_HS_SUFFIX
14186 
14187 
14188 #ifndef ENTT_HWS_SUFFIX
14189 #define ENTT_HWS_SUFFIX _hws
14190 #endif // ENTT_HWS_SUFFIX
14191 
14192 
14193 #ifndef ENTT_NO_ATOMIC
14194 #include <atomic>
14195 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
14196 #else // ENTT_NO_ATOMIC
14197 #define ENTT_MAYBE_ATOMIC(Type) Type
14198 #endif // ENTT_NO_ATOMIC
14199 
14200 
14201 #ifndef ENTT_DISABLE_ETO
14202 #include <type_traits>
14203 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
14204 #else // ENTT_DISABLE_ETO
14205 // sfinae-friendly definition
14206 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
14207 #endif // ENTT_DISABLE_ETO
14208 
14209 
14210 #ifndef ENTT_ID_TYPE
14211 #include <cstdint>
14212 #define ENTT_ID_TYPE std::uint32_t
14213 #endif // ENTT_ID_TYPE
14214 
14215 
14216 #ifndef ENTT_PAGE_SIZE
14217 #define ENTT_PAGE_SIZE 32768
14218 #endif // ENTT_PAGE_SIZE
14219 
14220 
14221 #ifndef ENTT_DISABLE_ASSERT
14222 #include <cassert>
14223 #define ENTT_ASSERT(condition) assert(condition)
14224 #else // ENTT_DISABLE_ASSERT
14225 #define ENTT_ASSERT(...) ((void)0)
14226 #endif // ENTT_DISABLE_ASSERT
14227 
14228 
14229 #endif // ENTT_CONFIG_CONFIG_H
14230 
14231 
14232 
14233 namespace entt {
14234 
14235 
14295 template<typename Derived, typename Delta>
14296 class process {
14297  enum class state: unsigned int {
14298  UNINITIALIZED = 0,
14299  RUNNING,
14300  PAUSED,
14301  SUCCEEDED,
14302  FAILED,
14303  ABORTED,
14304  FINISHED
14305  };
14306 
14307  template<state value>
14308  using state_value_t = std::integral_constant<state, value>;
14309 
14310  template<typename Target = Derived>
14311  auto tick(int, state_value_t<state::UNINITIALIZED>)
14312  -> decltype(std::declval<Target>().init()) {
14313  static_cast<Target *>(this)->init();
14314  }
14315 
14316  template<typename Target = Derived>
14317  auto tick(int, state_value_t<state::RUNNING>, Delta delta, void *data)
14318  -> decltype(std::declval<Target>().update(delta, data)) {
14319  static_cast<Target *>(this)->update(delta, data);
14320  }
14321 
14322  template<typename Target = Derived>
14323  auto tick(int, state_value_t<state::SUCCEEDED>)
14324  -> decltype(std::declval<Target>().succeeded()) {
14325  static_cast<Target *>(this)->succeeded();
14326  }
14327 
14328  template<typename Target = Derived>
14329  auto tick(int, state_value_t<state::FAILED>)
14330  -> decltype(std::declval<Target>().failed()) {
14331  static_cast<Target *>(this)->failed();
14332  }
14333 
14334  template<typename Target = Derived>
14335  auto tick(int, state_value_t<state::ABORTED>)
14336  -> decltype(std::declval<Target>().aborted()) {
14337  static_cast<Target *>(this)->aborted();
14338  }
14339 
14340  template<state value, typename... Args>
14341  void tick(char, state_value_t<value>, Args &&...) const ENTT_NOEXCEPT {}
14342 
14343 protected:
14351  if(alive()) {
14352  current = state::SUCCEEDED;
14353  }
14354  }
14355 
14363  if(alive()) {
14364  current = state::FAILED;
14365  }
14366  }
14367 
14375  if(current == state::RUNNING) {
14376  current = state::PAUSED;
14377  }
14378  }
14379 
14387  if(current == state::PAUSED) {
14388  current = state::RUNNING;
14389  }
14390  }
14391 
14392 public:
14394  using delta_type = Delta;
14395 
14398  static_assert(std::is_base_of_v<process, Derived>);
14399  }
14400 
14409  void abort(const bool immediately = false) ENTT_NOEXCEPT {
14410  if(alive()) {
14411  current = state::ABORTED;
14412 
14413  if(immediately) {
14414  tick({});
14415  }
14416  }
14417  }
14418 
14423  bool alive() const ENTT_NOEXCEPT {
14424  return current == state::RUNNING || current == state::PAUSED;
14425  }
14426 
14431  bool dead() const ENTT_NOEXCEPT {
14432  return current == state::FINISHED;
14433  }
14434 
14439  bool paused() const ENTT_NOEXCEPT {
14440  return current == state::PAUSED;
14441  }
14442 
14447  bool rejected() const ENTT_NOEXCEPT {
14448  return stopped;
14449  }
14450 
14456  void tick(const Delta delta, void *data = nullptr) {
14457  switch (current) {
14458  case state::UNINITIALIZED:
14459  tick(0, state_value_t<state::UNINITIALIZED>{});
14460  current = state::RUNNING;
14461  break;
14462  case state::RUNNING:
14463  tick(0, state_value_t<state::RUNNING>{}, delta, data);
14464  break;
14465  default:
14466  // suppress warnings
14467  break;
14468  }
14469 
14470  // if it's dead, it must be notified and removed immediately
14471  switch(current) {
14472  case state::SUCCEEDED:
14473  tick(0, state_value_t<state::SUCCEEDED>{});
14474  current = state::FINISHED;
14475  break;
14476  case state::FAILED:
14477  tick(0, state_value_t<state::FAILED>{});
14478  current = state::FINISHED;
14479  stopped = true;
14480  break;
14481  case state::ABORTED:
14482  tick(0, state_value_t<state::ABORTED>{});
14483  current = state::FINISHED;
14484  stopped = true;
14485  break;
14486  default:
14487  // suppress warnings
14488  break;
14489  }
14490  }
14491 
14492 private:
14493  state current{state::UNINITIALIZED};
14494  bool stopped{false};
14495 };
14496 
14497 
14537 template<typename Func, typename Delta>
14538 struct process_adaptor: process<process_adaptor<Func, Delta>, Delta>, private Func {
14544  template<typename... Args>
14545  process_adaptor(Args &&... args)
14546  : Func{std::forward<Args>(args)...}
14547  {}
14548 
14554  void update(const Delta delta, void *data) {
14555  Func::operator()(delta, data, [this]() { this->succeed(); }, [this]() { this->fail(); });
14556  }
14557 };
14558 
14559 
14560 }
14561 
14562 
14563 #endif // ENTT_PROCESS_PROCESS_HPP
14564 
14565 // #include "process/scheduler.hpp"
14566 #ifndef ENTT_PROCESS_SCHEDULER_HPP
14567 #define ENTT_PROCESS_SCHEDULER_HPP
14568 
14569 
14570 #include <vector>
14571 #include <memory>
14572 #include <utility>
14573 #include <algorithm>
14574 #include <type_traits>
14575 // #include "../config/config.h"
14576 
14577 // #include "process.hpp"
14578 
14579 
14580 
14581 namespace entt {
14582 
14583 
14610 template<typename Delta>
14611 class scheduler {
14612  struct process_handler {
14613  using instance_type = std::unique_ptr<void, void(*)(void *)>;
14614  using update_fn_type = bool(process_handler &, Delta, void *);
14615  using abort_fn_type = void(process_handler &, bool);
14616  using next_type = std::unique_ptr<process_handler>;
14617 
14618  instance_type instance;
14619  update_fn_type *update;
14620  abort_fn_type *abort;
14621  next_type next;
14622  };
14623 
14624  struct continuation {
14625  continuation(process_handler *ref)
14626  : handler{ref}
14627  {
14628  ENTT_ASSERT(handler);
14629  }
14630 
14631  template<typename Proc, typename... Args>
14632  continuation then(Args &&... args) {
14633  static_assert(std::is_base_of_v<process<Proc, Delta>, Proc>);
14634  auto proc = typename process_handler::instance_type{new Proc{std::forward<Args>(args)...}, &scheduler::deleter<Proc>};
14635  handler->next.reset(new process_handler{std::move(proc), &scheduler::update<Proc>, &scheduler::abort<Proc>, nullptr});
14636  handler = handler->next.get();
14637  return *this;
14638  }
14639 
14640  template<typename Func>
14641  continuation then(Func &&func) {
14642  return then<process_adaptor<std::decay_t<Func>, Delta>>(std::forward<Func>(func));
14643  }
14644 
14645  private:
14646  process_handler *handler;
14647  };
14648 
14649  template<typename Proc>
14650  static bool update(process_handler &handler, const Delta delta, void *data) {
14651  auto *process = static_cast<Proc *>(handler.instance.get());
14652  process->tick(delta, data);
14653 
14654  auto dead = process->dead();
14655 
14656  if(dead) {
14657  if(handler.next && !process->rejected()) {
14658  handler = std::move(*handler.next);
14659  // forces the process to exit the uninitialized state
14660  dead = handler.update(handler, {}, nullptr);
14661  } else {
14662  handler.instance.reset();
14663  }
14664  }
14665 
14666  return dead;
14667  }
14668 
14669  template<typename Proc>
14670  static void abort(process_handler &handler, const bool immediately) {
14671  static_cast<Proc *>(handler.instance.get())->abort(immediately);
14672  }
14673 
14674  template<typename Proc>
14675  static void deleter(void *proc) {
14676  delete static_cast<Proc *>(proc);
14677  }
14678 
14679 public:
14681  using size_type = std::size_t;
14682 
14684  scheduler() ENTT_NOEXCEPT = default;
14685 
14687  scheduler(scheduler &&) = default;
14688 
14690  scheduler & operator=(scheduler &&) = default;
14691 
14696  size_type size() const ENTT_NOEXCEPT {
14697  return handlers.size();
14698  }
14699 
14704  bool empty() const ENTT_NOEXCEPT {
14705  return handlers.empty();
14706  }
14707 
14714  void clear() {
14715  handlers.clear();
14716  }
14717 
14743  template<typename Proc, typename... Args>
14744  auto attach(Args &&... args) {
14745  static_assert(std::is_base_of_v<process<Proc, Delta>, Proc>);
14746  auto proc = typename process_handler::instance_type{new Proc{std::forward<Args>(args)...}, &scheduler::deleter<Proc>};
14747  process_handler handler{std::move(proc), &scheduler::update<Proc>, &scheduler::abort<Proc>, nullptr};
14748  // forces the process to exit the uninitialized state
14749  handler.update(handler, {}, nullptr);
14750  return continuation{&handlers.emplace_back(std::move(handler))};
14751  }
14752 
14804  template<typename Func>
14805  auto attach(Func &&func) {
14806  using Proc = process_adaptor<std::decay_t<Func>, Delta>;
14807  return attach<Proc>(std::forward<Func>(func));
14808  }
14809 
14821  void update(const Delta delta, void *data = nullptr) {
14822  bool clean = false;
14823 
14824  for(auto pos = handlers.size(); pos; --pos) {
14825  auto &handler = handlers[pos-1];
14826  const bool dead = handler.update(handler, delta, data);
14827  clean = clean || dead;
14828  }
14829 
14830  if(clean) {
14831  handlers.erase(std::remove_if(handlers.begin(), handlers.end(), [](auto &handler) {
14832  return !handler.instance;
14833  }), handlers.end());
14834  }
14835  }
14836 
14847  void abort(const bool immediately = false) {
14848  decltype(handlers) exec;
14849  exec.swap(handlers);
14850 
14851  std::for_each(exec.begin(), exec.end(), [immediately](auto &handler) {
14852  handler.abort(handler, immediately);
14853  });
14854 
14855  std::move(handlers.begin(), handlers.end(), std::back_inserter(exec));
14856  handlers.swap(exec);
14857  }
14858 
14859 private:
14860  std::vector<process_handler> handlers{};
14861 };
14862 
14863 
14864 }
14865 
14866 
14867 #endif // ENTT_PROCESS_SCHEDULER_HPP
14868 
14869 // #include "resource/cache.hpp"
14870 #ifndef ENTT_RESOURCE_CACHE_HPP
14871 #define ENTT_RESOURCE_CACHE_HPP
14872 
14873 
14874 #include <memory>
14875 #include <utility>
14876 #include <type_traits>
14877 #include <unordered_map>
14878 // #include "../config/config.h"
14879 #ifndef ENTT_CONFIG_CONFIG_H
14880 #define ENTT_CONFIG_CONFIG_H
14881 
14882 
14883 #ifndef ENTT_NOEXCEPT
14884 #define ENTT_NOEXCEPT noexcept
14885 #endif // ENTT_NOEXCEPT
14886 
14887 
14888 #ifndef ENTT_HS_SUFFIX
14889 #define ENTT_HS_SUFFIX _hs
14890 #endif // ENTT_HS_SUFFIX
14891 
14892 
14893 #ifndef ENTT_HWS_SUFFIX
14894 #define ENTT_HWS_SUFFIX _hws
14895 #endif // ENTT_HWS_SUFFIX
14896 
14897 
14898 #ifndef ENTT_NO_ATOMIC
14899 #include <atomic>
14900 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
14901 #else // ENTT_NO_ATOMIC
14902 #define ENTT_MAYBE_ATOMIC(Type) Type
14903 #endif // ENTT_NO_ATOMIC
14904 
14905 
14906 #ifndef ENTT_DISABLE_ETO
14907 #include <type_traits>
14908 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
14909 #else // ENTT_DISABLE_ETO
14910 // sfinae-friendly definition
14911 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
14912 #endif // ENTT_DISABLE_ETO
14913 
14914 
14915 #ifndef ENTT_ID_TYPE
14916 #include <cstdint>
14917 #define ENTT_ID_TYPE std::uint32_t
14918 #endif // ENTT_ID_TYPE
14919 
14920 
14921 #ifndef ENTT_PAGE_SIZE
14922 #define ENTT_PAGE_SIZE 32768
14923 #endif // ENTT_PAGE_SIZE
14924 
14925 
14926 #ifndef ENTT_DISABLE_ASSERT
14927 #include <cassert>
14928 #define ENTT_ASSERT(condition) assert(condition)
14929 #else // ENTT_DISABLE_ASSERT
14930 #define ENTT_ASSERT(...) ((void)0)
14931 #endif // ENTT_DISABLE_ASSERT
14932 
14933 
14934 #endif // ENTT_CONFIG_CONFIG_H
14935 
14936 // #include "handle.hpp"
14937 #ifndef ENTT_RESOURCE_HANDLE_HPP
14938 #define ENTT_RESOURCE_HANDLE_HPP
14939 
14940 
14941 #include <memory>
14942 #include <utility>
14943 // #include "../config/config.h"
14944 
14945 // #include "fwd.hpp"
14946 #ifndef ENTT_RESOURCE_FWD_HPP
14947 #define ENTT_RESOURCE_FWD_HPP
14948 
14949 
14950 namespace entt {
14951 
14952 
14954 template<typename>
14955 struct cache;
14956 
14958 template<typename>
14959 class handle;
14960 
14962 template<typename, typename>
14963 class loader;
14964 
14965 
14966 }
14967 
14968 
14969 #endif // ENTT_RESOURCE_FWD_HPP
14970 
14971 
14972 
14973 namespace entt {
14974 
14975 
14988 template<typename Resource>
14989 class handle {
14991  friend struct cache<Resource>;
14992 
14993  handle(std::shared_ptr<Resource> res) ENTT_NOEXCEPT
14994  : resource{std::move(res)}
14995  {}
14996 
14997 public:
14999  handle() ENTT_NOEXCEPT = default;
15000 
15011  const Resource & get() const ENTT_NOEXCEPT {
15012  ENTT_ASSERT(static_cast<bool>(resource));
15013  return *resource;
15014  }
15015 
15017  Resource & get() ENTT_NOEXCEPT {
15018  return const_cast<Resource &>(std::as_const(*this).get());
15019  }
15020 
15022  operator const Resource & () const ENTT_NOEXCEPT { return get(); }
15023 
15025  operator Resource & () ENTT_NOEXCEPT { return get(); }
15026 
15028  const Resource & operator *() const ENTT_NOEXCEPT { return get(); }
15029 
15031  Resource & operator *() ENTT_NOEXCEPT { return get(); }
15032 
15044  const Resource * operator->() const ENTT_NOEXCEPT {
15045  ENTT_ASSERT(static_cast<bool>(resource));
15046  return resource.get();
15047  }
15048 
15050  Resource * operator->() ENTT_NOEXCEPT {
15051  return const_cast<Resource *>(std::as_const(*this).operator->());
15052  }
15053 
15058  explicit operator bool() const { return static_cast<bool>(resource); }
15059 
15060 private:
15061  std::shared_ptr<Resource> resource;
15062 };
15063 
15064 
15065 }
15066 
15067 
15068 #endif // ENTT_RESOURCE_HANDLE_HPP
15069 
15070 // #include "loader.hpp"
15071 #ifndef ENTT_RESOURCE_LOADER_HPP
15072 #define ENTT_RESOURCE_LOADER_HPP
15073 
15074 
15075 #include <memory>
15076 // #include "fwd.hpp"
15077 
15078 
15079 
15080 namespace entt {
15081 
15082 
15115 template<typename Loader, typename Resource>
15116 class loader {
15118  friend struct cache<Resource>;
15119 
15126  template<typename... Args>
15127  std::shared_ptr<Resource> get(Args &&... args) const {
15128  return static_cast<const Loader *>(this)->load(std::forward<Args>(args)...);
15129  }
15130 };
15131 
15132 
15133 }
15134 
15135 
15136 #endif // ENTT_RESOURCE_LOADER_HPP
15137 
15138 // #include "fwd.hpp"
15139 
15140 
15141 
15142 namespace entt {
15143 
15144 
15155 template<typename Resource>
15156 struct cache {
15158  using size_type = std::size_t;
15160  using resource_type = Resource;
15163 
15165  cache() = default;
15166 
15168  cache(cache &&) = default;
15169 
15171  cache & operator=(cache &&) = default;
15172 
15178  return resources.size();
15179  }
15180 
15185  bool empty() const ENTT_NOEXCEPT {
15186  return resources.empty();
15187  }
15188 
15196  resources.clear();
15197  }
15198 
15221  template<typename Loader, typename... Args>
15222  entt::handle<Resource> load(const id_type id, Args &&... args) {
15223  static_assert(std::is_base_of_v<loader<Loader, Resource>, Loader>);
15224  entt::handle<Resource> resource{};
15225 
15226  if(auto it = resources.find(id); it == resources.cend()) {
15227  if(auto instance = Loader{}.get(std::forward<Args>(args)...); instance) {
15228  resources[id] = instance;
15229  resource = std::move(instance);
15230  }
15231  } else {
15232  resource = it->second;
15233  }
15234 
15235  return resource;
15236  }
15237 
15261  template<typename Loader, typename... Args>
15262  entt::handle<Resource> reload(const id_type id, Args &&... args) {
15263  return (discard(id), load<Loader>(id, std::forward<Args>(args)...));
15264  }
15265 
15278  template<typename Loader, typename... Args>
15279  entt::handle<Resource> temp(Args &&... args) const {
15280  return { Loader{}.get(std::forward<Args>(args)...) };
15281  }
15282 
15297  auto it = resources.find(id);
15298  return { it == resources.end() ? nullptr : it->second };
15299  }
15300 
15306  bool contains(const id_type id) const ENTT_NOEXCEPT {
15307  return (resources.find(id) != resources.cend());
15308  }
15309 
15318  void discard(const id_type id) ENTT_NOEXCEPT {
15319  if(auto it = resources.find(id); it != resources.end()) {
15320  resources.erase(it);
15321  }
15322  }
15323 
15341  template <typename Func>
15342  void each(Func func) const {
15343  auto begin = resources.begin();
15344  auto end = resources.end();
15345 
15346  while(begin != end) {
15347  auto curr = begin++;
15348 
15349  if constexpr(std::is_invocable_v<Func, id_type>) {
15350  func(curr->first);
15351  } else if constexpr(std::is_invocable_v<Func, entt::handle<Resource>>) {
15352  func(entt::handle{ curr->second });
15353  } else {
15354  func(curr->first, entt::handle{ curr->second });
15355  }
15356  }
15357  }
15358 
15359 private:
15360  std::unordered_map<id_type, std::shared_ptr<Resource>> resources;
15361 };
15362 
15363 
15364 }
15365 
15366 
15367 #endif // ENTT_RESOURCE_CACHE_HPP
15368 
15369 // #include "resource/handle.hpp"
15370 
15371 // #include "resource/loader.hpp"
15372 
15373 // #include "signal/delegate.hpp"
15374 #ifndef ENTT_SIGNAL_DELEGATE_HPP
15375 #define ENTT_SIGNAL_DELEGATE_HPP
15376 
15377 
15378 #include <tuple>
15379 #include <cstring>
15380 #include <utility>
15381 #include <algorithm>
15382 #include <functional>
15383 #include <type_traits>
15384 // #include "../config/config.h"
15385 #ifndef ENTT_CONFIG_CONFIG_H
15386 #define ENTT_CONFIG_CONFIG_H
15387 
15388 
15389 #ifndef ENTT_NOEXCEPT
15390 #define ENTT_NOEXCEPT noexcept
15391 #endif // ENTT_NOEXCEPT
15392 
15393 
15394 #ifndef ENTT_HS_SUFFIX
15395 #define ENTT_HS_SUFFIX _hs
15396 #endif // ENTT_HS_SUFFIX
15397 
15398 
15399 #ifndef ENTT_HWS_SUFFIX
15400 #define ENTT_HWS_SUFFIX _hws
15401 #endif // ENTT_HWS_SUFFIX
15402 
15403 
15404 #ifndef ENTT_NO_ATOMIC
15405 #include <atomic>
15406 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
15407 #else // ENTT_NO_ATOMIC
15408 #define ENTT_MAYBE_ATOMIC(Type) Type
15409 #endif // ENTT_NO_ATOMIC
15410 
15411 
15412 #ifndef ENTT_DISABLE_ETO
15413 #include <type_traits>
15414 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
15415 #else // ENTT_DISABLE_ETO
15416 // sfinae-friendly definition
15417 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
15418 #endif // ENTT_DISABLE_ETO
15419 
15420 
15421 #ifndef ENTT_ID_TYPE
15422 #include <cstdint>
15423 #define ENTT_ID_TYPE std::uint32_t
15424 #endif // ENTT_ID_TYPE
15425 
15426 
15427 #ifndef ENTT_PAGE_SIZE
15428 #define ENTT_PAGE_SIZE 32768
15429 #endif // ENTT_PAGE_SIZE
15430 
15431 
15432 #ifndef ENTT_DISABLE_ASSERT
15433 #include <cassert>
15434 #define ENTT_ASSERT(condition) assert(condition)
15435 #else // ENTT_DISABLE_ASSERT
15436 #define ENTT_ASSERT(...) ((void)0)
15437 #endif // ENTT_DISABLE_ASSERT
15438 
15439 
15440 #endif // ENTT_CONFIG_CONFIG_H
15441 
15442 
15443 
15444 namespace entt {
15445 
15446 
15453 namespace internal {
15454 
15455 
15456 template<typename Ret, typename... Args>
15457 auto to_function_pointer(Ret(*)(Args...)) -> Ret(*)(Args...);
15458 
15459 
15460 template<typename Ret, typename... Args, typename Type, typename Payload, typename = std::enable_if_t<std::is_convertible_v<const Payload *, const Type *>>>
15461 auto to_function_pointer(Ret(*)(Type &, Args...), const Payload *) -> Ret(*)(Args...);
15462 
15463 
15464 template<typename Ret, typename... Args, typename Type, typename Payload, typename = std::enable_if_t<std::is_convertible_v<const Payload *, const Type *>>>
15465 auto to_function_pointer(Ret(*)(Type *, Args...), const Payload *) -> Ret(*)(Args...);
15466 
15467 
15468 template<typename Class, typename Ret, typename... Args>
15469 auto to_function_pointer(Ret(Class:: *)(Args...), const Class *) -> Ret(*)(Args...);
15470 
15471 
15472 template<typename Class, typename Ret, typename... Args>
15473 auto to_function_pointer(Ret(Class:: *)(Args...) const, const Class *) -> Ret(*)(Args...);
15474 
15475 
15476 template<typename Class, typename Type>
15477 auto to_function_pointer(Type Class:: *, const Class *) -> Type(*)();
15478 
15479 
15480 template<typename... Type>
15481 using to_function_pointer_t = decltype(internal::to_function_pointer(std::declval<Type>()...));
15482 
15483 
15484 template<typename Ret, typename... Args>
15485 constexpr auto index_sequence_for(Ret(*)(Args...)) {
15486  return std::index_sequence_for<Args...>{};
15487 }
15488 
15489 
15490 }
15491 
15492 
15500 template<auto>
15501 struct connect_arg_t {};
15502 
15503 
15505 template<auto Func>
15506 constexpr connect_arg_t<Func> connect_arg{};
15507 
15508 
15515 template<typename>
15516 class delegate;
15517 
15518 
15532 template<typename Ret, typename... Args>
15533 class delegate<Ret(Args...)> {
15534  using proto_fn_type = Ret(const void *, std::tuple<Args &&...>);
15535 
15536  template<auto Function, std::size_t... Index>
15537  void connect(std::index_sequence<Index...>) ENTT_NOEXCEPT {
15538  static_assert(std::is_invocable_r_v<Ret, decltype(Function), std::tuple_element_t<Index, std::tuple<Args...>>...>);
15539  data = nullptr;
15540 
15541  fn = [](const void *, std::tuple<Args &&...> args) -> Ret {
15542  // Ret(...) makes void(...) eat the return values to avoid errors
15543  return Ret(std::invoke(Function, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
15544  };
15545  }
15546 
15547  template<auto Candidate, typename Type, std::size_t... Index>
15548  void connect(Type &value_or_instance, std::index_sequence<Index...>) ENTT_NOEXCEPT {
15549  static_assert(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, std::tuple_element_t<Index, std::tuple<Args...>>...>);
15550  data = &value_or_instance;
15551 
15552  fn = [](const void *payload, std::tuple<Args &&...> args) -> Ret {
15553  Type *curr = static_cast<Type *>(const_cast<std::conditional_t<std::is_const_v<Type>, const void *, void *>>(payload));
15554  // Ret(...) makes void(...) eat the return values to avoid errors
15555  return Ret(std::invoke(Candidate, *curr, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
15556  };
15557  }
15558 
15559  template<auto Candidate, typename Type, std::size_t... Index>
15560  void connect(Type *value_or_instance, std::index_sequence<Index...>) ENTT_NOEXCEPT {
15561  static_assert(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, std::tuple_element_t<Index, std::tuple<Args...>>...>);
15562  data = value_or_instance;
15563 
15564  fn = [](const void *payload, std::tuple<Args &&...> args) -> Ret {
15565  Type *curr = static_cast<Type *>(const_cast<std::conditional_t<std::is_const_v<Type>, const void *, void *>>(payload));
15566  // Ret(...) makes void(...) eat the return values to avoid errors
15567  return Ret(std::invoke(Candidate, curr, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
15568  };
15569  }
15570 
15571 public:
15573  using function_type = Ret(Args...);
15574 
15577  : fn{nullptr}, data{nullptr}
15578  {}
15579 
15584  template<auto Function>
15585  delegate(connect_arg_t<Function>) ENTT_NOEXCEPT
15586  : delegate{}
15587  {
15588  connect<Function>();
15589  }
15590 
15598  template<auto Candidate, typename Type>
15599  delegate(connect_arg_t<Candidate>, Type &value_or_instance) ENTT_NOEXCEPT
15600  : delegate{}
15601  {
15602  connect<Candidate>(value_or_instance);
15603  }
15604 
15612  template<auto Candidate, typename Type>
15613  delegate(connect_arg_t<Candidate>, Type *value_or_instance) ENTT_NOEXCEPT
15614  : delegate{}
15615  {
15616  connect<Candidate>(value_or_instance);
15617  }
15618 
15623  template<auto Function>
15624  void connect() ENTT_NOEXCEPT {
15625  connect<Function>(internal::index_sequence_for(internal::to_function_pointer_t<decltype(Function)>{}));
15626  }
15627 
15643  template<auto Candidate, typename Type>
15644  void connect(Type &value_or_instance) ENTT_NOEXCEPT {
15645  connect<Candidate>(value_or_instance, internal::index_sequence_for(internal::to_function_pointer_t<decltype(Candidate), Type *>{}));
15646  }
15647 
15663  template<auto Candidate, typename Type>
15664  void connect(Type *value_or_instance) ENTT_NOEXCEPT {
15665  connect<Candidate>(value_or_instance, internal::index_sequence_for(internal::to_function_pointer_t<decltype(Candidate), Type *>{}));
15666  }
15667 
15673  void reset() ENTT_NOEXCEPT {
15674  fn = nullptr;
15675  data = nullptr;
15676  }
15677 
15682  const void * instance() const ENTT_NOEXCEPT {
15683  return data;
15684  }
15685 
15700  Ret operator()(Args... args) const {
15701  ENTT_ASSERT(fn);
15702  return fn(data, std::forward_as_tuple(std::forward<Args>(args)...));
15703  }
15704 
15709  explicit operator bool() const ENTT_NOEXCEPT {
15710  // no need to test also data
15711  return fn;
15712  }
15713 
15719  bool operator==(const delegate<Ret(Args...)> &other) const ENTT_NOEXCEPT {
15720  return fn == other.fn && data == other.data;
15721  }
15722 
15723 private:
15724  proto_fn_type *fn;
15725  const void *data;
15726 };
15727 
15728 
15737 template<typename Ret, typename... Args>
15738 bool operator!=(const delegate<Ret(Args...)> &lhs, const delegate<Ret(Args...)> &rhs) ENTT_NOEXCEPT {
15739  return !(lhs == rhs);
15740 }
15741 
15742 
15751 template<auto Function>
15752 delegate(connect_arg_t<Function>) ENTT_NOEXCEPT
15753 -> delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Function)>>>;
15754 
15755 
15765 template<auto Candidate, typename Type>
15766 delegate(connect_arg_t<Candidate>, Type &) ENTT_NOEXCEPT
15767 -> delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Candidate), Type *>>>;
15768 
15769 
15779 template<auto Candidate, typename Type>
15780 delegate(connect_arg_t<Candidate>, Type *) ENTT_NOEXCEPT
15781 -> delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Candidate), Type *>>>;
15782 
15783 
15784 }
15785 
15786 
15787 #endif // ENTT_SIGNAL_DELEGATE_HPP
15788 
15789 // #include "signal/dispatcher.hpp"
15790 #ifndef ENTT_SIGNAL_DISPATCHER_HPP
15791 #define ENTT_SIGNAL_DISPATCHER_HPP
15792 
15793 
15794 #include <vector>
15795 #include <memory>
15796 #include <cstddef>
15797 #include <utility>
15798 #include <algorithm>
15799 #include <type_traits>
15800 // #include "../config/config.h"
15801 
15802 // #include "../core/family.hpp"
15803 #ifndef ENTT_CORE_FAMILY_HPP
15804 #define ENTT_CORE_FAMILY_HPP
15805 
15806 
15807 #include <type_traits>
15808 // #include "../config/config.h"
15809 #ifndef ENTT_CONFIG_CONFIG_H
15810 #define ENTT_CONFIG_CONFIG_H
15811 
15812 
15813 #ifndef ENTT_NOEXCEPT
15814 #define ENTT_NOEXCEPT noexcept
15815 #endif // ENTT_NOEXCEPT
15816 
15817 
15818 #ifndef ENTT_HS_SUFFIX
15819 #define ENTT_HS_SUFFIX _hs
15820 #endif // ENTT_HS_SUFFIX
15821 
15822 
15823 #ifndef ENTT_HWS_SUFFIX
15824 #define ENTT_HWS_SUFFIX _hws
15825 #endif // ENTT_HWS_SUFFIX
15826 
15827 
15828 #ifndef ENTT_NO_ATOMIC
15829 #include <atomic>
15830 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
15831 #else // ENTT_NO_ATOMIC
15832 #define ENTT_MAYBE_ATOMIC(Type) Type
15833 #endif // ENTT_NO_ATOMIC
15834 
15835 
15836 #ifndef ENTT_DISABLE_ETO
15837 #include <type_traits>
15838 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
15839 #else // ENTT_DISABLE_ETO
15840 // sfinae-friendly definition
15841 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
15842 #endif // ENTT_DISABLE_ETO
15843 
15844 
15845 #ifndef ENTT_ID_TYPE
15846 #include <cstdint>
15847 #define ENTT_ID_TYPE std::uint32_t
15848 #endif // ENTT_ID_TYPE
15849 
15850 
15851 #ifndef ENTT_PAGE_SIZE
15852 #define ENTT_PAGE_SIZE 32768
15853 #endif // ENTT_PAGE_SIZE
15854 
15855 
15856 #ifndef ENTT_DISABLE_ASSERT
15857 #include <cassert>
15858 #define ENTT_ASSERT(condition) assert(condition)
15859 #else // ENTT_DISABLE_ASSERT
15860 #define ENTT_ASSERT(...) ((void)0)
15861 #endif // ENTT_DISABLE_ASSERT
15862 
15863 
15864 #endif // ENTT_CONFIG_CONFIG_H
15865 
15866 
15867 
15868 namespace entt {
15869 
15870 
15878 template<typename...>
15879 class family {
15880  inline static ENTT_MAYBE_ATOMIC(ENTT_ID_TYPE) identifier{};
15881 
15882 public:
15884  using family_type = ENTT_ID_TYPE;
15885 
15887  template<typename... Type>
15888  // at the time I'm writing, clang crashes during compilation if auto is used instead of family_type
15889  inline static const family_type type = identifier++;
15890 };
15891 
15892 
15893 }
15894 
15895 
15896 #endif // ENTT_CORE_FAMILY_HPP
15897 
15898 // #include "../core/type_traits.hpp"
15899 #ifndef ENTT_CORE_TYPE_TRAITS_HPP
15900 #define ENTT_CORE_TYPE_TRAITS_HPP
15901 
15902 
15903 #include <cstddef>
15904 #include <type_traits>
15905 // #include "../config/config.h"
15906 
15907 // #include "../core/hashed_string.hpp"
15908 #ifndef ENTT_CORE_HASHED_STRING_HPP
15909 #define ENTT_CORE_HASHED_STRING_HPP
15910 
15911 
15912 #include <cstddef>
15913 // #include "../config/config.h"
15914 #ifndef ENTT_CONFIG_CONFIG_H
15915 #define ENTT_CONFIG_CONFIG_H
15916 
15917 
15918 #ifndef ENTT_NOEXCEPT
15919 #define ENTT_NOEXCEPT noexcept
15920 #endif // ENTT_NOEXCEPT
15921 
15922 
15923 #ifndef ENTT_HS_SUFFIX
15924 #define ENTT_HS_SUFFIX _hs
15925 #endif // ENTT_HS_SUFFIX
15926 
15927 
15928 #ifndef ENTT_HWS_SUFFIX
15929 #define ENTT_HWS_SUFFIX _hws
15930 #endif // ENTT_HWS_SUFFIX
15931 
15932 
15933 #ifndef ENTT_NO_ATOMIC
15934 #include <atomic>
15935 #define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
15936 #else // ENTT_NO_ATOMIC
15937 #define ENTT_MAYBE_ATOMIC(Type) Type
15938 #endif // ENTT_NO_ATOMIC
15939 
15940 
15941 #ifndef ENTT_DISABLE_ETO
15942 #include <type_traits>
15943 #define ENTT_ENABLE_ETO(Type) std::is_empty_v<Type>
15944 #else // ENTT_DISABLE_ETO
15945 // sfinae-friendly definition
15946 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>)
15947 #endif // ENTT_DISABLE_ETO
15948 
15949 
15950 #ifndef ENTT_ID_TYPE
15951 #include <cstdint>
15952 #define ENTT_ID_TYPE std::uint32_t
15953 #endif // ENTT_ID_TYPE
15954 
15955 
15956 #ifndef ENTT_PAGE_SIZE
15957 #define ENTT_PAGE_SIZE 32768
15958 #endif // ENTT_PAGE_SIZE
15959 
15960 
15961 #ifndef ENTT_DISABLE_ASSERT
15962 #include <cassert>
15963 #define ENTT_ASSERT(condition) assert(condition)
15964 #else // ENTT_DISABLE_ASSERT
15965 #define ENTT_ASSERT(...) ((void)0)
15966 #endif // ENTT_DISABLE_ASSERT
15967 
15968 
15969 #endif // ENTT_CONFIG_CONFIG_H
15970 
15971 
15972 
15973 namespace entt {
15974 
15975 
15982 namespace internal {
15983 
15984 
15985 template<typename>
15986 struct fnv1a_traits;
15987 
15988 
15989 template<>
15990 struct fnv1a_traits<std::uint32_t> {
15991  static constexpr std::uint32_t offset = 2166136261;
15992  static constexpr std::uint32_t prime = 16777619;
15993 };
15994 
15995 
15996 template<>
15997 struct fnv1a_traits<std::uint64_t> {
15998  static constexpr std::uint64_t offset = 14695981039346656037ull;
15999  static constexpr std::uint64_t prime = 1099511628211ull;
16000 };
16001 
16002 
16003 }
16004 
16005 
16023 template<typename Char>
16024 class basic_hashed_string {
16025  using traits_type = internal::fnv1a_traits<ENTT_ID_TYPE>;
16026 
16027  struct const_wrapper {
16028  // non-explicit constructor on purpose
16029  constexpr const_wrapper(const Char *curr) ENTT_NOEXCEPT: str{curr} {}
16030  const Char *str;
16031  };
16032 
16033  // Fowler–Noll–Vo hash function v. 1a - the good
16034  static constexpr ENTT_ID_TYPE helper(ENTT_ID_TYPE partial, const Char *curr) ENTT_NOEXCEPT {
16035  return curr[0] == 0 ? partial : helper((partial^curr[0])*traits_type::prime, curr+1);
16036  }
16037 
16038 public:
16040  using value_type = Char;
16042  using hash_type = ENTT_ID_TYPE;
16043 
16059  template<std::size_t N>
16060  static constexpr hash_type to_value(const value_type (&str)[N]) ENTT_NOEXCEPT {
16061  return helper(traits_type::offset, str);
16062  }
16063 
16069  static hash_type to_value(const_wrapper wrapper) ENTT_NOEXCEPT {
16070  return helper(traits_type::offset, wrapper.str);
16071  }
16072 
16079  static hash_type to_value(const value_type *str, std::size_t size) ENTT_NOEXCEPT {
16080  ENTT_ID_TYPE partial{traits_type::offset};
16081  while(size--) { partial = (partial^(str++)[0])*traits_type::prime; }
16082  return partial;
16083  }
16084 
16087  : str{nullptr}, hash{}
16088  {}
16089 
16104  template<std::size_t N>
16105  constexpr basic_hashed_string(const value_type (&curr)[N]) ENTT_NOEXCEPT
16106  : str{curr}, hash{helper(traits_type::offset, curr)}
16107  {}
16108 
16114  explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
16115  : str{wrapper.str}, hash{helper(traits_type::offset, wrapper.str)}
16116  {}
16117 
16122  constexpr const value_type * data() const ENTT_NOEXCEPT {
16123  return str;
16124  }
16125 
16130  constexpr hash_type value() const ENTT_NOEXCEPT {
16131  return hash;
16132  }
16133 
16138  constexpr operator const value_type *() const ENTT_NOEXCEPT { return str; }
16139 
16141  constexpr operator hash_type() const ENTT_NOEXCEPT { return hash; }
16142 
16148  constexpr bool operator==(const basic_hashed_string &other) const ENTT_NOEXCEPT {
16149  return hash == other.hash;
16150  }
16151 
16152 private:
16153  const value_type *str;
16154  hash_type hash;
16155 };
16156 
16157 
16168 template<typename Char, std::size_t N>
16169 basic_hashed_string(const Char (&str)[N]) ENTT_NOEXCEPT
16170 -> basic_hashed_string<Char>;
16171 
16172 
16180 template<typename Char>
16181 constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
16182  return !(lhs == rhs);
16183 }
16184 
16185 
16187 using hashed_string = basic_hashed_string<char>;
16188 
16189 
16191 using hashed_wstring = basic_hashed_string<wchar_t>;
16192 
16193 
16194 }
16195 
16196 
16202 constexpr entt::hashed_string operator"" ENTT_HS_SUFFIX(const char *str, std::size_t) ENTT_NOEXCEPT {
16203  return entt::hashed_string{str};
16204 }
16205 
16206 
16212 constexpr entt::hashed_wstring operator"" ENTT_HWS_SUFFIX(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
16213  return entt::hashed_wstring{str};
16214 }
16215 
16216 
16217 #endif // ENTT_CORE_HASHED_STRING_HPP
16218 
16219 
16220 
16221 namespace entt {
16222 
16223 
16228 template<std::size_t N>
16229 struct choice_t
16230  // Unfortunately, doxygen cannot parse such a construct.
16232  : choice_t<N-1>
16234 {};
16235 
16236 
16238 template<>
16239 struct choice_t<0> {};
16240 
16241 
16246 template<std::size_t N>
16247 constexpr choice_t<N> choice{};
16248 
16249 
16251 template<typename...>
16252 struct type_list {};
16253 
16254 
16256 template<typename>
16257 struct type_list_size;
16258 
16259 
16264 template<typename... Type>
16265 struct type_list_size<type_list<Type...>>
16266  : std::integral_constant<std::size_t, sizeof...(Type)>
16267 {};
16268 
16269 
16274 template<class List>
16275 constexpr auto type_list_size_v = type_list_size<List>::value;
16276 
16277 
16279 template<typename...>
16280 struct type_list_cat;
16281 
16282 
16284 template<>
16285 struct type_list_cat<> {
16287  using type = type_list<>;
16288 };
16289 
16290 
16297 template<typename... Type, typename... Other, typename... List>
16298 struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
16300  using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
16301 };
16302 
16303 
16308 template<typename... Type>
16309 struct type_list_cat<type_list<Type...>> {
16311  using type = type_list<Type...>;
16312 };
16313 
16314 
16319 template<typename... List>
16320 using type_list_cat_t = typename type_list_cat<List...>::type;
16321 
16322 
16324 template<typename>
16325 struct type_list_unique;
16326 
16327 
16333 template<typename Type, typename... Other>
16334 struct type_list_unique<type_list<Type, Other...>> {
16336  using type = std::conditional_t<
16337  std::disjunction_v<std::is_same<Type, Other>...>,
16338  typename type_list_unique<type_list<Other...>>::type,
16339  type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>
16340  >;
16341 };
16342 
16343 
16345 template<>
16346 struct type_list_unique<type_list<>> {
16348  using type = type_list<>;
16349 };
16350 
16351 
16356 template<typename Type>
16357 using type_list_unique_t = typename type_list_unique<Type>::type;
16358 
16359 
16365 template<typename Type, typename = std::void_t<>>
16366 struct is_equality_comparable: std::false_type {};
16367 
16368 
16370 template<typename Type>
16371 struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>: std::true_type {};
16372 
16373 
16378 template<class Type>
16379 constexpr auto is_equality_comparable_v = is_equality_comparable<Type>::value;
16380 
16381 
16383 template<typename>
16384 struct named_type_traits;
16385 
16386 
16391 template<typename Type>
16392 struct named_type_traits<const Type>
16393  : named_type_traits<Type>
16394 {};
16395 
16396 
16401 template<typename Type>
16402 using named_type_traits_t = typename named_type_traits<Type>::type;
16403 
16404 
16409 template<class Type>
16410 constexpr auto named_type_traits_v = named_type_traits<Type>::value;
16411 
16412 
16418 template<typename Type, typename = std::void_t<>>
16419 struct is_named_type: std::false_type {};
16420 
16421 
16423 template<typename Type>
16424 struct is_named_type<Type, std::void_t<named_type_traits_t<std::decay_t<Type>>>>: std::true_type {};
16425 
16426 
16431 template<class Type>
16432 constexpr auto is_named_type_v = is_named_type<Type>::value;
16433 
16434 
16441 #define ENTT_OPAQUE_TYPE(clazz, type)\
16442  enum class clazz: type {};\
16443  constexpr auto to_integer(const clazz id) ENTT_NOEXCEPT {\
16444  return std::underlying_type_t<clazz>(id);\
16445  }\
16446  static_assert(true)
16447 
16448 
16449 }
16450 
16451 
16459 #define ENTT_EXPAND(args) args
16460 
16461 
16479 #define ENTT_NAMED_TYPE(type)\
16480  template<>\
16481  struct entt::named_type_traits<type>\
16482  : std::integral_constant<ENTT_ID_TYPE, entt::basic_hashed_string<std::remove_cv_t<std::remove_pointer_t<std::decay_t<decltype(#type)>>>>{#type}>\
16483  {\
16484  static_assert(std::is_same_v<std::remove_cv_t<type>, type>);\
16485  static_assert(std::is_object_v<type>);\
16486  }
16487 
16488 
16494 #define ENTT_NAMED_STRUCT_ONLY(clazz, body)\
16495  struct clazz body;\
16496  ENTT_NAMED_TYPE(clazz)
16497 
16498 
16505 #define ENTT_NAMED_STRUCT_WITH_NAMESPACE(ns, clazz, body)\
16506  namespace ns { struct clazz body; }\
16507  ENTT_NAMED_TYPE(ns::clazz)
16508 
16509 
16511 #define ENTT_NAMED_STRUCT_OVERLOAD(_1, _2, _3, FUNC, ...) FUNC
16512 
16513 #define ENTT_NAMED_STRUCT(...) ENTT_EXPAND(ENTT_NAMED_STRUCT_OVERLOAD(__VA_ARGS__, ENTT_NAMED_STRUCT_WITH_NAMESPACE, ENTT_NAMED_STRUCT_ONLY,)(__VA_ARGS__))
16514 
16515 
16521 #define ENTT_NAMED_CLASS_ONLY(clazz, body)\
16522  class clazz body;\
16523  ENTT_NAMED_TYPE(clazz)
16524 
16525 
16532 #define ENTT_NAMED_CLASS_WITH_NAMESPACE(ns, clazz, body)\
16533  namespace ns { class clazz body; }\
16534  ENTT_NAMED_TYPE(ns::clazz)
16535 
16536 
16538 #define ENTT_NAMED_CLASS_MACRO(_1, _2, _3, FUNC, ...) FUNC
16539 
16540 #define ENTT_NAMED_CLASS(...) ENTT_EXPAND(ENTT_NAMED_CLASS_MACRO(__VA_ARGS__, ENTT_NAMED_CLASS_WITH_NAMESPACE, ENTT_NAMED_CLASS_ONLY,)(__VA_ARGS__))
16541 
16542 
16543 #endif // ENTT_CORE_TYPE_TRAITS_HPP
16544 
16545 // #include "sigh.hpp"
16546 #ifndef ENTT_SIGNAL_SIGH_HPP
16547 #define ENTT_SIGNAL_SIGH_HPP
16548 
16549 
16550 #include <vector>
16551 #include <utility>
16552 #include <iterator>
16553 #include <algorithm>
16554 #include <functional>
16555 #include <type_traits>
16556 // #include "../config/config.h"
16557 
16558 // #include "delegate.hpp"
16559 
16560 // #include "fwd.hpp"
16561 #ifndef ENTT_SIGNAL_FWD_HPP
16562 #define ENTT_SIGNAL_FWD_HPP
16563 
16564 
16565 namespace entt {
16566 
16567 
16569 template<typename>
16570 class delegate;
16571 
16573 template<typename>
16574 class sink;
16575 
16577 template<typename>
16578 class sigh;
16579 
16580 
16581 }
16582 
16583 
16584 #endif // ENTT_SIGNAL_FWD_HPP
16585 
16586 
16587 
16588 namespace entt {
16589 
16590 
16599 template<typename Function>
16600 class sink;
16601 
16602 
16611 template<typename Function>
16612 class sigh;
16613 
16614 
16630 template<typename Ret, typename... Args>
16631 class sigh<Ret(Args...)> {
16633  friend class sink<Ret(Args...)>;
16634 
16635 public:
16637  using size_type = std::size_t;
16639  using sink_type = entt::sink<Ret(Args...)>;
16640 
16645  template<typename Class>
16646  using instance_type = Class *;
16647 
16652  size_type size() const ENTT_NOEXCEPT {
16653  return calls.size();
16654  }
16655 
16660  bool empty() const ENTT_NOEXCEPT {
16661  return calls.empty();
16662  }
16663 
16671  void publish(Args... args) const {
16672  std::for_each(calls.cbegin(), calls.cend(), [&args...](auto &&call) {
16673  call(args...);
16674  });
16675  }
16676 
16691  template<typename Func>
16692  void collect(Func func, Args... args) const {
16693  for(auto &&call: calls) {
16694  if constexpr(std::is_void_v<Ret>) {
16695  if constexpr(std::is_invocable_r_v<bool, Func>) {
16696  call(args...);
16697  if(func()) { break; }
16698  } else {
16699  call(args...);
16700  func();
16701  }
16702  } else {
16703  if constexpr(std::is_invocable_r_v<bool, Func, Ret>) {
16704  if(func(call(args...))) { break; }
16705  } else {
16706  func(call(args...));
16707  }
16708  }
16709  }
16710  }
16711 
16712 private:
16713  std::vector<delegate<Ret(Args...)>> calls;
16714 };
16715 
16716 
16724 class connection {
16726  template<typename>
16727  friend class sink;
16728 
16729  connection(delegate<void(void *)> fn, void *ref)
16730  : disconnect{fn}, signal{ref}
16731  {}
16732 
16733 public:
16735  connection() = default;
16736 
16738  connection(const connection &) = default;
16739 
16744  connection(connection &&other)
16745  : connection{}
16746  {
16747  std::swap(disconnect, other.disconnect);
16748  std::swap(signal, other.signal);
16749  }
16750 
16752  connection & operator=(const connection &) = default;
16753 
16759  connection & operator=(connection &&other) {
16760  if(this != &other) {
16761  auto tmp{std::move(other)};
16762  disconnect = tmp.disconnect;
16763  signal = tmp.signal;
16764  }
16765 
16766  return *this;
16767  }
16768 
16773  explicit operator bool() const ENTT_NOEXCEPT {
16774  return static_cast<bool>(disconnect);
16775  }
16776 
16778  void release() {
16779  if(disconnect) {
16780  disconnect(signal);
16781  disconnect.reset();
16782  }
16783  }
16784 
16785 private:
16786  delegate<void(void *)> disconnect;
16787  void *signal{};
16788 };
16789 
16790 
16800 struct scoped_connection: private connection {
16801  using connection::operator bool;
16802  using connection::release;
16803 
16805  scoped_connection() = default;
16806 
16811  scoped_connection(const connection &conn)
16812  : connection{conn}
16813  {}
16814 
16816  scoped_connection(const scoped_connection &) = delete;
16817 
16819  scoped_connection(scoped_connection &&) = default;
16820 
16822  ~scoped_connection() {
16824  }
16825 
16830  scoped_connection & operator=(const scoped_connection &) = delete;
16831 
16836  scoped_connection & operator=(scoped_connection &&) = default;
16837 
16843  scoped_connection & operator=(const connection &other) {
16844  static_cast<connection &>(*this) = other;
16845  return *this;
16846  }
16847 
16853  scoped_connection & operator=(connection &&other) {
16854  static_cast<connection &>(*this) = std::move(other);
16855  return *this;
16856  }
16857 };
16858 
16859 
16874 template<typename Ret, typename... Args>
16875 class sink<Ret(Args...)> {
16876  using signal_type = sigh<Ret(Args...)>;
16877  using difference_type = typename std::iterator_traits<typename decltype(signal_type::calls)::iterator>::difference_type;
16878 
16879  template<auto Candidate, typename Type>
16880  static void release(Type value_or_instance, void *signal) {
16881  sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>(value_or_instance);
16882  }
16883 
16884  template<auto Function>
16885  static void release(void *signal) {
16886  sink{*static_cast<signal_type *>(signal)}.disconnect<Function>();
16887  }
16888 
16889 public:
16894  sink(sigh<Ret(Args...)> &ref) ENTT_NOEXCEPT
16895  : offset{},
16896  signal{&ref}
16897  {}
16898 
16903  bool empty() const ENTT_NOEXCEPT {
16904  return signal->calls.empty();
16905  }
16906 
16912  template<auto Function>
16913  sink before() {
16914  delegate<Ret(Args...)> call{};
16915  call.template connect<Function>();
16916 
16917  const auto &calls = signal->calls;
16918  const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
16919 
16920  sink other{*this};
16921  other.offset = std::distance(it, calls.cend());
16922  return other;
16923  }
16924 
16933  template<auto Candidate, typename Type>
16934  sink before(Type &value_or_instance) {
16935  delegate<Ret(Args...)> call{};
16936  call.template connect<Candidate>(value_or_instance);
16937 
16938  const auto &calls = signal->calls;
16939  const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
16940 
16941  sink other{*this};
16942  other.offset = std::distance(it, calls.cend());
16943  return other;
16944  }
16945 
16954  template<auto Candidate, typename Type>
16955  sink before(Type *value_or_instance) {
16956  delegate<Ret(Args...)> call{};
16957  call.template connect<Candidate>(value_or_instance);
16958 
16959  const auto &calls = signal->calls;
16960  const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
16961 
16962  sink other{*this};
16963  other.offset = std::distance(it, calls.cend());
16964  return other;
16965  }
16966 
16974  template<typename Type>
16975  sink before(Type &value_or_instance) {
16976  return before(&value_or_instance);
16977  }
16978 
16986  template<typename Type>
16987  sink before(Type *value_or_instance) {
16988  sink other{*this};
16989 
16990  if(value_or_instance) {
16991  const auto &calls = signal->calls;
16992  const auto it = std::find_if(calls.cbegin(), calls.cend(), [value_or_instance](const auto &delegate) {
16993  return delegate.instance() == value_or_instance;
16994  });
16995 
16996  other.offset = std::distance(it, calls.cend());
16997  }
16998 
16999  return other;
17000  }
17001 
17006  sink before() {
17007  sink other{*this};
17008  other.offset = signal->calls.size();
17009  return other;
17010  }
17011 
17021  template<auto Function>
17022  connection connect() {
17023  disconnect<Function>();
17024 
17025  delegate<Ret(Args...)> call{};
17026  call.template connect<Function>();
17027  signal->calls.insert(signal->calls.end() - offset, std::move(call));
17028 
17029  delegate<void(void *)> conn{};
17030  conn.template connect<&release<Function>>();
17031  return { std::move(conn), signal };
17032  }
17033 
17051  template<auto Candidate, typename Type>
17052  connection connect(Type &value_or_instance) {
17053  disconnect<Candidate>(value_or_instance);
17054 
17055  delegate<Ret(Args...)> call{};
17056  call.template connect<Candidate>(value_or_instance);
17057  signal->calls.insert(signal->calls.end() - offset, std::move(call));
17058 
17059  delegate<void(void *)> conn{};
17060  conn.template connect<&release<Candidate, Type &>>(value_or_instance);
17061  return { std::move(conn), signal };
17062  }
17063 
17081  template<auto Candidate, typename Type>
17082  connection connect(Type *value_or_instance) {
17083  disconnect<Candidate>(value_or_instance);
17084 
17085  delegate<Ret(Args...)> call{};
17086  call.template connect<Candidate>(value_or_instance);
17087  signal->calls.insert(signal->calls.end() - offset, std::move(call));
17088 
17089  delegate<void(void *)> conn{};
17090  conn.template connect<&release<Candidate, Type *>>(value_or_instance);
17091  return { std::move(conn), signal };
17092  }
17093 
17098  template<auto Function>
17099  void disconnect() {
17100  auto &calls = signal->calls;
17101  delegate<Ret(Args...)> call{};
17102  call.template connect<Function>();
17103  calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
17104  }
17105 
17113  template<auto Candidate, typename Type>
17114  void disconnect(Type &value_or_instance) {
17115  auto &calls = signal->calls;
17116  delegate<Ret(Args...)> call{};
17117  call.template connect<Candidate>(value_or_instance);
17118  calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
17119  }
17120 
17128  template<auto Candidate, typename Type>
17129  void disconnect(Type *value_or_instance) {
17130  auto &calls = signal->calls;
17131  delegate<Ret(Args...)> call{};
17132  call.template connect<Candidate>(value_or_instance);
17133  calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
17134  }
17135 
17142  template<typename Type>
17143  void disconnect(Type &value_or_instance) {
17144  disconnect(&value_or_instance);
17145  }
17146 
17153  template<typename Type>
17154  void disconnect(Type *value_or_instance) {
17155  if(value_or_instance) {
17156  auto &calls = signal->calls;
17157  calls.erase(std::remove_if(calls.begin(), calls.end(), [value_or_instance](const auto &delegate) {
17158  return delegate.instance() == value_or_instance;
17159  }), calls.end());
17160  }
17161  }
17162 
17164  void disconnect() {
17165  signal->calls.clear();
17166  }
17167 
17168 private:
17169  difference_type offset;
17170  signal_type *signal;
17171 };
17172 
17173 
17183 template<typename Ret, typename... Args>
17184 sink(sigh<Ret(Args...)> &) ENTT_NOEXCEPT -> sink<Ret(Args...)>;
17185 
17186 
17187 }
17188 
17189 
17190 #endif // ENTT_SIGNAL_SIGH_HPP
17191 
17192 
17193 
17194 namespace entt {
17195 
17196 
17210 class dispatcher {
17212 
17213  template<typename Class, typename Event>
17214  using instance_type = typename sigh<void(const Event &)>::template instance_type<Class>;
17215 
17216  struct base_wrapper {
17217  virtual ~base_wrapper() = default;
17218  virtual void publish() = 0;
17219  virtual void clear() = 0;
17220  };
17221 
17222  template<typename Event>
17223  struct signal_wrapper: base_wrapper {
17224  using signal_type = sigh<void(const Event &)>;
17225  using sink_type = typename signal_type::sink_type;
17226 
17227  void publish() override {
17228  const auto length = events.size();
17229 
17230  for(std::size_t pos{}; pos < length; ++pos) {
17231  signal.publish(events[pos]);
17232  }
17233 
17234  events.erase(events.cbegin(), events.cbegin()+length);
17235  }
17236 
17237  void clear() override {
17238  events.clear();
17239  }
17240 
17242  return entt::sink{signal};
17243  }
17244 
17245  template<typename... Args>
17246  void trigger(Args &&... args) {
17247  signal.publish({ std::forward<Args>(args)... });
17248  }
17249 
17250  template<typename... Args>
17251  void enqueue(Args &&... args) {
17252  events.emplace_back(std::forward<Args>(args)...);
17253  }
17254 
17255  private:
17256  signal_type signal{};
17257  std::vector<Event> events;
17258  };
17259 
17260  struct wrapper_data {
17261  std::unique_ptr<base_wrapper> wrapper;
17262  ENTT_ID_TYPE runtime_type;
17263  };
17264 
17265  template<typename Event>
17266  static auto type() ENTT_NOEXCEPT {
17267  if constexpr(is_named_type_v<Event>) {
17268  return named_type_traits_v<Event>;
17269  } else {
17270  return event_family::type<std::decay_t<Event>>;
17271  }
17272  }
17273 
17274  template<typename Event>
17275  signal_wrapper<Event> & assure() {
17276  const auto wtype = type<Event>();
17277  wrapper_data *wdata = nullptr;
17278 
17279  if constexpr(is_named_type_v<Event>) {
17280  const auto it = std::find_if(wrappers.begin(), wrappers.end(), [wtype](const auto &candidate) {
17281  return candidate.wrapper && candidate.runtime_type == wtype;
17282  });
17283 
17284  wdata = (it == wrappers.cend() ? &wrappers.emplace_back() : &(*it));
17285  } else {
17286  if(!(wtype < wrappers.size())) {
17287  wrappers.resize(wtype+1);
17288  }
17289 
17290  wdata = &wrappers[wtype];
17291 
17292  if(wdata->wrapper && wdata->runtime_type != wtype) {
17293  wrappers.emplace_back();
17294  std::swap(wrappers[wtype], wrappers.back());
17295  wdata = &wrappers[wtype];
17296  }
17297  }
17298 
17299  if(!wdata->wrapper) {
17300  wdata->wrapper = std::make_unique<signal_wrapper<Event>>();
17301  wdata->runtime_type = wtype;
17302  }
17303 
17304  return static_cast<signal_wrapper<Event> &>(*wdata->wrapper);
17305  }
17306 
17307 public:
17309  template<typename Event>
17310  using sink_type = typename signal_wrapper<Event>::sink_type;
17311 
17329  template<typename Event>
17331  return assure<Event>().sink();
17332  }
17333 
17344  template<typename Event, typename... Args>
17345  void trigger(Args &&... args) {
17346  assure<Event>().trigger(std::forward<Args>(args)...);
17347  }
17348 
17358  template<typename Event>
17359  void trigger(Event &&event) {
17360  assure<std::decay_t<Event>>().trigger(std::forward<Event>(event));
17361  }
17362 
17373  template<typename Event, typename... Args>
17374  void enqueue(Args &&... args) {
17375  assure<Event>().enqueue(std::forward<Args>(args)...);
17376  }
17377 
17387  template<typename Event>
17388  void enqueue(Event &&event) {
17389  assure<std::decay_t<Event>>().enqueue(std::forward<Event>(event));
17390  }
17391 
17400  template<typename... Event>
17401  void discard() {
17402  if constexpr(sizeof...(Event) == 0) {
17403  std::for_each(wrappers.begin(), wrappers.end(), [](auto &&wdata) {
17404  if(wdata.wrapper) {
17405  wdata.wrapper->clear();
17406  }
17407  });
17408  } else {
17409  (assure<std::decay_t<Event>>().clear(), ...);
17410  }
17411  }
17412 
17422  template<typename Event>
17423  void update() {
17424  assure<Event>().publish();
17425  }
17426 
17434  void update() const {
17435  for(auto pos = wrappers.size(); pos; --pos) {
17436  if(auto &wdata = wrappers[pos-1]; wdata.wrapper) {
17437  wdata.wrapper->publish();
17438  }
17439  }
17440  }
17441 
17442 private:
17443  std::vector<wrapper_data> wrappers;
17444 };
17445 
17446 
17447 }
17448 
17449 
17450 #endif // ENTT_SIGNAL_DISPATCHER_HPP
17451 
17452 // #include "signal/emitter.hpp"
17453 #ifndef ENTT_SIGNAL_EMITTER_HPP
17454 #define ENTT_SIGNAL_EMITTER_HPP
17455 
17456 
17457 #include <type_traits>
17458 #include <functional>
17459 #include <algorithm>
17460 #include <utility>
17461 #include <memory>
17462 #include <vector>
17463 #include <list>
17464 // #include "../config/config.h"
17465 
17466 // #include "../core/family.hpp"
17467 
17468 // #include "../core/type_traits.hpp"
17469 
17470 
17471 
17472 namespace entt {
17473 
17474 
17496 template<typename Derived>
17497 class emitter {
17499 
17500  struct base_handler {
17501  virtual ~base_handler() = default;
17502  virtual bool empty() const ENTT_NOEXCEPT = 0;
17503  virtual void clear() ENTT_NOEXCEPT = 0;
17504  };
17505 
17506  template<typename Event>
17507  struct event_handler: base_handler {
17508  using listener_type = std::function<void(const Event &, Derived &)>;
17509  using element_type = std::pair<bool, listener_type>;
17510  using container_type = std::list<element_type>;
17511  using connection_type = typename container_type::iterator;
17512 
17513  bool empty() const ENTT_NOEXCEPT override {
17514  auto pred = [](auto &&element) { return element.first; };
17515 
17516  return std::all_of(once_list.cbegin(), once_list.cend(), pred) &&
17517  std::all_of(on_list.cbegin(), on_list.cend(), pred);
17518  }
17519 
17520  void clear() ENTT_NOEXCEPT override {
17521  if(publishing) {
17522  auto func = [](auto &&element) { element.first = true; };
17523  std::for_each(once_list.begin(), once_list.end(), func);
17524  std::for_each(on_list.begin(), on_list.end(), func);
17525  } else {
17526  once_list.clear();
17527  on_list.clear();
17528  }
17529  }
17530 
17531  connection_type once(listener_type listener) {
17532  return once_list.emplace(once_list.cend(), false, std::move(listener));
17533  }
17534 
17535  connection_type on(listener_type listener) {
17536  return on_list.emplace(on_list.cend(), false, std::move(listener));
17537  }
17538 
17539  void erase(connection_type conn) ENTT_NOEXCEPT {
17540  conn->first = true;
17541 
17542  if(!publishing) {
17543  auto pred = [](auto &&element) { return element.first; };
17544  once_list.remove_if(pred);
17545  on_list.remove_if(pred);
17546  }
17547  }
17548 
17549  void publish(const Event &event, Derived &ref) {
17550  container_type swap_list;
17551  once_list.swap(swap_list);
17552 
17553  auto func = [&event, &ref](auto &&element) {
17554  return element.first ? void() : element.second(event, ref);
17555  };
17556 
17557  publishing = true;
17558 
17559  std::for_each(on_list.rbegin(), on_list.rend(), func);
17560  std::for_each(swap_list.rbegin(), swap_list.rend(), func);
17561 
17562  publishing = false;
17563 
17564  on_list.remove_if([](auto &&element) { return element.first; });
17565  }
17566 
17567  private:
17568  bool publishing{false};
17569  container_type once_list{};
17570  container_type on_list{};
17571  };
17572 
17573  struct handler_data {
17574  std::unique_ptr<base_handler> handler;
17575  ENTT_ID_TYPE runtime_type;
17576  };
17577 
17578  template<typename Event>
17579  static auto type() ENTT_NOEXCEPT {
17580  if constexpr(is_named_type_v<Event>) {
17581  return named_type_traits_v<Event>;
17582  } else {
17583  return handler_family::type<std::decay_t<Event>>;
17584  }
17585  }
17586 
17587  template<typename Event>
17588  event_handler<Event> * assure() const ENTT_NOEXCEPT {
17589  const auto htype = type<Event>();
17590  handler_data *hdata = nullptr;
17591 
17592  if constexpr(is_named_type_v<Event>) {
17593  const auto it = std::find_if(handlers.begin(), handlers.end(), [htype](const auto &candidate) {
17594  return candidate.handler && candidate.runtime_type == htype;
17595  });
17596 
17597  hdata = (it == handlers.cend() ? &handlers.emplace_back() : &(*it));
17598  } else {
17599  if(!(htype < handlers.size())) {
17600  handlers.resize(htype+1);
17601  }
17602 
17603  hdata = &handlers[htype];
17604 
17605  if(hdata->handler && hdata->runtime_type != htype) {
17606  handlers.emplace_back();
17607  std::swap(handlers[htype], handlers.back());
17608  hdata = &handlers[htype];
17609  }
17610  }
17611 
17612  if(!hdata->handler) {
17613  hdata->handler = std::make_unique<event_handler<Event>>();
17614  hdata->runtime_type = htype;
17615  }
17616 
17617  return static_cast<event_handler<Event> *>(hdata->handler.get());
17618  }
17619 
17620 public:
17622  template<typename Event>
17623  using listener = typename event_handler<Event>::listener_type;
17624 
17634  template<typename Event>
17635  struct connection: private event_handler<Event>::connection_type {
17637  friend class emitter;
17638 
17640  connection() ENTT_NOEXCEPT = default;
17641 
17646  connection(typename event_handler<Event>::connection_type conn)
17647  : event_handler<Event>::connection_type{std::move(conn)}
17648  {}
17649  };
17650 
17652  emitter() ENTT_NOEXCEPT = default;
17653 
17655  virtual ~emitter() ENTT_NOEXCEPT {
17656  static_assert(std::is_base_of_v<emitter<Derived>, Derived>);
17657  }
17658 
17660  emitter(emitter &&) = default;
17661 
17663  emitter & operator=(emitter &&) = default;
17664 
17676  template<typename Event, typename... Args>
17677  void publish(Args &&... args) {
17678  assure<Event>()->publish({ std::forward<Args>(args)... }, *static_cast<Derived *>(this));
17679  }
17680 
17701  template<typename Event>
17703  return assure<Event>()->on(std::move(instance));
17704  }
17705 
17726  template<typename Event>
17728  return assure<Event>()->once(std::move(instance));
17729  }
17730 
17740  template<typename Event>
17742  assure<Event>()->erase(std::move(conn));
17743  }
17744 
17753  template<typename Event>
17755  assure<Event>()->clear();
17756  }
17757 
17765  std::for_each(handlers.begin(), handlers.end(), [](auto &&hdata) {
17766  return hdata.handler ? hdata.handler->clear() : void();
17767  });
17768  }
17769 
17775  template<typename Event>
17776  bool empty() const ENTT_NOEXCEPT {
17777  return assure<Event>()->empty();
17778  }
17779 
17784  bool empty() const ENTT_NOEXCEPT {
17785  return std::all_of(handlers.cbegin(), handlers.cend(), [](auto &&hdata) {
17786  return !hdata.handler || hdata.handler->empty();
17787  });
17788  }
17789 
17790 private:
17791  mutable std::vector<handler_data> handlers{};
17792 };
17793 
17794 
17795 }
17796 
17797 
17798 #endif // ENTT_SIGNAL_EMITTER_HPP
17799 
17800 // #include "signal/sigh.hpp"
17801 
void arrange(iterator_type first, iterator_type last, Apply apply, Compare compare, Sort algo=Sort{}, Args &&... args)
Sort elements according to the given comparison function.
Definition: entt.hpp:4375
delegate(connect_arg_t< Candidate >, Type &value_or_instance) ENTT_NOEXCEPT
Constructs a delegate and connects a member for a given instance or a free function with payload.
Definition: entt.hpp:2690
void each(Func func) const
Iterates all resources.
Definition: entt.hpp:15342
ENTT_ID_TYPE identifier() const ENTT_NOEXCEPT
Returns the identifier assigned to a given meta object.
Definition: entt.hpp:12841
bool orphan(const entity_type entity) const
Checks if an entity has components assigned.
Definition: entt.hpp:8941
iterator_type begin() const ENTT_NOEXCEPT
Returns an iterator to the first entity of the observer.
Definition: entt.hpp:10294
iterator_type find(const entity_type entt) const ENTT_NOEXCEPT
Finds an entity.
Definition: entt.hpp:6749
meta_handle(Type &obj) ENTT_NOEXCEPT
Constructs a meta handle from a given instance.
Definition: entt.hpp:12188
constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
Explicit constructor on purpose to avoid constructing a hashed string directly from a const value_typ...
Definition: entt.hpp:503
bool operator==(const meta_type &other) const ENTT_NOEXCEPT
Checks if two meta objects refer to the same node.
Definition: entt.hpp:13204
ENTT_ID_TYPE identifier() const ENTT_NOEXCEPT
Returns the identifier assigned to a given meta object.
Definition: entt.hpp:12694
void unpause() ENTT_NOEXCEPT
Restarts a process if it's paused.
Definition: entt.hpp:14386
Shared resource handle.
Definition: entt.hpp:14959
Empty class type used to request the as-is policy.
Definition: entt.hpp:11342
const basic_snapshot_loader & orphans() const
Destroys those entities that have no components.
Definition: entt.hpp:5010
auto type(const ENTT_ID_TYPE identifier) ENTT_NOEXCEPT
Extends a meta type by assigning it an identifier.
Definition: entt.hpp:13588
void create(It first, It last, entity_type src, const basic_registry &other, exclude_t< Exclude... >={})
Assigns each element in a range an entity from a prototype entity.
Definition: entt.hpp:8368
meta_type parent() const ENTT_NOEXCEPT
Returns the meta type to which a meta object belongs.
Definition: entt.hpp:13252
std::int64_t difference_type
Difference type.
Definition: entt.hpp:3648
void orphans(Func func) const
Iterates orphans and applies them the given function object.
Definition: entt.hpp:8970
meta_factory< Type > meta() ENTT_NOEXCEPT
Utility function to use for reflection.
Definition: entt.hpp:14117
constexpr bool operator==(const basic_hashed_string &other) const ENTT_NOEXCEPT
Compares two hashed strings.
Definition: entt.hpp:537
delegate(connect_arg_t< Function >) ENTT_NOEXCEPT -> delegate< std::remove_pointer_t< internal::to_function_pointer_t< decltype(Function)>>>
Deduction guide.
meta_base base(const ENTT_ID_TYPE identifier) const ENTT_NOEXCEPT
Returns the meta base associated with a given identifier.
Definition: entt.hpp:12993
void disconnect()
Disconnects a free function from a signal.
Definition: entt.hpp:3434
bool is_static() const ENTT_NOEXCEPT
Indicates whether a given meta data is static or not.
Definition: entt.hpp:12562
bool operator==(const meta_any &other) const ENTT_NOEXCEPT
Checks if two containers differ in their content.
Definition: entt.hpp:12113
void sort() const
Sort the shared pool of entities according to the given component.
Definition: entt.hpp:6509
bool contains(const entity_type entt) const ENTT_NOEXCEPT
Checks if a view contains an entity.
Definition: entt.hpp:4670
static constexpr identifier_type type
Statically generated unique identifier for the given type.
Definition: entt.hpp:666
void discard()
Discards all the events queued so far.
Definition: entt.hpp:17401
decltype(auto) assign(Args &&... args)
Assigns the given component to an actor.
Definition: entt.hpp:9678
connection()=default
Default constructor.
meta_any(const meta_any &other)
Copy constructor.
Definition: entt.hpp:11905
void shrink_to_fit()
Requests the removal of unused capacity.
Definition: entt.hpp:4061
constexpr connect_arg_t< Func > connect_arg
Constant of type connect_arg_t used to disambiguate calls.
Definition: entt.hpp:2597
bool rejected() const ENTT_NOEXCEPT
Returns true if a process terminated with errors.
Definition: entt.hpp:14447
delegate(connect_arg_t< Candidate >, Type *value_or_instance) ENTT_NOEXCEPT
Constructs a delegate and connects a member for a given instance or a free function with payload.
Definition: entt.hpp:2704
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:4593
connection< Event > on(listener< Event > instance)
Registers a long-lived listener with the event emitter.
Definition: entt.hpp:17702
std::uint32_t entity_type
Underlying entity type.
Definition: entt.hpp:3618
version_type current(const entity_type entity) const ENTT_NOEXCEPT
Returns the actual version for an entity identifier.
Definition: entt.hpp:8255
#define ENTT_ID_TYPE
Definition: entt.hpp:58
bool is_enum() const ENTT_NOEXCEPT
Indicates whether a given meta type refers to an enum or not.
Definition: entt.hpp:12885
monostate< Value > monostate_v
Helper variable template.
Definition: entt.hpp:732
void reset()
Resets the pool of the given component.
Definition: entt.hpp:8872
void disconnect(Type &value_or_instance)
Disconnects a member function or a free function with payload from a signal.
Definition: entt.hpp:3449
basic_observer() ENTT_NOEXCEPT
Default constructor.
Definition: entt.hpp:10195
decltype(auto) assign_or_replace(const entity_type entity, Args &&... args)
Assigns or replaces the given component for an entity.
Definition: entt.hpp:8643
Collector.
Definition: entt.hpp:9973
std::enable_if_t< std::is_invocable_v< Op, meta_prop >, void > prop(Op op) const ENTT_NOEXCEPT
Iterates all the properties assigned to a meta type.
Definition: entt.hpp:13175
const Type & cast() const ENTT_NOEXCEPT
Tries to cast an instance to a given type.
Definition: entt.hpp:12031
bool contains(const entity_type entt) const ENTT_NOEXCEPT
Checks if a view contains an entity.
Definition: entt.hpp:7302
decltype(auto) replace(const entity_type entity, Args &&... args)
Replaces the given component for an entity.
Definition: entt.hpp:8615
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:6181
void swap(const entity_type lhs, const entity_type rhs) ENTT_NOEXCEPT override
Swaps entities and objects in the internal packed arrays.
Definition: entt.hpp:5720
scoped_connection & operator=(connection &&other)
Moves a connection.
Definition: entt.hpp:3188
Basic sparse set implementation.
Definition: entt.hpp:3863
~service_locator()=delete
Default destructor, deleted on purpose.
const basic_snapshot_loader & component(Archive &archive) const
Restores components and assigns them to the right entities.
Definition: entt.hpp:4995
constexpr auto type_list_size_v
Helper variable template.
Definition: entt.hpp:1117
iterator< true > const_iterator_type
Constant random access iterator type.
Definition: entt.hpp:5489
virtual ~basic_actor()
Default destructor.
Definition: entt.hpp:9622
meta_type resolve() ENTT_NOEXCEPT
Returns the meta type associated with a given type.
Definition: entt.hpp:14128
void less(Func func) const
Iterates entities and components and applies the given function object to them.
Definition: entt.hpp:7721
meta_prop(const internal::meta_prop_node *curr=nullptr) ENTT_NOEXCEPT
Constructs an instance from a given node.
Definition: entt.hpp:12237
void collect(Func func, Args... args) const
Collects return values from the listeners.
Definition: entt.hpp:3027
std::enable_if_t< std::is_invocable_v< Op, meta_data >, void > data(Op op) const ENTT_NOEXCEPT
Iterates all the meta data of a meta type.
Definition: entt.hpp:13069
void disconnect(Type &value_or_instance)
Disconnects member functions or free functions based on an instance or specific payload.
Definition: entt.hpp:3478
size_type size() const ENTT_NOEXCEPT
Returns the number of existing components of the given type.
Definition: entt.hpp:6191
Provides the member constant value to true if a given type is equality comparable,...
Definition: entt.hpp:1208
iterator_type begin() const ENTT_NOEXCEPT
Returns an iterator to the first entity that has the given components.
Definition: entt.hpp:6720
bool empty() const ENTT_NOEXCEPT
Returns false if at least a listener is connected to the sink.
Definition: entt.hpp:3238
void operator()(It first, It last, Getter getter=Getter{}) const
Sorts the elements in a range.
Definition: entt.hpp:267
sparse_set & operator=(const sparse_set &other)
Copy assignment operator.
Definition: entt.hpp:4027
Base class for resource loaders.
Definition: entt.hpp:14963
DualNumber operator-(DualNumber a, DualNumber b)
Definition: DualNumber.h:61
std::uint64_t entity_type
Underlying entity type.
Definition: entt.hpp:3644
std::enable_if_t< std::is_invocable_v< Op, meta_prop >, void > prop(Op op) const ENTT_NOEXCEPT
Iterates all the properties assigned to a meta data.
Definition: entt.hpp:12644
void update(const Delta delta, void *data=nullptr)
Updates all scheduled processes.
Definition: entt.hpp:14821
meta_type type() const ENTT_NOEXCEPT
Returns the meta type of the underlying object.
Definition: entt.hpp:13267
bool has() const ENTT_NOEXCEPT
Checks if an actor has the given components.
Definition: entt.hpp:9697
#define ENTT_NOEXCEPT
Definition: entt.hpp:25
registry_type & backend() ENTT_NOEXCEPT
Returns a reference to the underlying registry.
Definition: entt.hpp:9742
Primary template isn't defined on purpose.
Definition: entt.hpp:1122
static Service & ref() ENTT_NOEXCEPT
Returns a weak reference to a service implementation, if any.
Definition: entt.hpp:10510
ENTT_ID_TYPE identifier_type
Unsigned integer type.
Definition: entt.hpp:662
iterator iterator_type
Input iterator type.
Definition: entt.hpp:4595
as_group(basic_registry< Entity > &) ENTT_NOEXCEPT -> as_group< false, Entity >
Deduction guide.
bool alive() const ENTT_NOEXCEPT
Returns true if a process is either running or paused.
Definition: entt.hpp:14423
basic_registry() ENTT_NOEXCEPT=default
Default constructor.
iterator_type end() const ENTT_NOEXCEPT
Returns an iterator that is past the last entity that has the given component.
Definition: entt.hpp:7603
void reserve(const size_type cap)
Increases the capacity of a sparse set.
Definition: entt.hpp:4047
#define ENTT_MAYBE_ATOMIC(Type)
Definition: entt.hpp:41
constexpr choice_t< N > choice
Variable template for the choice trick.
Definition: entt.hpp:1089
object_type & get(const entity_type entt) ENTT_NOEXCEPT
Returns the object associated with an entity.
Definition: entt.hpp:5607
bool contains(const entity_type entt) const ENTT_NOEXCEPT
Checks if a view contains an entity.
Definition: entt.hpp:7632
void respect(const sparse_set &other) ENTT_NOEXCEPT
Sort entities according to their order in another sparse set.
Definition: entt.hpp:4421
entt::handle< Resource > load(const id_type id, Args &&... args)
Loads the resource that corresponds to a given identifier.
Definition: entt.hpp:15222
Entity entity_type
Underlying entity identifier.
Definition: entt.hpp:6606
Group.
Definition: entt.hpp:3761
const object_type * try_get(const entity_type entt) const ENTT_NOEXCEPT
Returns a pointer to the object associated with an entity, if any.
Definition: entt.hpp:5616
bool dead() const ENTT_NOEXCEPT
Returns true if a process is already terminated.
Definition: entt.hpp:14431
std::enable_if_t< std::is_invocable_v< Op, meta_func >, void > func(Op op) const ENTT_NOEXCEPT
Iterates all the meta functions of a meta type.
Definition: entt.hpp:13101
void emplace(Args &&... args)
Replaces the contained object by initializing a new instance directly.
Definition: entt.hpp:12095
void disconnect()
Disconnects an observer from the registry it keeps track of.
Definition: entt.hpp:10247
sparse_set(const sparse_set &other)
Copy constructor.
Definition: entt.hpp:4004
connection< Event > once(listener< Event > instance)
Registers a short-lived listener with the event emitter.
Definition: entt.hpp:17727
static component type() ENTT_NOEXCEPT
Returns the opaque identifier of a component.
Definition: entt.hpp:8051
typename type_list_cat< type_list< Type..., Other... >, List... >::type type
A type list composed by the types of all the type lists.
Definition: entt.hpp:1142
size_type size() const ENTT_NOEXCEPT
Returns the number of elements in a sparse set.
Definition: entt.hpp:4095
object_type & construct(const entity_type entt, Args &&... args)
Assigns an entity to a storage and constructs its object.
Definition: entt.hpp:5644
Scoped connection class.
Definition: entt.hpp:3135
void reset() ENTT_NOEXCEPT
Resets a delegate.
Definition: entt.hpp:2764
constexpr basic_hashed_string(const value_type(&curr)[N]) ENTT_NOEXCEPT
Constructs a hashed string from an array of const characters.
Definition: entt.hpp:494
Used to wrap a function or a member of a specified type.
Definition: entt.hpp:2592
Definition: ComplexGeoData.h:39
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) ENTT_NOEXCEPT
Compares two hashed strings.
Definition: entt.hpp:570
basic_continuous_loader & shrink()
Helps to purge entities that no longer have a conterpart.
Definition: entt.hpp:5242
const_iterator_type end() const ENTT_NOEXCEPT
Returns an iterator to the end.
Definition: entt.hpp:5581
meta_prop prop(meta_any key) const ENTT_NOEXCEPT
Returns the property associated with a given key.
Definition: entt.hpp:13189
size_type extent() const ENTT_NOEXCEPT
If a given meta type refers to an array type, provides the number of elements of the array.
Definition: entt.hpp:12949
auto on_replace() ENTT_NOEXCEPT
Returns a sink object for the given component.
Definition: entt.hpp:8708
entity_type operator[](const size_type pos) const ENTT_NOEXCEPT
Returns the identifier that occupies the given position.
Definition: entt.hpp:6340
bool empty() const ENTT_NOEXCEPT
Checks whether an observer is empty.
Definition: entt.hpp:10266
static version_type version(const entity_type entity) ENTT_NOEXCEPT
Returns the version stored along with an entity identifier.
Definition: entt.hpp:8238
void reserve(const size_type cap)
Increases the capacity of the registry or of the pools for the given components.
Definition: entt.hpp:8111
bool is_floating_point() const ENTT_NOEXCEPT
Indicates whether a given meta type refers to a floating-point type or not.
Definition: entt.hpp:12868
iterator_type begin() const ENTT_NOEXCEPT
Returns an iterator to the first entity that has the given component.
Definition: entt.hpp:7584
Grouping matcher.
Definition: entt.hpp:9951
void destroy(const entity_type entity)
Destroys an entity and lets the registry recycle the identifier.
Definition: entt.hpp:8401
raw_type * raw() const ENTT_NOEXCEPT
Direct access to the list of components.
Definition: entt.hpp:7550
Type & cast() ENTT_NOEXCEPT
Tries to cast an instance to a given type.
Definition: entt.hpp:12039
typename named_type_traits< Type >::type named_type_traits_t
Helper type.
Definition: entt.hpp:1244
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:5485
meta_type parent() const ENTT_NOEXCEPT
Returns the meta type to which a meta object belongs.
Definition: entt.hpp:13297
basic_continuous_loader(basic_registry< entity_type > &source) ENTT_NOEXCEPT
Constructs a loader that is bound to a given registry.
Definition: entt.hpp:5166
void publish(Args... args) const
Triggers a signal.
Definition: entt.hpp:3006
decltype(auto) operator()(Args &&... args) const
Invokes a y-combinator and therefore its underlying function.
Definition: entt.hpp:157
const entity_type * data() const ENTT_NOEXCEPT
Direct access to the list of entities of a given pool.
Definition: entt.hpp:6267
const entity_type * data() const ENTT_NOEXCEPT
Direct access to the list of entities of a given pool.
Definition: entt.hpp:8210
decltype(auto) get([[maybe_unused]] const entity_type entity) const
Returns references to the given components for an entity.
Definition: entt.hpp:8508
auto func(const ENTT_ID_TYPE identifier) ENTT_NOEXCEPT
Assigns a meta funcion to a meta type.
Definition: entt.hpp:13946
void batch(It first, It last)
Assigns one or more entities to a sparse set.
Definition: entt.hpp:4234
sink before(Type *value_or_instance)
Returns a sink that connects before a given instance or specific payload.
Definition: entt.hpp:3322
object_type get([[maybe_unused]] const entity_type entt) const ENTT_NOEXCEPT
Returns the object associated with an entity.
Definition: entt.hpp:5976
entt::basic_view< Entity, exclude_t< Exclude... >, Component... > view(exclude_t< Exclude... >={}) const
Returns a view for the given components.
Definition: entt.hpp:9020
std::int64_t difference_type
Difference type.
Definition: entt.hpp:3622
void * data() ENTT_NOEXCEPT
Returns an opaque pointer to the contained instance.
Definition: entt.hpp:12202
std::conditional_t< Const, const entt::basic_registry< Entity >, entt::basic_registry< Entity > > registry_type
Type of registry to convert.
Definition: entt.hpp:9802
const entity_type * data() const ENTT_NOEXCEPT
Direct access to the list of entities of a given pool.
Definition: entt.hpp:7239
const entity_type * data() const ENTT_NOEXCEPT
Direct access to the internal packed array.
Definition: entt.hpp:4122
auto data(const ENTT_ID_TYPE identifier) ENTT_NOEXCEPT
Assigns a meta data to a meta type by means of its setter and getter.
Definition: entt.hpp:13906
Provides the member constant value to true if a given type has a name. In all other cases,...
Definition: entt.hpp:1261
Definition: GlobalId.h:61
auto on_destroy() ENTT_NOEXCEPT
Returns a sink object for the given component.
Definition: entt.hpp:8740
sink before(Type &value_or_instance)
Returns a sink that connects before a given instance or specific payload.
Definition: entt.hpp:3310
entt::basic_group< Entity, exclude_t< Exclude... >, get_t<>, Owned... > group(exclude_t< Exclude... >={}) const
Returns a group for the given components.
Definition: entt.hpp:9201
void trigger(Event &&event)
Triggers an immediate event of the given type.
Definition: entt.hpp:17359
meta_handle() ENTT_NOEXCEPT
Default constructor.
Definition: entt.hpp:12168
meta_type remove_extent() const ENTT_NOEXCEPT
Provides the meta type for which the array is defined.
Definition: entt.hpp:12967
void reset(const entity_type entity)
Resets the given component for an entity.
Definition: entt.hpp:8855
const basic_snapshot & destroyed(Archive &archive) const
Puts aside destroyed entities.
Definition: entt.hpp:4819
iterator_type begin() ENTT_NOEXCEPT
Returns an iterator to the beginning.
Definition: entt.hpp:5557
meta_data data(const ENTT_ID_TYPE identifier) const ENTT_NOEXCEPT
Returns the meta data associated with a given identifier.
Definition: entt.hpp:13083
Definition: entt.hpp:79
Entity entity_type
Underlying entity identifier.
Definition: entt.hpp:9596
Char value_type
Character type.
Definition: entt.hpp:429
void connect() ENTT_NOEXCEPT
Connects a free function to a delegate.
Definition: entt.hpp:2715
entt::basic_group< Entity, exclude_t< Exclude... >, get_t< Get... >, Owned... > group(get_t< Get... >, exclude_t< Exclude... >={}) const
Returns a group for the given components.
Definition: entt.hpp:9172
meta_any(Type &&type)
Constructs a meta any from a given value.
Definition: entt.hpp:11897
size_type size() const ENTT_NOEXCEPT
Returns the number of existing components of the given type.
Definition: entt.hpp:6618
bool has(const entity_type entt) const ENTT_NOEXCEPT
Checks if a sparse set contains an entity.
Definition: entt.hpp:4177
Type & ctx() ENTT_NOEXCEPT
Returns a reference to an object in the context of the registry.
Definition: entt.hpp:9553
iterator_type end() const ENTT_NOEXCEPT
Returns an iterator that is past the last entity that has the given components.
Definition: entt.hpp:7278
meta_type type() const ENTT_NOEXCEPT
Returns the meta type of the underlying object.
Definition: entt.hpp:13247
void sort(iterator_type first, iterator_type last, Compare compare, Sort algo=Sort{}, Args &&... args)
Sort elements according to the given comparison function.
Definition: entt.hpp:6006
static entity_type entity(const entity_type entity) ENTT_NOEXCEPT
Returns the entity identifier without the version.
Definition: entt.hpp:8229
const registry_type & backend() const ENTT_NOEXCEPT
Returns a reference to the underlying registry.
Definition: entt.hpp:9737
void remove()
Removes the given component from an actor.
Definition: entt.hpp:9687
sink before()
Returns a sink that connects before anything else.
Definition: entt.hpp:3341
std::enable_if_t< std::is_invocable_v< Op, meta_base >, void > base(Op op) const ENTT_NOEXCEPT
Iterates all the meta base of a meta type.
Definition: entt.hpp:12981
typename sparse_set< Entity >::iterator_type iterator_type
Input iterator type.
Definition: entt.hpp:6183
std::int32_t difference_type
Difference type.
Definition: entt.hpp:3596
entt::basic_group< Entity, exclude_t< Exclude... >, get_t< Get... >, Owned... > group(get_t< Get... >, exclude_t< Exclude... >={})
Returns a group for the given components.
Definition: entt.hpp:9064
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:3993
Extended meta factory to be used for reflection purposes.
Definition: entt.hpp:13542
typename sparse_set< Entity >::iterator_type iterator_type
Input iterator type.
Definition: entt.hpp:10192
const entity_type * data() const ENTT_NOEXCEPT
Direct access to the list of entities.
Definition: entt.hpp:6283
size_type size() const ENTT_NOEXCEPT
Number of resources managed by a cache.
Definition: entt.hpp:15177
sink(sigh< Ret(Args...)> &) ENTT_NOEXCEPT -> sink< Ret(Args...)>
Deduction guide.
void update()
Delivers all the pending events of the given type.
Definition: entt.hpp:17423
void operator()(It first, It last, Compare compare=Compare{}, Args &&... args) const
Sorts the elements in a range.
Definition: entt.hpp:205
bool is_integral() const ENTT_NOEXCEPT
Indicates whether a given meta type refers to an integral type or not.
Definition: entt.hpp:12858
Zero overhead unique identifier.
Definition: entt.hpp:413
void operator=(Type val) const ENTT_NOEXCEPT
Assigns a value of a specific type to a given key.
Definition: entt.hpp:707
Entity entity_type
Underlying entity identifier.
Definition: entt.hpp:5160
decltype(auto) get_or_assign(const entity_type entity, Args &&... args) ENTT_NOEXCEPT
Returns a reference to the given component for an entity.
Definition: entt.hpp:8555
constexpr exclude_t< Type... > exclude
Variable template for exclusion lists.
Definition: entt.hpp:6052
const object_type & get(const entity_type entt) const ENTT_NOEXCEPT
Returns the object associated with an entity.
Definition: entt.hpp:5602
Converts a registry to a group.
Definition: entt.hpp:9849
basic_hashed_string(const Char(&str)[N]) ENTT_NOEXCEPT -> basic_hashed_string< Char >
Deduction guide.
meta_type arg(size_type index) const ENTT_NOEXCEPT
Returns the meta type of the i-th argument of a meta function.
Definition: entt.hpp:13307
Delta delta_type
Type used to provide elapsed time.
Definition: entt.hpp:14394
sink_type< Event > sink() ENTT_NOEXCEPT
Returns a sink object for the given event.
Definition: entt.hpp:17330
sink before(Type *value_or_instance)
Returns a sink that connects before a given member function or free function with payload.
Definition: entt.hpp:3290
connection connect()
Connects a free function to a signal.
Definition: entt.hpp:3357
sink(sigh< Ret(Args...)> &ref) ENTT_NOEXCEPT
Constructs a sink that is allowed to modify a given signal.
Definition: entt.hpp:3229
void each(Func func) const
Iterates entities and components and applies the given function object to them.
Definition: entt.hpp:7682
bool empty() const ENTT_NOEXCEPT
Checks whether the group or the pools of the given components are empty.
Definition: entt.hpp:6638
const basic_snapshot_loader & destroyed(Archive &archive) const
Restores entities that were destroyed during serialization.
Definition: entt.hpp:4975
basic_continuous_loader & component(Archive &archive, Member Type::*... member)
Restores components and assigns them to the right entities.
Definition: entt.hpp:5228
meta_any() ENTT_NOEXCEPT
Default constructor.
Definition: entt.hpp:11840
static void set(Args &&... args)
Sets or replaces a service.
Definition: entt.hpp:10521
Simple cache for resources of a given type.
Definition: entt.hpp:14955
size_type index(const entity_type entt) const ENTT_NOEXCEPT
Returns the position of an entity in a sparse set.
Definition: entt.hpp:4195
Connection class.
Definition: entt.hpp:3059
auto ctor() ENTT_NOEXCEPT
Assigns a meta constructor to a meta type.
Definition: entt.hpp:13711
meta_any get(meta_handle handle, std::size_t index) const ENTT_NOEXCEPT
Gets the i-th element of an array enclosed by a given meta type.
Definition: entt.hpp:12632
void reserve(const size_type cap)
Increases the capacity of a storage.
Definition: entt.hpp:5499
void * data() ENTT_NOEXCEPT
Returns an opaque pointer to the contained instance.
Definition: entt.hpp:11983
entt::basic_view< Entity, exclude_t< Exclude... >, Component... > view(exclude_t< Exclude... >={})
Returns a view for the given components.
Definition: entt.hpp:9013
as_view(basic_registry< Entity > &) ENTT_NOEXCEPT -> as_view< false, Entity >
Deduction guide.
void pause() ENTT_NOEXCEPT
Stops a process if it's in a running state.
Definition: entt.hpp:14374
void succeed() ENTT_NOEXCEPT
Terminates a process with success if it's still alive.
Definition: entt.hpp:14350
Basic delegate implementation.
Definition: entt.hpp:2607
size_type alive() const ENTT_NOEXCEPT
Returns the number of entities still in use.
Definition: entt.hpp:8086
bool paused() const ENTT_NOEXCEPT
Returns true if a process is currently paused.
Definition: entt.hpp:14439
typename sparse_set< Entity >::iterator_type iterator_type
Input iterator type.
Definition: entt.hpp:7520
void abort(const bool immediately=false) ENTT_NOEXCEPT
Aborts a process if it's still alive.
Definition: entt.hpp:14409
void shrink_to_fit()
Requests the removal of unused capacity for the given components.
Definition: entt.hpp:8144
basic_snapshot_loader & operator=(basic_snapshot_loader &&)=default
Default move assignment operator.
Class * instance_type
Instance type when it comes to connecting member functions.
Definition: entt.hpp:2981
Entity entity_type
Underlying entity identifier.
Definition: entt.hpp:7516
void discard(const id_type id) ENTT_NOEXCEPT
Discards the resource that corresponds to a given identifier.
Definition: entt.hpp:15318
bool destroy(meta_handle handle) const
Destroys an instance of the underlying type.
Definition: entt.hpp:13160
ENTT_OPAQUE_TYPE(entity, ENTT_ID_TYPE)
Alias declaration for the most common use case.
connection & operator=(connection &&other)
Default move assignment operator.
Definition: entt.hpp:3094
scoped_connection & operator=(const connection &other)
Copies a connection.
Definition: entt.hpp:3178
bool is_member_object_pointer() const ENTT_NOEXCEPT
Indicates whether a given meta type refers to a pointer to data member or not.
Definition: entt.hpp:12929
auto try_get() const ENTT_NOEXCEPT
Returns pointers to the given components for an actor.
Definition: entt.hpp:9723
void transform(Container container, OutputIt out, BinaryFunction function)
Definition: Algorithms.h:29
bool empty() const ENTT_NOEXCEPT
Checks whether the view or the pools of the given components are empty.
Definition: entt.hpp:7197
Primary template isn't defined on purpose.
Definition: entt.hpp:1099
bool operator==(const meta_conv &other) const ENTT_NOEXCEPT
Checks if two meta objects refer to the same node.
Definition: entt.hpp:12371
iterator_type end() const ENTT_NOEXCEPT
Returns an iterator that is past the last entity of the observer.
Definition: entt.hpp:10308
void publish(Args &&... args)
Emits the given event.
Definition: entt.hpp:17677
void sort(Compare compare, Sort algo=Sort{}, Args &&... args)
Sort a group according to the given comparison function.
Definition: entt.hpp:6477
void destroy(const entity_type entt)
Removes an entity from a sparse set.
Definition: entt.hpp:4256
const basic_snapshot & component(Archive &archive, It first, It last) const
Puts aside the given components for the entities in a range.
Definition: entt.hpp:4868
entt::basic_snapshot< Entity > snapshot() const ENTT_NOEXCEPT
Returns a temporary object to use to create snapshots.
Definition: entt.hpp:9388
void operator()(It first, It last, Compare compare=Compare{}) const
Sorts the elements in a range.
Definition: entt.hpp:225
meta_any invoke(Args &&... args) const
Creates an instance of the underlying type, if possible.
Definition: entt.hpp:12426
connection connect(Type &value_or_instance)
Connects a member function or a free function with payload to a signal.
Definition: entt.hpp:3387
typename signal_wrapper< Event >::sink_type sink_type
Type of sink for the given event.
Definition: entt.hpp:17310
Comp * raw() const ENTT_NOEXCEPT
Direct access to the list of components of a given pool.
Definition: entt.hpp:7220
Ret operator()(Args... args) const
Triggers a delegate.
Definition: entt.hpp:2791
bool empty() const ENTT_NOEXCEPT
Checks whether the group or the pools of the given components are empty.
Definition: entt.hpp:6225
Generic connection type for events.
Definition: entt.hpp:17635
meta_func(const internal::meta_func_node *curr=nullptr) ENTT_NOEXCEPT
Constructs an instance from a given node.
Definition: entt.hpp:12689
Basic storage implementation.
Definition: entt.hpp:6019
entt::basic_group< Entity, exclude_t< Exclude... >, get_t<>, Owned... > group(exclude_t< Exclude... >={})
Returns a group for the given components.
Definition: entt.hpp:9187
iterator_type begin() const ENTT_NOEXCEPT
Returns an iterator to the beginning.
Definition: entt.hpp:4139
void destroy(It first, It last)
Destroys all the entities in a range.
Definition: entt.hpp:8425
Opaque container for meta destructors.
Definition: entt.hpp:12484
Opaque container for meta data.
Definition: entt.hpp:12532
const_iterator_type cbegin() const ENTT_NOEXCEPT
Returns an iterator to the beginning.
Definition: entt.hpp:5546
Traits class used mainly to push things across boundaries.
Definition: entt.hpp:1226
bool operator==(const meta_ctor &other) const ENTT_NOEXCEPT
Checks if two meta objects refer to the same node.
Definition: entt.hpp:12468
void each(Func func)
Iterates entities and applies the given function object to them, then clears the observer.
Definition: entt.hpp:10352
void sort(Compare compare, Sort algo=Sort{}, Args &&... args)
Sort a group according to the given comparison function.
Definition: entt.hpp:6907
const_iterator_type begin() const ENTT_NOEXCEPT
Returns an iterator to the beginning.
Definition: entt.hpp:5552
ENTT_ID_TYPE id_type
Unique identifier type for resources.
Definition: entt.hpp:15162
void release()
Breaks the connection.
Definition: entt.hpp:3113
Utility class for continuous loading.
Definition: entt.hpp:3781
std::enable_if_t< std::is_invocable_v< Op, meta_prop >, void > prop(Op op) const ENTT_NOEXCEPT
Iterates all the properties assigned to a meta function.
Definition: entt.hpp:12777
constexpr auto null
Compile-time constant for null entities.
Definition: entt.hpp:3726
static hash_type to_value(const value_type *str, std::size_t size) ENTT_NOEXCEPT
Returns directly the numeric representation of a string view.
Definition: entt.hpp:468
bool sortable() const ENTT_NOEXCEPT
Checks whether the group can be sorted.
Definition: entt.hpp:6859
constexpr basic_collector collector
Variable template used to ease the definition of collectors.
Definition: entt.hpp:10045
virtual ~sparse_set() ENTT_NOEXCEPT=default
Default destructor.
size_type extent() const ENTT_NOEXCEPT
Returns the extent of a sparse set.
Definition: entt.hpp:4081
void tick(const Delta delta, void *data=nullptr)
Updates a process and its internal state if required.
Definition: entt.hpp:14456
size_type size() const ENTT_NOEXCEPT
Returns the number of entities created so far.
Definition: entt.hpp:8078
void less(Func func) const
Iterates entities and components and applies the given function object to them.
Definition: entt.hpp:7456
Opaque container for meta constructors.
Definition: entt.hpp:12387
as_view(registry_type &source) ENTT_NOEXCEPT
Constructs a converter for a given registry.
Definition: entt.hpp:9808
auto data(const ENTT_ID_TYPE identifier) ENTT_NOEXCEPT
Assigns a meta data to a meta type.
Definition: entt.hpp:13821
bool operator==(const meta_base &other) const ENTT_NOEXCEPT
Checks if two meta objects refer to the same node.
Definition: entt.hpp:12325
const entity_type * data() const ENTT_NOEXCEPT
Direct access to the list of entities of the observer.
Definition: entt.hpp:10282
void stomp(It first, It last, const entity_type src, const basic_registry &other, exclude_t< Exclude... >={})
Stomps the entities in a range and their components.
Definition: entt.hpp:9359
bool contains(const entity_type entt) const ENTT_NOEXCEPT
Checks if a group contains an entity.
Definition: entt.hpp:6768
Dynamic identifier generator.
Definition: entt.hpp:333
Utility class to restore a snapshot as a whole.
Definition: entt.hpp:3777
void sort(iterator_type first, iterator_type last, Compare compare, Sort algo=Sort{}, Args &&... args)
Sort elements according to the given comparison function.
Definition: entt.hpp:4330
Entity entity_type
Underlying entity identifier.
Definition: entt.hpp:8026
void disconnect(Type *value_or_instance)
Disconnects member functions or free functions based on an instance or specific payload.
Definition: entt.hpp:3489
auto on_construct() ENTT_NOEXCEPT
Returns a sink object for the given component.
Definition: entt.hpp:8677
iterator_type end() const ENTT_NOEXCEPT
Returns an iterator to the end.
Definition: entt.hpp:5956
DualNumber operator+(DualNumber a, DualNumber b)
Definition: DualNumber.h:51
meta_prop prop(meta_any key) const ENTT_NOEXCEPT
Returns the property associated with a given key.
Definition: entt.hpp:12786
Basic storage implementation.
Definition: entt.hpp:5373
void trigger(Args &&... args)
Triggers an immediate event of the given type.
Definition: entt.hpp:17345
Utility class to disambiguate overloaded functions.
Definition: entt.hpp:1071
entt::handle< Resource > reload(const id_type id, Args &&... args)
Reloads a resource or loads it for the first time if not present.
Definition: entt.hpp:15262
bool contains(const entity_type entt) const ENTT_NOEXCEPT
Checks if a group contains an entity.
Definition: entt.hpp:6349
General purpose event emitter.
Definition: entt.hpp:17497
Entity entity_type
Underlying entity identifier.
Definition: entt.hpp:10188
bool is_union() const ENTT_NOEXCEPT
Indicates whether a given meta type refers to an union or not.
Definition: entt.hpp:12893
typename type_list_cat< List... >::type type_list_cat_t
Helper type.
Definition: entt.hpp:1162
iterator_type find(const entity_type entt) const ENTT_NOEXCEPT
Finds an entity.
Definition: entt.hpp:6330
meta_any(std::in_place_type_t< Type >, [[maybe_unused]] Args &&... args)
Constructs a meta any by directly initializing the new object.
Definition: entt.hpp:11856
~basic_observer()=default
Default destructor.
void less(Func func) const
Iterates entities and components and applies the given function object to them.
Definition: entt.hpp:7423
meta_ctor ctor() const ENTT_NOEXCEPT
Returns the meta constructor that accepts a given list of types of arguments.
Definition: entt.hpp:13046
Opaque pointers to instances of any type.
Definition: entt.hpp:12162
basic_snapshot & operator=(basic_snapshot &&)=default
Default move assignment operator.
bool valid(const entity_type entity) const ENTT_NOEXCEPT
Checks if an entity identifier refers to a valid entity.
Definition: entt.hpp:8219
Fast and reliable entity-component system.
Definition: entt.hpp:3749
size_type capacity() const ENTT_NOEXCEPT
Returns the number of elements that a sparse set has currently allocated space for.
Definition: entt.hpp:4056
View.
Definition: entt.hpp:3753
auto attach(Func &&func)
Schedules a process for the next tick.
Definition: entt.hpp:14805
basic_observer(basic_registry< entity_type > &reg, basic_collector< Matcher... >) ENTT_NOEXCEPT
Creates an observer and connects it to a given registry.
Definition: entt.hpp:10210
constexpr auto is_equality_comparable_v
Helper variable template.
Definition: entt.hpp:1221
meta_type arg(size_type index) const ENTT_NOEXCEPT
Returns the meta type of the i-th argument of a meta constructor.
Definition: entt.hpp:13277
void less(Func func) const
Iterates entities and components and applies the given function object to them.
Definition: entt.hpp:6849
Resource & operator *() ENTT_NOEXCEPT
Gets a reference to the managed resource.
Definition: entt.hpp:15031
meta_any(std::reference_wrapper< Type > type)
Constructs a meta any that holds an unmanaged object.
Definition: entt.hpp:11878
basic_continuous_loader & orphans()
Destroys those entities that have no components.
Definition: entt.hpp:5274
const Resource & operator *() const ENTT_NOEXCEPT
Gets a reference to the managed resource.
Definition: entt.hpp:15028
bool operator==(const delegate< Ret(Args...)> &other) const ENTT_NOEXCEPT
Compares the contents of two delegates.
Definition: entt.hpp:2810
Service locator, nothing more.
Definition: entt.hpp:10465
void each(Func func) const
Iterates entities and components and applies the given function object to them.
Definition: entt.hpp:6824
meta_any value() const ENTT_NOEXCEPT
Returns the stored value.
Definition: entt.hpp:12253
basic_registry clone(exclude_t< Exclude... >={}) const
Returns a full or partial copy of a registry.
Definition: entt.hpp:9275
void prepare()
Prepares pools for the given types if required.
Definition: entt.hpp:8060
entity_type create(entity_type src, const basic_registry &other, exclude_t< Exclude... >={})
Creates a new entity from a prototype entity.
Definition: entt.hpp:8339
size_type capacity() const ENTT_NOEXCEPT
Returns the capacity of the pool for the given component.
Definition: entt.hpp:8125
entity_type entity_type
Underlying entity identifier.
Definition: entt.hpp:3991
void each(Func func) const
Iterates all the entities that are still in use.
Definition: entt.hpp:8916
bool empty() const ENTT_NOEXCEPT
Returns false if at least a listener is connected to the signal.
Definition: entt.hpp:2995
const entity_type * data() const ENTT_NOEXCEPT
Direct access to the list of entities.
Definition: entt.hpp:6702
meta_any construct(Args &&... args) const
Creates an instance of the underlying type, if possible.
Definition: entt.hpp:13133
Types identifiers.
Definition: entt.hpp:651
meta_type parent() const ENTT_NOEXCEPT
Returns the meta type to which a meta object belongs.
Definition: entt.hpp:13282
Opaque container for meta properties of any type.
Definition: entt.hpp:12232
overloaded(Type...) -> overloaded< Type... >
Deduction guide.
bool is_array() const ENTT_NOEXCEPT
Indicates whether a given meta type refers to an array type or not.
Definition: entt.hpp:12877
void connect(Type *value_or_instance) ENTT_NOEXCEPT
Connects a member function for a given instance or a free function with payload to a delegate.
Definition: entt.hpp:2755
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:2972
Primary template isn't defined on purpose.
Definition: entt.hpp:1167
bool is_pointer() const ENTT_NOEXCEPT
Indicates whether a given meta type refers to a pointer or not.
Definition: entt.hpp:12909
auto dtor() ENTT_NOEXCEPT
Assigns a meta destructor to a meta type.
Definition: entt.hpp:13784
basic_snapshot_loader< Entity > loader() ENTT_NOEXCEPT
Returns a temporary object to use to load snapshots.
Definition: entt.hpp:9419
void shrink_to_fit()
Requests the removal of unused capacity.
Definition: entt.hpp:6213
void clear()
Resets the underlying container.
Definition: entt.hpp:10313
friend void swap(meta_any &lhs, meta_any &rhs) ENTT_NOEXCEPT
Swaps two meta any objects.
Definition: entt.hpp:12122
object_type * try_get(const entity_type entt) ENTT_NOEXCEPT
Returns a pointer to the object associated with an entity, if any.
Definition: entt.hpp:5621
meta_type remove_pointer() const ENTT_NOEXCEPT
Provides the meta type for which the pointer is defined.
Definition: entt.hpp:12958
constexpr Type && operator()(Type &&value) const ENTT_NOEXCEPT
Returns its argument unchanged.
Definition: entt.hpp:91
void less(Func func) const
Iterates entities and components and applies the given function object to them.
Definition: entt.hpp:6430
Collector.
Definition: entt.hpp:9961
Unmanaged signal handler.
Definition: entt.hpp:2966
bool set(meta_handle handle, std::size_t index, Type &&value) const
Sets the i-th element of an array enclosed by a given meta type.
Definition: entt.hpp:12604
meta_conv(const internal::meta_conv_node *curr=nullptr) ENTT_NOEXCEPT
Constructs an instance from a given node.
Definition: entt.hpp:12343
const Component * raw() const ENTT_NOEXCEPT
Direct access to the list of components of a given pool.
Definition: entt.hpp:8186
const basic_snapshot_loader & entities(Archive &archive) const
Restores entities that were in use during serialization.
Definition: entt.hpp:4958
y_combinator(Func recursive)
Constructs a y-combinator from a given function.
Definition: entt.hpp:146
Opaque container for meta types.
Definition: entt.hpp:12817
A class to use to push around lists of types, nothing more.
Definition: entt.hpp:1094
const basic_snapshot & component(Archive &archive) const
Puts aside the given components.
Definition: entt.hpp:4848
auto try_get([[maybe_unused]] const entity_type entity) const ENTT_NOEXCEPT
Returns pointers to the given components for an entity.
Definition: entt.hpp:8574
basic_actor(registry_type &ref)
Constructs an actor from a given registry.
Definition: entt.hpp:9606
basic_observer & operator=(const basic_observer &)=delete
Default copy assignment operator, deleted on purpose.
void reset() ENTT_NOEXCEPT
Resets a meta type and all its parts.
Definition: entt.hpp:13982
constexpr hash_type value() const ENTT_NOEXCEPT
Returns the numeric representation of a hashed string.
Definition: entt.hpp:519
meta_dtor(const internal::meta_dtor_node *curr=nullptr) ENTT_NOEXCEPT
Constructs an instance from a given node.
Definition: entt.hpp:12486
iterator_type end() const ENTT_NOEXCEPT
Returns an iterator that is past the last entity that has the given components.
Definition: entt.hpp:6739
virtual ~process() ENTT_NOEXCEPT
Default destructor.
Definition: entt.hpp:14397
auto create(It first, It last)
Assigns each element in a range an entity.
Definition: entt.hpp:8310
Function object to wrap std::sort in a class type.
Definition: entt.hpp:190
bool empty() const ENTT_NOEXCEPT
Checks whether the view is empty.
Definition: entt.hpp:7534
auto try_get() ENTT_NOEXCEPT
Returns pointers to the given components for an actor.
Definition: entt.hpp:9729
iterator_type end() const ENTT_NOEXCEPT
Returns an iterator that is past the last entity that has the given components.
Definition: entt.hpp:6320
const Resource * operator->() const ENTT_NOEXCEPT
Gets a pointer to the managed resource.
Definition: entt.hpp:15044
typename internal::meta_type_node::size_type size_type
Unsigned integer type.
Definition: entt.hpp:12830
scoped_connection()=default
Default constructor.
iterator_type begin() const ENTT_NOEXCEPT
Returns an iterator to the beginning.
Definition: entt.hpp:5933
bool empty() const ENTT_NOEXCEPT
Returns true if at least a process is currently scheduled.
Definition: entt.hpp:14704
static void bind(meta_ctx other) ENTT_NOEXCEPT
Binds the meta system to the given context.
Definition: entt.hpp:13219
size_type size() const ENTT_NOEXCEPT
Returns the number of existing components of the given type.
Definition: entt.hpp:7172
Sink class.
Definition: entt.hpp:3210
meta_type ret() const ENTT_NOEXCEPT
Returns the meta type of the return type of a meta function.
Definition: entt.hpp:13302
iterator_type batch(It first, It last, const object_type &={})
Assigns one or more entities to a storage.
Definition: entt.hpp:5999
void each(Func func) const
Iterates entities and components and applies the given function object to them.
Definition: entt.hpp:7397
auto ctor() ENTT_NOEXCEPT
Assigns a meta constructor to a meta type.
Definition: entt.hpp:13745
meta_any key() const ENTT_NOEXCEPT
Returns the stored key.
Definition: entt.hpp:12245
Entity entity_type
Underlying entity identifier.
Definition: entt.hpp:6179
object_type * raw() ENTT_NOEXCEPT
Direct access to the array of objects.
Definition: entt.hpp:5530
Opaque container for meta functions.
Definition: entt.hpp:12684
void update(const Delta delta, void *data)
Updates a process and its internal state if required.
Definition: entt.hpp:14554
void shrink_to_fit()
Requests the removal of unused capacity.
Definition: entt.hpp:5505
void connect(basic_registry< entity_type > &reg, basic_collector< Matcher... >)
Connects an observer to a given registry.
Definition: entt.hpp:10239
connection(connection &&other)
Default move constructor.
Definition: entt.hpp:3079
scoped_connection(const connection &conn)
Constructs a scoped connection from a basic connection.
Definition: entt.hpp:3146
const Type * try_cast() const ENTT_NOEXCEPT
Tries to cast an instance to a given type.
Definition: entt.hpp:11993
const Type & ctx() const ENTT_NOEXCEPT
Returns a reference to an object in the context of the registry.
Definition: entt.hpp:9545
Identity function object (waiting for C++20).
Definition: entt.hpp:83
Base class for processes.
Definition: entt.hpp:14296
meta_type type() const ENTT_NOEXCEPT
Returns the meta type of the underlying object.
Definition: entt.hpp:13257
entt::handle< Resource > temp(Args &&... args) const
Creates a temporary handle for a resource.
Definition: entt.hpp:15279
basic_continuous_loader & destroyed(Archive &archive)
Restores entities that were destroyed during serialization.
Definition: entt.hpp:5203
bool operator==(const meta_func &other) const ENTT_NOEXCEPT
Checks if two meta objects refer to the same node.
Definition: entt.hpp:12801
entity_type operator[](const size_type pos) const ENTT_NOEXCEPT
Returns the identifier that occupies the given position.
Definition: entt.hpp:6759
Adaptor for lambdas and functors to turn them into processes.
Definition: entt.hpp:14538
void enqueue(Args &&... args)
Enqueues an event of the given type.
Definition: entt.hpp:17374
static void set(std::shared_ptr< Service > ptr)
Sets or replaces a service.
Definition: entt.hpp:10529
bool empty() const ENTT_NOEXCEPT
Checks if the view is definitely empty.
Definition: entt.hpp:4609
void disconnect()
Disconnects all the listeners from a signal.
Definition: entt.hpp:3499
iterator_type end() ENTT_NOEXCEPT
Returns an iterator to the end.
Definition: entt.hpp:5586
meta_any convert() const
Tries to convert an instance to a given type and returns it.
Definition: entt.hpp:12050
void ctor(Op op) const ENTT_NOEXCEPT
Iterates all the meta constructors of a meta type.
Definition: entt.hpp:13036
Resource resource_type
Type of resources managed by a cache.
Definition: entt.hpp:15160
meta_type(const internal::meta_type_node *curr=nullptr) ENTT_NOEXCEPT
Constructs an instance from a given node.
Definition: entt.hpp:12833
connection connect(Type *value_or_instance)
Connects a member function or a free function with payload to a signal.
Definition: entt.hpp:3417
meta_any & operator=(meta_any &&other) ENTT_NOEXCEPT
Move assignment operator.
Definition: entt.hpp:11962
typename traits_type::version_type version_type
Underlying version type.
Definition: entt.hpp:8028
ENTT_ID_TYPE family_type
Unsigned integer type.
Definition: entt.hpp:338
iterator iterator_type
Input iterator type.
Definition: entt.hpp:7161
std::enable_if_t< std::is_invocable_v< Op, meta_prop >, void > prop(Op op) const ENTT_NOEXCEPT
Iterates all the properties assigned to a meta constructor.
Definition: entt.hpp:12444
constexpr basic_hashed_string() ENTT_NOEXCEPT
Constructs an empty hashed string.
Definition: entt.hpp:475
size_type capacity() const ENTT_NOEXCEPT
Returns the number of elements that a group has currently allocated space for.
Definition: entt.hpp:6208
Service service_type
Type of service offered.
Definition: entt.hpp:10467
bool empty() const ENTT_NOEXCEPT
Checks if there are listeners registered for the specific event.
Definition: entt.hpp:17776
iterator_type begin() const ENTT_NOEXCEPT
Returns an iterator to the first entity that has the given components.
Definition: entt.hpp:4627
Function object for performing LSD radix sort.
Definition: entt.hpp:248
void erase(connection< Event > conn) ENTT_NOEXCEPT
Disconnects a listener from the event emitter.
Definition: entt.hpp:17741
static constexpr auto replace() ENTT_NOEXCEPT
Adds an observing matcher to the collector.
Definition: entt.hpp:9991
bool operator==(const meta_data &other) const ENTT_NOEXCEPT
Checks if two meta objects refer to the same node.
Definition: entt.hpp:12668
basic_actor(entity_type entity, registry_type &ref)
Constructs an actor from a given entity.
Definition: entt.hpp:9615
void reset()
Resets a whole registry.
Definition: entt.hpp:8891
~meta_any()
Frees the internal storage, whatever it means.
Definition: entt.hpp:11931
meta_type type() const ENTT_NOEXCEPT
Returns the meta type of the underlying object.
Definition: entt.hpp:13292
payload_type object_type
Type of the objects associated with the entities.
Definition: entt.hpp:5481
Opaque container for a meta context.
Definition: entt.hpp:13214
iterator_type batch(It first, It last, Args &&... args)
Assigns one or more entities to a storage and default constructs or copy constructs their objects.
Definition: entt.hpp:5678
bool empty() const ENTT_NOEXCEPT
Checks if there are listeners registered with the event emitter.
Definition: entt.hpp:17784
const void * instance() const ENTT_NOEXCEPT
Returns the instance or the payload linked to a delegate, if any.
Definition: entt.hpp:2773
meta_base(const internal::meta_base_node *curr=nullptr) ENTT_NOEXCEPT
Constructs an instance from a given node.
Definition: entt.hpp:12294
meta_type parent() const ENTT_NOEXCEPT
Returns the meta type to which a meta object belongs.
Definition: entt.hpp:13262
void conv(Op op) const ENTT_NOEXCEPT
Iterates all the meta conversion functions of a meta type.
Definition: entt.hpp:13009
const entity_type * data() const ENTT_NOEXCEPT
Direct access to the list of entities of a given pool.
Definition: entt.hpp:6686
Unmanaged signal handler.
Definition: entt.hpp:2913
double distance(const Geom::Vec &v1, const Geom::Vec &v2)
Returns the distance between two points.
Definition: Vec.h:345
decltype(auto) assign(const entity_type entity, [[maybe_unused]] Args &&... args)
Assigns the given component to an entity.
Definition: entt.hpp:8451
basic_registry< Entity > registry_type
Type of registry used internally.
Definition: entt.hpp:9594
Converts a registry to a view.
Definition: entt.hpp:9800
constexpr const value_type * data() const ENTT_NOEXCEPT
Returns the human-readable representation of a hashed string.
Definition: entt.hpp:511
Alias for exclusion lists.
Definition: entt.hpp:6044
Opaque container for meta base classes.
Definition: entt.hpp:12292
void each(Func func) const
Iterates entities and components and applies the given function object to them.
Definition: entt.hpp:6405
entity_type map(entity_type entt) const ENTT_NOEXCEPT
Returns the identifier to which an entity refers.
Definition: entt.hpp:5296
#define ENTT_HS_SUFFIX
Definition: entt.hpp:30
typename internal::meta_func_node::size_type size_type
Unsigned integer type.
Definition: entt.hpp:12686
meta_handle(meta_any &any) ENTT_NOEXCEPT
Constructs a meta handle from a meta any object.
Definition: entt.hpp:12177
std::uint16_t entity_type
Underlying entity type.
Definition: entt.hpp:3592
basic_actor & operator=(basic_actor &&other)
Move assignment operator.
Definition: entt.hpp:9653
void sort()
Sorts two pools of components in the same way.
Definition: entt.hpp:8834
meta_any & operator=(const meta_any &other)
Copy assignment operator.
Definition: entt.hpp:11953
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:6608
static constexpr auto group(exclude_t< NoneOf... >={}) ENTT_NOEXCEPT
Adds a grouping matcher to the collector.
Definition: entt.hpp:10016
basic_actor(basic_actor &&other)
Move constructor.
Definition: entt.hpp:9637
void clear()
Discards all scheduled processes.
Definition: entt.hpp:14714
static constexpr auto group(exclude_t< NoneOf... >={}) ENTT_NOEXCEPT
Adds a grouping matcher to the collector.
Definition: entt.hpp:9981
void each(Func func) const
Iterates entities and applies the given function object to them.
Definition: entt.hpp:4692
const_iterator_type cend() const ENTT_NOEXCEPT
Returns an iterator to the end.
Definition: entt.hpp:5576
const Type * try_ctx() const ENTT_NOEXCEPT
Returns a pointer to an object in the context of the registry.
Definition: entt.hpp:9518
void remove(const entity_type entity)
Removes the given component from an entity.
Definition: entt.hpp:8470
~scoped_connection()
Automatically breaks the link on destruction.
Definition: entt.hpp:3157
entity_type operator[](const size_type pos) const ENTT_NOEXCEPT
Returns the identifier that occupies the given position.
Definition: entt.hpp:7623
Opaque container for meta conversion functions.
Definition: entt.hpp:12341
const object_type * raw() const ENTT_NOEXCEPT
Direct access to the array of objects.
Definition: entt.hpp:5525
basic_hashed_string< char > hashed_string
Aliases for common character types.
Definition: entt.hpp:576
constexpr get_t< Type... > get
Variable template for lists of observed components.
Definition: entt.hpp:6068
ENTT_ID_TYPE identifier() const ENTT_NOEXCEPT
Returns the identifier assigned to a given meta object.
Definition: entt.hpp:12539
Basic implementation of a y-combinator.
Definition: entt.hpp:141
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:10190
std::uint32_t version_type
Underlying version type.
Definition: entt.hpp:3646
auto conv() ENTT_NOEXCEPT
Assigns a meta conversion function to a meta type.
Definition: entt.hpp:13644
typename event_handler< Event >::listener_type listener
Type of listeners accepted for the given event.
Definition: entt.hpp:17623
meta_type parent() const ENTT_NOEXCEPT
Returns the meta type to which a meta object belongs.
Definition: entt.hpp:13272
entt::basic_runtime_view< Entity > runtime_view(It first, It last) const
Returns a runtime view for the given components.
Definition: entt.hpp:9227
virtual void swap(const entity_type lhs, const entity_type rhs) ENTT_NOEXCEPT
Swaps two entities in the internal packed array.
Definition: entt.hpp:4281
decltype(auto) get() const ENTT_NOEXCEPT
Returns references to the given components for an actor.
Definition: entt.hpp:9707
meta_dtor dtor() const ENTT_NOEXCEPT
Returns the meta destructor associated with a given type.
Definition: entt.hpp:13054
iterator_type cbegin() const ENTT_NOEXCEPT
Returns an iterator to the beginning.
Definition: entt.hpp:5927
size_type capacity() const ENTT_NOEXCEPT
Returns the number of entities that a registry has currently allocated space for.
Definition: entt.hpp:8134
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:7159
Type & ctx_or_set(Args &&... args)
Binds an object to the context of the registry.
Definition: entt.hpp:9506
Resource * operator->() ENTT_NOEXCEPT
Gets a pointer to the managed resource.
Definition: entt.hpp:15050
Component * raw() ENTT_NOEXCEPT
Direct access to the list of components of a given pool.
Definition: entt.hpp:8192
Opaque container for values of any type.
Definition: entt.hpp:11773
void abort(const bool immediately=false)
Aborts all scheduled processes.
Definition: entt.hpp:14847
delegate(connect_arg_t< Function >) ENTT_NOEXCEPT
Constructs a delegate and connects a free function to it.
Definition: entt.hpp:2676
auto type() ENTT_NOEXCEPT
Extends a meta type by assigning it an identifier.
Definition: entt.hpp:13600
auto create()
Creates a new entity and returns it.
Definition: entt.hpp:8284
meta_prop prop(meta_any key) const ENTT_NOEXCEPT
Returns the property associated with a given key.
Definition: entt.hpp:12653
meta_prop prop(meta_any key) const ENTT_NOEXCEPT
Returns the property associated with a given key.
Definition: entt.hpp:12453
basic_view< entity, Types... > view
Alias declaration for the most common use case.
Definition: entt.hpp:3812
bool convert()
Tries to convert an instance to a given type.
Definition: entt.hpp:12074
Key
Definition: EventInterface.h:7
#define ENTT_ENABLE_ETO(Type)
Definition: entt.hpp:49
void update() const
Delivers all the pending events.
Definition: entt.hpp:17434
static constexpr auto replace() ENTT_NOEXCEPT
Adds an observing matcher to the collector.
Definition: entt.hpp:10026
void fail() ENTT_NOEXCEPT
Terminates a process with errors if it's still alive.
Definition: entt.hpp:14362
void clear() ENTT_NOEXCEPT
Clears a cache and discards all its resources.
Definition: entt.hpp:15195
#define ENTT_HWS_SUFFIX
Definition: entt.hpp:35
void connect(Type &value_or_instance) ENTT_NOEXCEPT
Connects a member function for a given instance or a free function with payload to a delegate.
Definition: entt.hpp:2735
void disconnect(Type *value_or_instance)
Disconnects a member function or a free function with payload from a signal.
Definition: entt.hpp:3464
Cooperative scheduler for processes.
Definition: entt.hpp:14611
sink before(Type &value_or_instance)
Returns a sink that connects before a given member function or free function with payload.
Definition: entt.hpp:3269
as_group(registry_type &source) ENTT_NOEXCEPT
Constructs a converter for a given registry.
Definition: entt.hpp:9857
size_type size() const ENTT_NOEXCEPT
Estimates the number of entities that have the given components.
Definition: entt.hpp:4601
Entity entity_type
Underlying entity identifier.
Definition: entt.hpp:4591
bool is_function_pointer() const ENTT_NOEXCEPT
Indicates whether a given meta type refers to a function pointer or not.
Definition: entt.hpp:12919
size_type size() const ENTT_NOEXCEPT
Number of listeners connected to the signal.
Definition: entt.hpp:2987
size_type size() const ENTT_NOEXCEPT
Returns the number of entities that have the given component.
Definition: entt.hpp:7526
bool is_void() const ENTT_NOEXCEPT
Indicates whether a given meta type refers to void or not.
Definition: entt.hpp:12849
Concatenates multiple type lists.
Definition: entt.hpp:1127
void swap(double &a, double &b)
Definition: l2d_base_defs.h:29
constexpr auto overload(Type Class::*member) ENTT_NOEXCEPT
Constant utility to disambiguate overloaded member functions.
Definition: entt.hpp:105
process_adaptor(Args &&... args)
Constructs a process adaptor from a lambda or a functor.
Definition: entt.hpp:14545
bool contains(const id_type id) const ENTT_NOEXCEPT
Checks if a cache contains a given identifier.
Definition: entt.hpp:15306
Alias for lists of observed components.
Definition: entt.hpp:6060
void enqueue(Event &&event)
Enqueues an event of the given type.
Definition: entt.hpp:17388
static void reset()
Resets a service.
Definition: entt.hpp:10539
void stomp(const entity_type dst, const entity_type src, const basic_registry &other, exclude_t< Exclude... >={})
Stomps an entity and its components.
Definition: entt.hpp:9340
Function object for performing insertion sort.
Definition: entt.hpp:212
meta_type type() const ENTT_NOEXCEPT
Returns the meta type of the underlying object.
Definition: entt.hpp:13242
meta_func func(const ENTT_ID_TYPE identifier) const ENTT_NOEXCEPT
Returns the meta function associated with a given identifier.
Definition: entt.hpp:13115
connection & operator=(const connection &)=default
Default copy assignment operator.
service_locator()=delete
Default constructor, deleted on purpose.
iterator_type begin() const ENTT_NOEXCEPT
Returns an iterator to the first entity that has the given components.
Definition: entt.hpp:7257
size_type size() const ENTT_NOEXCEPT
Estimates the number of entities iterated by the view.
Definition: entt.hpp:7180
bool empty() const ENTT_NOEXCEPT
Checks whether a sparse set is empty.
Definition: entt.hpp:4103
meta_conv conv() const ENTT_NOEXCEPT
Returns the meta conversion function associated with a given type.
Definition: entt.hpp:13024
bool is_const() const ENTT_NOEXCEPT
Indicates whether a given meta function is constant or not.
Definition: entt.hpp:12713
Entity entity_type
Underlying entity identifier.
Definition: entt.hpp:7157
meta_any get(meta_handle handle) const ENTT_NOEXCEPT
Gets the value of the variable enclosed by a given meta type.
Definition: entt.hpp:12618
void each(Func func) const
Iterates entities and applies the given function object to them, then clears the observer.
Definition: entt.hpp:10332
basic_group< entity, Types... > group
Alias declaration for the most common use case.
Definition: entt.hpp:3822
void each(Func func) const
Iterates entities and components and applies the given function object to them.
Definition: entt.hpp:7361
Dedicated to those who aren't confident with the entity-component-system architecture.
Definition: entt.hpp:3769
typename internal::meta_ctor_node::size_type size_type
Unsigned integer type.
Definition: entt.hpp:12389
basic_continuous_loader & entities(Archive &archive)
Restores entities that were in use during serialization.
Definition: entt.hpp:5187
Ret(Args...) function_type
Function type of the delegate.
Definition: entt.hpp:2664
iterator_type find(const entity_type entt) const ENTT_NOEXCEPT
Finds an entity.
Definition: entt.hpp:7613
iterator_type begin() const ENTT_NOEXCEPT
Returns an iterator to the first entity that has the given components.
Definition: entt.hpp:6301
auto try_get([[maybe_unused]] const entity_type entity) ENTT_NOEXCEPT
Returns pointers to the given components for an entity.
Definition: entt.hpp:8586
auto prop(PropertyOrKey &&property_or_key, Value &&... value) &&
Assigns a property to the last meta object created.
Definition: entt.hpp:14074
static bool empty() ENTT_NOEXCEPT
Tests if a valid service implementation is set.
Definition: entt.hpp:10478
static constexpr hash_type to_value(const value_type(&str)[N]) ENTT_NOEXCEPT
Returns directly the numeric representation of a string.
Definition: entt.hpp:449
meta_any(meta_any &&other) ENTT_NOEXCEPT
Move constructor.
Definition: entt.hpp:11924
std::conditional_t< Const, const entt::basic_registry< Entity >, entt::basic_registry< Entity > > registry_type
Type of registry to convert.
Definition: entt.hpp:9851
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:14681
delegate() ENTT_NOEXCEPT
Default constructor.
Definition: entt.hpp:2667
iterator_type end() const ENTT_NOEXCEPT
Returns an iterator that is past the last entity that has the given components.
Definition: entt.hpp:4654
extended_meta_factory(entt::internal::meta_prop_node **target)
Constructs an extended factory from a given node.
Definition: entt.hpp:14058
#define ENTT_PAGE_SIZE
Definition: entt.hpp:63
sparse_set()=default
Default constructor.
Component * raw() const ENTT_NOEXCEPT
Direct access to the list of components of a given pool.
Definition: entt.hpp:6664
Empty class type used to request the as void policy.
Definition: entt.hpp:11346
Empty class type used to request the as alias policy.
Definition: entt.hpp:11334
Component raw_type
Type of component iterated by the view.
Definition: entt.hpp:7514
Type * try_cast() ENTT_NOEXCEPT
Tries to cast an instance to a given type.
Definition: entt.hpp:12012
Basic dispatcher implementation.
Definition: entt.hpp:17210
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:15158
static std::weak_ptr< Service > get() ENTT_NOEXCEPT
Returns a weak pointer to a service implementation, if any.
Definition: entt.hpp:10492
Utility class to create snapshots from a registry.
Definition: entt.hpp:3773
bool operator==(const meta_prop &other) const ENTT_NOEXCEPT
Checks if two meta objects refer to the same node.
Definition: entt.hpp:12271
void sort(iterator_type first, iterator_type last, Compare compare, Sort algo=Sort{}, Args &&... args)
Sort elements according to the given comparison function.
Definition: entt.hpp:5771
const basic_snapshot & entities(Archive &archive) const
Puts aside all the entities that are still in use.
Definition: entt.hpp:4802
meta_type parent() const ENTT_NOEXCEPT
Returns the meta type to which a meta object belongs.
Definition: entt.hpp:13287
iterator_type end() const ENTT_NOEXCEPT
Returns an iterator to the end.
Definition: entt.hpp:4158
size_type size() const ENTT_NOEXCEPT
Returns the number of elements in an observer.
Definition: entt.hpp:10258
size_type size() const ENTT_NOEXCEPT
Returns the number of entities that have the given components.
Definition: entt.hpp:6199
std::integral_constant< ENTT_ID_TYPE, Value > tag
Alias template to ease the assignment of tags to entities.
Definition: entt.hpp:9913
typename sparse_set< Entity >::iterator_type iterator_type
Input iterator type.
Definition: entt.hpp:6610
sink before()
Returns a sink that connects before a given function.
Definition: entt.hpp:3248
void clear() ENTT_NOEXCEPT
Disconnects all the listeners for the given event type.
Definition: entt.hpp:17754
static constexpr auto where(exclude_t< NoneOf... >={}) ENTT_NOEXCEPT
Updates the filter of the last added matcher.
Definition: entt.hpp:10037
Observer.
Definition: entt.hpp:3765
void reset()
Resets a sparse set.
Definition: entt.hpp:4443
constexpr auto is_named_type_v
Helper variable template.
Definition: entt.hpp:1274
void sort(Compare compare, Sort algo=Sort{}, Args &&... args)
Sorts the pool of entities for the given component.
Definition: entt.hpp:8792
scoped_connection & operator=(const scoped_connection &)=delete
Default copy assignment operator, deleted on purpose.
bool is_class() const ENTT_NOEXCEPT
Indicates whether a given meta type refers to a class or not.
Definition: entt.hpp:12901
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:7518
auto props(Property... property) &&
Assigns properties to the last meta object created.
Definition: entt.hpp:14095
entt::handle< Resource > handle(const id_type id) const
Creates a handle for a given resource identifier.
Definition: entt.hpp:15296
void destroy(const entity_type entt)
Removes an entity from a storage and destroys its object.
Definition: entt.hpp:5701
ENTT_ID_TYPE hash_type
Unsigned integer type.
Definition: entt.hpp:431
iterator_type find(const entity_type entt) const ENTT_NOEXCEPT
Finds an entity.
Definition: entt.hpp:7290
auto attach(Args &&... args)
Schedules a process for the next tick.
Definition: entt.hpp:14744
iterator_type cend() const ENTT_NOEXCEPT
Returns an iterator to the end.
Definition: entt.hpp:5951
meta_data(const internal::meta_data_node *curr=nullptr) ENTT_NOEXCEPT
Constructs an instance from a given node.
Definition: entt.hpp:12534
basic_actor() ENTT_NOEXCEPT
Definition: entt.hpp:9598
size_type size() const ENTT_NOEXCEPT
Returns the number of entities that have the given components.
Definition: entt.hpp:6626
entity_type entity() const ENTT_NOEXCEPT
Returns the entity associated with an actor.
Definition: entt.hpp:9750
constexpr auto named_type_traits_v
Helper variable template.
Definition: entt.hpp:1252
typename type_list_unique< Type >::type type_list_unique_t
Helper type.
Definition: entt.hpp:1199
bool has(entity_type entt) const ENTT_NOEXCEPT
Tests if a loader knows about a given entity.
Definition: entt.hpp:5287
Resource & get() ENTT_NOEXCEPT
Gets a reference to the managed resource.
Definition: entt.hpp:15017
bool empty() const ENTT_NOEXCEPT
Returns true if a cache contains no resources, false otherwise.
Definition: entt.hpp:15185
void reset()
Resets a storage.
Definition: entt.hpp:5792
std::conditional_t< std::disjunction_v< std::is_same< Type, Other >... >, typename type_list_unique< type_list< Other... > >::type, type_list_cat_t< type_list< Type >, typename type_list_unique< type_list< Other... > >::type > > type
A type list without duplicate types.
Definition: entt.hpp:1182
Component * raw() const ENTT_NOEXCEPT
Direct access to the list of components of a given pool.
Definition: entt.hpp:6248
constexpr as_alias_t as_alias
Disambiguation tag.
Definition: entt.hpp:11338
iterator_type find(const entity_type entt) const ENTT_NOEXCEPT
Finds an entity.
Definition: entt.hpp:4168
bool operator==(const meta_dtor &other) const ENTT_NOEXCEPT
Checks if two meta objects refer to the same node.
Definition: entt.hpp:12516
bool sortable() const ENTT_NOEXCEPT
Checks whether the given components belong to any group.
Definition: entt.hpp:9032
bool is_static() const ENTT_NOEXCEPT
Indicates whether a given meta function is static or not.
Definition: entt.hpp:12725
DualNumber operator *(DualNumber a, DualNumber b)
Definition: DualNumber.h:71
bool is_member_function_pointer() const ENTT_NOEXCEPT
Indicates whether a given meta type refers to a pointer to member function or not.
Definition: entt.hpp:12939
std::uint8_t version_type
Underlying version type.
Definition: entt.hpp:3594
meta_ctor(const internal::meta_ctor_node *curr=nullptr) ENTT_NOEXCEPT
Constructs an instance from a given node.
Definition: entt.hpp:12392
#define ENTT_ASSERT(condition)
Definition: entt.hpp:69
void unset()
Unsets a context variable if it exists.
Definition: entt.hpp:9488
basic_continuous_loader & operator=(basic_continuous_loader &&)=default
Default move assignment operator.
std::uint16_t version_type
Underlying version type.
Definition: entt.hpp:3620
bool empty() const ENTT_NOEXCEPT
Checks whether the registry or the pools of the given components are empty.
Definition: entt.hpp:8160
Entity traits.
Definition: entt.hpp:3578
Runtime view.
Definition: entt.hpp:3757
auto base() ENTT_NOEXCEPT
Assigns a meta base to a meta type.
Definition: entt.hpp:13614
static hash_type to_value(const_wrapper wrapper) ENTT_NOEXCEPT
Returns directly the numeric representation of a string.
Definition: entt.hpp:458
Sink class.
Definition: entt.hpp:2909
Type & set(Args &&... args)
Binds an object to the context of the registry.
Definition: entt.hpp:9463
Helper type for visitors.
Definition: entt.hpp:123
iterator iterator_type
Random access iterator type.
Definition: entt.hpp:3995
Minimal implementation of the monostate pattern.
Definition: entt.hpp:700
const entity_type * data() const ENTT_NOEXCEPT
Direct access to the list of entities.
Definition: entt.hpp:7566
void construct(const entity_type entt)
Assigns an entity to a sparse set.
Definition: entt.hpp:4212
bool has(const entity_type entity) const ENTT_NOEXCEPT
Checks if an entity has all the given components.
Definition: entt.hpp:8488
Type object_type
Type of the objects associated with the entities.
Definition: entt.hpp:5907
size_type size() const ENTT_NOEXCEPT
Returns the number of existing components of the given type.
Definition: entt.hpp:8070
void clear() ENTT_NOEXCEPT
Disconnects all the listeners.
Definition: entt.hpp:17764
Type * try_ctx() ENTT_NOEXCEPT
Returns a pointer to an object in the context of the registry.
Definition: entt.hpp:9528
A meta factory to be used for reflection purposes.
Definition: entt.hpp:13556
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:8030
basic_hashed_string< wchar_t > hashed_wstring
Aliases for common character types.
Definition: entt.hpp:580
meta_any & operator=(Type &&type)
Assignment operator.
Definition: entt.hpp:11944
std::enable_if_t< std::is_invocable_v< Op, meta_type >, void > resolve(Op op) ENTT_NOEXCEPT
Iterates all the reflected types.
Definition: entt.hpp:14152