1#ifndef ENTT_ENTITY_REGISTRY_HPP
2#define ENTT_ENTITY_REGISTRY_HPP
13#include "../config/config.h"
14#include "../container/dense_map.hpp"
15#include "../core/algorithm.hpp"
16#include "../core/any.hpp"
17#include "../core/fwd.hpp"
18#include "../core/iterator.hpp"
19#include "../core/memory.hpp"
20#include "../core/type_info.hpp"
21#include "../core/type_traits.hpp"
22#include "../core/utility.hpp"
27#include "sparse_set.hpp"
37class registry_storage_iterator final {
38 template<
typename Other>
39 friend class registry_storage_iterator;
41 using mapped_type = std::remove_reference_t<decltype(std::declval<It>()->second)>;
44 using value_type = std::pair<id_type, constness_as_t<typename mapped_type::element_type, mapped_type> &>;
45 using pointer = input_iterator_pointer<value_type>;
46 using reference = value_type;
47 using difference_type = std::ptrdiff_t;
48 using iterator_category = std::input_iterator_tag;
49 using iterator_concept = std::random_access_iterator_tag;
51 constexpr registry_storage_iterator() noexcept
54 constexpr registry_storage_iterator(It iter) noexcept
57 template<
typename Other,
typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
58 constexpr registry_storage_iterator(
const registry_storage_iterator<Other> &other) noexcept
59 : registry_storage_iterator{other.it} {}
61 constexpr registry_storage_iterator &operator++() noexcept {
65 constexpr registry_storage_iterator operator++(
int)
noexcept {
66 registry_storage_iterator orig = *
this;
67 return ++(*this), orig;
70 constexpr registry_storage_iterator &operator--() noexcept {
74 constexpr registry_storage_iterator operator--(
int)
noexcept {
75 registry_storage_iterator orig = *
this;
76 return operator--(), orig;
79 constexpr registry_storage_iterator &operator+=(
const difference_type value)
noexcept {
84 constexpr registry_storage_iterator
operator+(
const difference_type value)
const noexcept {
85 registry_storage_iterator copy = *
this;
86 return (copy += value);
89 constexpr registry_storage_iterator &operator-=(
const difference_type value)
noexcept {
90 return (*
this += -value);
93 constexpr registry_storage_iterator operator-(
const difference_type value)
const noexcept {
94 return (*
this + -value);
97 [[nodiscard]]
constexpr reference operator[](
const difference_type value)
const noexcept {
98 return {it[value].first, *it[value].second};
101 [[nodiscard]]
constexpr reference operator*() const noexcept {
102 return {it->first, *it->second};
105 [[nodiscard]]
constexpr pointer operator->() const noexcept {
109 template<
typename Lhs,
typename Rhs>
110 friend constexpr std::ptrdiff_t operator-(
const registry_storage_iterator<Lhs> &,
const registry_storage_iterator<Rhs> &)
noexcept;
112 template<
typename Lhs,
typename Rhs>
113 friend constexpr bool operator==(
const registry_storage_iterator<Lhs> &,
const registry_storage_iterator<Rhs> &)
noexcept;
115 template<
typename Lhs,
typename Rhs>
116 friend constexpr bool operator<(
const registry_storage_iterator<Lhs> &,
const registry_storage_iterator<Rhs> &)
noexcept;
122template<
typename Lhs,
typename Rhs>
123[[nodiscard]]
constexpr std::ptrdiff_t operator-(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
124 return lhs.it - rhs.it;
127template<
typename Lhs,
typename Rhs>
128[[nodiscard]]
constexpr bool operator==(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
129 return lhs.it == rhs.it;
132template<
typename Lhs,
typename Rhs>
133[[nodiscard]]
constexpr bool operator!=(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
134 return !(lhs == rhs);
137template<
typename Lhs,
typename Rhs>
138[[nodiscard]]
constexpr bool operator<(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
139 return lhs.it < rhs.it;
142template<
typename Lhs,
typename Rhs>
143[[nodiscard]]
constexpr bool operator>(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
147template<
typename Lhs,
typename Rhs>
148[[nodiscard]]
constexpr bool operator<=(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
152template<
typename Lhs,
typename Rhs>
153[[nodiscard]]
constexpr bool operator>=(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
157template<
typename Allocator>
158class registry_context {
159 using alloc_traits = std::allocator_traits<Allocator>;
160 using allocator_type =
typename alloc_traits::template rebind_alloc<std::pair<const id_type, basic_any<0u>>>;
163 explicit registry_context(
const allocator_type &allocator)
166 template<
typename Type,
typename... Args>
167 Type &emplace_as(
const id_type
id, Args &&...args) {
168 return any_cast<Type &>(ctx.try_emplace(
id, std::in_place_type<Type>, std::forward<Args>(args)...).first->second);
171 template<
typename Type,
typename... Args>
172 Type &emplace(Args &&...args) {
173 return emplace_as<Type>(type_id<Type>().hash(), std::forward<Args>(args)...);
176 template<
typename Type>
177 Type &insert_or_assign(
const id_type
id, Type &&value) {
178 return any_cast<std::remove_cv_t<std::remove_reference_t<Type>> &>(ctx.insert_or_assign(
id, std::forward<Type>(value)).first->second);
181 template<
typename Type>
182 Type &insert_or_assign(Type &&value) {
183 return insert_or_assign(type_id<Type>().hash(), std::forward<Type>(value));
186 template<
typename Type>
187 bool erase(
const id_type
id = type_id<Type>().hash()) {
188 const auto it = ctx.find(
id);
189 return it != ctx.end() && it->second.type() == type_id<Type>() ? (ctx.erase(it),
true) : false;
192 template<
typename Type>
193 [[nodiscard]]
const Type &
get(
const id_type
id = type_id<Type>().hash())
const {
194 return any_cast<const Type &>(ctx.at(
id));
197 template<
typename Type>
198 [[nodiscard]] Type &
get(
const id_type
id = type_id<Type>().hash()) {
199 return any_cast<Type &>(ctx.at(
id));
202 template<
typename Type>
203 [[nodiscard]]
const Type *find(
const id_type
id = type_id<Type>().hash())
const {
204 const auto it = ctx.find(
id);
205 return it != ctx.cend() ? any_cast<const Type>(&it->second) : nullptr;
208 template<
typename Type>
209 [[nodiscard]] Type *find(
const id_type
id = type_id<Type>().hash()) {
210 const auto it = ctx.find(
id);
211 return it != ctx.end() ? any_cast<Type>(&it->second) : nullptr;
214 template<
typename Type>
215 [[nodiscard]]
bool contains(
const id_type
id = type_id<Type>().hash())
const {
216 const auto it = ctx.find(
id);
217 return it != ctx.cend() && it->second.type() == type_id<Type>();
221 dense_map<id_type, basic_any<0u>, identity, std::equal_to<id_type>, allocator_type> ctx;
232template<
typename Entity,
typename Allocator>
236 using alloc_traits = std::allocator_traits<Allocator>;
237 static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>,
"Invalid value type");
243 template<
typename Type>
245 static_assert(std::is_same_v<Type, std::decay_t<Type>>,
"Non-decayed types not allowed");
247 if constexpr(std::is_same_v<Type, entity_type>) {
250 auto &cpool = pools[id];
254 using alloc_type =
typename storage_type::allocator_type;
256 if constexpr(std::is_void_v<Type> && !std::is_constructible_v<alloc_type, allocator_type>) {
258 cpool = std::allocate_shared<storage_type>(
get_allocator(), alloc_type{});
266 ENTT_ASSERT(cpool->type() == type_id<Type>(),
"Unexpected type");
271 template<
typename Type>
273 static_assert(std::is_same_v<Type, std::decay_t<Type>>,
"Non-decayed types not allowed");
275 if constexpr(std::is_same_v<Type, entity_type>) {
278 if(
const auto it = pools.
find(
id); it != pools.
cend()) {
279 ENTT_ASSERT(it->second->type() == type_id<Type>(),
"Unexpected type");
290 for(
auto &&curr: pools) {
309 using context = internal::registry_context<allocator_type>;
319 template<
typename Type>
342 entities{allocator} {
352 : vars{std::move(other.vars)},
353 pools{std::move(other.pools)},
354 groups{std::move(other.groups)},
355 entities{std::move(other.entities)} {
365 vars = std::move(other.vars);
366 pools = std::move(other.pools);
367 groups = std::move(other.groups);
368 entities = std::move(other.entities);
382 swap(vars, other.vars);
383 swap(pools, other.pools);
384 swap(groups, other.groups);
385 swap(entities, other.entities);
396 return entities.get_allocator();
408 return iterable_adaptor{internal::registry_storage_iterator{pools.
begin()}, internal::registry_storage_iterator{pools.
end()}};
413 return iterable_adaptor{internal::registry_storage_iterator{pools.
cbegin()}, internal::registry_storage_iterator{pools.
cend()}};
422 return const_cast<common_type *
>(std::as_const(*this).storage(
id));
431 const auto it = pools.
find(
id);
432 return it == pools.
cend() ? nullptr : it->second.get();
441 template<
typename Type>
443 return assure<Type>(
id);
452 template<
typename Type>
454 return assure<Type>(
id);
463 return entities.contains(
entt) && (entities.index(
entt) < entities.free_list());
473 return entities.current(
entt);
481 return entities.emplace();
494 return entities.emplace(hint);
506 template<
typename It>
508 entities.insert(std::move(first), std::move(last));
523 pools.
begin()[pos - 1u].second->remove(
entt);
526 entities.erase(
entt);
527 return entities.current(
entt);
544 const auto elem = traits_type::construct(traits_type::to_entity(
entt), version);
545 return entities.bump((elem ==
tombstone) ? traits_type::next(elem) : elem);
557 template<
typename It>
559 entities.sort_as(first, last);
561 const auto from = entities.cbegin(0);
562 const auto to = from + std::distance(first, last);
564 for(
auto &&curr: pools) {
565 curr.second->remove(from, to);
568 entities.erase(from, to);
586 template<
typename Type,
typename... Args>
588 return assure<Type>().emplace(
entt, std::forward<Args>(args)...);
602 template<
typename Type,
typename It>
603 void insert(It first, It last,
const Type &value = {}) {
604 assure<Type>().insert(std::move(first), std::move(last), value);
619 template<typename Type, typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<CIt>::value_type, Type>>>
620 void insert(EIt first, EIt last, CIt from) {
621 assure<Type>().insert(first, last, from);
636 template<
typename Type,
typename... Args>
638 if(
auto &cpool = assure<Type>(); cpool.contains(
entt)) {
639 return cpool.patch(
entt, [&args...](
auto &...curr) { ((curr = Type{std::forward<Args>(args)...}), ...); });
641 return cpool.emplace(
entt, std::forward<Args>(args)...);
664 template<
typename Type,
typename... Func>
666 return assure<Type>().patch(
entt, std::forward<Func>(func)...);
684 template<
typename Type,
typename... Args>
686 return patch<Type>(
entt, [&args...](
auto &...curr) { ((curr = Type{std::forward<Args>(args)...}), ...); });
696 template<
typename Type,
typename... Other>
698 return (assure<Type>().remove(
entt) + ... + assure<Other>().remove(
entt));
713 template<
typename Type,
typename... Other,
typename It>
717 if constexpr(std::is_same_v<It, typename common_type::iterator>) {
718 common_type *cpools[
sizeof...(Other) + 1u]{&assure<Type>(), &assure<Other>()...};
720 for(
size_type pos{}, len =
sizeof...(Other) + 1u; pos < len; ++pos) {
721 if constexpr(
sizeof...(Other) != 0u) {
722 if(cpools[pos]->data() == first.data()) {
723 std::swap(cpools[pos], cpools[
sizeof...(Other)]);
727 count += cpools[pos]->remove(first, last);
730 for(
auto cpools = std::forward_as_tuple(assure<Type>(), assure<Other>()...); first != last; ++first) {
731 count += std::apply([
entt = *first](
auto &...curr) {
return (curr.remove(
entt) + ... + 0u); }, cpools);
749 template<
typename Type,
typename... Other>
751 (assure<Type>().erase(
entt), (assure<Other>().erase(
entt), ...));
765 template<
typename Type,
typename... Other,
typename It>
767 if constexpr(std::is_same_v<It, typename common_type::iterator>) {
768 common_type *cpools[
sizeof...(Other) + 1u]{&assure<Type>(), &assure<Other>()...};
770 for(
size_type pos{}, len =
sizeof...(Other) + 1u; pos < len; ++pos) {
771 if constexpr(
sizeof...(Other) != 0u) {
772 if(cpools[pos]->data() == first.data()) {
773 std::swap(cpools[pos], cpools[
sizeof...(Other)]);
777 cpools[pos]->erase(first, last);
780 for(
auto cpools = std::forward_as_tuple(assure<Type>(), assure<Other>()...); first != last; ++first) {
781 std::apply([
entt = *first](
auto &...curr) { (curr.erase(
entt), ...); }, cpools);
801 template<
typename Func>
803 for(
auto [
id, cpool]:
storage()) {
804 if(cpool.contains(
entt) && func(
id, std::as_const(cpool))) {
815 template<
typename... Type>
817 if constexpr(
sizeof...(Type) == 0u) {
818 for(
auto &&curr: pools) {
819 curr.second->compact();
822 (assure<Type>().compact(), ...);
832 template<
typename... Type>
834 if constexpr(
sizeof...(Type) == 1u) {
835 auto *cpool = assure<std::remove_const_t<Type>...>();
836 return cpool && cpool->contains(
entt);
838 return (all_of<Type>(
entt) && ...);
849 template<
typename... Type>
851 return (all_of<Type>(
entt) || ...);
865 template<
typename... Type>
867 if constexpr(
sizeof...(Type) == 1u) {
868 return (assure<std::remove_const_t<Type>>()->get(
entt), ...);
870 return std::forward_as_tuple(get<Type>(
entt)...);
875 template<
typename... Type>
877 if constexpr(
sizeof...(Type) == 1u) {
880 return std::forward_as_tuple(get<Type>(
entt)...);
899 template<
typename Type,
typename... Args>
901 if(
auto &cpool = assure<Type>(); cpool.contains(
entt)) {
902 return cpool.get(
entt);
904 return cpool.emplace(
entt, std::forward<Args>(args)...);
918 template<
typename... Type>
920 if constexpr(
sizeof...(Type) == 1u) {
921 const auto *cpool = assure<std::remove_const_t<Type>...>();
922 return (cpool && cpool->contains(
entt)) ? std::addressof(cpool->get(
entt)) :
nullptr;
924 return std::make_tuple(try_get<Type>(
entt)...);
929 template<
typename... Type>
931 if constexpr(
sizeof...(Type) == 1u) {
932 return (
const_cast<Type *
>(std::as_const(*this).template try_get<Type>(
entt)), ...);
934 return std::make_tuple(try_get<Type>(
entt)...);
942 template<
typename... Type>
944 if constexpr(
sizeof...(Type) == 0u) {
945 for(
size_type pos = pools.size(); pos; --pos) {
946 pools.begin()[pos - 1u].second->clear();
949 const auto elem = entities.each();
950 entities.erase(elem.begin().base(), elem.end().base());
952 (assure<Type>().clear(), ...);
962 return std::none_of(pools.cbegin(), pools.cend(), [
entt](
auto &&curr) { return curr.second->contains(entt); });
984 template<
typename Type>
986 return assure<Type>(
id).on_construct();
1008 template<
typename Type>
1010 return assure<Type>(
id).on_update();
1032 template<
typename Type>
1034 return assure<Type>(
id).on_destroy();
1044 template<
typename Type,
typename... Other,
typename... Exclude>
1047 const auto cpools = std::make_tuple(assure<std::remove_const_t<Type>>(), assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Exclude>>()...);
1049 std::apply([&elem](
const auto *...curr) { ((curr ? elem.storage(*curr) : void()), ...); }, cpools);
1054 template<
typename Type,
typename... Other,
typename... Exclude>
1055 [[nodiscard]] basic_view<get_t<storage_for_type<Type>, storage_for_type<Other>...>, exclude_t<storage_for_type<Exclude>...>>
1057 return {assure<std::remove_const_t<Type>>(), assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Exclude>>()...};
1067 template<
typename... Owned,
typename... Get,
typename... Exclude>
1068 basic_group<owned_t<storage_for_type<Owned>...>, get_t<storage_for_type<Get>...>, exclude_t<storage_for_type<Exclude>...>>
1070 using handler_type =
typename basic_group<owned_t<storage_for_type<Owned>...>, get_t<storage_for_type<Get>...>, exclude_t<storage_for_type<Exclude>...>>::handler;
1073 return {*std::static_pointer_cast<handler_type>(it->second)};
1076 std::shared_ptr<handler_type> handler{};
1078 if constexpr(
sizeof...(Owned) == 0u) {
1079 handler = std::allocate_shared<handler_type>(get_allocator(), get_allocator(), assure<std::remove_const_t<Get>>()..., assure<std::remove_const_t<Exclude>>()...);
1081 handler = std::allocate_shared<handler_type>(get_allocator(), assure<std::remove_const_t<Owned>>()..., assure<std::remove_const_t<Get>>()..., assure<std::remove_const_t<Exclude>>()...);
1082 [[maybe_unused]]
const id_type elem[]{type_hash<std::remove_const_t<Owned>>::value()..., type_hash<std::remove_const_t<Get>>::value()..., type_hash<std::remove_const_t<Exclude>>::value()...};
1083 ENTT_ASSERT(std::all_of(groups.cbegin(), groups.cend(), [&elem](
const auto &data) { return data.second->owned(elem, sizeof...(Owned)) == 0u; }),
"Conflicting groups");
1091 template<
typename... Owned,
typename... Get,
typename... Exclude>
1092 basic_group<owned_t<storage_for_type<const Owned>...>, get_t<storage_for_type<const Get>...>, exclude_t<storage_for_type<const Exclude>...>>
1094 using handler_type =
typename basic_group<owned_t<storage_for_type<const Owned>...>, get_t<storage_for_type<const Get>...>, exclude_t<storage_for_type<const Exclude>...>>::handler;
1097 return {*std::static_pointer_cast<handler_type>(it->second)};
1110 template<
typename Type,
typename... Other>
1113 return std::any_of(groups.cbegin(), groups.cend(), [&elem](
auto &&data) { return data.second->owned(elem, 1u + sizeof...(Other)); });
1149 template<
typename Type,
typename Compare,
typename Sort =
std_sort,
typename... Args>
1150 void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
1151 ENTT_ASSERT(!owned<Type>(),
"Cannot sort owned storage");
1152 auto &cpool = assure<Type>();
1154 if constexpr(std::is_invocable_v<Compare,
decltype(cpool.get({})),
decltype(cpool.get({}))>) {
1155 auto comp = [&cpool, compare = std::move(compare)](
const auto lhs,
const auto rhs) {
return compare(std::as_const(cpool.get(lhs)), std::as_const(cpool.get(rhs))); };
1156 cpool.sort(std::move(comp), std::move(algo), std::forward<Args>(args)...);
1158 cpool.sort(std::move(compare), std::move(algo), std::forward<Args>(args)...);
1175 template<
typename To,
typename From>
1177 ENTT_ASSERT(!owned<To>(),
"Cannot sort owned storage");
1178 const base_type &cpool = assure<From>();
1179 assure<To>().sort_as(cpool.
begin(), cpool.
end());
1197 pool_container_type pools;
1198 group_container_type groups;
1199 storage_for_type<entity_type> entities;
Fast and reliable entity-component system.
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 component.
bool any_of(const entity_type entt) const
Check if an entity is part of at least one given storage.
typename base_type::traits_type traits_type
Entity traits.
decltype(auto) get_or_emplace(const entity_type entt, Args &&...args)
Returns a reference to the given component for an entity.
bool orphan(const entity_type entt) const
Checks if an entity has components assigned.
decltype(auto) replace(const entity_type entt, Args &&...args)
Replaces the given component 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 component.
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 components for an entity.
decltype(auto) emplace_or_replace(const entity_type entt, Args &&...args)
Assigns or replaces the given component 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 components satisfying specific criteria from an entity.
version_type destroy(const entity_type entt)
Destroys an entity and releases its identifier.
typename traits_type::version_type version_type
Underlying version type.
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 components in the same way.
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 components.
void create(It first, It last)
Assigns each element in a range an identifier.
bool owned() const
Checks whether the given components belong to any group.
size_type remove(It first, It last)
Removes the given components 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 components.
decltype(auto) patch(const entity_type entt, Func &&...func)
Patches the given component 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 components.
size_type remove(const entity_type entt)
Removes the given components 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 components.
auto try_get(const entity_type entt)
Returns pointers to the given components for an entity.
common_type * storage(const id_type id)
Finds the storage associated with a given name, if any.
void destroy(It first, It last)
Destroys all entities in a range and releases their identifiers.
decltype(auto) get(const entity_type entt)
Returns references to the given components for an entity.
void swap(basic_registry &other)
Exchanges the contents with those of a given registry.
void erase(It first, It last)
Erases the given components from all the entities in a range.
Allocator allocator_type
Allocator type.
void sort(Compare compare, Sort algo=Sort{}, Args &&...args)
Sorts the elements of a given component.
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
decltype(auto) emplace(const entity_type entt, Args &&...args)
Assigns the given component to an entity.
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 component.
storage_for_type< Type > & storage(const id_type id=type_hash< Type >::value())
Returns the storage for a given component type.
typename traits_type::value_type entity_type
Underlying entity identifier.
decltype(auto) get(const entity_type entt) const
Returns references to the given components for an entity.
std::size_t size_type
Unsigned integer type.
basic_registry(basic_registry &&other) noexcept
Move constructor.
void compact()
Removes all tombstones from a registry or only the pools for the given components.
typename storage_for< Type, Entity, typename alloc_traits::template rebind_alloc< std::remove_const_t< Type > > >::type storage_for_type
const_iterable storage() const noexcept
Returns an iterable object to use to visit a registry.
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 components.
void insert(It first, It last, const Type &value={})
Assigns each entity in a range the given component.
const storage_for_type< Type > * storage(const id_type id=type_hash< Type >::value()) const
Returns the storage for a given component type, if any.
void insert(EIt first, EIt last, CIt from)
Assigns each entity in a range the given components.
internal::registry_context< allocator_type > context
Context type.
basic_registry()
Default constructor.
void erase(const entity_type entt)
Erases the given components from an entity.
Basic sparse set implementation.
iterator begin() const noexcept
Returns an iterator to the beginning.
iterator end() const noexcept
Returns an iterator to the end.
entt_traits< Entity > traits_type
Entity traits.
const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
size_type size() const noexcept
Returns the number of elements in a container.
void reserve(const size_type cnt)
Reserves space for at least the specified number of elements and regenerates the hash table.
const_iterator cend() const noexcept
Returns an iterator to the end.
iterator find(const key_type &key)
Finds an element with a given key.
const_iterator begin() const noexcept
Returns an iterator to the beginning.
const_iterator end() const noexcept
Returns an iterator to the end.
std::uint32_t id_type
Alias declaration for type identifiers.
basic_storage< Type > storage
Alias declaration for the most common use case.
constexpr tombstone_t tombstone
Compile-time constant for tombstone entities.
constexpr get_t< Type... > get
Variable template for lists of observed components.
constexpr bool operator<=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator<(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr type_list< Type..., Other... > operator+(type_list< Type... >, type_list< Other... >)
Concatenates multiple type lists.
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator>=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator>(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
basic_any< Len, Align > forward_as_any(Type &&value)
Forwards its argument and avoids copies for lvalue references.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Alias for exclusion lists.
Alias for lists of observed components.
Identity function object (waiting for C++20).
Utility class to create an iterable object from a pair of iterators.
Function object to wrap std::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.