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;
 
  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>
 
  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>
 
 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;
 
 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>
 
 2968     friend class sink<Ret(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);
 
 3083         std::swap(signal, other.signal);
 
 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;
 
 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) {
 
 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));
 
 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));
 
 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));
 
 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;
 
 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 {
 
 3912             return iterator{direct, 
index-value};
 
 3915         iterator & operator-=(
const difference_type value) 
ENTT_NOEXCEPT {
 
 3916             return (*
this += -value);
 
 3920             return (*
this + -value);
 
 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;
 
 3984         const auto page = 
size_type(identifier / entt_per_page);
 
 3985         const auto offset = 
size_type(identifier & (entt_per_page - 1));
 
 3986         return std::make_pair(page, offset);
 
 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 {
 
 4236             ENTT_ASSERT(!has(entt));
 
 4237             auto [page, offset] = map(entt);
 
 4239             reverse[page][offset] = entity_type(next++);
 
 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];
 
 4287         std::swap(from, to);
 
 4329     template<
typename Compare, 
typename Sort = 
std_sort, 
typename... Args>
 
 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>
 
 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 {
 
 4509     friend class basic_registry<Entity>;
 
 4514         friend class basic_runtime_view<Entity>;
 
 4516         iterator(underlying_iterator_type first, underlying_iterator_type last, 
const sparse_set<Entity> * 
const *others, 
const sparse_set<Entity> * 
const *length) 
ENTT_NOEXCEPT 
 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;
 
 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) {
 
 4672             return view->find(entt) != view->end();
 
 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 {
 
 4743     friend class basic_registry<Entity>;
 
 4746     using traits_type = entt_traits<std::underlying_type_t<Entity>>;
 
 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), ...);
 
 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>
 
 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>
 
 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));
 
 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), ...);
 
 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));
 
 5087         std::swap(container, other);
 
 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 {
 
 5421             return iterator{instances, 
index-value};
 
 5424         iterator & operator-=(
const difference_type value) 
ENTT_NOEXCEPT {
 
 5425             return (*
this += -value);
 
 5429             return (*
this + -value);
 
 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());
 
 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>
 
 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 {
 
 5850             return iterator{
index-value};
 
 5853         iterator & operator-=(
const difference_type value) 
ENTT_NOEXCEPT {
 
 5854             return (*
this += -value);
 
 5858             return (*
this + -value);
 
 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>
 
 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>
 
 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>
 
 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;
 
 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;
 
 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>...>);
 
 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) {
 
 9138                 if((std::get<pool_type<Owned> *>(cpools)->has(entity) && ...)
 
 9139                         && (std::get<pool_type<Get> *>(cpools)->has(entity) && ...)
 
 9140                         && !(std::get<pool_type<Exclude> *>(cpools)->has(entity) || ...))
 
 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>...>);
 
 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>...>);
 
 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>
 
 9341         const entity_type 
entt[1]{dst};
 
 9342         stomp<Component...>(std::begin(
entt), std::end(
entt), src, other, 
exclude<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 {
 
 9431                     return entity_type(curr++);
 
 9435             others[
entt] = entity;
 
 9438                 reg.destroy(entity);
 
 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{};
 
 9563     entity_type destroyed{
null};
 
 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)};
 
 9656             std::swap(reg, tmp.reg);
 
 9657             std::swap(
entt, tmp.entt);
 
 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);
 
12130             std::swap(rhs.instance, lhs.instance);
 
12131         } 
else if(rhs.steal_fn) {
 
12132             rhs.instance = rhs.steal_fn(lhs.storage, rhs.instance, rhs.destroy_fn);
 
12133             std::swap(rhs.instance, lhs.instance);
 
12135             std::swap(lhs.instance, rhs.instance);
 
12138         std::swap(lhs.node, rhs.node);
 
12139         std::swap(lhs.destroy_fn, rhs.destroy_fn);
 
12140         std::swap(lhs.copy_fn, rhs.copy_fn);
 
12141         std::swap(lhs.steal_fn, rhs.steal_fn);
 
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) {
 
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>
 
14991     friend struct cache<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>
 
15118     friend struct cache<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);
 
16748         std::swap(signal, other.signal);
 
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));
 
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));
 
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));
 
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;
 
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