1#ifndef ENTT_ENTITY_REGISTRY_HPP
2#define ENTT_ENTITY_REGISTRY_HPP
5#include "../config/config.h"
6#include "../container/dense_map.hpp"
7#include "../core/algorithm.hpp"
8#include "../core/any.hpp"
9#include "../core/concepts.hpp"
10#include "../core/fwd.hpp"
11#include "../core/iterator.hpp"
12#include "../core/memory.hpp"
13#include "../core/type_info.hpp"
14#include "../core/type_traits.hpp"
15#include "../stl/algorithm.hpp"
16#include "../stl/array.hpp"
17#include "../stl/concepts.hpp"
18#include "../stl/cstddef.hpp"
19#include "../stl/functional.hpp"
20#include "../stl/iterator.hpp"
21#include "../stl/memory.hpp"
22#include "../stl/tuple.hpp"
23#include "../stl/type_traits.hpp"
24#include "../stl/utility.hpp"
29#include "sparse_set.hpp"
39class registry_storage_iterator final {
41 friend class registry_storage_iterator;
43 using mapped_type = stl::remove_reference_t<decltype(stl::declval<It>()->second)>;
46 using value_type = stl::pair<id_type, constness_as_t<typename mapped_type::element_type, mapped_type> &>;
47 using pointer = input_iterator_pointer<value_type>;
48 using reference = value_type;
49 using difference_type = stl::ptrdiff_t;
50 using iterator_category = stl::input_iterator_tag;
51 using iterator_concept = stl::random_access_iterator_tag;
53 constexpr registry_storage_iterator() noexcept
56 constexpr registry_storage_iterator(It iter) noexcept
59 template<
typename Other>
60 requires (!stl::same_as<It, Other> && stl::constructible_from<It, Other>)
61 constexpr registry_storage_iterator(
const registry_storage_iterator<Other> &other) noexcept
62 : registry_storage_iterator{other.it} {}
64 constexpr registry_storage_iterator &operator++() noexcept {
68 constexpr registry_storage_iterator operator++(
int)
noexcept {
69 const registry_storage_iterator orig = *
this;
70 return ++(*this), orig;
73 constexpr registry_storage_iterator &operator--() noexcept {
77 constexpr registry_storage_iterator operator--(
int)
noexcept {
78 const registry_storage_iterator orig = *
this;
79 return operator--(), orig;
82 constexpr registry_storage_iterator &operator+=(
const difference_type value)
noexcept {
87 constexpr registry_storage_iterator
operator+(
const difference_type value)
const noexcept {
88 registry_storage_iterator copy = *
this;
89 return (copy += value);
92 constexpr registry_storage_iterator &operator-=(
const difference_type value)
noexcept {
93 return (*
this += -value);
96 constexpr registry_storage_iterator operator-(
const difference_type value)
const noexcept {
97 return (*
this + -value);
100 [[nodiscard]]
constexpr reference operator[](
const difference_type value)
const noexcept {
101 return {it[value].first, *it[value].second};
104 [[nodiscard]]
constexpr reference operator*() const noexcept {
105 return operator[](0);
108 [[nodiscard]]
constexpr pointer operator->() const noexcept {
112 template<
typename Other>
113 [[nodiscard]]
constexpr stl::ptrdiff_t operator-(
const registry_storage_iterator<Other> &other)
const noexcept {
114 return it - other.it;
117 template<
typename Other>
118 [[nodiscard]]
constexpr bool operator==(
const registry_storage_iterator<Other> &other)
const noexcept {
119 return it == other.it;
122 template<
typename Other>
123 [[nodiscard]]
constexpr auto operator<=>(
const registry_storage_iterator<Other> &other)
const noexcept {
124 return it <=> other.it;
131template<
typename Allocator>
132class registry_context {
133 using alloc_traits = stl::allocator_traits<Allocator>;
134 using allocator_type = alloc_traits::template rebind_alloc<stl::pair<const id_type, basic_any<0u>>>;
137 explicit registry_context(
const allocator_type &allocator)
140 void clear() noexcept {
144 template<
typename Type,
typename... Args>
145 Type &emplace_as(
const id_type
id, Args &&...args) {
146 return any_cast<Type &>(ctx.try_emplace(
id, stl::in_place_type<Type>, stl::forward<Args>(args)...).first->second);
149 template<
typename Type,
typename... Args>
150 Type &emplace(Args &&...args) {
151 return emplace_as<Type>(type_id<Type>().hash(), stl::forward<Args>(args)...);
154 template<
typename Type>
155 Type &insert_or_assign(
const id_type
id, Type &&value) {
156 return any_cast<stl::remove_cvref_t<Type> &>(ctx.insert_or_assign(
id, stl::forward<Type>(value)).first->second);
159 template<
typename Type>
160 Type &insert_or_assign(Type &&value) {
161 return insert_or_assign(type_id<Type>().hash(), stl::forward<Type>(value));
164 template<
typename Type>
165 bool erase(
const id_type
id = type_id<Type>().hash()) {
166 const auto it = ctx.find(
id);
167 return it != ctx.end() && it->second.info() == type_id<Type>() ? (ctx.erase(it),
true) :
false;
170 template<
typename Type>
171 [[nodiscard]]
const Type &
get(
const id_type
id = type_id<Type>().hash())
const {
172 return any_cast<const Type &>(ctx.at(
id));
175 template<
typename Type>
176 [[nodiscard]] Type &
get(
const id_type
id = type_id<Type>().hash()) {
177 return any_cast<Type &>(ctx.at(
id));
180 template<
typename Type>
181 [[nodiscard]]
const Type *find(
const id_type
id = type_id<Type>().hash())
const {
182 const auto it = ctx.find(
id);
183 return it != ctx.cend() ? any_cast<const Type>(&it->second) : nullptr;
186 template<
typename Type>
187 [[nodiscard]] Type *find(
const id_type
id = type_id<Type>().hash()) {
188 const auto it = ctx.find(
id);
189 return it != ctx.end() ? any_cast<Type>(&it->second) : nullptr;
192 template<
typename Type>
193 [[nodiscard]]
bool contains(
const id_type
id = type_id<Type>().hash())
const {
194 const auto it = ctx.find(
id);
195 return it != ctx.cend() && it->second.info() == type_id<Type>();
199 dense_map<id_type, basic_any<0u>, stl::identity, stl::equal_to<>, allocator_type> ctx;
210template<
typename Entity,
typename Allocator>
213 using alloc_traits = stl::allocator_traits<Allocator>;
214 static_assert(stl::is_same_v<typename alloc_traits::value_type, Entity>,
"Invalid value type");
220 template<cvref_unqualified Type>
222 if constexpr(stl::is_same_v<Type, entity_type>) {
228 if(
auto it = pools.find(
id); it != pools.cend()) {
229 ENTT_ASSERT(it->second->info() ==
type_id<Type>(),
"Unexpected type");
234 pools.emplace(
id, cpool);
241 template<cvref_unqualified Type>
243 if constexpr(stl::is_same_v<Type, entity_type>) {
247 if(
const auto it = pools.find(
id); it != pools.cend()) {
248 ENTT_ASSERT(it->second->info() ==
type_id<Type>(),
"Unexpected type");
257 entities.bind(*
this);
259 for(
auto &&curr: pools) {
260 curr.second->bind(*
this);
276 using context = internal::registry_context<allocator_type>;
286 template<
typename Type>
309 entities{allocator} {
322 : vars{stl::move(other.vars)},
323 pools{stl::move(other.pools)},
324 groups{stl::move(other.groups)},
325 entities{stl::move(other.entities)} {
355 swap(vars, other.vars);
356 swap(pools, other.pools);
357 swap(groups, other.groups);
358 swap(entities, other.entities);
369 return entities.get_allocator();
381 return iterable{pools.begin(), pools.end()};
395 return const_cast<common_type *
>(stl::as_const(*this).storage(
id));
404 const auto it = pools.
find(
id);
405 return it == pools.cend() ? nullptr : it->second.get();
414 template<
typename Type>
416 return assure<stl::remove_const_t<Type>>(id);
425 template<
typename Type>
427 return assure<stl::remove_const_t<Type>>(id);
437 return !(pools.erase(
id) == 0u);
446 return static_cast<size_type>(entities.find(
entt).index()) < entities.free_list();
456 return entities.current(
entt);
464 return entities.generate();
477 return entities.generate(hint);
489 template<stl::output_iterator<entity_type> It>
491 entities.generate(stl::move(first), stl::move(last));
505 for(
size_type pos = pools.size(); pos != 0u; --pos) {
509 entities.erase(
entt);
510 return entities.current(
entt);
539 void destroy(stl::input_iterator
auto first, stl::input_iterator
auto last) {
540 const auto to = entities.sort_as(first, last);
543 for(
auto &&curr: pools) {
544 curr.second->remove(from, to);
547 entities.erase(from, to);
565 template<
typename Type,
typename... Args>
567 ENTT_ASSERT(
valid(
entt),
"Invalid entity");
568 return assure<Type>().emplace(
entt, stl::forward<Args>(args)...);
581 template<
typename Type>
582 void insert(stl::input_iterator
auto first, stl::input_iterator
auto last,
const Type &value = {}) {
583 ENTT_ASSERT(stl::all_of(first, last, [
this](
const auto entt) {
return valid(
entt); }),
"Invalid entity");
584 assure<Type>().insert(stl::move(first), stl::move(last), value);
599 template<
typename Type,
typename EIt,
typename CIt>
600 requires stl::same_as<typename stl::iterator_traits<CIt>::value_type, Type>
601 void insert(EIt first, EIt last, CIt from) {
602 ENTT_ASSERT(stl::all_of(first, last, [
this](
const auto entt) {
return valid(
entt); }),
"Invalid entity");
603 assure<Type>().insert(first, last, from);
618 template<
typename Type,
typename... Args>
620 auto &cpool = assure<Type>();
621 ENTT_ASSERT(
valid(
entt),
"Invalid entity");
622 return cpool.contains(
entt) ? cpool.patch(
entt, [&args...](
auto &...curr) { ((curr = Type{stl::forward<Args>(args)...}), ...); }) : cpool.
emplace(
entt,
stl::forward<Args>(args)...);
644 template<
typename Type,
typename... Func>
646 return assure<Type>().patch(
entt, stl::forward<Func>(func)...);
664 template<
typename Type,
typename... Args>
666 return patch<Type>(
entt, [&args...](
auto &...curr) { ((curr = Type{stl::forward<Args>(args)...}), ...); });
676 template<
typename Type,
typename... Other>
693 template<
typename Type,
typename... Other, stl::input_iterator It>
697 if constexpr(stl::is_same_v<It, typename common_type::iterator>) {
698 stl::array cpools{
static_cast<common_type *
>(&assure<Type>()),
static_cast<common_type *
>(&assure<Other>())...};
700 for(
auto from = cpools.begin(), to = cpools.end(); from != to; ++from) {
701 if constexpr(
sizeof...(Other) != 0u) {
702 if((*from)->data() == first.data()) {
703 stl::swap((*from), cpools.back());
707 count += (*from)->remove(first, last);
711 for(
auto cpools = stl::forward_as_tuple(assure<Type>(), assure<Other>()...); first != last; ++first) {
712 count += stl::apply([
entt = *first](
auto &...curr) {
return (curr.remove(
entt) + ... + 0u); }, cpools);
730 template<
typename Type,
typename... Other>
732 (assure<Type>().erase(
entt), (assure<Other>().erase(
entt), ...));
746 template<
typename Type,
typename... Other, stl::input_iterator It>
748 if constexpr(stl::is_same_v<It, typename common_type::iterator>) {
749 stl::array cpools{
static_cast<common_type *
>(&assure<Type>()),
static_cast<common_type *
>(&assure<Other>())...};
751 for(
auto from = cpools.begin(), to = cpools.end(); from != to; ++from) {
752 if constexpr(
sizeof...(Other) != 0u) {
753 if((*from)->data() == first.data()) {
754 stl::swap(*from, cpools.back());
758 (*from)->erase(first, last);
761 for(
auto cpools = stl::forward_as_tuple(assure<Type>(), assure<Other>()...); first != last; ++first) {
762 stl::apply([
entt = *first](
auto &...curr) { (curr.erase(
entt), ...); }, cpools);
782 template<
typename Func>
784 for(
auto [
id, cpool]:
storage()) {
785 if(cpool.contains(
entt) && func(
id, stl::as_const(cpool))) {
796 template<
typename... Type>
798 if constexpr(
sizeof...(Type) == 0u) {
799 for(
auto &&curr: pools) {
800 curr.second->compact();
803 (assure<Type>().compact(), ...);
813 template<
typename... Type>
815 if constexpr(
sizeof...(Type) == 1u) {
816 auto *cpool = assure<stl::remove_const_t<Type>...>();
817 return cpool && cpool->contains(
entt);
830 template<
typename... Type>
846 template<
typename... Type>
848 if constexpr(
sizeof...(Type) == 1u) {
849 return (assure<stl::remove_const_t<Type>>()->
get(
entt), ...);
856 template<
typename... Type>
858 if constexpr(
sizeof...(Type) == 1u) {
880 template<
typename Type,
typename... Args>
882 auto &cpool = assure<Type>();
883 ENTT_ASSERT(
valid(
entt),
"Invalid entity");
884 return cpool.contains(
entt) ? cpool.get(
entt) : cpool.emplace(
entt, stl::forward<Args>(args)...);
897 template<
typename... Type>
899 if constexpr(
sizeof...(Type) == 1u) {
900 const auto *cpool = assure<stl::remove_const_t<Type>...>();
901 return (cpool && cpool->contains(
entt)) ? stl::addressof(cpool->get(
entt)) :
nullptr;
908 template<
typename... Type>
910 if constexpr(
sizeof...(Type) == 1u) {
911 return (
const_cast<Type *
>(stl::as_const(*this).template
try_get<Type>(
entt)), ...);
921 template<
typename... Type>
923 if constexpr(
sizeof...(Type) == 0u) {
924 for(
size_type pos = pools.size(); pos; --pos) {
928 const auto elem = entities.each();
929 entities.erase(elem.begin().base(), elem.end().base());
931 (assure<Type>().clear(), ...);
941 return stl::none_of(pools.cbegin(), pools.cend(), [
entt](
auto &&curr) { return curr.second->contains(entt); });
963 template<
typename Type>
965 return assure<Type>(
id).on_construct();
987 template<
typename Type>
989 return assure<Type>(
id).on_update();
1011 template<
typename Type>
1013 return assure<Type>(
id).on_destroy();
1023 template<
typename Type,
typename... Other,
typename... Exclude>
1027 [&elem](
const auto *...curr) { ((curr ? elem.storage(*curr) :
void()), ...); }(assure<stl::remove_const_t<Exclude>>()..., assure<stl::remove_const_t<Other>>()..., assure<stl::remove_const_t<Type>>());
1032 template<
typename Type,
typename... Other,
typename... Exclude>
1033 [[nodiscard]] basic_view<get_t<storage_for_type<Type>, storage_for_type<Other>...>, exclude_t<storage_for_type<Exclude>...>>
1035 return {assure<stl::remove_const_t<Type>>(), assure<stl::remove_const_t<Other>>()..., assure<stl::remove_const_t<Exclude>>()...};
1045 template<
typename... Owned,
typename... Get,
typename... Exclude>
1046 basic_group<owned_t<storage_for_type<Owned>...>, get_t<storage_for_type<Get>...>, exclude_t<storage_for_type<Exclude>...>>
1048 using group_type = basic_group<owned_t<storage_for_type<Owned>...>, get_t<storage_for_type<Get>...>, exclude_t<storage_for_type<Exclude>...>>;
1049 using handler_type = group_type::handler;
1051 if(
auto it = groups.find(group_type::group_id()); it != groups.cend()) {
1052 return {*stl::static_pointer_cast<handler_type>(it->second)};
1055 stl::shared_ptr<handler_type> handler{};
1057 if constexpr(
sizeof...(Owned) == 0u) {
1058 handler = stl::allocate_shared<handler_type>(get_allocator(), get_allocator(), stl::forward_as_tuple(assure<stl::remove_const_t<Get>>()...), stl::forward_as_tuple(assure<stl::remove_const_t<Exclude>>()...));
1060 handler = stl::allocate_shared<handler_type>(get_allocator(), stl::forward_as_tuple(assure<stl::remove_const_t<Owned>>()..., assure<stl::remove_const_t<Get>>()...), stl::forward_as_tuple(assure<stl::remove_const_t<Exclude>>()...));
1061 ENTT_ASSERT(stl::all_of(groups.cbegin(), groups.cend(), [](
const auto &data) { return !(data.second->owned(type_id<Owned>().hash()) || ...); }),
"Conflicting groups");
1064 groups.emplace(group_type::group_id(), handler);
1069 template<
typename... Owned,
typename... Get,
typename... Exclude>
1070 [[nodiscard]] basic_group<owned_t<storage_for_type<const Owned>...>, get_t<storage_for_type<const Get>...>, exclude_t<storage_for_type<const Exclude>...>>
1072 using group_type = basic_group<owned_t<storage_for_type<const Owned>...>, get_t<storage_for_type<const Get>...>, exclude_t<storage_for_type<const Exclude>...>>;
1073 using handler_type = group_type::handler;
1075 if(
auto it = groups.find(group_type::group_id()); it != groups.cend()) {
1076 return {*stl::static_pointer_cast<handler_type>(it->second)};
1088 template<
typename... Type>
1090 return stl::any_of(groups.cbegin(), groups.cend(), [](
auto &&data) { return (data.second->owned(type_id<Type>().hash()) || ...); });
1126 template<
typename Type,
typename Compare,
typename Sort =
std_sort,
typename... Args>
1127 void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
1128 ENTT_ASSERT(!
owned<Type>(),
"Cannot sort owned storage");
1129 auto &cpool = assure<Type>();
1131 if constexpr(stl::is_invocable_v<Compare,
decltype(cpool.get({})),
decltype(cpool.get({}))>) {
1132 auto comp = [&cpool, compare = stl::move(compare)](
const auto lhs,
const auto rhs) {
return compare(stl::as_const(cpool.get(lhs)), stl::as_const(cpool.get(rhs))); };
1133 cpool.sort(stl::move(comp), stl::move(algo), stl::forward<Args>(args)...);
1135 cpool.sort(stl::move(compare), stl::move(algo), stl::forward<Args>(args)...);
1152 template<
typename To,
typename From>
1154 ENTT_ASSERT(!
owned<To>(),
"Cannot sort owned storage");
1155 const base_type &cpool = assure<From>();
1156 assure<To>().sort_as(cpool.
begin(), cpool.
end());
1174 pool_container_type pools;
1175 group_container_type groups;
1176 storage_for_type<entity_type> entities;
static constexpr value_type construct(const entity_type entity, const version_type version) noexcept
static constexpr value_type next(const value_type value) noexcept
static constexpr entity_type to_entity(const value_type value) noexcept
internal::entt_traits< Type >::value_type value_type
internal::entt_traits< Type >::version_type version_type
context & ctx() noexcept
Returns the context object, that is, a general purpose container.
auto on_destroy(const id_type id=type_hash< Type >::value())
Returns a sink object for the given element.
bool any_of(const entity_type entt) const
Check if an entity is part of at least one given storage.
bool owned() const
Checks whether the given elements belong to any group.
decltype(auto) get_or_emplace(const entity_type entt, Args &&...args)
Returns a reference to the given element for an entity.
bool orphan(const entity_type entt) const
Checks if an entity has elements assigned.
decltype(auto) replace(const entity_type entt, Args &&...args)
Replaces the given element for an entity.
basic_registry(const size_type count, const allocator_type &allocator=allocator_type{})
Allocates enough memory upon construction to store count pools.
auto on_update(const id_type id=type_hash< Type >::value())
Returns a sink object for the given element.
storage_for< Type, Entity, typename alloc_traits::template rebind_alloc< stl::remove_const_t< Type > > >::type storage_for_type
traits_type::version_type version_type
const common_type * storage(const id_type id) const
Finds the storage associated with a given name, if any.
auto try_get(const entity_type entt) const
Returns pointers to the given elements for an entity.
void swap(basic_registry &other) noexcept
Exchanges the contents with those of a given registry.
iterable_adaptor< internal::registry_storage_iterator< typename pool_container_type::iterator > > iterable
decltype(auto) emplace_or_replace(const entity_type entt, Args &&...args)
Assigns or replaces the given element for an entity.
iterable storage() noexcept
Returns an iterable object to use to visit a registry.
bool valid(const entity_type entt) const
Checks if an identifier refers to a valid entity.
bool all_of(const entity_type entt) const
Check if an entity is part of all the given storage.
void erase_if(const entity_type entt, Func func)
Erases elements satisfying specific criteria from an entity.
version_type destroy(const entity_type entt)
Destroys an entity and releases its identifier.
entity_type create()
Creates a new entity or recycles a destroyed one.
const context & ctx() const noexcept
Returns the context object, that is, a general purpose container.
void sort()
Sorts two pools of elements in the same way.
void insert(EIt first, EIt last, CIt from)
Assigns each entity in a range the given elements.
version_type destroy(const entity_type entt, const version_type version)
Destroys an entity and releases its identifier.
basic_view< get_t< storage_for_type< const Type >, storage_for_type< const Other >... >, exclude_t< storage_for_type< const Exclude >... > > view(exclude_t< Exclude... >=exclude_t{}) const
Returns a view for the given elements.
traits_type::value_type entity_type
void create(It first, It last)
Assigns each element in a range an identifier.
size_type remove(It first, It last)
Removes the given elements from all the entities in a range.
entity_type create(const entity_type hint)
Creates a new entity or recycles a destroyed one.
void clear()
Clears a whole registry or the pools for the given elements.
bool reset(const id_type id)
Discards the storage associated with a given name, if any.
decltype(auto) patch(const entity_type entt, Func &&...func)
Patches the given element for an entity.
basic_group< owned_t< storage_for_type< const Owned >... >, get_t< storage_for_type< const Get >... >, exclude_t< storage_for_type< const Exclude >... > > group_if_exists(get_t< Get... >=get_t{}, exclude_t< Exclude... >=exclude_t{}) const
Returns a group for the given elements.
size_type remove(const entity_type entt)
Removes the given elements from an entity.
basic_registry & operator=(basic_registry &&other) noexcept
Move assignment operator.
basic_view< get_t< storage_for_type< Type >, storage_for_type< Other >... >, exclude_t< storage_for_type< Exclude >... > > view(exclude_t< Exclude... >=exclude_t{})
Returns a view for the given elements.
auto try_get(const entity_type entt)
Returns pointers to the given elements for an entity.
common_type * storage(const id_type id)
Finds the storage associated with a given name, if any.
decltype(auto) get(const entity_type entt)
Returns references to the given elements for an entity.
void erase(It first, It last)
Erases the given elements from all the entities in a range.
void sort(Compare compare, Sort algo=Sort{}, Args &&...args)
Sorts the elements of a given element.
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
decltype(auto) emplace(const entity_type entt, Args &&...args)
Assigns the given element to an entity.
void destroy(stl::input_iterator auto first, stl::input_iterator auto last)
Destroys all entities in a range and releases their identifiers.
basic_registry & operator=(const basic_registry &)=delete
Default copy assignment operator, deleted on purpose.
basic_registry(const allocator_type &allocator)
Constructs an empty registry with a given allocator.
auto on_construct(const id_type id=type_hash< Type >::value())
Returns a sink object for the given element.
storage_for_type< Type > & storage(const id_type id=type_hash< Type >::value())
Returns the storage for a given element type.
decltype(auto) get(const entity_type entt) const
Returns references to the given elements for an entity.
basic_registry(basic_registry &&other) noexcept
Move constructor.
void compact()
Removes all tombstones from a registry or only the pools for the given elements.
const_iterable storage() const noexcept
Returns an iterable object to use to visit a registry.
~basic_registry()=default
Default destructor.
version_type current(const entity_type entt) const
Returns the actual version for an identifier.
basic_group< owned_t< storage_for_type< Owned >... >, get_t< storage_for_type< Get >... >, exclude_t< storage_for_type< Exclude >... > > group(get_t< Get... >=get_t{}, exclude_t< Exclude... >=exclude_t{})
Returns a group for the given elements.
const storage_for_type< Type > * storage(const id_type id=type_hash< Type >::value()) const
Returns the storage for a given element type, if any.
void insert(stl::input_iterator auto first, stl::input_iterator auto last, const Type &value={})
Assigns each entity in a range the given element.
basic_registry(const basic_registry &)=delete
Default copy constructor, deleted on purpose.
internal::registry_context< allocator_type > context
iterable_adaptor< internal::registry_storage_iterator< typename pool_container_type::const_iterator > > const_iterable
basic_registry()
Default constructor.
void erase(const entity_type entt)
Erases the given elements from an entity.
Sparse set implementation.
iterator begin() const noexcept
Returns an iterator to the beginning.
iterator end() const noexcept
Returns an iterator to the end.
const_iterator find(const entity_type entt) const noexcept
Finds an entity.
stl::ptrdiff_t difference_type
Signed integer type.
Associative container for key-value pairs with unique keys.
stl::ptrdiff_t difference_type
void reserve(const size_type cnt)
Reserves space for at least the specified number of elements and regenerates the hash table.
stl::shared_ptr< base_type > mapped_type
Custom EnTT namespace for the standard template library.
constexpr tombstone_t tombstone
Compile-time constant for tombstone entities.
constexpr get_t< Type... > get
Variable template for lists of observed elements.
constexpr type_list< Type..., Other... > operator+(type_list< Type... >, type_list< Other... >)
Concatenates multiple type lists.
constexpr owned_t< Type... > owned
Variable template for lists of owned elements.
const type_info & type_id() noexcept
Returns the type info object associated to a given type.
stl::uint32_t id_type
Alias declaration for type identifiers.
Alias for exclusion lists.
Alias for lists of observed elements.
Utility class to create an iterable object from a pair of iterators.
Function object to wrap stl::sort in a class type.
Provides a common way to define storage types.
static constexpr id_type value() noexcept
Returns the numeric representation of a given type.