6 #ifndef ENTT_CORE_ALGORITHM_HPP 7 #define ENTT_CORE_ALGORITHM_HPP 15 #ifndef ENTT_CORE_UTILITY_HPP 16 #define ENTT_CORE_UTILITY_HPP 20 #ifndef ENTT_CONFIG_CONFIG_H 21 #define ENTT_CONFIG_CONFIG_H 25 #define ENTT_NOEXCEPT noexcept 26 #endif // ENTT_NOEXCEPT 29 #ifndef ENTT_HS_SUFFIX 30 #define ENTT_HS_SUFFIX _hs 31 #endif // ENTT_HS_SUFFIX 34 #ifndef ENTT_HWS_SUFFIX 35 #define ENTT_HWS_SUFFIX _hws 36 #endif // ENTT_HWS_SUFFIX 39 #ifndef ENTT_NO_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 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 52 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 53 #endif // ENTT_DISABLE_ETO 58 #define ENTT_ID_TYPE std::uint32_t 59 #endif // ENTT_ID_TYPE 62 #ifndef ENTT_PAGE_SIZE 63 #define ENTT_PAGE_SIZE 32768 64 #endif // ENTT_PAGE_SIZE 67 #ifndef ENTT_DISABLE_ASSERT 69 #define ENTT_ASSERT(condition) assert(condition) 70 #else // ENTT_DISABLE_ASSERT 71 #define ENTT_ASSERT(...) ((void)0) 72 #endif // ENTT_DISABLE_ASSERT 75 #endif // ENTT_CONFIG_CONFIG_H 92 return std::forward<Type>(value);
104 template<
typename Type,
typename Class>
114 template<
typename Type>
122 template<
class... Func>
124 using Func::operator()...;
132 template<
class... Type>
147 func{std::move(recursive)}
156 template <
class... Args>
157 decltype(
auto) operator()(Args &&... args)
const {
158 return func(*
this, std::forward<Args>(args)...);
162 template <
class... Args>
163 decltype(
auto) operator()(Args &&... args) {
164 return func(*
this, std::forward<Args>(args)...);
175 #endif // ENTT_CORE_UTILITY_HPP 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));
224 template<
typename It,
typename Compare = std::less<>>
225 void operator()(It first, It last, Compare compare = Compare{})
const {
227 for(
auto it = first+1; it < last; ++it) {
228 auto value = std::move(*it);
231 for(; pre > first && compare(value, *(pre-1)); --pre) {
232 *pre = std::move(*(pre-1));
235 *pre = std::move(value);
247 template<std::
size_t Bit, std::
size_t N>
249 static_assert((N % Bit) == 0);
266 template<
typename It,
typename Getter =
identity>
267 void operator()(It first, It last, Getter getter = Getter{})
const {
269 static constexpr
auto mask = (1 << Bit) - 1;
270 static constexpr
auto buckets = 1 << Bit;
271 static constexpr
auto passes = N / Bit;
273 using value_type =
typename std::iterator_traits<It>::value_type;
274 std::vector<value_type> aux(std::distance(first, last));
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]{};
280 std::for_each(from, to, [&getter, &count, start](
const value_type &item) {
281 ++count[(getter(item) >> start) & mask];
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++);
288 std::for_each(from, to, [&getter, &out, &index, start](value_type &item) {
289 out[index[(getter(item) >> start) & mask]++] = std::move(item);
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);
298 if constexpr(passes & 1) {
299 part(first, last, aux.begin(), (passes - 1) * Bit);
300 std::move(aux.begin(), aux.end(), first);
310 #endif // ENTT_CORE_ALGORITHM_HPP 313 #ifndef ENTT_CORE_FAMILY_HPP 314 #define ENTT_CORE_FAMILY_HPP 317 #include <type_traits> 332 template<
typename...>
341 template<
typename... Type>
350 #endif // ENTT_CORE_FAMILY_HPP 353 #ifndef ENTT_CORE_HASHED_STRING_HPP 354 #define ENTT_CORE_HASHED_STRING_HPP 379 struct fnv1a_traits<
std::uint32_t> {
380 static constexpr std::uint32_t offset = 2166136261;
381 static constexpr std::uint32_t prime = 16777619;
386 struct fnv1a_traits<
std::uint64_t> {
387 static constexpr std::uint64_t offset = 14695981039346656037ull;
388 static constexpr std::uint64_t prime = 1099511628211ull;
412 template<
typename Char>
414 using traits_type = internal::fnv1a_traits<ENTT_ID_TYPE>;
416 struct const_wrapper {
418 constexpr const_wrapper(
const Char *curr)
ENTT_NOEXCEPT: str{curr} {}
424 return curr[0] == 0 ? partial : helper((partial^curr[0])*traits_type::prime, curr+1);
448 template<std::
size_t N>
450 return helper(traits_type::offset, str);
459 return helper(traits_type::offset, wrapper.str);
470 while(size--) { partial = (partial^(str++)[0])*traits_type::prime; }
476 : str{
nullptr}, hash{}
493 template<std::
size_t N>
495 : str{curr}, hash{helper(traits_type::offset, curr)}
504 : str{wrapper.str}, hash{helper(traits_type::offset, wrapper.str)}
538 return hash == other.hash;
557 template<
typename Char, std::
size_t N>
559 -> basic_hashed_string<Char>;
569 template<
typename Char>
571 return !(lhs == rhs);
606 #endif // ENTT_CORE_HASHED_STRING_HPP 609 #ifndef ENTT_CORE_IDENT_HPP 610 #define ENTT_CORE_IDENT_HPP 615 #include <type_traits> 650 template<
typename... Types>
652 using tuple_type = std::tuple<std::decay_t<Types>...>;
654 template<
typename Type, std::size_t... Indexes>
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{}));
665 template<
typename Type>
673 #endif // ENTT_CORE_IDENT_HPP 676 #ifndef ENTT_CORE_MONOSTATE_HPP 677 #define ENTT_CORE_MONOSTATE_HPP 699 template<ENTT_ID_TYPE>
706 template<
typename Type>
716 template<
typename Type>
722 template<
typename Type>
723 inline static ENTT_MAYBE_ATOMIC(Type) value{};
731 template<ENTT_ID_TYPE Value>
738 #endif // ENTT_CORE_MONOSTATE_HPP 741 #ifndef ENTT_CORE_TYPE_TRAITS_HPP 742 #define ENTT_CORE_TYPE_TRAITS_HPP 746 #include <type_traits> 750 #ifndef ENTT_CORE_HASHED_STRING_HPP 751 #define ENTT_CORE_HASHED_STRING_HPP 756 #ifndef ENTT_CONFIG_CONFIG_H 757 #define ENTT_CONFIG_CONFIG_H 760 #ifndef ENTT_NOEXCEPT 761 #define ENTT_NOEXCEPT noexcept 762 #endif // ENTT_NOEXCEPT 765 #ifndef ENTT_HS_SUFFIX 766 #define ENTT_HS_SUFFIX _hs 767 #endif // ENTT_HS_SUFFIX 770 #ifndef ENTT_HWS_SUFFIX 771 #define ENTT_HWS_SUFFIX _hws 772 #endif // ENTT_HWS_SUFFIX 775 #ifndef ENTT_NO_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 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 788 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 789 #endif // ENTT_DISABLE_ETO 794 #define ENTT_ID_TYPE std::uint32_t 795 #endif // ENTT_ID_TYPE 798 #ifndef ENTT_PAGE_SIZE 799 #define ENTT_PAGE_SIZE 32768 800 #endif // ENTT_PAGE_SIZE 803 #ifndef ENTT_DISABLE_ASSERT 805 #define ENTT_ASSERT(condition) assert(condition) 806 #else // ENTT_DISABLE_ASSERT 807 #define ENTT_ASSERT(...) ((void)0) 808 #endif // ENTT_DISABLE_ASSERT 811 #endif // ENTT_CONFIG_CONFIG_H 832 struct fnv1a_traits<
std::uint32_t> {
833 static constexpr std::uint32_t offset = 2166136261;
834 static constexpr std::uint32_t prime = 16777619;
839 struct fnv1a_traits<
std::uint64_t> {
840 static constexpr std::uint64_t offset = 14695981039346656037ull;
841 static constexpr std::uint64_t prime = 1099511628211ull;
865 template<
typename Char>
867 using traits_type = internal::fnv1a_traits<ENTT_ID_TYPE>;
869 struct const_wrapper {
871 constexpr const_wrapper(
const Char *curr)
ENTT_NOEXCEPT: str{curr} {}
877 return curr[0] == 0 ? partial : helper((partial^curr[0])*traits_type::prime, curr+1);
901 template<std::
size_t N>
903 return helper(traits_type::offset, str);
912 return helper(traits_type::offset, wrapper.str);
923 while(size--) { partial = (partial^(str++)[0])*traits_type::prime; }
929 : str{
nullptr}, hash{}
946 template<std::
size_t N>
948 : str{curr}, hash{helper(traits_type::offset, curr)}
957 : str{wrapper.str}, hash{helper(traits_type::offset, wrapper.str)}
991 return hash == other.hash;
1010 template<
typename Char, std::
size_t N>
1012 -> basic_hashed_string<Char>;
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);
1059 #endif // ENTT_CORE_HASHED_STRING_HPP 1070 template<std::
size_t N>
1088 template<std::
size_t N>
1093 template<
typename...>
1106 template<
typename... Type>
1108 : std::integral_constant<std::size_t, sizeof...(Type)>
1116 template<
class List>
1121 template<
typename...>
1139 template<
typename... Type,
typename... Other,
typename... List>
1150 template<
typename... Type>
1161 template<
typename... List>
1175 template<
typename Type,
typename... Other>
1178 using type = std::conditional_t<
1179 std::disjunction_v<std::is_same<Type, Other>...>,
1198 template<
typename Type>
1207 template<
typename Type,
typename = std::
void_t<>>
1212 template<
typename Type>
1220 template<
class Type>
1233 template<
typename Type>
1243 template<
typename Type>
1251 template<
class Type>
1260 template<
typename Type,
typename = std::
void_t<>>
1265 template<
typename Type>
1266 struct is_named_type<Type,
std::void_t<named_type_traits_t<std::decay_t<Type>>>>: std::true_type {};
1273 template<
class Type>
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);\ 1301 #define ENTT_EXPAND(args) args 1321 #define ENTT_NAMED_TYPE(type)\ 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}>\ 1326 static_assert(std::is_same_v<std::remove_cv_t<type>, type>);\ 1327 static_assert(std::is_object_v<type>);\ 1336 #define ENTT_NAMED_STRUCT_ONLY(clazz, body)\ 1338 ENTT_NAMED_TYPE(clazz) 1347 #define ENTT_NAMED_STRUCT_WITH_NAMESPACE(ns, clazz, body)\ 1348 namespace ns { struct clazz body; }\ 1349 ENTT_NAMED_TYPE(ns::clazz) 1353 #define ENTT_NAMED_STRUCT_OVERLOAD(_1, _2, _3, FUNC, ...) FUNC 1355 #define ENTT_NAMED_STRUCT(...) ENTT_EXPAND(ENTT_NAMED_STRUCT_OVERLOAD(__VA_ARGS__, ENTT_NAMED_STRUCT_WITH_NAMESPACE, ENTT_NAMED_STRUCT_ONLY,)(__VA_ARGS__)) 1363 #define ENTT_NAMED_CLASS_ONLY(clazz, body)\ 1365 ENTT_NAMED_TYPE(clazz) 1374 #define ENTT_NAMED_CLASS_WITH_NAMESPACE(ns, clazz, body)\ 1375 namespace ns { class clazz body; }\ 1376 ENTT_NAMED_TYPE(ns::clazz) 1380 #define ENTT_NAMED_CLASS_MACRO(_1, _2, _3, FUNC, ...) FUNC 1382 #define ENTT_NAMED_CLASS(...) ENTT_EXPAND(ENTT_NAMED_CLASS_MACRO(__VA_ARGS__, ENTT_NAMED_CLASS_WITH_NAMESPACE, ENTT_NAMED_CLASS_ONLY,)(__VA_ARGS__)) 1385 #endif // ENTT_CORE_TYPE_TRAITS_HPP 1390 #ifndef ENTT_ENTITY_ACTOR_HPP 1391 #define ENTT_ENTITY_ACTOR_HPP 1396 #include <type_traits> 1398 #ifndef ENTT_CONFIG_CONFIG_H 1399 #define ENTT_CONFIG_CONFIG_H 1402 #ifndef ENTT_NOEXCEPT 1403 #define ENTT_NOEXCEPT noexcept 1404 #endif // ENTT_NOEXCEPT 1407 #ifndef ENTT_HS_SUFFIX 1408 #define ENTT_HS_SUFFIX _hs 1409 #endif // ENTT_HS_SUFFIX 1412 #ifndef ENTT_HWS_SUFFIX 1413 #define ENTT_HWS_SUFFIX _hws 1414 #endif // ENTT_HWS_SUFFIX 1417 #ifndef ENTT_NO_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 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 1430 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 1431 #endif // ENTT_DISABLE_ETO 1434 #ifndef ENTT_ID_TYPE 1436 #define ENTT_ID_TYPE std::uint32_t 1437 #endif // ENTT_ID_TYPE 1440 #ifndef ENTT_PAGE_SIZE 1441 #define ENTT_PAGE_SIZE 32768 1442 #endif // ENTT_PAGE_SIZE 1445 #ifndef ENTT_DISABLE_ASSERT 1447 #define ENTT_ASSERT(condition) assert(condition) 1448 #else // ENTT_DISABLE_ASSERT 1449 #define ENTT_ASSERT(...) ((void)0) 1450 #endif // ENTT_DISABLE_ASSERT 1453 #endif // ENTT_CONFIG_CONFIG_H 1456 #ifndef ENTT_ENTITY_REGISTRY_HPP 1457 #define ENTT_ENTITY_REGISTRY_HPP 1466 #include <algorithm> 1467 #include <type_traits> 1471 #ifndef ENTT_CORE_FAMILY_HPP 1472 #define ENTT_CORE_FAMILY_HPP 1475 #include <type_traits> 1477 #ifndef ENTT_CONFIG_CONFIG_H 1478 #define ENTT_CONFIG_CONFIG_H 1481 #ifndef ENTT_NOEXCEPT 1482 #define ENTT_NOEXCEPT noexcept 1483 #endif // ENTT_NOEXCEPT 1486 #ifndef ENTT_HS_SUFFIX 1487 #define ENTT_HS_SUFFIX _hs 1488 #endif // ENTT_HS_SUFFIX 1491 #ifndef ENTT_HWS_SUFFIX 1492 #define ENTT_HWS_SUFFIX _hws 1493 #endif // ENTT_HWS_SUFFIX 1496 #ifndef ENTT_NO_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 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 1509 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 1510 #endif // ENTT_DISABLE_ETO 1513 #ifndef ENTT_ID_TYPE 1515 #define ENTT_ID_TYPE std::uint32_t 1516 #endif // ENTT_ID_TYPE 1519 #ifndef ENTT_PAGE_SIZE 1520 #define ENTT_PAGE_SIZE 32768 1521 #endif // ENTT_PAGE_SIZE 1524 #ifndef ENTT_DISABLE_ASSERT 1526 #define ENTT_ASSERT(condition) assert(condition) 1527 #else // ENTT_DISABLE_ASSERT 1528 #define ENTT_ASSERT(...) ((void)0) 1529 #endif // ENTT_DISABLE_ASSERT 1532 #endif // ENTT_CONFIG_CONFIG_H 1546 template<
typename...>
1555 template<
typename... Type>
1557 inline static const family_type type = identifier++;
1564 #endif // ENTT_CORE_FAMILY_HPP 1567 #ifndef ENTT_CORE_ALGORITHM_HPP 1568 #define ENTT_CORE_ALGORITHM_HPP 1573 #include <algorithm> 1574 #include <functional> 1576 #ifndef ENTT_CORE_UTILITY_HPP 1577 #define ENTT_CORE_UTILITY_HPP 1595 template<
class Type>
1597 return std::forward<Type>(value);
1609 template<
typename Type,
typename Class>
1619 template<
typename Type>
1627 template<
class... Func>
1629 using Func::operator()...;
1637 template<
class... Type>
1645 template<
class Func>
1646 struct y_combinator {
1652 func{std::move(recursive)}
1661 template <
class... Args>
1662 decltype(
auto) operator()(Args &&... args)
const {
1663 return func(*
this, std::forward<Args>(args)...);
1667 template <
class... Args>
1668 decltype(
auto) operator()(Args &&... args) {
1669 return func(*
this, std::forward<Args>(args)...);
1680 #endif // ENTT_CORE_UTILITY_HPP 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));
1717 struct insertion_sort {
1729 template<
typename It,
typename Compare = std::less<>>
1730 void operator()(It first, It last, Compare compare = Compare{})
const {
1732 for(
auto it = first+1; it < last; ++it) {
1733 auto value = std::move(*it);
1736 for(; pre > first && compare(value, *(pre-1)); --pre) {
1737 *pre = std::move(*(pre-1));
1740 *pre = std::move(value);
1752 template<std::
size_t Bit, std::
size_t N>
1754 static_assert((N % Bit) == 0);
1771 template<
typename It,
typename Getter =
identity>
1772 void operator()(It first, It last, Getter getter = Getter{})
const {
1774 static constexpr
auto mask = (1 << Bit) - 1;
1775 static constexpr
auto buckets = 1 << Bit;
1776 static constexpr
auto passes = N / Bit;
1778 using value_type =
typename std::iterator_traits<It>::value_type;
1779 std::vector<value_type> aux(std::distance(first, last));
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]{};
1785 std::for_each(from, to, [&getter, &count, start](
const value_type &item) {
1786 ++count[(getter(item) >> start) & mask];
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++);
1793 std::for_each(from, to, [&getter, &out, &index, start](value_type &item) {
1794 out[index[(getter(item) >> start) & mask]++] = std::move(item);
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);
1803 if constexpr(passes & 1) {
1804 part(first, last, aux.begin(), (passes - 1) * Bit);
1805 std::move(aux.begin(), aux.end(), first);
1815 #endif // ENTT_CORE_ALGORITHM_HPP 1818 #ifndef ENTT_CORE_TYPE_TRAITS_HPP 1819 #define ENTT_CORE_TYPE_TRAITS_HPP 1823 #include <type_traits> 1827 #ifndef ENTT_CORE_HASHED_STRING_HPP 1828 #define ENTT_CORE_HASHED_STRING_HPP 1833 #ifndef ENTT_CONFIG_CONFIG_H 1834 #define ENTT_CONFIG_CONFIG_H 1837 #ifndef ENTT_NOEXCEPT 1838 #define ENTT_NOEXCEPT noexcept 1839 #endif // ENTT_NOEXCEPT 1842 #ifndef ENTT_HS_SUFFIX 1843 #define ENTT_HS_SUFFIX _hs 1844 #endif // ENTT_HS_SUFFIX 1847 #ifndef ENTT_HWS_SUFFIX 1848 #define ENTT_HWS_SUFFIX _hws 1849 #endif // ENTT_HWS_SUFFIX 1852 #ifndef ENTT_NO_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 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 1865 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 1866 #endif // ENTT_DISABLE_ETO 1869 #ifndef ENTT_ID_TYPE 1871 #define ENTT_ID_TYPE std::uint32_t 1872 #endif // ENTT_ID_TYPE 1875 #ifndef ENTT_PAGE_SIZE 1876 #define ENTT_PAGE_SIZE 32768 1877 #endif // ENTT_PAGE_SIZE 1880 #ifndef ENTT_DISABLE_ASSERT 1882 #define ENTT_ASSERT(condition) assert(condition) 1883 #else // ENTT_DISABLE_ASSERT 1884 #define ENTT_ASSERT(...) ((void)0) 1885 #endif // ENTT_DISABLE_ASSERT 1888 #endif // ENTT_CONFIG_CONFIG_H 1901 namespace internal {
1905 struct fnv1a_traits;
1909 struct fnv1a_traits<
std::uint32_t> {
1910 static constexpr std::uint32_t offset = 2166136261;
1911 static constexpr std::uint32_t prime = 16777619;
1916 struct fnv1a_traits<
std::uint64_t> {
1917 static constexpr std::uint64_t offset = 14695981039346656037ull;
1918 static constexpr std::uint64_t prime = 1099511628211ull;
1942 template<
typename Char>
1944 using traits_type = internal::fnv1a_traits<ENTT_ID_TYPE>;
1946 struct const_wrapper {
1948 constexpr const_wrapper(
const Char *curr)
ENTT_NOEXCEPT: str{curr} {}
1954 return curr[0] == 0 ? partial : helper((partial^curr[0])*traits_type::prime, curr+1);
1978 template<std::
size_t N>
1980 return helper(traits_type::offset, str);
1989 return helper(traits_type::offset, wrapper.str);
2000 while(size--) { partial = (partial^(str++)[0])*traits_type::prime; }
2006 : str{
nullptr}, hash{}
2023 template<std::
size_t N>
2025 : str{curr}, hash{helper(traits_type::offset, curr)}
2034 : str{wrapper.str}, hash{helper(traits_type::offset, wrapper.str)}
2068 return hash == other.hash;
2087 template<
typename Char, std::
size_t N>
2089 -> basic_hashed_string<Char>;
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);
2136 #endif // ENTT_CORE_HASHED_STRING_HPP 2147 template<std::
size_t N>
2158 struct choice_t<0> {};
2165 template<std::
size_t N>
2166 constexpr choice_t<N>
choice{};
2170 template<
typename...>
2171 struct type_list {};
2176 struct type_list_size;
2183 template<
typename... Type>
2184 struct type_list_size<type_list<Type...>>
2185 : std::integral_constant<std::size_t, sizeof...(Type)>
2193 template<
class List>
2198 template<
typename...>
2199 struct type_list_cat;
2204 struct type_list_cat<> {
2206 using type = type_list<>;
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;
2227 template<
typename... Type>
2228 struct type_list_cat<type_list<Type...>> {
2230 using type = type_list<Type...>;
2238 template<
typename... List>
2244 struct type_list_unique;
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>
2265 struct type_list_unique<type_list<>> {
2267 using type = type_list<>;
2275 template<
typename Type>
2284 template<
typename Type,
typename = std::
void_t<>>
2285 struct is_equality_comparable: std::false_type {};
2289 template<
typename Type>
2290 struct is_equality_comparable<Type,
std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>: std::true_type {};
2297 template<
class Type>
2303 struct named_type_traits;
2310 template<
typename Type>
2311 struct named_type_traits<const Type>
2312 : named_type_traits<Type>
2320 template<
typename Type>
2328 template<
class Type>
2337 template<
typename Type,
typename = std::
void_t<>>
2338 struct is_named_type: std::false_type {};
2342 template<
typename Type>
2343 struct is_named_type<Type,
std::void_t<named_type_traits_t<std::decay_t<Type>>>>: std::true_type {};
2350 template<
class Type>
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);\ 2378 #define ENTT_EXPAND(args) args 2398 #define ENTT_NAMED_TYPE(type)\ 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}>\ 2403 static_assert(std::is_same_v<std::remove_cv_t<type>, type>);\ 2404 static_assert(std::is_object_v<type>);\ 2413 #define ENTT_NAMED_STRUCT_ONLY(clazz, body)\ 2415 ENTT_NAMED_TYPE(clazz) 2424 #define ENTT_NAMED_STRUCT_WITH_NAMESPACE(ns, clazz, body)\ 2425 namespace ns { struct clazz body; }\ 2426 ENTT_NAMED_TYPE(ns::clazz) 2430 #define ENTT_NAMED_STRUCT_OVERLOAD(_1, _2, _3, FUNC, ...) FUNC 2432 #define ENTT_NAMED_STRUCT(...) ENTT_EXPAND(ENTT_NAMED_STRUCT_OVERLOAD(__VA_ARGS__, ENTT_NAMED_STRUCT_WITH_NAMESPACE, ENTT_NAMED_STRUCT_ONLY,)(__VA_ARGS__)) 2440 #define ENTT_NAMED_CLASS_ONLY(clazz, body)\ 2442 ENTT_NAMED_TYPE(clazz) 2451 #define ENTT_NAMED_CLASS_WITH_NAMESPACE(ns, clazz, body)\ 2452 namespace ns { class clazz body; }\ 2453 ENTT_NAMED_TYPE(ns::clazz) 2457 #define ENTT_NAMED_CLASS_MACRO(_1, _2, _3, FUNC, ...) FUNC 2459 #define ENTT_NAMED_CLASS(...) ENTT_EXPAND(ENTT_NAMED_CLASS_MACRO(__VA_ARGS__, ENTT_NAMED_CLASS_WITH_NAMESPACE, ENTT_NAMED_CLASS_ONLY,)(__VA_ARGS__)) 2462 #endif // ENTT_CORE_TYPE_TRAITS_HPP 2465 #ifndef ENTT_SIGNAL_DELEGATE_HPP 2466 #define ENTT_SIGNAL_DELEGATE_HPP 2472 #include <algorithm> 2473 #include <functional> 2474 #include <type_traits> 2476 #ifndef ENTT_CONFIG_CONFIG_H 2477 #define ENTT_CONFIG_CONFIG_H 2480 #ifndef ENTT_NOEXCEPT 2481 #define ENTT_NOEXCEPT noexcept 2482 #endif // ENTT_NOEXCEPT 2485 #ifndef ENTT_HS_SUFFIX 2486 #define ENTT_HS_SUFFIX _hs 2487 #endif // ENTT_HS_SUFFIX 2490 #ifndef ENTT_HWS_SUFFIX 2491 #define ENTT_HWS_SUFFIX _hws 2492 #endif // ENTT_HWS_SUFFIX 2495 #ifndef ENTT_NO_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 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 2508 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 2509 #endif // ENTT_DISABLE_ETO 2512 #ifndef ENTT_ID_TYPE 2514 #define ENTT_ID_TYPE std::uint32_t 2515 #endif // ENTT_ID_TYPE 2518 #ifndef ENTT_PAGE_SIZE 2519 #define ENTT_PAGE_SIZE 32768 2520 #endif // ENTT_PAGE_SIZE 2523 #ifndef ENTT_DISABLE_ASSERT 2525 #define ENTT_ASSERT(condition) assert(condition) 2526 #else // ENTT_DISABLE_ASSERT 2527 #define ENTT_ASSERT(...) ((void)0) 2528 #endif // ENTT_DISABLE_ASSERT 2531 #endif // ENTT_CONFIG_CONFIG_H 2544 namespace internal {
2547 template<
typename Ret,
typename... Args>
2548 auto to_function_pointer(Ret(*)(Args...)) -> Ret(*)(Args...);
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...);
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...);
2559 template<
typename Class,
typename Ret,
typename... Args>
2560 auto to_function_pointer(Ret(Class:: *)(Args...),
const Class *) -> Ret(*)(Args...);
2563 template<
typename Class,
typename Ret,
typename... Args>
2564 auto to_function_pointer(Ret(Class:: *)(Args...)
const,
const Class *) -> Ret(*)(Args...);
2567 template<
typename Class,
typename Type>
2568 auto to_function_pointer(Type Class:: *,
const Class *) -> Type(*)();
2571 template<
typename... Type>
2572 using to_function_pointer_t = decltype(internal::to_function_pointer(std::declval<Type>()...));
2575 template<
typename Ret,
typename... Args>
2576 constexpr
auto index_sequence_for(Ret(*)(Args...)) {
2577 return std::index_sequence_for<Args...>{};
2623 template<
typename Ret,
typename... Args>
2625 using proto_fn_type = Ret(
const void *, std::tuple<Args &&...>);
2627 template<
auto Function, std::size_t... Index>
2629 static_assert(std::is_invocable_r_v<Ret, decltype(Function), std::tuple_element_t<Index, std::tuple<Args...>>...>);
2632 fn = [](
const void *, std::tuple<Args &&...> args) -> Ret {
2634 return Ret(std::invoke(Function, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
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;
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));
2646 return Ret(std::invoke(Candidate, *curr, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
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;
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));
2658 return Ret(std::invoke(Candidate, curr, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
2668 : fn{
nullptr}, data{
nullptr}
2675 template<auto Function>
2679 connect<Function>();
2689 template<auto Cand
idate,
typename Type>
2693 connect<Candidate>(value_or_instance);
2703 template<auto Cand
idate,
typename Type>
2707 connect<Candidate>(value_or_instance);
2714 template<auto Function>
2716 connect<Function>(internal::index_sequence_for(internal::to_function_pointer_t<decltype(Function)>{}));
2734 template<auto Cand
idate,
typename Type>
2736 connect<Candidate>(value_or_instance, internal::index_sequence_for(internal::to_function_pointer_t<decltype(Candidate), Type *>{}));
2754 template<auto Cand
idate,
typename Type>
2756 connect<Candidate>(value_or_instance, internal::index_sequence_for(internal::to_function_pointer_t<decltype(Candidate), Type *>{}));
2793 return fn(data, std::forward_as_tuple(std::forward<Args>(args)...));
2811 return fn == other.fn && data == other.data;
2828 template<
typename Ret,
typename... Args>
2830 return !(lhs == rhs);
2842 template<auto Function>
2844 ->
delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Function)>>>;
2856 template<auto Cand
idate,
typename Type>
2858 ->
delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Candidate), Type *>>>;
2870 template<auto Cand
idate,
typename Type>
2872 ->
delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Candidate), Type *>>>;
2878 #endif // ENTT_SIGNAL_DELEGATE_HPP 2881 #ifndef ENTT_SIGNAL_SIGH_HPP 2882 #define ENTT_SIGNAL_SIGH_HPP 2888 #include <algorithm> 2889 #include <functional> 2890 #include <type_traits> 2896 #ifndef ENTT_SIGNAL_FWD_HPP 2897 #define ENTT_SIGNAL_FWD_HPP 2919 #endif // ENTT_SIGNAL_FWD_HPP 2934 template<
typename Function>
2946 template<
typename Function>
2965 template<
typename Ret,
typename... Args>
2980 template<
typename Class>
2988 return calls.size();
2996 return calls.empty();
3007 std::for_each(calls.cbegin(), calls.cend(), [&args...](
auto &&call) {
3026 template<
typename Func>
3028 for(
auto &&call: calls) {
3029 if constexpr(std::is_void_v<Ret>) {
3030 if constexpr(std::is_invocable_r_v<bool, Func>) {
3032 if(func()) {
break; }
3038 if constexpr(std::is_invocable_r_v<bool, Func, Ret>) {
3039 if(func(call(args...))) {
break; }
3041 func(call(args...));
3048 std::vector<
delegate<Ret(Args...)>> calls;
3065 : disconnect{fn}, signal{ref}
3082 std::swap(disconnect, other.disconnect);
3095 if(
this != &other) {
3096 auto tmp{std::move(other)};
3097 disconnect = tmp.disconnect;
3098 signal = tmp.signal;
3109 return static_cast<bool>(disconnect);
3136 using connection::operator bool;
3179 static_cast<connection &>(*
this) = other;
3189 static_cast<connection &>(*
this) = std::move(other);
3209 template<
typename Ret,
typename... Args>
3212 using difference_type =
typename std::iterator_traits<
typename decltype(signal_type::calls)::iterator>::difference_type;
3214 template<auto Cand
idate,
typename Type>
3215 static void release(Type value_or_instance,
void *signal) {
3216 sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>(value_or_instance);
3219 template<auto Function>
3220 static void release(
void *signal) {
3221 sink{*static_cast<signal_type *>(signal)}.disconnect<Function>();
3239 return signal->calls.empty();
3247 template<auto Function>
3250 call.template connect<Function>();
3252 const auto &calls = signal->calls;
3253 const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
3256 other.offset = std::distance(it, calls.cend());
3268 template<auto Cand
idate,
typename Type>
3271 call.template connect<Candidate>(value_or_instance);
3273 const auto &calls = signal->calls;
3274 const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
3277 other.offset = std::distance(it, calls.cend());
3289 template<auto Cand
idate,
typename Type>
3292 call.template connect<Candidate>(value_or_instance);
3294 const auto &calls = signal->calls;
3295 const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
3298 other.offset = std::distance(it, calls.cend());
3309 template<
typename Type>
3311 return before(&value_or_instance);
3321 template<
typename Type>
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;
3331 other.offset = std::distance(it, calls.cend());
3343 other.offset = signal->calls.size();
3356 template<auto Function>
3358 disconnect<Function>();
3361 call.template connect<Function>();
3362 signal->calls.insert(signal->calls.end() - offset, std::move(call));
3365 conn.template connect<&release<Function>>();
3366 return { std::move(conn), signal };
3386 template<auto Cand
idate,
typename Type>
3388 disconnect<Candidate>(value_or_instance);
3391 call.template connect<Candidate>(value_or_instance);
3392 signal->calls.insert(signal->calls.end() - offset, std::move(call));
3395 conn.template connect<&release<Candidate, Type &>>(value_or_instance);
3396 return { std::move(conn), signal };
3416 template<auto Cand
idate,
typename Type>
3418 disconnect<Candidate>(value_or_instance);
3421 call.template connect<Candidate>(value_or_instance);
3422 signal->calls.insert(signal->calls.end() - offset, std::move(call));
3425 conn.template connect<&release<Candidate, Type *>>(value_or_instance);
3426 return { std::move(conn), signal };
3433 template<auto Function>
3435 auto &calls = signal->calls;
3437 call.template connect<Function>();
3438 calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
3448 template<auto Cand
idate,
typename Type>
3450 auto &calls = signal->calls;
3452 call.template connect<Candidate>(value_or_instance);
3453 calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
3463 template<auto Cand
idate,
typename Type>
3465 auto &calls = signal->calls;
3467 call.template connect<Candidate>(value_or_instance);
3468 calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
3477 template<
typename Type>
3479 disconnect(&value_or_instance);
3488 template<
typename Type>
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;
3500 signal->calls.clear();
3504 difference_type offset;
3505 signal_type *signal;
3518 template<
typename Ret,
typename... Args>
3525 #endif // ENTT_SIGNAL_SIGH_HPP 3528 #ifndef ENTT_ENTITY_RUNTIME_VIEW_HPP 3529 #define ENTT_ENTITY_RUNTIME_VIEW_HPP 3536 #include <algorithm> 3537 #include <type_traits> 3541 #ifndef ENTT_ENTITY_SPARSE_SET_HPP 3542 #define ENTT_ENTITY_SPARSE_SET_HPP 3545 #include <algorithm> 3552 #include <type_traits> 3558 #ifndef ENTT_ENTITY_ENTITY_HPP 3559 #define ENTT_ENTITY_ENTITY_HPP 3563 #include <type_traits> 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;
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;
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;
3665 namespace internal {
3669 template<
typename Entity>
3673 template<
typename Entity>
3675 return Entity{traits_type<Entity>::entity_mask};
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));
3691 template<
typename Entity>
3693 return !(entity == *
this);
3698 template<
typename Entity>
3699 constexpr
bool operator==(
const Entity entity,
null other)
ENTT_NOEXCEPT {
3700 return other == entity;
3704 template<
typename Entity>
3706 return other != entity;
3732 #endif // ENTT_ENTITY_ENTITY_HPP 3735 #ifndef ENTT_ENTITY_FWD_HPP 3736 #define ENTT_ENTITY_FWD_HPP 3752 template<
typename...>
3760 template<
typename...>
3811 template<
typename... Types>
3821 template<
typename... Types>
3828 #endif // ENTT_ENTITY_FWD_HPP 3862 template<
typename Entity>
3867 static constexpr
auto entt_per_page =
ENTT_PAGE_SIZE /
sizeof(
typename traits_type::entity_type);
3872 using direct_type =
const std::vector<Entity>;
3873 using index_type =
typename traits_type::difference_type;
3875 iterator(direct_type *ref,
const index_type idx)
ENTT_NOEXCEPT 3876 : direct{ref},
index{idx}
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;
3889 return --
index, *
this;
3893 iterator orig = *
this;
3894 return ++(*this), orig;
3898 return ++
index, *
this;
3902 iterator orig = *
this;
3903 return --(*this), orig;
3906 iterator & operator+=(
const difference_type value)
ENTT_NOEXCEPT {
3911 iterator operator+(
const difference_type value)
const ENTT_NOEXCEPT {
3912 return iterator{direct,
index-value};
3915 iterator & operator-=(
const difference_type value)
ENTT_NOEXCEPT {
3916 return (*
this += -value);
3919 iterator operator-(
const difference_type value)
const ENTT_NOEXCEPT {
3920 return (*
this + -value);
3923 difference_type operator-(
const iterator &other)
const ENTT_NOEXCEPT {
3924 return other.index -
index;
3927 reference operator[](
const difference_type value)
const ENTT_NOEXCEPT {
3929 return (*direct)[pos];
3932 bool operator==(
const iterator &other)
const ENTT_NOEXCEPT {
3933 return other.index ==
index;
3937 return !(*
this == other);
3941 return index > other.index;
3945 return index < other.index;
3948 bool operator<=(
const iterator &other)
const ENTT_NOEXCEPT {
3949 return !(*
this > other);
3952 bool operator>=(
const iterator &other)
const ENTT_NOEXCEPT {
3953 return !(*
this < other);
3958 return &(*direct)[pos];
3962 return *operator->();
3966 direct_type *direct;
3970 void assure(
const std::size_t page) {
3971 if(!(page < reverse.size())) {
3972 reverse.resize(page+1);
3975 if(!reverse[page]) {
3976 reverse[page] = std::make_unique<entity_type[]>(entt_per_page);
3978 std::fill_n(reverse[page].
get(), entt_per_page,
null);
3983 const auto identifier = to_integer(
entt) & traits_type::entity_mask;
3986 return std::make_pair(page, offset);
4006 direct{other.direct}
4008 for(
size_type pos{}, last = other.reverse.size(); pos < last; ++pos) {
4009 if(other.reverse[pos]) {
4011 std::copy_n(other.reverse[pos].get(), entt_per_page, reverse[pos].get());
4028 if(&other !=
this) {
4030 *
this = std::move(tmp);
4048 direct.reserve(cap);
4057 return direct.capacity();
4063 if(direct.empty()) {
4067 reverse.shrink_to_fit();
4068 direct.shrink_to_fit();
4082 return reverse.size() * entt_per_page;
4096 return direct.size();
4104 return direct.empty();
4123 return direct.data();
4140 const typename traits_type::difference_type pos = direct.size();
4178 auto [page, offset] = map(
entt);
4180 return (page < reverse.size() && reverse[page] && reverse[page][offset] !=
null);
4197 auto [page, offset] = map(
entt);
4198 return size_type(reverse[page][offset]);
4214 auto [page, offset] = map(
entt);
4216 reverse[page][offset] =
entity_type(direct.size());
4217 direct.push_back(
entt);
4233 template<
typename It>
4235 std::for_each(first, last, [
this, next = direct.size()](
const auto entt)
mutable {
4237 auto [page, offset] = map(
entt);
4242 direct.insert(direct.end(), first, last);
4258 auto [from_page, from_offset] = map(
entt);
4259 auto [to_page, to_offset] = map(direct.back());
4261 reverse[to_page][to_offset] = reverse[from_page][from_offset];
4262 reverse[from_page][from_offset] =
null;
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];
4329 template<
typename Compare,
typename Sort =
std_sort,
typename... Args>
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;
4339 algo(from, to, std::move(compare), std::forward<Args>(args)...);
4342 auto [page, offset] = map(direct[pos]);
4374 template<
typename Apply,
typename Compare,
typename Sort = std_sort,
typename... Args>
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;
4384 algo(from, to, std::move(compare), std::forward<Args>(args)...);
4388 auto next =
index(direct[curr]);
4390 while(curr != next) {
4391 apply(direct[curr], direct[next]);
4392 auto [page, offset] = map(direct[curr]);
4396 next =
index(direct[curr]);
4422 const auto to = other.end();
4423 auto from = other.begin();
4427 while(pos && from != to) {
4429 if(*from != direct[pos]) {
4430 swap(direct[pos], *from);
4449 std::vector<std::unique_ptr<entity_type[]>> reverse;
4450 std::vector<entity_type> direct;
4457 #endif // ENTT_ENTITY_SPARSE_SET_HPP 4506 template<
typename Entity>
4507 class basic_runtime_view {
4528 return std::all_of(from, to, [
entt = *
begin](
const auto *
view) {
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;
4543 return (++
begin !=
end && !valid()) ? ++(*this) : *
this;
4547 iterator orig = *
this;
4548 return ++(*this), orig;
4551 bool operator==(
const iterator &other)
const ENTT_NOEXCEPT {
4552 return other.begin ==
begin;
4556 return !(*
this == other);
4560 return begin.operator->();
4564 return *operator->();
4568 underlying_iterator_type
begin;
4569 underlying_iterator_type
end;
4570 const sparse_set<Entity> *
const *from;
4571 const sparse_set<Entity> *
const *to;
4574 basic_runtime_view(std::vector<
const sparse_set<Entity> *> others)
ENTT_NOEXCEPT 4575 : pools{std::move(others)}
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());
4582 std::rotate(pools.begin(), it, pools.end());
4586 return !pools.empty() && pools.front();
4602 return valid() ? pools.front()->size() :
size_type{};
4610 return !valid() || pools.front()->empty();
4631 const auto &pool = *pools.front();
4632 const auto *
const *data = pools.data();
4633 it = { pool.begin(), pool.end(), data + 1, data + pools.size() };
4658 const auto &pool = *pools.front();
4659 it = { pool.end(), pool.end(),
nullptr,
nullptr };
4671 return valid() && std::all_of(pools.cbegin(), pools.cend(), [
entt](
const auto *
view) {
4691 template<
typename Func>
4693 std::for_each(
begin(),
end(), func);
4697 std::vector<const sparse_set<Entity> *> pools;
4704 #endif // ENTT_ENTITY_RUNTIME_VIEW_HPP 4709 #ifndef ENTT_ENTITY_SNAPSHOT_HPP 4710 #define ENTT_ENTITY_SNAPSHOT_HPP 4717 #include <type_traits> 4718 #include <unordered_map> 4740 template<
typename Entity>
4741 class basic_snapshot {
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));
4758 while(first != last) {
4759 const auto entt = *(first++);
4761 if(reg->template has<Component>(
entt)) {
4762 if constexpr(std::is_empty_v<Component>) {
4765 archive(
entt, reg->template get<Component>(
entt));
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{};
4776 while(begin != last) {
4777 const auto entt = *(begin++);
4778 ((reg->template has<Component>(
entt) ? ++size[Indexes] : size[Indexes]), ...);
4781 (get<Component>(archive, size[Indexes], first, last), ...);
4786 basic_snapshot(basic_snapshot &&) =
default;
4789 basic_snapshot &
operator=(basic_snapshot &&) =
default;
4801 template<
typename Archive>
4803 archive(
typename traits_type::entity_type(reg->alive()));
4804 reg->each([&archive](
const auto entt) { archive(
entt); });
4818 template<
typename Archive>
4820 auto size = reg->size() - reg->alive();
4821 archive(
typename traits_type::entity_type(size));
4827 for(--size; size; --size) {
4828 curr = follow(*reg, curr);
4847 template<
typename... Component,
typename Archive>
4849 (component<Component>(archive, reg->template data<Component>(), reg->template data<Component>() + reg->template size<Component>()), ...);
4867 template<
typename... Component,
typename Archive,
typename It>
4869 component<Component...>(archive, first, last, std::index_sequence_for<Component...>{});
4876 follow_fn_type *follow;
4890 template<
typename Entity>
4891 class basic_snapshot_loader {
4906 template<
typename Archive>
4907 void assure(Archive &archive,
bool discard)
const {
4908 typename traits_type::entity_type length{};
4914 force(*reg,
entt, discard);
4918 template<
typename Type,
typename Archive,
typename... Args>
4919 void assign(Archive &archive, Args... args)
const {
4920 typename traits_type::entity_type length{};
4924 static constexpr
auto discard =
false;
4927 if constexpr(std::is_empty_v<Type>) {
4929 force(*reg,
entt, discard);
4930 reg->template assign<Type>(args...,
entt);
4933 archive(
entt, instance);
4934 force(*reg,
entt, discard);
4935 reg->template assign<Type>(args...,
entt, std::as_const(instance));
4942 basic_snapshot_loader(basic_snapshot_loader &&) =
default;
4945 basic_snapshot_loader &
operator=(basic_snapshot_loader &&) =
default;
4957 template<
typename Archive>
4959 static constexpr
auto discard =
false;
4960 assure(archive, discard);
4974 template<
typename Archive>
4976 static constexpr
auto discard =
true;
4977 assure(archive, discard);
4994 template<
typename... Component,
typename Archive>
4996 (assign<Component>(archive), ...);
5011 reg->orphans([
this](
const auto entt) {
5020 force_fn_type *force;
5040 template<
typename Entity>
5041 class basic_continuous_loader {
5042 using traits_type = entt_traits<std::underlying_type_t<Entity>>;
5044 void destroy(Entity
entt) {
5045 const auto it = remloc.find(
entt);
5047 if(it == remloc.cend()) {
5048 const auto local = reg->
create();
5049 remloc.emplace(
entt, std::make_pair(local,
true));
5054 void restore(Entity
entt) {
5055 const auto it = remloc.find(
entt);
5057 if(it == remloc.cend()) {
5058 const auto local = reg->
create();
5059 remloc.emplace(
entt, std::make_pair(local,
true));
5063 remloc[
entt].second =
true;
5067 template<
typename Container>
5068 auto update(
int, Container &container)
5069 -> decltype(
typename Container::mapped_type{}, void()) {
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;
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));
5082 static_assert(std::is_same_v<second_type, Entity>);
5083 other.emplace(std::move(pair.first),
map(pair.second));
5090 template<
typename Container>
5091 auto update(
char, Container &container)
5092 -> decltype(
typename Container::value_type{}, void()) {
5094 static_assert(std::is_same_v<typename Container::value_type, Entity>);
5096 for(
auto &&
entt: container) {
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>) {
5105 }
else if constexpr(std::is_same_v<Member, Entity>) {
5106 instance.*member =
map(instance.*member);
5109 update(0, instance.*member);
5113 template<
typename Archive>
5115 typename traits_type::entity_type length{};
5121 (this->*member)(
entt);
5125 template<
typename Component>
5127 for(
auto &&ref: remloc) {
5128 const auto local = ref.second.first;
5130 if(reg->
valid(local)) {
5131 reg->template reset<Component>(local);
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{};
5144 if constexpr(std::is_empty_v<Other>) {
5147 reg->template assign_or_replace<Other>(
map(
entt));
5150 archive(
entt, instance);
5151 (update(instance, member), ...);
5153 reg->template assign_or_replace<Other>(
map(
entt), std::as_const(instance));
5186 template<
typename Archive>
5188 assure(archive, &basic_continuous_loader::restore);
5202 template<
typename Archive>
5204 assure(archive, &basic_continuous_loader::destroy);
5227 template<
typename... Component,
typename Archive,
typename... Type,
typename... Member>
5229 (reset<Component>(), ...);
5230 (assign<Component>(archive, member...), ...);
5243 auto it = remloc.begin();
5245 while(it != remloc.cend()) {
5246 const auto local = it->second.first;
5247 bool &dirty = it->second.second;
5253 if(reg->
valid(local)) {
5257 it = remloc.erase(it);
5288 return (remloc.find(
entt) != remloc.cend());
5297 const auto it = remloc.find(
entt);
5300 if(it != remloc.cend()) {
5301 other = it->second.first;
5308 std::unordered_map<entity_type, std::pair<entity_type, bool>> remloc;
5316 #endif // ENTT_ENTITY_SNAPSHOT_HPP 5319 #ifndef ENTT_ENTITY_STORAGE_HPP 5320 #define ENTT_ENTITY_STORAGE_HPP 5323 #include <algorithm> 5329 #include <type_traits> 5372 template<
typename Entity,
typename Type,
typename = std::
void_t<>>
5377 template<
bool Const>
5381 using instance_type = std::conditional_t<Const, const std::vector<Type>, std::vector<Type>>;
5382 using index_type =
typename traits_type::difference_type;
5384 iterator(instance_type *ref,
const index_type idx)
ENTT_NOEXCEPT 5385 : instances{ref},
index{idx}
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;
5398 return --
index, *
this;
5402 iterator orig = *
this;
5403 return ++(*this), orig;
5407 return ++
index, *
this;
5411 iterator orig = *
this;
5412 return --(*this), orig;
5415 iterator & operator+=(
const difference_type value)
ENTT_NOEXCEPT {
5420 iterator operator+(
const difference_type value)
const ENTT_NOEXCEPT {
5421 return iterator{instances,
index-value};
5424 iterator & operator-=(
const difference_type value)
ENTT_NOEXCEPT {
5425 return (*
this += -value);
5428 iterator operator-(
const difference_type value)
const ENTT_NOEXCEPT {
5429 return (*
this + -value);
5432 difference_type operator-(
const iterator &other)
const ENTT_NOEXCEPT {
5433 return other.index -
index;
5436 reference operator[](
const difference_type value)
const ENTT_NOEXCEPT {
5438 return (*instances)[pos];
5441 bool operator==(
const iterator &other)
const ENTT_NOEXCEPT {
5442 return other.index ==
index;
5446 return !(*
this == other);
5450 return index > other.index;
5454 return index < other.index;
5457 bool operator<=(
const iterator &other)
const ENTT_NOEXCEPT {
5458 return !(*
this > other);
5461 bool operator>=(
const iterator &other)
const ENTT_NOEXCEPT {
5462 return !(*
this < other);
5467 return &(*instances)[pos];
5471 return *operator->();
5475 instance_type *instances;
5501 instances.reserve(cap);
5507 instances.shrink_to_fit();
5526 return instances.data();
5531 return const_cast<object_type *>(std::as_const(*this).raw());
5608 return const_cast<object_type &>(std::as_const(*this).get(
entt));
5622 return const_cast<object_type *>(std::as_const(*this).try_get(
entt));
5643 template<
typename... Args>
5645 if constexpr(std::is_aggregate_v<object_type>) {
5646 instances.emplace_back(Type{std::forward<Args>(args)...});
5648 instances.emplace_back(std::forward<Args>(args)...);
5653 return instances.back();
5677 template<
typename It,
typename... Args>
5679 if constexpr(
sizeof...(Args) == 0) {
5680 instances.resize(instances.size() + std::distance(first, last));
5682 instances.resize(instances.size() + std::distance(first, last), Type{std::forward<Args>(args)...});
5702 auto other = std::move(instances.back());
5704 instances.pop_back();
5770 template<
typename Compare,
typename Sort =
std_sort,
typename... Args>
5776 const auto to = from + std::distance(first, last);
5778 const auto apply = [
this](
const auto lhs,
const auto rhs) {
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) {
5785 }, std::move(algo), std::forward<Args>(args)...);
5787 underlying_type::arrange(from, to, std::move(apply), std::move(compare), std::move(algo), std::forward<Args>(args)...);
5798 std::vector<object_type> instances;
5803 template<
typename Entity,
typename Type>
5811 using index_type =
typename traits_type::difference_type;
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;
5827 return --
index, *
this;
5831 iterator orig = *
this;
5832 return ++(*this), orig;
5836 return ++
index, *
this;
5840 iterator orig = *
this;
5841 return --(*this), orig;
5844 iterator & operator+=(
const difference_type value)
ENTT_NOEXCEPT {
5849 iterator operator+(
const difference_type value)
const ENTT_NOEXCEPT {
5850 return iterator{
index-value};
5853 iterator & operator-=(
const difference_type value)
ENTT_NOEXCEPT {
5854 return (*
this += -value);
5857 iterator operator-(
const difference_type value)
const ENTT_NOEXCEPT {
5858 return (*
this + -value);
5861 difference_type operator-(
const iterator &other)
const ENTT_NOEXCEPT {
5862 return other.index -
index;
5865 reference operator[](
const difference_type)
const ENTT_NOEXCEPT {
5869 bool operator==(
const iterator &other)
const ENTT_NOEXCEPT {
5870 return other.index ==
index;
5874 return !(*
this == other);
5878 return index > other.index;
5882 return index < other.index;
5885 bool operator<=(
const iterator &other)
const ENTT_NOEXCEPT {
5886 return !(*
this > other);
5889 bool operator>=(
const iterator &other)
const ENTT_NOEXCEPT {
5890 return !(*
this < other);
5998 template<
typename It>
6005 template<
typename Compare,
typename Sort = std_sort,
typename... Args>
6011 const auto to = from + std::distance(first, last);
6018 template<
typename Entity,
typename Type>
6025 #endif // ENTT_ENTITY_STORAGE_HPP 6028 #ifndef ENTT_ENTITY_UTILITY_HPP 6029 #define ENTT_ENTITY_UTILITY_HPP 6043 template<
typename... Type>
6051 template<
typename... Type>
6059 template<
typename... Type>
6067 template<
typename... Type>
6074 #endif // ENTT_ENTITY_UTILITY_HPP 6079 #ifndef ENTT_ENTITY_GROUP_HPP 6080 #define ENTT_ENTITY_GROUP_HPP 6085 #include <type_traits> 6109 template<
typename...>
6152 template<
typename Entity,
typename... Exclude,
typename... Get>
6157 template<
typename Component>
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>({}))...>) {
6190 template<
typename Component>
6192 return std::get<pool_type<Component> *>(pools)->size();
6200 return handler->size();
6209 return handler->capacity();
6214 handler->shrink_to_fit();
6224 template<
typename... Component>
6226 if constexpr(
sizeof...(Component) == 0) {
6227 return handler->empty();
6229 return (
std::get<pool_type<Component> *>(pools)->empty() && ...);
6247 template<
typename Component>
6249 return std::get<pool_type<Component> *>(pools)->raw();
6266 template<
typename Component>
6268 return std::get<pool_type<Component> *>(pools)->data();
6284 return handler->data();
6302 return handler->begin();
6321 return handler->end();
6331 const auto it = handler->find(
entt);
6332 return it != end() && *it ==
entt ? it : end();
6341 return begin()[pos];
6350 return find(
entt) != end();
6370 template<
typename... Component>
6374 if constexpr(
sizeof...(Component) == 1) {
6377 return std::tuple<decltype(get<Component>({}))...>{get<Component>(
entt)...};
6404 template<
typename Func>
6429 template<
typename Func>
6432 traverse(std::move(func), get_type_list{});
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)...);
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)...);
6508 template<
typename Component>
6510 handler->respect(*
std::get<pool_type<Component> *>(pools));
6515 const std::tuple<pool_type<Get> *...> pools;
6566 template<
typename Entity,
typename... Exclude,
typename... Get,
typename... Owned>
6571 template<
typename Component>
6574 template<
typename Component>
6575 using component_iterator_type = decltype(std::declval<pool_type<Component>>().begin());
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...},
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;
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)++)...);
6594 const auto entt = *(data++);
6595 func(*(
std::get<component_iterator_type<Strong>>(it)++)...,
std::get<pool_type<Weak> *>(pools)->
get(
entt)...);
6598 const auto entt = *(data++);
6617 template<
typename Component>
6619 return std::get<pool_type<Component> *>(pools)->size();
6637 template<
typename... Component>
6639 if constexpr(
sizeof...(Component) == 0) {
6642 return (
std::get<pool_type<Component> *>(pools)->empty() && ...);
6663 template<
typename Component>
6665 return std::get<pool_type<Component> *>(pools)->raw();
6685 template<
typename Component>
6687 return std::get<pool_type<Component> *>(pools)->data();
6703 return std::get<0>(pools)->data();
6721 return std::get<0>(pools)->sparse_set<entity_type>::end() - *length;
6740 return std::get<0>(pools)->sparse_set<entity_type>::end();
6750 const auto it = std::get<0>(pools)->find(
entt);
6751 return it != end() && it >= begin() && *it ==
entt ? it : end();
6760 return begin()[pos];
6769 return find(
entt) != end();
6789 template<
typename... Component>
6793 if constexpr(
sizeof...(Component) == 1) {
6796 return std::tuple<decltype(get<Component>({}))...>{get<Component>(
entt)...};
6823 template<
typename Func>
6848 template<
typename Func>
6852 traverse(std::move(func), owned_type_list{}, get_type_list{});
6860 constexpr
auto size =
sizeof...(Owned) +
sizeof...(Get) +
sizeof...(Exclude);
6861 return *super == size;
6906 template<
typename... Component,
typename Compare,
typename Sort =
std_sort,
typename... Args>
6907 void sort(Compare compare, Sort algo = Sort{}, Args &&... args) {
6909 auto *cpool = std::get<0>(pools);
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)...);
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)...);
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), ...);
6930 }(std::get<pool_type<Owned> *>(pools)...);
6934 const std::tuple<pool_type<Owned> *..., pool_type<Get> *...> pools;
6935 const size_type *length;
6936 const size_type *super;
6943 #endif // ENTT_ENTITY_GROUP_HPP 6946 #ifndef ENTT_ENTITY_VIEW_HPP 6947 #define ENTT_ENTITY_VIEW_HPP 6954 #include <algorithm> 6955 #include <type_traits> 6981 template<
typename...>
7022 template<
typename Entity,
typename... Exclude,
typename... Component>
7027 template<
typename Comp>
7030 template<
typename Comp>
7031 using component_iterator_type = decltype(std::declval<pool_type<Comp>>().begin());
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)>;
7040 iterator(underlying_iterator_type first, underlying_iterator_type last, unchecked_type other, filter_type ignore)
ENTT_NOEXCEPT 7046 if(begin != end && !valid()) {
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); });
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;
7066 return (++begin != end && !valid()) ? ++(*this) : *
this;
7070 iterator orig = *
this;
7071 return ++(*this), orig;
7074 bool operator==(
const iterator &other)
const ENTT_NOEXCEPT {
7075 return other.begin == begin;
7079 return !(*
this == other);
7083 return begin.operator->();
7087 return *operator->();
7091 underlying_iterator_type begin;
7092 underlying_iterator_type end;
7093 unchecked_type unchecked;
7098 basic_view(storage<Entity, std::remove_const_t<Component>> *... component, storage<Entity, std::remove_const_t<Exclude>> *... epool)
ENTT_NOEXCEPT 7099 : pools{component...},
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();
7111 unchecked_type other{};
7112 ((std::get<pool_type<Component> *>(pools) ==
view ?
nullptr : (other[pos++] =
std::get<pool_type<Component> *>(pools))), ...);
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>) {
7121 return cpool->get(
entt);
7125 template<
typename Comp,
typename Func,
typename... Other,
typename... Type>
7126 void traverse(Func func, type_list<Other...>, type_list<Type...>)
const {
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 {
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)...);
7138 func(entity, get<Comp, Type>(curr,
std::get<pool_type<Type> *>(pools), entity)...);
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)...);
7148 func(entity,
std::get<pool_type<Type> *>(pools)->
get(entity)...);
7171 template<
typename Comp>
7173 return std::get<pool_type<Comp> *>(pools)->size();
7181 return std::min({ std::get<pool_type<Component> *>(pools)->size()... });
7196 template<
typename... Comp>
7198 if constexpr(
sizeof...(Comp) == 0) {
7199 return (
std::get<pool_type<Component> *>(pools)->empty() || ...);
7201 return (
std::get<pool_type<Comp> *>(pools)->empty() && ...);
7219 template<
typename Comp>
7221 return std::get<pool_type<Comp> *>(pools)->raw();
7238 template<
typename Comp>
7240 return std::get<pool_type<Comp> *>(pools)->data();
7258 const auto *
view = candidate();
7259 const filter_type ignore{std::get<pool_type<Exclude> *>(filter)...};
7279 const auto *
view = candidate();
7280 const filter_type ignore{std::get<pool_type<Exclude> *>(filter)...};
7291 const auto *
view = candidate();
7292 const filter_type ignore{std::get<pool_type<Exclude> *>(filter)...};
7294 return (it != end() && *it ==
entt) ? it : end();
7303 return find(
entt) != end();
7323 template<
typename... Comp>
7327 if constexpr(
sizeof...(Comp) == 0) {
7328 static_assert(
sizeof...(Component) == 1);
7330 }
else if constexpr(
sizeof...(Comp) == 1) {
7333 return std::tuple<decltype(get<Comp>({}))...>{get<Comp>(
entt)...};
7360 template<
typename Func>
7362 const auto *
view = candidate();
7363 ((std::get<pool_type<Component> *>(pools) ==
view ? each<Component>(std::move(func)) :
void()), ...);
7396 template<
typename Comp,
typename Func>
7399 traverse<Comp>(std::move(func), other_type{},
type_list<Component...>{});
7422 template<
typename Func>
7424 const auto *
view = candidate();
7425 ((std::get<pool_type<Component> *>(pools) ==
view ? less<Component>(std::move(func)) :
void()), ...);
7455 template<
typename Comp,
typename Func>
7459 traverse<Comp>(std::move(func), other_type{}, non_empty_type{});
7463 const std::tuple<pool_type<Component> *...> pools;
7464 const std::tuple<pool_type<Exclude> *...> filter;
7501 template<
typename Entity,
typename Component>
7527 return pool->size();
7535 return pool->empty();
7567 return pool->data();
7585 return pool->sparse_set<Entity>::begin();
7604 return pool->sparse_set<Entity>::end();
7614 const auto it = pool->find(
entt);
7615 return it != end() && *it ==
entt ? it : end();
7624 return begin()[pos];
7633 return find(
entt) != end();
7651 template<
typename Comp = Component>
7653 static_assert(std::is_same_v<Comp, Component>);
7655 return pool->get(
entt);
7681 template<
typename Func>
7683 if constexpr(std::is_invocable_v<Func, decltype(
get({}))>) {
7684 std::for_each(pool->begin(), pool->end(), std::move(func));
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++));
7720 template<
typename Func>
7723 if constexpr(std::is_invocable_v<Func>) {
7724 for(
auto pos = pool->size(); pos; --pos) {
7728 std::for_each(pool->sparse_set<Entity>::begin(), pool->sparse_set<Entity>::end(), std::move(func));
7731 each(std::move(func));
7743 #endif // ENTT_ENTITY_VIEW_HPP 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>>;
7768 template<
typename Component>
7769 struct pool_handler: storage<Entity, Component> {
7770 std::size_t super{};
7772 template<
typename... Args>
7773 pool_handler(Args &&... args)
7774 : storage<Entity, Component>{std::forward<Args>(args)...},
7779 return sink{construction};
7783 return sink{update};
7787 return sink{destruction};
7790 template<
typename... Args>
7794 construction.publish(
entt, owner, Component{});
7795 return Component{std::forward<Args>(args)...};
7798 construction.publish(
entt, owner, component);
7803 template<
typename It,
typename... Args>
7807 if(!construction.empty()) {
7808 std::for_each(first, last, [
this, &owner, it](
const auto entt)
mutable {
7809 construction.publish(
entt, owner, *(it++));
7817 destruction.publish(
entt, owner);
7821 template<
typename... Args>
7825 update.publish(
entt, owner, Component{});
7826 return Component{std::forward<Args>(args)...};
7828 Component component{std::forward<Args>(args)...};
7829 update.publish(
entt, owner, component);
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{};
7841 template<
typename Component>
7842 using pool_type = pool_handler<std::decay_t<Component>>;
7844 template<
typename...>
7845 struct group_handler;
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{};
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)) && ...)
7861 }
else if constexpr(std::disjunction_v<std::is_same<Exclude, Component>...>) {
7863 && ((std::is_same_v<Exclude, Component> || !
std::get<pool_type<Exclude> *>(cpools)->
has(
entt)) && ...)
7871 void discard_if(
const Entity
entt) {
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{};
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)) && ...)
7889 && !(std::get<0>(cpools)->index(
entt) < owned))
7891 const auto pos = owned++;
7892 (std::get<pool_type<Owned> *>(cpools)->
swap(
std::get<pool_type<Owned> *>(cpools)->data()[pos],
entt), ...);
7894 }
else if constexpr(std::disjunction_v<std::is_same<Exclude, Component>...>) {
7897 && ((std::is_same_v<Exclude, Component> || !
std::get<pool_type<Exclude> *>(cpools)->
has(
entt)) && ...)
7898 && !(std::get<0>(cpools)->index(
entt) < owned))
7900 const auto pos = owned++;
7901 (std::get<pool_type<Owned> *>(cpools)->
swap(
std::get<pool_type<Owned> *>(cpools)->data()[pos],
entt), ...);
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), ...);
7915 std::unique_ptr<sparse_set<Entity>> pool;
7917 std::unique_ptr<sparse_set<Entity>>(* clone)(
const sparse_set<Entity> &);
7923 std::size_t extent[3];
7924 std::unique_ptr<void, void(*)(
void *)>
group;
7930 struct ctx_variable {
7931 std::unique_ptr<void, void(*)(
void *)> value;
7935 template<
typename Type,
typename Family>
7937 if constexpr(is_named_type_v<Type>) {
7938 return named_type_traits_v<Type>;
7940 return Family::template type<std::decay_t<Type>>;
7947 if(destroyed ==
null) {
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};
7956 entities[curr] =
entt;
7962 void release(
const Entity
entity) {
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};
7971 template<
typename Component>
7972 const pool_type<Component> * assure()
const {
7973 const auto ctype = to_integer(type<Component>());
7974 pool_data *pdata =
nullptr;
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;
7981 pdata = (it == pools.cend() ? &pools.emplace_back() : &(*it));
7983 if(!(ctype < skip_family_pools)) {
7984 pools.reserve(pools.size()+ctype-skip_family_pools+1);
7986 while(!(ctype < skip_family_pools)) {
7987 pools.emplace(pools.begin()+(skip_family_pools++), pool_data{});
7991 pdata = &pools[ctype];
7995 pdata->runtime_type = ctype;
7996 pdata->pool = std::make_unique<pool_type<Component>>();
7998 pdata->remove = [](sparse_set<Entity> &cpool,
basic_registry &owner,
const Entity
entt) {
7999 static_cast<pool_type<Component> &
>(cpool).
remove(owner,
entt);
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));
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));
8011 pdata->clone =
nullptr;
8012 pdata->stomp =
nullptr;
8016 return static_cast<pool_type<Component> *
>(pdata->pool.get());
8019 template<
typename Component>
8020 pool_type<Component> * assure() {
8021 return const_cast<pool_type<Component> *
>(std::as_const(*this).template assure<Component>());
8050 template<typename Component>
8052 return component{runtime_type<Component, component_family>()};
8059 template<
typename... Component>
8061 (assure<Component>(), ...);
8069 template<
typename Component>
8071 return assure<Component>()->size();
8079 return entities.size();
8087 auto sz = entities.size();
8088 auto curr = destroyed;
8090 for(; curr !=
null; --sz) {
8091 curr = entities[to_integer(curr) & traits_type::entity_mask];
8110 template<
typename... Component>
8112 if constexpr(
sizeof...(Component) == 0) {
8113 entities.reserve(cap);
8115 (assure<Component>()->reserve(cap), ...);
8124 template<
typename Component>
8126 return assure<Component>()->capacity();
8135 return entities.capacity();
8143 template<
typename... Component>
8145 (assure<Component>()->shrink_to_fit(), ...);
8159 template<
typename... Component>
8161 if constexpr(
sizeof...(Component) == 0) {
8164 return (assure<Component>()->
empty() && ...);
8185 template<
typename Component>
8187 return assure<Component>()->raw();
8191 template<
typename Component>
8193 return const_cast<Component *>(std::as_const(*this).template raw<Component>());
8209 template<
typename Component>
8211 return assure<Component>()->data();
8220 const auto pos =
size_type(to_integer(
entity) & traits_type::entity_mask);
8221 return (pos < entities.size() && entities[pos] ==
entity);
8256 const auto pos =
size_type(to_integer(
entity) & traits_type::entity_mask);
8258 return version_type(to_integer(entities[pos]) >> traits_type::entity_shift);
8283 template<
typename... Component>
8285 if constexpr(
sizeof...(Component) == 0) {
8289 return std::tuple<entity_type, decltype(assign<Component>({}))...>{
entt, assign<Component>(
entt)...};
8309 template<
typename... Component,
typename It>
8311 std::generate(first, last, [
this]() {
return generate(); });
8313 if constexpr(
sizeof...(Component) > 0) {
8315 return std::make_tuple(assure<Component>()->batch(*
this, std::make_reverse_iterator(last), std::make_reverse_iterator(first))...);
8338 template<
typename... Component,
typename... Exclude>
8367 template<
typename... Component,
typename It,
typename... Exclude>
8371 if constexpr(
sizeof...(Component) == 0) {
8372 stomp<Component...>(first, last, src, other,
exclude<Exclude...>);
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)), ...);
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);
8424 template<
typename It>
8450 template<
typename Component,
typename... Args>
8453 return assure<Component>()->assign(*
this,
entity, std::forward<Args>(args)...);
8469 template<
typename Component>
8472 assure<Component>()->remove(*
this,
entity);
8487 template<
typename... Component>
8490 return (assure<Component>()->
has(
entity) && ...);
8507 template<
typename... Component>
8511 if constexpr(
sizeof...(Component) == 1) {
8512 return (assure<Component>()->
get(
entity), ...);
8514 return std::tuple<decltype(get<Component>({}))...>{get<Component>(
entity)...};
8519 template<
typename... Component>
8523 if constexpr(
sizeof...(Component) == 1) {
8524 return (assure<Component>()->
get(
entity), ...);
8526 return std::tuple<decltype(get<Component>({}))...>{get<Component>(
entity)...};
8554 template<
typename Component,
typename... Args>
8557 auto *cpool = assure<Component>();
8558 return cpool->has(
entity) ? cpool->get(
entity) : cpool->assign(*
this,
entity, std::forward<Args>(args)...);
8573 template<
typename... Component>
8577 if constexpr(
sizeof...(Component) == 1) {
8580 return std::tuple<decltype(try_get<Component>({}))...>{try_get<Component>(
entity)...};
8585 template<
typename... Component>
8587 if constexpr(
sizeof...(Component) == 1) {
8590 return std::tuple<decltype(try_get<Component>({}))...>{try_get<Component>(
entity)...};
8614 template<
typename Component,
typename... Args>
8617 return assure<Component>()->replace(*
this,
entity, std::forward<Args>(args)...);
8642 template<
typename Component,
typename... 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)...);
8676 template<
typename Component>
8678 return assure<Component>()->on_construct();
8707 template<
typename Component>
8709 return assure<Component>()->on_replace();
8739 template<
typename Component>
8741 return assure<Component>()->on_destroy();
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>();
8795 cpool->sort(cpool->begin(), cpool->end(), std::move(compare), std::move(algo), std::forward<Args>(args)...);
8833 template<
typename To,
typename From>
8835 auto *cpool = assure<To>();
8837 cpool->respect(*assure<From>());
8854 template<
typename Component>
8858 if(
auto *cpool = assure<Component>(); cpool->has(
entity)) {
8859 cpool->remove(*
this,
entity);
8871 template<
typename Component>
8873 if(
auto *cpool = assure<Component>(); cpool->on_destroy().empty()) {
8878 cpool->remove(*
this,
entity);
8915 template<
typename Func>
8917 static_assert(std::is_invocable_v<Func, entity_type>);
8919 if(destroyed ==
null) {
8920 for(
auto pos = entities.size(); pos; --pos) {
8921 func(entities[pos-1]);
8924 for(
auto pos = entities.size(); pos; --pos) {
8926 const auto entity = entities[to_integer(curr)];
8945 for(std::size_t pos{}, last = pools.size(); pos < last &&
orphan; ++pos) {
8946 const auto &pdata = pools[pos];
8969 template<
typename Func>
8971 static_assert(std::is_invocable_v<Func, entity_type>);
9012 template<
typename... Component,
typename... Exclude>
9014 static_assert(
sizeof...(Component) > 0);
9015 return { assure<Component>()..., assure<Exclude>()... };
9019 template<
typename... Component,
typename... Exclude>
9021 static_assert(std::conjunction_v<std::is_const<Component>...>);
9022 return const_cast<basic_registry *>(
this)->view<Component...>(
exclude<Exclude...>);
9031 template<
typename... Component>
9033 return !(assure<Component>()->super || ...);
9063 template<
typename... Owned,
typename... Get,
typename... Exclude>
9065 static_assert(
sizeof...(Owned) +
sizeof...(Get) > 0);
9066 static_assert(
sizeof...(Owned) +
sizeof...(Get) +
sizeof...(Exclude) > 1);
9068 using handler_type = group_handler<
exclude_t<Exclude...>,
get_t<Get...>, Owned...>;
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;
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())
9082 handler = static_cast<handler_type *>(it->group.get());
9086 const void *maybe_valid_if =
nullptr;
9087 const void *discard_if =
nullptr;
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>()) || ...); }
9097 if constexpr(
sizeof...(Owned) == 0) {
9098 handler = static_cast<handler_type *>(groups.emplace_back(std::move(gdata)).group.get());
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)));
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]));
9110 const auto prev = std::find_if(std::make_reverse_iterator(next), groups.crend(), [](
const auto &curr) {
9111 return (0u + ... + curr.owned(type<Owned>()));
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());
9119 ((std::get<pool_type<Owned> *>(cpools)->super = std::max(
std::get<pool_type<Owned> *>(cpools)->super,
size)), ...);
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), ...);
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), ...);
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();
9137 std::for_each(cpool->data(), cpool->data() + cpool->size(), [cpools, handler](
const auto entity) {
9139 && (std::get<pool_type<Get> *>(cpools)->
has(
entity) && ...)
9140 && !(std::get<pool_type<Exclude> *>(cpools)->
has(
entity) || ...))
9142 if constexpr(
sizeof...(Owned) == 0) {
9143 handler->set.construct(
entity);
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), ...);
9154 if constexpr(
sizeof...(Owned) == 0) {
9155 return { &handler->set, std::get<pool_type<Get> *>(cpools)... };
9157 return { &std::get<0>(cpools)->super, &handler->owned, std::get<pool_type<Owned> *>(cpools)... ,
std::get<pool_type<Get> *>(cpools)... };
9171 template<
typename... Owned,
typename... Get,
typename... Exclude>
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...>);
9186 template<
typename... Owned,
typename... Exclude>
9188 return group<Owned...>(entt::get<>,
exclude<Exclude...>);
9200 template<
typename... Owned,
typename... Exclude>
9202 static_assert(std::conjunction_v<std::is_const<Owned>...>);
9203 return const_cast<basic_registry *>(
this)->group<Owned...>(
exclude<Exclude...>);
9226 template<
typename It>
9228 std::vector<const sparse_set<Entity> *> selected(std::distance(first, last));
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;
9235 return it != pools.cend() && it->pool ? it->pool.get() :
nullptr;
9238 return { std::move(selected) };
9274 template<
typename... Component,
typename... Exclude>
9276 static_assert(std::conjunction_v<std::is_copy_constructible<Component>...>);
9279 other.pools.resize(pools.size());
9281 for(
auto pos = pools.size(); pos; --pos) {
9282 const auto &pdata = pools[pos-1];
9283 ENTT_ASSERT(!
sizeof...(Component) || !pdata.pool || pdata.clone);
9285 if(pdata.pool && pdata.clone
9286 && (!
sizeof...(Component) || ... || (pdata.runtime_type == to_integer(type<Component>())))
9287 && ((pdata.runtime_type != to_integer(type<Exclude>())) && ...))
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;
9298 other.skip_family_pools = skip_family_pools;
9299 other.destroyed = destroyed;
9300 other.entities = entities;
9302 other.pools.erase(std::remove_if(other.pools.begin()+skip_family_pools, other.pools.end(), [](
const auto &pdata) {
9304 }), other.pools.end());
9339 template<
typename... Component,
typename... Exclude>
9358 template<
typename... Component,
typename It,
typename... Exclude>
9360 static_assert(
sizeof...(Component) == 0 ||
sizeof...(Exclude) == 0);
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);
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))
9371 std::for_each(first, last, [
this, &pdata, src](
const auto entity) {
9372 pdata.stomp(*pdata.pool, src, *
this,
entity);
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))};
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))};
9401 return {
this, seed, follow };
9423 const auto entt = to_integer(
entity) & traits_type::entity_mask;
9424 auto &others = reg.entities;
9426 if(!(
entt < others.size())) {
9427 auto curr = others.size();
9428 others.resize(
entt + 1);
9430 std::generate(others.data() + curr, others.data() +
entt, [curr]()
mutable {
9439 const auto version = to_integer(
entity) & (traits_type::version_mask << traits_type::entity_shift);
9448 return {
this, force };
9462 template<
typename Type,
typename... 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;
9469 if(it == vars.cend()) {
9471 decltype(ctx_variable::value){
new Type{std::forward<Args>(args)...}, [](
void *ptr) {
delete static_cast<Type *>(ptr); }},
9475 it = std::prev(vars.end());
9477 it->value.reset(
new Type{std::forward<Args>(args)...});
9480 return *static_cast<Type *>(it->value.get());
9487 template<
typename Type>
9489 vars.erase(std::remove_if(vars.begin(), vars.end(), [](
auto &var) {
9490 return var.runtime_type == runtime_type<Type, context_family>();
9505 template<
typename Type,
typename... Args>
9507 auto *value = try_ctx<Type>();
9508 return value ? *value : set<Type>(std::forward<Args>(args)...);
9517 template<
typename Type>
9519 const auto it = std::find_if(vars.begin(), vars.end(), [](
const auto &var) {
9520 return var.runtime_type == runtime_type<Type, context_family>();
9523 return (it == vars.cend()) ?
nullptr : static_cast<const Type *>(it->value.get());
9527 template<
typename Type>
9529 return const_cast<Type *>(std::as_const(*this).template try_ctx<Type>());
9544 template<
typename Type>
9546 const auto *instance = try_ctx<Type>();
9552 template<
typename Type>
9554 return const_cast<Type &>(std::as_const(*this).template ctx<Type>());
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{};
9570 #endif // ENTT_ENTITY_REGISTRY_HPP 9591 template<
typename Entity>
9592 struct basic_actor {
9638 :
entt{other.entt}, reg{other.reg}
9654 if(
this != &other) {
9655 auto tmp{std::move(other)};
9677 template<
typename Component,
typename... Args>
9679 return reg->template assign_or_replace<Component>(
entt, std::forward<Args>(args)...);
9686 template<
typename Component>
9688 reg->template remove<Component>(
entt);
9696 template<
typename... Component>
9698 return (reg->template has<Component>(
entt) && ...);
9706 template<
typename... Component>
9708 return std::as_const(*reg).template get<Component...>(
entt);
9712 template<
typename... Component>
9714 return reg->template
get<Component...>(
entt);
9722 template<
typename... Component>
9724 return std::as_const(*reg).template try_get<Component...>(
entt);
9728 template<
typename... Component>
9743 return const_cast<registry_type &>(std::as_const(*this).backend());
9771 #endif // ENTT_ENTITY_ACTOR_HPP 9778 #ifndef ENTT_ENTITY_HELPER_HPP 9779 #define ENTT_ENTITY_HELPER_HPP 9782 #include <type_traits> 9799 template<
bool Const,
typename Entity>
9816 template<
typename Exclude,
typename... Component>
9818 return reg.template
view<Component...>(Exclude{});
9834 template<
typename Entity>
9839 template<
typename Entity>
9848 template<
bool Const,
typename Entity>
9866 template<
typename Exclude,
typename Get,
typename... Owned>
9868 return reg.template
group<Owned...>(Get{}, Exclude{});
9884 template<
typename Entity>
9889 template<
typename Entity>
9912 template<ENTT_ID_TYPE Value>
9913 using tag = std::integral_constant<ENTT_ID_TYPE, Value>;
9919 #endif // ENTT_ENTITY_HELPER_HPP 9922 #ifndef ENTT_ENTITY_OBSERVER_HPP 9923 #define ENTT_ENTITY_OBSERVER_HPP 9930 #include <algorithm> 9931 #include <type_traits> 9950 template<
typename...>
9960 template<
typename...>
9980 template<
typename... AllOf,
typename... NoneOf>
9990 template<
typename AnyOf>
10004 template<
typename... Reject,
typename... Require,
typename... Rule,
typename... Other>
10015 template<
typename... AllOf,
typename... NoneOf>
10025 template<
typename AnyOf>
10036 template<
typename... AllOf,
typename... NoneOf>
10097 template<
typename Entity>
10098 class basic_observer {
10099 using payload_type = std::uint32_t;
10102 struct matcher_handler;
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> ®) {
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);
10114 template<std::
size_t Index>
10116 if(
auto *value = obs.view.try_get(
entt); value && !(*value &= (~(1 << Index)))) {
10117 obs.view.destroy(
entt);
10121 template<std::
size_t Index>
10122 static void connect(
basic_observer &obs, basic_registry<Entity> ®) {
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);
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);
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> ®) {
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);
10147 template<std::
size_t Index>
10149 if(
auto *value = obs.view.try_get(
entt); value && !(*value &= (~(1 << Index)))) {
10150 obs.view.destroy(
entt);
10154 template<std::
size_t Index>
10155 static void connect(
basic_observer &obs, basic_registry<Entity> ®) {
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), ...);
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), ...);
10174 template<
typename... Matcher>
10176 (matcher_handler<Matcher>::disconnect(obs, reg), ...);
10179 template<
typename... Matcher, std::size_t... Index>
10180 void connect(basic_registry<Entity> ®, std::index_sequence<Index...>) {
10181 static_assert(
sizeof...(Matcher) < std::numeric_limits<payload_type>::digits);
10182 (matcher_handler<Matcher>::template connect<Index>(*
this, reg), ...);
10196 : target{}, release{}, view{}
10209 template<
typename... Matcher>
10215 connect<Matcher...>(reg, std::index_sequence_for<Matcher...>{});
10238 template<
typename... Matcher>
10241 connect<Matcher...>(reg, std::index_sequence_for<Matcher...>{});
10249 release(*
this, *target);
10259 return view.size();
10267 return view.empty();
10283 return view.data();
10295 return view.sparse_set<entity_type>::begin();
10309 return view.sparse_set<entity_type>::end();
10331 template<
typename Func>
10333 static_assert(std::is_invocable_v<Func, entity_type>);
10334 std::for_each(
begin(),
end(), std::move(func));
10351 template<
typename Func>
10353 std::as_const(*this).each(std::move(func));
10367 #endif // ENTT_ENTITY_OBSERVER_HPP 10384 #ifndef ENTT_LOCATOR_LOCATOR_HPP 10385 #define ENTT_LOCATOR_LOCATOR_HPP 10391 #ifndef ENTT_CONFIG_CONFIG_H 10392 #define ENTT_CONFIG_CONFIG_H 10395 #ifndef ENTT_NOEXCEPT 10396 #define ENTT_NOEXCEPT noexcept 10397 #endif // ENTT_NOEXCEPT 10400 #ifndef ENTT_HS_SUFFIX 10401 #define ENTT_HS_SUFFIX _hs 10402 #endif // ENTT_HS_SUFFIX 10405 #ifndef ENTT_HWS_SUFFIX 10406 #define ENTT_HWS_SUFFIX _hws 10407 #endif // ENTT_HWS_SUFFIX 10410 #ifndef ENTT_NO_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 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 10423 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 10424 #endif // ENTT_DISABLE_ETO 10427 #ifndef ENTT_ID_TYPE 10429 #define ENTT_ID_TYPE std::uint32_t 10430 #endif // ENTT_ID_TYPE 10433 #ifndef ENTT_PAGE_SIZE 10434 #define ENTT_PAGE_SIZE 32768 10435 #endif // ENTT_PAGE_SIZE 10438 #ifndef ENTT_DISABLE_ASSERT 10440 #define ENTT_ASSERT(condition) assert(condition) 10441 #else // ENTT_DISABLE_ASSERT 10442 #define ENTT_ASSERT(...) ((void)0) 10443 #endif // ENTT_DISABLE_ASSERT 10446 #endif // ENTT_CONFIG_CONFIG_H 10464 template<
typename Service>
10479 return !static_cast<bool>(service);
10520 template<
typename Impl = Service,
typename... Args>
10521 static void set(Args &&... args) {
10522 service = std::make_shared<Impl>(std::forward<Args>(args)...);
10529 static void set(std::shared_ptr<Service> ptr) {
10531 service = std::move(ptr);
10544 inline static std::shared_ptr<Service> service =
nullptr;
10551 #endif // ENTT_LOCATOR_LOCATOR_HPP 10554 #ifndef ENTT_META_FACTORY_HPP 10555 #define ENTT_META_FACTORY_HPP 10562 #include <functional> 10563 #include <type_traits> 10565 #ifndef ENTT_CONFIG_CONFIG_H 10566 #define ENTT_CONFIG_CONFIG_H 10569 #ifndef ENTT_NOEXCEPT 10570 #define ENTT_NOEXCEPT noexcept 10571 #endif // ENTT_NOEXCEPT 10574 #ifndef ENTT_HS_SUFFIX 10575 #define ENTT_HS_SUFFIX _hs 10576 #endif // ENTT_HS_SUFFIX 10579 #ifndef ENTT_HWS_SUFFIX 10580 #define ENTT_HWS_SUFFIX _hws 10581 #endif // ENTT_HWS_SUFFIX 10584 #ifndef ENTT_NO_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 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 10597 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 10598 #endif // ENTT_DISABLE_ETO 10601 #ifndef ENTT_ID_TYPE 10603 #define ENTT_ID_TYPE std::uint32_t 10604 #endif // ENTT_ID_TYPE 10607 #ifndef ENTT_PAGE_SIZE 10608 #define ENTT_PAGE_SIZE 32768 10609 #endif // ENTT_PAGE_SIZE 10612 #ifndef ENTT_DISABLE_ASSERT 10614 #define ENTT_ASSERT(condition) assert(condition) 10615 #else // ENTT_DISABLE_ASSERT 10616 #define ENTT_ASSERT(...) ((void)0) 10617 #endif // ENTT_DISABLE_ASSERT 10620 #endif // ENTT_CONFIG_CONFIG_H 10623 #ifndef ENTT_CORE_TYPE_TRAITS_HPP 10624 #define ENTT_CORE_TYPE_TRAITS_HPP 10628 #include <type_traits> 10630 #ifndef ENTT_CONFIG_CONFIG_H 10631 #define ENTT_CONFIG_CONFIG_H 10634 #ifndef ENTT_NOEXCEPT 10635 #define ENTT_NOEXCEPT noexcept 10636 #endif // ENTT_NOEXCEPT 10639 #ifndef ENTT_HS_SUFFIX 10640 #define ENTT_HS_SUFFIX _hs 10641 #endif // ENTT_HS_SUFFIX 10644 #ifndef ENTT_HWS_SUFFIX 10645 #define ENTT_HWS_SUFFIX _hws 10646 #endif // ENTT_HWS_SUFFIX 10649 #ifndef ENTT_NO_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 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 10662 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 10663 #endif // ENTT_DISABLE_ETO 10666 #ifndef ENTT_ID_TYPE 10668 #define ENTT_ID_TYPE std::uint32_t 10669 #endif // ENTT_ID_TYPE 10672 #ifndef ENTT_PAGE_SIZE 10673 #define ENTT_PAGE_SIZE 32768 10674 #endif // ENTT_PAGE_SIZE 10677 #ifndef ENTT_DISABLE_ASSERT 10679 #define ENTT_ASSERT(condition) assert(condition) 10680 #else // ENTT_DISABLE_ASSERT 10681 #define ENTT_ASSERT(...) ((void)0) 10682 #endif // ENTT_DISABLE_ASSERT 10685 #endif // ENTT_CONFIG_CONFIG_H 10688 #ifndef ENTT_CORE_HASHED_STRING_HPP 10689 #define ENTT_CORE_HASHED_STRING_HPP 10694 #ifndef ENTT_CONFIG_CONFIG_H 10695 #define ENTT_CONFIG_CONFIG_H 10698 #ifndef ENTT_NOEXCEPT 10699 #define ENTT_NOEXCEPT noexcept 10700 #endif // ENTT_NOEXCEPT 10703 #ifndef ENTT_HS_SUFFIX 10704 #define ENTT_HS_SUFFIX _hs 10705 #endif // ENTT_HS_SUFFIX 10708 #ifndef ENTT_HWS_SUFFIX 10709 #define ENTT_HWS_SUFFIX _hws 10710 #endif // ENTT_HWS_SUFFIX 10713 #ifndef ENTT_NO_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 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 10726 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 10727 #endif // ENTT_DISABLE_ETO 10730 #ifndef ENTT_ID_TYPE 10732 #define ENTT_ID_TYPE std::uint32_t 10733 #endif // ENTT_ID_TYPE 10736 #ifndef ENTT_PAGE_SIZE 10737 #define ENTT_PAGE_SIZE 32768 10738 #endif // ENTT_PAGE_SIZE 10741 #ifndef ENTT_DISABLE_ASSERT 10743 #define ENTT_ASSERT(condition) assert(condition) 10744 #else // ENTT_DISABLE_ASSERT 10745 #define ENTT_ASSERT(...) ((void)0) 10746 #endif // ENTT_DISABLE_ASSERT 10749 #endif // ENTT_CONFIG_CONFIG_H 10762 namespace internal {
10766 struct fnv1a_traits;
10770 struct fnv1a_traits<
std::uint32_t> {
10771 static constexpr std::uint32_t offset = 2166136261;
10772 static constexpr std::uint32_t prime = 16777619;
10777 struct fnv1a_traits<
std::uint64_t> {
10778 static constexpr std::uint64_t offset = 14695981039346656037ull;
10779 static constexpr std::uint64_t prime = 1099511628211ull;
10803 template<
typename Char>
10805 using traits_type = internal::fnv1a_traits<ENTT_ID_TYPE>;
10807 struct const_wrapper {
10809 constexpr const_wrapper(
const Char *curr)
ENTT_NOEXCEPT: str{curr} {}
10815 return curr[0] == 0 ? partial : helper((partial^curr[0])*traits_type::prime, curr+1);
10839 template<std::
size_t N>
10841 return helper(traits_type::offset, str);
10850 return helper(traits_type::offset, wrapper.str);
10861 while(size--) { partial = (partial^(str++)[0])*traits_type::prime; }
10867 : str{
nullptr}, hash{}
10884 template<std::
size_t N>
10886 : str{curr}, hash{helper(traits_type::offset, curr)}
10895 : str{wrapper.str}, hash{helper(traits_type::offset, wrapper.str)}
10929 return hash == other.hash;
10948 template<
typename Char, std::
size_t N>
10950 -> basic_hashed_string<Char>;
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);
10997 #endif // ENTT_CORE_HASHED_STRING_HPP 11008 template<std::
size_t N>
11019 struct choice_t<0> {};
11026 template<std::
size_t N>
11027 constexpr choice_t<N>
choice{};
11031 template<
typename...>
11032 struct type_list {};
11037 struct type_list_size;
11044 template<
typename... Type>
11045 struct type_list_size<type_list<Type...>>
11046 : std::integral_constant<std::size_t, sizeof...(Type)>
11054 template<
class List>
11059 template<
typename...>
11060 struct type_list_cat;
11065 struct type_list_cat<> {
11067 using type = type_list<>;
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;
11088 template<
typename... Type>
11089 struct type_list_cat<type_list<Type...>> {
11091 using type = type_list<Type...>;
11099 template<
typename... List>
11105 struct type_list_unique;
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>
11126 struct type_list_unique<type_list<>> {
11128 using type = type_list<>;
11136 template<
typename Type>
11145 template<
typename Type,
typename = std::
void_t<>>
11146 struct is_equality_comparable: std::false_type {};
11150 template<
typename Type>
11151 struct is_equality_comparable<Type,
std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>: std::true_type {};
11158 template<
class Type>
11164 struct named_type_traits;
11171 template<
typename Type>
11172 struct named_type_traits<const Type>
11173 : named_type_traits<Type>
11181 template<
typename Type>
11189 template<
class Type>
11198 template<
typename Type,
typename = std::
void_t<>>
11199 struct is_named_type: std::false_type {};
11203 template<
typename Type>
11204 struct is_named_type<Type,
std::void_t<named_type_traits_t<std::decay_t<Type>>>>: std::true_type {};
11211 template<
class Type>
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);\ 11226 static_assert(true) 11239 #define ENTT_EXPAND(args) args 11259 #define ENTT_NAMED_TYPE(type)\ 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}>\ 11264 static_assert(std::is_same_v<std::remove_cv_t<type>, type>);\ 11265 static_assert(std::is_object_v<type>);\ 11274 #define ENTT_NAMED_STRUCT_ONLY(clazz, body)\ 11275 struct clazz body;\ 11276 ENTT_NAMED_TYPE(clazz) 11285 #define ENTT_NAMED_STRUCT_WITH_NAMESPACE(ns, clazz, body)\ 11286 namespace ns { struct clazz body; }\ 11287 ENTT_NAMED_TYPE(ns::clazz) 11291 #define ENTT_NAMED_STRUCT_OVERLOAD(_1, _2, _3, FUNC, ...) FUNC 11293 #define ENTT_NAMED_STRUCT(...) ENTT_EXPAND(ENTT_NAMED_STRUCT_OVERLOAD(__VA_ARGS__, ENTT_NAMED_STRUCT_WITH_NAMESPACE, ENTT_NAMED_STRUCT_ONLY,)(__VA_ARGS__)) 11301 #define ENTT_NAMED_CLASS_ONLY(clazz, body)\ 11303 ENTT_NAMED_TYPE(clazz) 11312 #define ENTT_NAMED_CLASS_WITH_NAMESPACE(ns, clazz, body)\ 11313 namespace ns { class clazz body; }\ 11314 ENTT_NAMED_TYPE(ns::clazz) 11318 #define ENTT_NAMED_CLASS_MACRO(_1, _2, _3, FUNC, ...) FUNC 11320 #define ENTT_NAMED_CLASS(...) ENTT_EXPAND(ENTT_NAMED_CLASS_MACRO(__VA_ARGS__, ENTT_NAMED_CLASS_WITH_NAMESPACE, ENTT_NAMED_CLASS_ONLY,)(__VA_ARGS__)) 11323 #endif // ENTT_CORE_TYPE_TRAITS_HPP 11326 #ifndef ENTT_META_POLICY_HPP 11327 #define ENTT_META_POLICY_HPP 11352 #endif // ENTT_META_POLICY_HPP 11355 #ifndef ENTT_META_META_HPP 11356 #define ENTT_META_META_HPP 11363 #include <type_traits> 11369 #ifndef ENTT_CORE_UTILITY_HPP 11370 #define ENTT_CORE_UTILITY_HPP 11388 template<
class Type>
11390 return std::forward<Type>(value);
11402 template<
typename Type,
typename Class>
11412 template<
typename Type>
11420 template<
class... Func>
11422 using Func::operator()...;
11430 template<
class... Type>
11438 template<
class Func>
11439 struct y_combinator {
11445 func{std::move(recursive)}
11454 template <
class... Args>
11455 decltype(
auto)
operator()(Args &&... args)
const {
11456 return func(*
this, std::forward<Args>(args)...);
11460 template <
class... Args>
11461 decltype(
auto)
operator()(Args &&... args) {
11462 return func(*
this, std::forward<Args>(args)...);
11473 #endif // ENTT_CORE_UTILITY_HPP 11491 namespace internal {
11494 struct meta_type_node;
11497 struct meta_prop_node {
11498 meta_prop_node * next;
11499 meta_any(*
const key)();
11500 meta_any(*
const value)();
11504 struct meta_base_node {
11505 meta_type_node *
const parent;
11506 meta_base_node * next;
11512 struct meta_conv_node {
11513 meta_type_node *
const parent;
11514 meta_conv_node * next;
11516 meta_any(* const conv)(const
void *);
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;
11527 meta_any(*
const invoke)(meta_any *
const);
11531 struct meta_dtor_node {
11532 meta_type_node *
const parent;
11533 bool(*
const invoke)(meta_handle);
11537 struct meta_data_node {
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;
11545 bool(* const set)(meta_handle, meta_any, meta_any);
11546 meta_any(* const
get)(meta_handle, meta_any);
11550 struct meta_func_node {
11551 using size_type = std::size_t;
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;
11561 meta_any(* const invoke)(meta_handle, meta_any *);
11565 struct meta_type_node {
11566 using size_type = std::size_t;
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 *);
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};
11594 template<
typename Type,
typename Op,
typename Node>
11603 template<auto Member,
typename Type,
typename Op>
11604 void iterate(Op op,
const meta_type_node *node)
ENTT_NOEXCEPT {
11606 auto *curr = node->base;
11607 iterate<Type>(op, node->*Member);
11610 iterate<Member, Type>(op, curr->type());
11617 template<
typename Op,
typename Node>
11619 while(curr && !op(curr)) {
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;
11633 ret = find_if(op, node->*Member);
11634 auto *curr = node->base;
11636 while(curr && !ret) {
11637 ret = find_if<Member>(op, curr->type());
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);
11656 template<
typename...>
11661 struct meta_node<> {
11662 inline static meta_type_node *local =
nullptr;
11663 inline static meta_type_node **global = &local;
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>>>);
11672 auto *
const node =
resolve();
11673 auto **it = meta_node<>::global;
11675 while(*it && *it != node) {
11683 const auto unregister_all = y_combinator{
11684 [](
auto &&
self,
auto **curr,
auto... member) {
11686 auto *prev = *curr;
11687 (
self(&(prev->*member)), ...);
11688 *curr = prev->next;
11689 prev->next =
nullptr;
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);
11701 node->identifier = {};
11702 node->dtor =
nullptr;
11703 node->next =
nullptr;
11707 static meta_type_node node{
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>,
11725 return meta_node<std::remove_const_t<std::remove_pointer_t<Type>>>
::resolve();
11728 return meta_node<std::remove_const_t<std::remove_extent_t<Type>>>
::resolve();
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);
11737 return candidate ? candidate : &node;
11745 template<
typename... Type>
11746 struct meta_info: meta_node<std::remove_cv_t<std::remove_reference_t<Type>>...> {};
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 *);
11782 template<
typename Type>
11783 static Type * release(Type *instance) {
11785 [[maybe_unused]]
const bool destroyed = (!node->dtor || node->dtor->invoke(*instance));
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();
11799 static void destroy(
void *instance) {
11800 delete release<Type>(static_cast<Type *>(instance));
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();
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};
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)...};
11823 static void destroy(
void *instance) {
11824 release<Type>(static_cast<Type *>(instance))->~Type();
11827 static void * copy(storage_type &storage,
const void *instance) {
11828 return new (&storage) Type{*static_cast<const Type *>(instance)};
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))};
11844 destroy_fn{
nullptr},
11855 template<
typename Type,
typename... Args>
11856 explicit meta_any(std::in_place_type_t<Type>, [[maybe_unused]] Args &&... args)
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>);
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;
11877 template<
typename Type>
11882 instance = &type.get();
11896 template<
typename Type,
typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, meta_any>>>
11898 :
meta_any{std::in_place_type<std::remove_cv_t<std::remove_reference_t<Type>>>, std::forward<Type>(type)}
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;
11927 swap(*
this, other);
11933 destroy_fn(instance);
11943 template<
typename Type,
typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, meta_any>>>
11945 return (*
this =
meta_any{std::forward<Type>(type)});
11984 return const_cast<void *>(std::as_const(*this).data());
11992 template<
typename Type>
11995 void *ret =
nullptr;
12000 const auto *base = internal::find_if<&internal::meta_type_node::base>([type](
auto *candidate) {
12001 return candidate->type() == type;
12004 ret = base ? base->cast(instance) :
nullptr;
12007 return static_cast<const Type *>(ret);
12011 template<
typename Type>
12013 return const_cast<Type *>(std::as_const(*this).try_cast<Type>());
12030 template<
typename Type>
12032 auto *
const actual = try_cast<Type>();
12038 template<
typename Type>
12040 return const_cast<Type &>(std::as_const(*this).cast<Type>());
12049 template<
typename Type>
12054 any = *static_cast<const Type *>(instance);
12056 const auto *
const conv = internal::find_if<&internal::meta_type_node::conv>([type](
auto *other) {
12057 return other->type() == type;
12061 any = conv->conv(instance);
12073 template<
typename Type>
12078 if(
auto any = std::as_const(*this).convert<Type>(); any) {
12094 template<
typename Type,
typename... Args>
12096 *
this =
meta_any{std::in_place_type_t<Type>{}, std::forward<Args>(args)...};
12114 return node == other.node && (!node || node->compare(instance, other.instance));
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);
12131 }
else if(rhs.steal_fn) {
12132 rhs.instance = rhs.steal_fn(lhs.storage, rhs.instance, rhs.destroy_fn);
12139 std::swap(lhs.destroy_fn, rhs.destroy_fn);
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;
12179 instance{any.instance}
12187 template<
typename Type,
typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, meta_handle>>>
12203 return const_cast<void *>(std::as_const(*this).data());
12215 const internal::meta_type_node *node;
12227 return !(lhs == rhs);
12246 return node->key();
12254 return node->value();
12272 return node == other.node;
12276 const internal::meta_prop_node *node;
12287 return !(lhs == rhs);
12313 return node->cast(instance);
12326 return node == other.node;
12330 const internal::meta_base_node *node;
12336 return !(lhs == rhs);
12359 return node->conv(instance);
12372 return node == other.node;
12376 const internal::meta_conv_node *node;
12382 return !(lhs == rhs);
12425 template<
typename... Args>
12427 std::array<
meta_any,
sizeof...(Args)> arguments{{std::forward<Args>(args)...}};
12430 if(
sizeof...(Args) == size()) {
12431 any = node->invoke(arguments.data());
12442 template<
typename Op>
12443 std::enable_if_t<std::is_invocable_v<Op, meta_prop>,
void>
12445 internal::iterate<meta_prop>(std::move(op), node->prop);
12454 return internal::find_if([key = std::move(key)](
auto *candidate) {
12455 return candidate->key() == key;
12469 return node == other.node;
12473 const internal::meta_ctor_node *node;
12479 return !(lhs == rhs);
12504 return node->invoke(
handle);
12517 return node == other.node;
12521 const internal::meta_dtor_node *node;
12527 return !(lhs == rhs);
12540 return node->identifier;
12551 return node->is_const;
12563 return node->is_static;
12583 template<typename Type>
12585 return node->set(
handle,
meta_any{}, std::forward<Type>(value));
12603 template<
typename Type>
12606 return node->set(
handle, index, std::forward<Type>(value));
12634 return node->get(
handle, index);
12642 template<
typename Op>
12643 std::enable_if_t<std::is_invocable_v<Op, meta_prop>,
void>
12645 internal::iterate<meta_prop>(std::move(op), node->prop);
12654 return internal::find_if([key = std::move(key)](
auto *candidate) {
12655 return candidate->key() == key;
12669 return node == other.node;
12673 const internal::meta_data_node *node;
12679 return !(lhs == rhs);
12695 return node->identifier;
12714 return node->is_const;
12726 return node->is_static;
12757 template<typename... Args>
12763 if(
sizeof...(Args) == size()) {
12764 any = node->invoke(
handle, arguments.data());
12775 template<
typename Op>
12776 std::enable_if_t<std::is_invocable_v<Op, meta_prop>,
void>
12778 internal::iterate<meta_prop>(std::move(op), node->prop);
12787 return internal::find_if([key = std::move(key)](
auto *candidate) {
12788 return candidate->key() == key;
12802 return node == other.node;
12806 const internal::meta_func_node *node;
12812 return !(lhs == rhs);
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);
12842 return node->identifier;
12850 return node->is_void;
12859 return node->is_integral;
12869 return node->is_floating_point;
12878 return node->is_array;
12886 return node->is_enum;
12894 return node->is_union;
12902 return node->is_class;
12910 return node->is_pointer;
12920 return node->is_function_pointer;
12930 return node->is_member_object_pointer;
12940 return node->is_member_function_pointer;
12950 return node->extent;
12959 return node->remove_pointer();
12968 return node->remove_extent();
12979 template<
typename Op>
12980 std::enable_if_t<std::is_invocable_v<Op, meta_base>,
void>
12982 internal::iterate<&internal::meta_type_node::base, meta_base>(std::move(op), node);
12994 return internal::find_if<&internal::meta_type_node::base>([
identifier](
auto *candidate) {
12995 return candidate->type()->identifier ==
identifier;
13008 template<
typename Op>
13010 internal::iterate<&internal::meta_type_node::conv, meta_conv>(std::move(op), node);
13023 template<
typename Type>
13026 return candidate->type() == type;
13035 template<
typename Op>
13037 internal::iterate<meta_ctor>(std::move(op), node->ctor);
13045 template<
typename... Args>
13047 return ctor<Args...>(std::index_sequence_for<Args...>{});
13067 template<
typename Op>
13068 std::enable_if_t<std::is_invocable_v<Op, meta_data>,
void>
13070 internal::iterate<&internal::meta_type_node::data, meta_data>(std::move(op), node);
13084 return internal::find_if<&internal::meta_type_node::data>([
identifier](
auto *candidate) {
13099 template<
typename Op>
13100 std::enable_if_t<std::is_invocable_v<Op, meta_func>,
void>
13102 internal::iterate<&internal::meta_type_node::func, meta_func>(std::move(op), node);
13116 return internal::find_if<&internal::meta_type_node::func>([
identifier](
auto *candidate) {
13132 template<
typename... Args>
13134 std::array<
meta_any,
sizeof...(Args)> arguments{{std::forward<Args>(args)...}};
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);
13142 return static_cast<bool>(any);
13161 return (
handle.type() == node) && (!node->dtor || node->dtor->invoke(
handle));
13173 template<
typename Op>
13174 std::enable_if_t<std::is_invocable_v<Op, meta_prop>,
void>
13176 internal::iterate<&internal::meta_type_node::prop, meta_prop>(std::move(op), node);
13190 return internal::find_if<&internal::meta_type_node::prop>([key = std::move(key)](
auto *candidate) {
13191 return candidate->key() == key;
13205 return node == other.node;
13209 const internal::meta_type_node *node;
13220 internal::meta_info<>::global = other.ctx;
13224 internal::meta_type_node **ctx{&internal::meta_info<>::local};
13230 return !(lhs == rhs);
13238 instance =
handle.instance;
13253 return node->parent;
13258 return node->type();
13263 return node->parent;
13268 return node->type();
13273 return node->parent;
13278 return index < size() ? node->arg(index) :
nullptr;
13283 return node->parent;
13288 return node->parent;
13293 return node->type();
13298 return node->parent;
13303 return node->ret();
13308 return index < size() ? node->arg(index) :
nullptr;
13315 #endif // ENTT_META_META_HPP 13328 namespace internal {
13332 struct meta_function_helper;
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>>...>;
13340 static constexpr std::index_sequence_for<Args...> index_sequence{};
13341 static constexpr
auto is_const =
false;
13343 static auto arg(
typename internal::meta_func_node::size_type index)
ENTT_NOEXCEPT {
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;
13355 template<
typename Ret,
typename... Args,
typename Class>
13356 constexpr meta_function_helper<Ret(Args...)>
13357 to_meta_function_helper(Ret(Class:: *)(Args...));
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);
13365 template<typename Ret, typename... Args>
13366 constexpr meta_function_helper<Ret(Args...)>
13367 to_meta_function_helper(Ret(*)(Args...));
13370 constexpr
void to_meta_function_helper(...);
13373 template<typename Candidate>
13374 using meta_function_helper_t = decltype(to_meta_function_helper(
std::declval<Candidate>()));
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>()...);
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>())...};
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;
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>();
13402 if(clazz && (direct || value.convert<data_type>())) {
13403 std::invoke(Data, *clazz, direct ? *direct : value.cast<data_type>());
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>();
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>();
13416 if(clazz && idx && (direct || value.convert<underlying_type>())) {
13417 std::invoke(Data, clazz)[*idx] = direct ? *direct : value.cast<underlying_type>();
13421 auto *
const direct = value.try_cast<data_type>();
13423 if(clazz && (direct || value.convert<data_type>())) {
13424 std::invoke(Data, clazz) = (direct ? *direct : value.cast<data_type>());
13429 static_assert(std::is_pointer_v<decltype(Data)>);
13430 using data_type = std::remove_cv_t<std::remove_reference_t<decltype(*Data)>>;
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>();
13437 if(idx && (direct || value.convert<underlying_type>())) {
13438 (*Data)[*idx] = (direct ? *direct : value.cast<underlying_type>());
13442 auto *
const direct = value.try_cast<data_type>();
13444 if(direct || value.convert<data_type>()) {
13445 *Data = (direct ? *direct : value.cast<data_type>());
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))};
13464 static_assert(std::is_same_v<Policy, as_is_t>);
13465 return meta_any{std::forward<decltype(value)>(value)};
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>();
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{};
13482 return clazz ? dispatch(std::invoke(Data, clazz)) : meta_any{};
13485 static_assert(std::is_pointer_v<std::decay_t<decltype(Data)>>);
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{};
13491 return dispatch(*Data);
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)>;
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...))};
13508 static_assert(std::is_same_v<Policy, as_is_t>);
13509 return meta_any{std::invoke(Candidate, *params...)};
13513 [[maybe_unused]]
const auto direct = std::make_tuple([](meta_any *any,
auto *instance) {
13514 using arg_type = std::remove_reference_t<decltype(*instance)>;
13516 if(!instance && any->convert<arg_type>()) {
13517 instance = any->try_cast<arg_type>();
13521 }(args+Indexes, (args+Indexes)->try_cast<std::tuple_element_t<Indexes, typename helper_type::args_type>>())...);
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{};
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{};
13541 template<
typename,
typename...>
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));
13562 template<
typename Node>
13571 ENTT_ASSERT(!duplicate(node, *internal::meta_info<>::global));
13573 node->next = *internal::meta_info<>::global;
13574 *internal::meta_info<>::global = node;
13589 static_assert(!is_named_type_v<Type>);
13601 static_assert(is_named_type_v<Type>);
13613 template<
typename Base>
13615 static_assert(std::is_base_of_v<Base, Type>);
13618 static internal::meta_base_node node{
13623 return static_cast<Base *>(static_cast<Type *>(instance));
13628 node.next = type->base;
13629 type->base = &node;
13643 template<
typename To>
13645 static_assert(std::is_convertible_v<Type, To>);
13648 static internal::meta_conv_node node{
13652 [](
const void *instance) ->
meta_any {
13653 return static_cast<To>(*static_cast<const Type *>(instance));
13658 node.next = type->conv;
13659 type->conv = &node;
13676 template<auto Cand
idate>
13678 using conv_type = std::invoke_result_t<decltype(Candidate), Type &>;
13681 static internal::meta_conv_node node{
13685 [](
const void *instance) ->
meta_any {
13686 return std::invoke(Candidate, *static_cast<const Type *>(instance));
13691 node.next = type->conv;
13692 type->conv = &node;
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>);
13716 static internal::meta_ctor_node node{
13720 helper_type::index_sequence.size(),
13723 return internal::invoke<Type, Func, Policy>({}, any, helper_type::index_sequence);
13728 node.next = type->ctor;
13729 type->ctor = &node;
13744 template<
typename... Args>
13746 using helper_type = internal::meta_function_helper_t<Type(*)(Args...)>;
13749 static internal::meta_ctor_node node{
13753 helper_type::index_sequence.size(),
13756 return internal::construct<Type, std::remove_cv_t<std::remove_reference_t<Args>>...>(any, helper_type::index_sequence);
13761 node.next = type->ctor;
13762 type->ctor = &node;
13783 template<auto Func>
13785 static_assert(std::is_invocable_v<decltype(Func), Type &>);
13788 static internal::meta_dtor_node node{
13802 type->dtor = &node;
13820 template<auto Data,
typename Policy = as_is_t>
13823 internal::meta_data_node *curr =
nullptr;
13825 if constexpr(std::is_same_v<Type, decltype(Data)>) {
13826 static_assert(std::is_same_v<Policy, as_is_t>);
13828 static internal::meta_data_node 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)>;
13844 static internal::meta_data_node node{
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>
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)>>;
13861 static internal::meta_data_node node{
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>
13879 curr->next = type->data;
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>);
13911 static internal::meta_data_node node{
13919 &internal::setter<false, Type, Setter>,
13920 &internal::getter<Type, Getter, Policy>
13926 node.next = type->data;
13927 type->data = &node;
13929 return extended_meta_factory<Type, std::integral_constant<decltype(Setter), Setter>, std::integral_constant<decltype(Getter), Getter>>{&node.
prop};
13945 template<auto Cand
idate,
typename Policy = as_is_t>
13947 using helper_type = internal::meta_function_helper_t<decltype(Candidate)>;
13950 static internal::meta_func_node node{
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,
13961 return internal::invoke<Type, Candidate, Policy>(
handle, any, helper_type::index_sequence);
13968 node.next = type->func;
13969 type->func = &node;
13983 internal::meta_info<Type>::reset();
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));
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)...);
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)...);
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)...);
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)...);
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)...);
14027 template<std::
size_t>
14028 void unroll(choice_t<0>) {}
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)...)};
14034 static internal::meta_prop_node node{
14037 return std::get<0>(property);
14040 if constexpr(
sizeof...(Value) == 0) {
14043 return std::get<1>(property);
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));
14078 assign(std::forward<PropertyOrKey>(property_or_key), std::forward<Value>(value)...);
14094 template <
typename... Property>
14096 unroll(choice<3>, std::forward<Property>(property)...);
14101 entt::internal::meta_prop_node **curr{
nullptr};
14116 template<
typename Type>
14127 template<
typename Type>
14139 return internal::find_if([
identifier](
auto *node) {
14141 }, *internal::meta_info<>::global);
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);
14160 #endif // ENTT_META_FACTORY_HPP 14167 #ifndef ENTT_PROCESS_PROCESS_HPP 14168 #define ENTT_PROCESS_PROCESS_HPP 14172 #include <type_traits> 14174 #ifndef ENTT_CONFIG_CONFIG_H 14175 #define ENTT_CONFIG_CONFIG_H 14178 #ifndef ENTT_NOEXCEPT 14179 #define ENTT_NOEXCEPT noexcept 14180 #endif // ENTT_NOEXCEPT 14183 #ifndef ENTT_HS_SUFFIX 14184 #define ENTT_HS_SUFFIX _hs 14185 #endif // ENTT_HS_SUFFIX 14188 #ifndef ENTT_HWS_SUFFIX 14189 #define ENTT_HWS_SUFFIX _hws 14190 #endif // ENTT_HWS_SUFFIX 14193 #ifndef ENTT_NO_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 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 14206 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 14207 #endif // ENTT_DISABLE_ETO 14210 #ifndef ENTT_ID_TYPE 14212 #define ENTT_ID_TYPE std::uint32_t 14213 #endif // ENTT_ID_TYPE 14216 #ifndef ENTT_PAGE_SIZE 14217 #define ENTT_PAGE_SIZE 32768 14218 #endif // ENTT_PAGE_SIZE 14221 #ifndef ENTT_DISABLE_ASSERT 14223 #define ENTT_ASSERT(condition) assert(condition) 14224 #else // ENTT_DISABLE_ASSERT 14225 #define ENTT_ASSERT(...) ((void)0) 14226 #endif // ENTT_DISABLE_ASSERT 14229 #endif // ENTT_CONFIG_CONFIG_H 14295 template<
typename Derived,
typename Delta>
14297 enum class state: unsigned int {
14307 template<state value>
14308 using state_value_t = std::integral_constant<state, value>;
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();
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);
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();
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();
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();
14340 template<state value,
typename... Args>
14341 void tick(
char, state_value_t<value>, Args &&...)
const ENTT_NOEXCEPT {}
14352 current = state::SUCCEEDED;
14364 current = state::FAILED;
14375 if(current == state::RUNNING) {
14376 current = state::PAUSED;
14387 if(current == state::PAUSED) {
14388 current = state::RUNNING;
14398 static_assert(std::is_base_of_v<process, Derived>);
14411 current = state::ABORTED;
14424 return current == state::RUNNING || current == state::PAUSED;
14432 return current == state::FINISHED;
14440 return current == state::PAUSED;
14456 void tick(
const Delta delta,
void *data =
nullptr) {
14458 case state::UNINITIALIZED:
14459 tick(0, state_value_t<state::UNINITIALIZED>{});
14460 current = state::RUNNING;
14462 case state::RUNNING:
14463 tick(0, state_value_t<state::RUNNING>{}, delta, data);
14472 case state::SUCCEEDED:
14473 tick(0, state_value_t<state::SUCCEEDED>{});
14474 current = state::FINISHED;
14476 case state::FAILED:
14477 tick(0, state_value_t<state::FAILED>{});
14478 current = state::FINISHED;
14481 case state::ABORTED:
14482 tick(0, state_value_t<state::ABORTED>{});
14483 current = state::FINISHED;
14493 state current{state::UNINITIALIZED};
14494 bool stopped{
false};
14537 template<
typename Func,
typename Delta>
14544 template<
typename... Args>
14546 : Func{std::forward<Args>(args)...}
14555 Func::operator()(delta, data, [
this]() { this->succeed(); }, [
this]() { this->fail(); });
14563 #endif // ENTT_PROCESS_PROCESS_HPP 14566 #ifndef ENTT_PROCESS_SCHEDULER_HPP 14567 #define ENTT_PROCESS_SCHEDULER_HPP 14573 #include <algorithm> 14574 #include <type_traits> 14610 template<
typename Delta>
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>;
14618 instance_type instance;
14619 update_fn_type *update;
14620 abort_fn_type *abort;
14624 struct continuation {
14625 continuation(process_handler *ref)
14631 template<
typename Proc,
typename... Args>
14632 continuation then(Args &&... args) {
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();
14640 template<
typename Func>
14641 continuation then(Func &&func) {
14642 return then<process_adaptor<std::decay_t<Func>, Delta>>(std::forward<Func>(func));
14646 process_handler *handler;
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());
14658 handler = std::move(*handler.next);
14660 dead = handler.update(handler, {},
nullptr);
14662 handler.instance.reset();
14669 template<
typename Proc>
14670 static void abort(process_handler &handler,
const bool immediately) {
14671 static_cast<Proc *>(handler.instance.get())->abort(immediately);
14674 template<
typename Proc>
14675 static void deleter(
void *proc) {
14676 delete static_cast<Proc *>(proc);
14697 return handlers.size();
14705 return handlers.empty();
14743 template<
typename Proc,
typename... Args>
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};
14749 handler.update(handler, {},
nullptr);
14750 return continuation{&handlers.emplace_back(std::move(handler))};
14804 template<
typename Func>
14807 return attach<Proc>(std::forward<Func>(func));
14821 void update(
const Delta delta,
void *data =
nullptr) {
14822 bool clean =
false;
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;
14831 handlers.erase(std::remove_if(handlers.begin(), handlers.end(), [](
auto &handler) {
14832 return !handler.instance;
14833 }), handlers.end());
14847 void abort(
const bool immediately =
false) {
14848 decltype(handlers) exec;
14849 exec.swap(handlers);
14851 std::for_each(exec.begin(), exec.end(), [immediately](
auto &handler) {
14852 handler.abort(handler, immediately);
14855 std::move(handlers.begin(), handlers.end(), std::back_inserter(exec));
14856 handlers.swap(exec);
14860 std::vector<process_handler> handlers{};
14867 #endif // ENTT_PROCESS_SCHEDULER_HPP 14870 #ifndef ENTT_RESOURCE_CACHE_HPP 14871 #define ENTT_RESOURCE_CACHE_HPP 14876 #include <type_traits> 14877 #include <unordered_map> 14879 #ifndef ENTT_CONFIG_CONFIG_H 14880 #define ENTT_CONFIG_CONFIG_H 14883 #ifndef ENTT_NOEXCEPT 14884 #define ENTT_NOEXCEPT noexcept 14885 #endif // ENTT_NOEXCEPT 14888 #ifndef ENTT_HS_SUFFIX 14889 #define ENTT_HS_SUFFIX _hs 14890 #endif // ENTT_HS_SUFFIX 14893 #ifndef ENTT_HWS_SUFFIX 14894 #define ENTT_HWS_SUFFIX _hws 14895 #endif // ENTT_HWS_SUFFIX 14898 #ifndef ENTT_NO_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 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 14911 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 14912 #endif // ENTT_DISABLE_ETO 14915 #ifndef ENTT_ID_TYPE 14917 #define ENTT_ID_TYPE std::uint32_t 14918 #endif // ENTT_ID_TYPE 14921 #ifndef ENTT_PAGE_SIZE 14922 #define ENTT_PAGE_SIZE 32768 14923 #endif // ENTT_PAGE_SIZE 14926 #ifndef ENTT_DISABLE_ASSERT 14928 #define ENTT_ASSERT(condition) assert(condition) 14929 #else // ENTT_DISABLE_ASSERT 14930 #define ENTT_ASSERT(...) ((void)0) 14931 #endif // ENTT_DISABLE_ASSERT 14934 #endif // ENTT_CONFIG_CONFIG_H 14937 #ifndef ENTT_RESOURCE_HANDLE_HPP 14938 #define ENTT_RESOURCE_HANDLE_HPP 14946 #ifndef ENTT_RESOURCE_FWD_HPP 14947 #define ENTT_RESOURCE_FWD_HPP 14962 template<
typename,
typename>
14969 #endif // ENTT_RESOURCE_FWD_HPP 14988 template<
typename Resource>
14994 : resource{std::move(res)}
15018 return const_cast<Resource &>(std::as_const(*this).get());
15046 return resource.get();
15051 return const_cast<Resource *>(std::as_const(*this).operator->());
15058 explicit operator bool()
const {
return static_cast<bool>(resource); }
15061 std::shared_ptr<Resource> resource;
15068 #endif // ENTT_RESOURCE_HANDLE_HPP 15071 #ifndef ENTT_RESOURCE_LOADER_HPP 15072 #define ENTT_RESOURCE_LOADER_HPP 15115 template<
typename Loader,
typename Resource>
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)...);
15136 #endif // ENTT_RESOURCE_LOADER_HPP 15155 template<
typename Resource>
15178 return resources.size();
15186 return resources.empty();
15221 template<
typename Loader,
typename... Args>
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);
15232 resource = it->second;
15261 template<
typename Loader,
typename... Args>
15263 return (discard(
id), load<Loader>(
id, std::forward<Args>(args)...));
15278 template<
typename Loader,
typename... Args>
15280 return { Loader{}.get(std::forward<Args>(args)...) };
15297 auto it = resources.find(
id);
15298 return { it == resources.end() ? nullptr : it->second };
15307 return (resources.find(
id) != resources.cend());
15319 if(
auto it = resources.find(
id); it != resources.end()) {
15320 resources.erase(it);
15341 template <
typename Func>
15343 auto begin = resources.begin();
15344 auto end = resources.end();
15346 while(begin != end) {
15347 auto curr = begin++;
15349 if constexpr(std::is_invocable_v<Func, id_type>) {
15360 std::unordered_map<id_type, std::shared_ptr<Resource>> resources;
15367 #endif // ENTT_RESOURCE_CACHE_HPP 15374 #ifndef ENTT_SIGNAL_DELEGATE_HPP 15375 #define ENTT_SIGNAL_DELEGATE_HPP 15381 #include <algorithm> 15382 #include <functional> 15383 #include <type_traits> 15385 #ifndef ENTT_CONFIG_CONFIG_H 15386 #define ENTT_CONFIG_CONFIG_H 15389 #ifndef ENTT_NOEXCEPT 15390 #define ENTT_NOEXCEPT noexcept 15391 #endif // ENTT_NOEXCEPT 15394 #ifndef ENTT_HS_SUFFIX 15395 #define ENTT_HS_SUFFIX _hs 15396 #endif // ENTT_HS_SUFFIX 15399 #ifndef ENTT_HWS_SUFFIX 15400 #define ENTT_HWS_SUFFIX _hws 15401 #endif // ENTT_HWS_SUFFIX 15404 #ifndef ENTT_NO_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 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 15417 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 15418 #endif // ENTT_DISABLE_ETO 15421 #ifndef ENTT_ID_TYPE 15423 #define ENTT_ID_TYPE std::uint32_t 15424 #endif // ENTT_ID_TYPE 15427 #ifndef ENTT_PAGE_SIZE 15428 #define ENTT_PAGE_SIZE 32768 15429 #endif // ENTT_PAGE_SIZE 15432 #ifndef ENTT_DISABLE_ASSERT 15434 #define ENTT_ASSERT(condition) assert(condition) 15435 #else // ENTT_DISABLE_ASSERT 15436 #define ENTT_ASSERT(...) ((void)0) 15437 #endif // ENTT_DISABLE_ASSERT 15440 #endif // ENTT_CONFIG_CONFIG_H 15453 namespace internal {
15456 template<
typename Ret,
typename... Args>
15457 auto to_function_pointer(Ret(*)(Args...)) -> Ret(*)(Args...);
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...);
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...);
15468 template<
typename Class,
typename Ret,
typename... Args>
15469 auto to_function_pointer(Ret(Class:: *)(Args...),
const Class *) -> Ret(*)(Args...);
15472 template<
typename Class,
typename Ret,
typename... Args>
15473 auto to_function_pointer(Ret(Class:: *)(Args...)
const,
const Class *) -> Ret(*)(Args...);
15476 template<
typename Class,
typename Type>
15477 auto to_function_pointer(Type Class:: *,
const Class *) -> Type(*)();
15480 template<
typename... Type>
15481 using to_function_pointer_t = decltype(internal::to_function_pointer(std::declval<Type>()...));
15484 template<
typename Ret,
typename... Args>
15485 constexpr
auto index_sequence_for(Ret(*)(Args...)) {
15486 return std::index_sequence_for<Args...>{};
15501 struct connect_arg_t {};
15505 template<auto Func>
15532 template<
typename Ret,
typename... Args>
15534 using proto_fn_type = Ret(
const void *, std::tuple<Args &&...>);
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...>>...>);
15541 fn = [](
const void *, std::tuple<Args &&...> args) -> Ret {
15543 return Ret(std::invoke(Function, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
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;
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));
15555 return Ret(std::invoke(Candidate, *curr, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
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;
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));
15567 return Ret(std::invoke(Candidate, curr, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
15573 using function_type = Ret(Args...);
15577 : fn{
nullptr}, data{
nullptr}
15584 template<auto Function>
15588 connect<Function>();
15598 template<auto Cand
idate,
typename Type>
15602 connect<Candidate>(value_or_instance);
15612 template<auto Cand
idate,
typename Type>
15616 connect<Candidate>(value_or_instance);
15623 template<auto Function>
15625 connect<Function>(internal::index_sequence_for(internal::to_function_pointer_t<decltype(Function)>{}));
15643 template<auto Cand
idate,
typename Type>
15645 connect<Candidate>(value_or_instance, internal::index_sequence_for(internal::to_function_pointer_t<decltype(Candidate), Type *>{}));
15663 template<auto Cand
idate,
typename Type>
15665 connect<Candidate>(value_or_instance, internal::index_sequence_for(internal::to_function_pointer_t<decltype(Candidate), Type *>{}));
15700 Ret operator()(Args... args)
const {
15702 return fn(data, std::forward_as_tuple(std::forward<Args>(args)...));
15720 return fn == other.fn && data == other.data;
15737 template<
typename Ret,
typename... Args>
15739 return !(lhs == rhs);
15751 template<auto Function>
15753 ->
delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Function)>>>;
15765 template<auto Cand
idate,
typename Type>
15767 ->
delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Candidate), Type *>>>;
15779 template<auto Cand
idate,
typename Type>
15781 ->
delegate<std::remove_pointer_t<internal::to_function_pointer_t<decltype(Candidate), Type *>>>;
15787 #endif // ENTT_SIGNAL_DELEGATE_HPP 15790 #ifndef ENTT_SIGNAL_DISPATCHER_HPP 15791 #define ENTT_SIGNAL_DISPATCHER_HPP 15798 #include <algorithm> 15799 #include <type_traits> 15803 #ifndef ENTT_CORE_FAMILY_HPP 15804 #define ENTT_CORE_FAMILY_HPP 15807 #include <type_traits> 15809 #ifndef ENTT_CONFIG_CONFIG_H 15810 #define ENTT_CONFIG_CONFIG_H 15813 #ifndef ENTT_NOEXCEPT 15814 #define ENTT_NOEXCEPT noexcept 15815 #endif // ENTT_NOEXCEPT 15818 #ifndef ENTT_HS_SUFFIX 15819 #define ENTT_HS_SUFFIX _hs 15820 #endif // ENTT_HS_SUFFIX 15823 #ifndef ENTT_HWS_SUFFIX 15824 #define ENTT_HWS_SUFFIX _hws 15825 #endif // ENTT_HWS_SUFFIX 15828 #ifndef ENTT_NO_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 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 15841 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 15842 #endif // ENTT_DISABLE_ETO 15845 #ifndef ENTT_ID_TYPE 15847 #define ENTT_ID_TYPE std::uint32_t 15848 #endif // ENTT_ID_TYPE 15851 #ifndef ENTT_PAGE_SIZE 15852 #define ENTT_PAGE_SIZE 32768 15853 #endif // ENTT_PAGE_SIZE 15856 #ifndef ENTT_DISABLE_ASSERT 15858 #define ENTT_ASSERT(condition) assert(condition) 15859 #else // ENTT_DISABLE_ASSERT 15860 #define ENTT_ASSERT(...) ((void)0) 15861 #endif // ENTT_DISABLE_ASSERT 15864 #endif // ENTT_CONFIG_CONFIG_H 15878 template<
typename...>
15887 template<
typename... Type>
15889 inline static const family_type type = identifier++;
15896 #endif // ENTT_CORE_FAMILY_HPP 15899 #ifndef ENTT_CORE_TYPE_TRAITS_HPP 15900 #define ENTT_CORE_TYPE_TRAITS_HPP 15904 #include <type_traits> 15908 #ifndef ENTT_CORE_HASHED_STRING_HPP 15909 #define ENTT_CORE_HASHED_STRING_HPP 15914 #ifndef ENTT_CONFIG_CONFIG_H 15915 #define ENTT_CONFIG_CONFIG_H 15918 #ifndef ENTT_NOEXCEPT 15919 #define ENTT_NOEXCEPT noexcept 15920 #endif // ENTT_NOEXCEPT 15923 #ifndef ENTT_HS_SUFFIX 15924 #define ENTT_HS_SUFFIX _hs 15925 #endif // ENTT_HS_SUFFIX 15928 #ifndef ENTT_HWS_SUFFIX 15929 #define ENTT_HWS_SUFFIX _hws 15930 #endif // ENTT_HWS_SUFFIX 15933 #ifndef ENTT_NO_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 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 15946 #define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v<Type>) 15947 #endif // ENTT_DISABLE_ETO 15950 #ifndef ENTT_ID_TYPE 15952 #define ENTT_ID_TYPE std::uint32_t 15953 #endif // ENTT_ID_TYPE 15956 #ifndef ENTT_PAGE_SIZE 15957 #define ENTT_PAGE_SIZE 32768 15958 #endif // ENTT_PAGE_SIZE 15961 #ifndef ENTT_DISABLE_ASSERT 15963 #define ENTT_ASSERT(condition) assert(condition) 15964 #else // ENTT_DISABLE_ASSERT 15965 #define ENTT_ASSERT(...) ((void)0) 15966 #endif // ENTT_DISABLE_ASSERT 15969 #endif // ENTT_CONFIG_CONFIG_H 15982 namespace internal {
15986 struct fnv1a_traits;
15990 struct fnv1a_traits<
std::uint32_t> {
15991 static constexpr std::uint32_t offset = 2166136261;
15992 static constexpr std::uint32_t prime = 16777619;
15997 struct fnv1a_traits<
std::uint64_t> {
15998 static constexpr std::uint64_t offset = 14695981039346656037ull;
15999 static constexpr std::uint64_t prime = 1099511628211ull;
16023 template<
typename Char>
16025 using traits_type = internal::fnv1a_traits<ENTT_ID_TYPE>;
16027 struct const_wrapper {
16029 constexpr const_wrapper(
const Char *curr)
ENTT_NOEXCEPT: str{curr} {}
16035 return curr[0] == 0 ? partial : helper((partial^curr[0])*traits_type::prime, curr+1);
16040 using value_type = Char;
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);
16069 static hash_type to_value(const_wrapper wrapper)
ENTT_NOEXCEPT {
16070 return helper(traits_type::offset, wrapper.str);
16079 static hash_type to_value(
const value_type *str, std::size_t size)
ENTT_NOEXCEPT {
16081 while(size--) { partial = (partial^(str++)[0])*traits_type::prime; }
16087 : str{
nullptr}, hash{}
16104 template<std::
size_t N>
16106 : str{curr}, hash{helper(traits_type::offset, curr)}
16115 : str{wrapper.str}, hash{helper(traits_type::offset, wrapper.str)}
16138 constexpr
operator const value_type *()
const ENTT_NOEXCEPT {
return str; }
16141 constexpr
operator hash_type() const
ENTT_NOEXCEPT {
return hash; }
16149 return hash == other.hash;
16153 const value_type *str;
16168 template<
typename Char, std::
size_t N>
16170 -> basic_hashed_string<Char>;
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);
16217 #endif // ENTT_CORE_HASHED_STRING_HPP 16228 template<std::
size_t N>
16239 struct choice_t<0> {};
16246 template<std::
size_t N>
16247 constexpr choice_t<N>
choice{};
16251 template<
typename...>
16252 struct type_list {};
16257 struct type_list_size;
16264 template<
typename... Type>
16265 struct type_list_size<type_list<Type...>>
16266 : std::integral_constant<std::size_t, sizeof...(Type)>
16274 template<
class List>
16279 template<
typename...>
16280 struct type_list_cat;
16285 struct type_list_cat<> {
16287 using type = type_list<>;
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;
16308 template<
typename... Type>
16309 struct type_list_cat<type_list<Type...>> {
16311 using type = type_list<Type...>;
16319 template<
typename... List>
16325 struct type_list_unique;
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>
16346 struct type_list_unique<type_list<>> {
16348 using type = type_list<>;
16356 template<
typename Type>
16365 template<
typename Type,
typename = std::
void_t<>>
16366 struct is_equality_comparable: std::false_type {};
16370 template<
typename Type>
16371 struct is_equality_comparable<Type,
std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>: std::true_type {};
16378 template<
class Type>
16384 struct named_type_traits;
16391 template<
typename Type>
16392 struct named_type_traits<const Type>
16393 : named_type_traits<Type>
16401 template<
typename Type>
16409 template<
class Type>
16418 template<
typename Type,
typename = std::
void_t<>>
16419 struct is_named_type: std::false_type {};
16423 template<
typename Type>
16424 struct is_named_type<Type,
std::void_t<named_type_traits_t<std::decay_t<Type>>>>: std::true_type {};
16431 template<
class Type>
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);\ 16446 static_assert(true) 16459 #define ENTT_EXPAND(args) args 16479 #define ENTT_NAMED_TYPE(type)\ 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}>\ 16484 static_assert(std::is_same_v<std::remove_cv_t<type>, type>);\ 16485 static_assert(std::is_object_v<type>);\ 16494 #define ENTT_NAMED_STRUCT_ONLY(clazz, body)\ 16495 struct clazz body;\ 16496 ENTT_NAMED_TYPE(clazz) 16505 #define ENTT_NAMED_STRUCT_WITH_NAMESPACE(ns, clazz, body)\ 16506 namespace ns { struct clazz body; }\ 16507 ENTT_NAMED_TYPE(ns::clazz) 16511 #define ENTT_NAMED_STRUCT_OVERLOAD(_1, _2, _3, FUNC, ...) FUNC 16513 #define ENTT_NAMED_STRUCT(...) ENTT_EXPAND(ENTT_NAMED_STRUCT_OVERLOAD(__VA_ARGS__, ENTT_NAMED_STRUCT_WITH_NAMESPACE, ENTT_NAMED_STRUCT_ONLY,)(__VA_ARGS__)) 16521 #define ENTT_NAMED_CLASS_ONLY(clazz, body)\ 16523 ENTT_NAMED_TYPE(clazz) 16532 #define ENTT_NAMED_CLASS_WITH_NAMESPACE(ns, clazz, body)\ 16533 namespace ns { class clazz body; }\ 16534 ENTT_NAMED_TYPE(ns::clazz) 16538 #define ENTT_NAMED_CLASS_MACRO(_1, _2, _3, FUNC, ...) FUNC 16540 #define ENTT_NAMED_CLASS(...) ENTT_EXPAND(ENTT_NAMED_CLASS_MACRO(__VA_ARGS__, ENTT_NAMED_CLASS_WITH_NAMESPACE, ENTT_NAMED_CLASS_ONLY,)(__VA_ARGS__)) 16543 #endif // ENTT_CORE_TYPE_TRAITS_HPP 16546 #ifndef ENTT_SIGNAL_SIGH_HPP 16547 #define ENTT_SIGNAL_SIGH_HPP 16552 #include <iterator> 16553 #include <algorithm> 16554 #include <functional> 16555 #include <type_traits> 16561 #ifndef ENTT_SIGNAL_FWD_HPP 16562 #define ENTT_SIGNAL_FWD_HPP 16584 #endif // ENTT_SIGNAL_FWD_HPP 16599 template<
typename Function>
16611 template<
typename Function>
16630 template<
typename Ret,
typename... Args>
16631 class sigh<Ret(Args...)> {
16633 friend class sink<Ret(Args...)>;
16637 using size_type = std::size_t;
16645 template<
typename Class>
16646 using instance_type = Class *;
16653 return calls.size();
16661 return calls.empty();
16671 void publish(Args... args)
const {
16672 std::for_each(calls.cbegin(), calls.cend(), [&args...](
auto &&call) {
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>) {
16697 if(func()) {
break; }
16703 if constexpr(std::is_invocable_r_v<bool, Func, Ret>) {
16704 if(func(call(args...))) {
break; }
16706 func(call(args...));
16713 std::vector<
delegate<Ret(Args...)>> calls;
16729 connection(
delegate<
void(
void *)> fn,
void *ref)
16730 : disconnect{fn}, signal{ref}
16735 connection() =
default;
16738 connection(
const connection &) =
default;
16744 connection(connection &&other)
16747 std::swap(disconnect, other.disconnect);
16752 connection & operator=(
const connection &) =
default;
16759 connection & operator=(connection &&other) {
16760 if(
this != &other) {
16761 auto tmp{std::move(other)};
16762 disconnect = tmp.disconnect;
16763 signal = tmp.signal;
16774 return static_cast<bool>(disconnect);
16780 disconnect(signal);
16781 disconnect.reset();
16786 delegate<void(
void *)> disconnect;
16800 struct scoped_connection:
private connection {
16801 using connection::operator bool;
16805 scoped_connection() =
default;
16811 scoped_connection(
const connection &conn)
16816 scoped_connection(
const scoped_connection &) =
delete;
16819 scoped_connection(scoped_connection &&) =
default;
16822 ~scoped_connection() {
16830 scoped_connection & operator=(
const scoped_connection &) =
delete;
16836 scoped_connection & operator=(scoped_connection &&) =
default;
16843 scoped_connection & operator=(
const connection &other) {
16844 static_cast<connection &>(*
this) = other;
16853 scoped_connection & operator=(connection &&other) {
16854 static_cast<connection &>(*
this) = std::move(other);
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;
16879 template<auto Cand
idate,
typename Type>
16880 static void release(Type value_or_instance,
void *signal) {
16881 sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>(value_or_instance);
16884 template<auto Function>
16885 static void release(
void *signal) {
16886 sink{*static_cast<signal_type *>(signal)}.disconnect<Function>();
16904 return signal->calls.empty();
16912 template<auto Function>
16915 call.template connect<Function>();
16917 const auto &calls = signal->calls;
16918 const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
16921 other.offset = std::distance(it, calls.cend());
16933 template<auto Cand
idate,
typename Type>
16934 sink before(Type &value_or_instance) {
16936 call.template connect<Candidate>(value_or_instance);
16938 const auto &calls = signal->calls;
16939 const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
16942 other.offset = std::distance(it, calls.cend());
16954 template<auto Cand
idate,
typename Type>
16955 sink before(Type *value_or_instance) {
16957 call.template connect<Candidate>(value_or_instance);
16959 const auto &calls = signal->calls;
16960 const auto it = std::find(calls.cbegin(), calls.cend(), std::move(call));
16963 other.offset = std::distance(it, calls.cend());
16974 template<
typename Type>
16975 sink before(Type &value_or_instance) {
16976 return before(&value_or_instance);
16986 template<
typename Type>
16987 sink before(Type *value_or_instance) {
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;
16996 other.offset = std::distance(it, calls.cend());
17008 other.offset = signal->calls.size();
17021 template<auto Function>
17022 connection connect() {
17023 disconnect<Function>();
17026 call.template connect<Function>();
17027 signal->calls.insert(signal->calls.end() - offset, std::move(call));
17030 conn.template connect<&release<Function>>();
17031 return { std::move(conn), signal };
17051 template<auto Cand
idate,
typename Type>
17052 connection connect(Type &value_or_instance) {
17053 disconnect<Candidate>(value_or_instance);
17056 call.template connect<Candidate>(value_or_instance);
17057 signal->calls.insert(signal->calls.end() - offset, std::move(call));
17060 conn.template connect<&release<Candidate, Type &>>(value_or_instance);
17061 return { std::move(conn), signal };
17081 template<auto Cand
idate,
typename Type>
17082 connection connect(Type *value_or_instance) {
17083 disconnect<Candidate>(value_or_instance);
17086 call.template connect<Candidate>(value_or_instance);
17087 signal->calls.insert(signal->calls.end() - offset, std::move(call));
17090 conn.template connect<&release<Candidate, Type *>>(value_or_instance);
17091 return { std::move(conn), signal };
17098 template<auto Function>
17099 void disconnect() {
17100 auto &calls = signal->calls;
17102 call.template connect<Function>();
17103 calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
17113 template<auto Cand
idate,
typename Type>
17114 void disconnect(Type &value_or_instance) {
17115 auto &calls = signal->calls;
17117 call.template connect<Candidate>(value_or_instance);
17118 calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
17128 template<auto Cand
idate,
typename Type>
17129 void disconnect(Type *value_or_instance) {
17130 auto &calls = signal->calls;
17132 call.template connect<Candidate>(value_or_instance);
17133 calls.erase(std::remove(calls.begin(), calls.end(), std::move(call)), calls.end());
17142 template<
typename Type>
17143 void disconnect(Type &value_or_instance) {
17144 disconnect(&value_or_instance);
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;
17164 void disconnect() {
17165 signal->calls.clear();
17169 difference_type offset;
17170 signal_type *signal;
17183 template<
typename Ret,
typename... Args>
17190 #endif // ENTT_SIGNAL_SIGH_HPP 17213 template<
typename Class,
typename Event>
17214 using instance_type =
typename sigh<void(
const Event &)>::template instance_type<Class>;
17216 struct base_wrapper {
17217 virtual ~base_wrapper() =
default;
17218 virtual void publish() = 0;
17219 virtual void clear() = 0;
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;
17227 void publish()
override {
17228 const auto length = events.size();
17230 for(std::size_t pos{}; pos < length; ++pos) {
17231 signal.publish(events[pos]);
17234 events.erase(events.cbegin(), events.cbegin()+length);
17237 void clear()
override {
17245 template<
typename... Args>
17246 void trigger(Args &&... args) {
17247 signal.publish({ std::forward<Args>(args)... });
17250 template<
typename... Args>
17251 void enqueue(Args &&... args) {
17252 events.emplace_back(std::forward<Args>(args)...);
17256 signal_type signal{};
17257 std::vector<Event> events;
17260 struct wrapper_data {
17261 std::unique_ptr<base_wrapper> wrapper;
17265 template<
typename Event>
17267 if constexpr(is_named_type_v<Event>) {
17268 return named_type_traits_v<Event>;
17270 return event_family::type<std::decay_t<Event>>;
17274 template<
typename Event>
17275 signal_wrapper<Event> & assure() {
17276 const auto wtype = type<Event>();
17277 wrapper_data *wdata =
nullptr;
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;
17284 wdata = (it == wrappers.cend() ? &wrappers.emplace_back() : &(*it));
17286 if(!(wtype < wrappers.size())) {
17287 wrappers.resize(wtype+1);
17290 wdata = &wrappers[wtype];
17292 if(wdata->wrapper && wdata->runtime_type != wtype) {
17293 wrappers.emplace_back();
17294 std::swap(wrappers[wtype], wrappers.back());
17295 wdata = &wrappers[wtype];
17299 if(!wdata->wrapper) {
17300 wdata->wrapper = std::make_unique<signal_wrapper<Event>>();
17301 wdata->runtime_type = wtype;
17304 return static_cast<signal_wrapper<Event> &
>(*wdata->wrapper);
17309 template<
typename Event>
17329 template<
typename Event>
17331 return assure<Event>().sink();
17344 template<
typename Event,
typename... Args>
17346 assure<Event>().trigger(std::forward<Args>(args)...);
17358 template<
typename Event>
17360 assure<std::decay_t<Event>>().trigger(std::forward<Event>(event));
17373 template<
typename Event,
typename... Args>
17375 assure<Event>().enqueue(std::forward<Args>(args)...);
17387 template<
typename Event>
17389 assure<std::decay_t<Event>>().enqueue(std::forward<Event>(event));
17400 template<
typename... Event>
17402 if constexpr(
sizeof...(Event) == 0) {
17403 std::for_each(wrappers.begin(), wrappers.end(), [](
auto &&wdata) {
17404 if(wdata.wrapper) {
17405 wdata.wrapper->clear();
17409 (assure<std::decay_t<Event>>().clear(), ...);
17422 template<
typename Event>
17424 assure<Event>().publish();
17435 for(
auto pos = wrappers.size(); pos; --pos) {
17436 if(
auto &wdata = wrappers[pos-1]; wdata.wrapper) {
17437 wdata.wrapper->publish();
17443 std::vector<wrapper_data> wrappers;
17450 #endif // ENTT_SIGNAL_DISPATCHER_HPP 17453 #ifndef ENTT_SIGNAL_EMITTER_HPP 17454 #define ENTT_SIGNAL_EMITTER_HPP 17457 #include <type_traits> 17458 #include <functional> 17459 #include <algorithm> 17496 template<
typename Derived>
17500 struct base_handler {
17501 virtual ~base_handler() =
default;
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;
17514 auto pred = [](
auto &&element) {
return element.first; };
17516 return std::all_of(once_list.cbegin(), once_list.cend(), pred) &&
17517 std::all_of(on_list.cbegin(), on_list.cend(), pred);
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);
17531 connection_type once(listener_type
listener) {
17532 return once_list.emplace(once_list.cend(),
false, std::move(
listener));
17535 connection_type on(listener_type
listener) {
17536 return on_list.emplace(on_list.cend(),
false, std::move(
listener));
17540 conn->first =
true;
17543 auto pred = [](
auto &&element) {
return element.first; };
17544 once_list.remove_if(pred);
17545 on_list.remove_if(pred);
17549 void publish(
const Event &event, Derived &ref) {
17550 container_type swap_list;
17551 once_list.swap(swap_list);
17553 auto func = [&event, &ref](
auto &&element) {
17554 return element.first ? void() : element.second(event, ref);
17559 std::for_each(on_list.rbegin(), on_list.rend(), func);
17560 std::for_each(swap_list.rbegin(), swap_list.rend(), func);
17562 publishing =
false;
17564 on_list.remove_if([](
auto &&element) {
return element.first; });
17568 bool publishing{
false};
17569 container_type once_list{};
17570 container_type on_list{};
17573 struct handler_data {
17574 std::unique_ptr<base_handler> handler;
17578 template<
typename Event>
17580 if constexpr(is_named_type_v<Event>) {
17581 return named_type_traits_v<Event>;
17583 return handler_family::type<std::decay_t<Event>>;
17587 template<
typename Event>
17589 const auto htype = type<Event>();
17590 handler_data *hdata =
nullptr;
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;
17597 hdata = (it == handlers.cend() ? &handlers.emplace_back() : &(*it));
17599 if(!(htype < handlers.size())) {
17600 handlers.resize(htype+1);
17603 hdata = &handlers[htype];
17605 if(hdata->handler && hdata->runtime_type != htype) {
17606 handlers.emplace_back();
17607 std::swap(handlers[htype], handlers.back());
17608 hdata = &handlers[htype];
17612 if(!hdata->handler) {
17613 hdata->handler = std::make_unique<event_handler<Event>>();
17614 hdata->runtime_type = htype;
17617 return static_cast<event_handler<Event> *
>(hdata->handler.get());
17622 template<
typename Event>
17623 using listener =
typename event_handler<Event>::listener_type;
17634 template<
typename Event>
17647 : event_handler<Event>::connection_type{std::move(conn)}
17676 template<
typename Event,
typename... Args>
17678 assure<Event>()->publish({ std::forward<Args>(args)... }, *static_cast<Derived *>(
this));
17701 template<
typename Event>
17703 return assure<Event>()->on(std::move(instance));
17726 template<
typename Event>
17728 return assure<Event>()->once(std::move(instance));
17740 template<
typename Event>
17742 assure<Event>()->erase(std::move(conn));
17753 template<
typename Event>
17755 assure<Event>()->clear();
17765 std::for_each(handlers.begin(), handlers.end(), [](
auto &&hdata) {
17766 return hdata.handler ? hdata.handler->clear() : void();
17775 template<
typename Event>
17777 return assure<Event>()->empty();
17785 return std::all_of(handlers.cbegin(), handlers.cend(), [](
auto &&hdata) {
17786 return !hdata.handler || hdata.handler->empty();
17791 mutable std::vector<handler_data> handlers{};
17798 #endif // ENTT_SIGNAL_EMITTER_HPP 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
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
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
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
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
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.
void disconnect()
Disconnects a free function from a signal.
Definition: entt.hpp:3434
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.
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
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
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
void collect(Func func, Args... args) const
Collects return values from the listeners.
Definition: entt.hpp:3027
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
std::uint64_t entity_type
Underlying entity type.
Definition: entt.hpp:3644
void update(const Delta delta, void *data=nullptr)
Updates all scheduled processes.
Definition: entt.hpp:14821
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
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
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
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
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
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
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
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
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
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:64
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
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
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
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
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
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
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
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.
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
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
void reserve(const size_type cap)
Increases the capacity of a storage.
Definition: entt.hpp:5499
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
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
auto try_get() const ENTT_NOEXCEPT
Returns pointers to the given components for an actor.
Definition: entt.hpp:9723
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
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
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
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
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
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
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
as_view(registry_type &source) ENTT_NOEXCEPT
Constructs a converter for a given registry.
Definition: entt.hpp:9808
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
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
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
~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
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 > ®, 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
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
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
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
Types identifiers.
Definition: entt.hpp:651
overloaded(Type...) -> overloaded< Type... >
Deduction guide.
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
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
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
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
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
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.
constexpr hash_type value() const ENTT_NOEXCEPT
Returns the numeric representation of a hashed string.
Definition: entt.hpp:519
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
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
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
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
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
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 > ®, 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 & 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
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
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
Resource resource_type
Type of resources managed by a cache.
Definition: entt.hpp:15160
connection connect(Type *value_or_instance)
Connects a member function or a free function with payload to a signal.
Definition: entt.hpp:3417
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
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
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
payload_type object_type
Type of the objects associated with the entities.
Definition: entt.hpp:5481
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
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
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
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
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
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
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
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
Geom::Vec operator *(const double Scalar, const Geom::Vec &V)
Definition: Vec.h:312
typename event_handler< Event >::listener_type listener
Type of listeners accepted for the given event.
Definition: entt.hpp:17623
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
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
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 create()
Creates a new entity and returns it.
Definition: entt.hpp:8284
basic_view< entity, Types... > view
Alias declaration for the most common use case.
Definition: entt.hpp:3812
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
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
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
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
Entity entity_type
Underlying entity identifier.
Definition: entt.hpp:7157
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
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
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
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
#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
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
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
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.
std::size_t size_type
Unsigned integer type.
Definition: entt.hpp:7518
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
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 sortable() const ENTT_NOEXCEPT
Checks whether the given components belong to any group.
Definition: entt.hpp:9032
std::uint8_t version_type
Underlying version type.
Definition: entt.hpp:3594
#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
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
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
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