1#ifndef ENTT_ENTITY_REGISTRY_HPP
2#define ENTT_ENTITY_REGISTRY_HPP
14#include "../config/config.h"
15#include "../container/dense_map.hpp"
16#include "../core/algorithm.hpp"
17#include "../core/any.hpp"
18#include "../core/fwd.hpp"
19#include "../core/iterator.hpp"
20#include "../core/memory.hpp"
21#include "../core/type_info.hpp"
22#include "../core/type_traits.hpp"
23#include "../core/utility.hpp"
28#include "sparse_set.hpp"
38class registry_storage_iterator final {
39 template<
typename Other>
40 friend class registry_storage_iterator;
42 using mapped_type = std::remove_reference_t<decltype(std::declval<It>()->second)>;
45 using value_type = std::pair<id_type, constness_as_t<typename mapped_type::element_type, mapped_type> &>;
46 using pointer = input_iterator_pointer<value_type>;
47 using reference = value_type;
48 using difference_type = std::ptrdiff_t;
49 using iterator_category = std::input_iterator_tag;
50 using iterator_concept = std::random_access_iterator_tag;
52 constexpr registry_storage_iterator() noexcept
55 constexpr registry_storage_iterator(It iter) noexcept
58 template<
typename Other,
typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
59 constexpr registry_storage_iterator(
const registry_storage_iterator<Other> &other) noexcept
60 : registry_storage_iterator{other.it} {}
62 constexpr registry_storage_iterator &operator++() noexcept {
66 constexpr registry_storage_iterator operator++(
int)
noexcept {
67 registry_storage_iterator orig = *
this;
68 return ++(*this), orig;
71 constexpr registry_storage_iterator &operator--() noexcept {
75 constexpr registry_storage_iterator operator--(
int)
noexcept {
76 registry_storage_iterator orig = *
this;
77 return operator--(), orig;
80 constexpr registry_storage_iterator &operator+=(
const difference_type value)
noexcept {
85 constexpr registry_storage_iterator
operator+(
const difference_type value)
const noexcept {
86 registry_storage_iterator copy = *
this;
87 return (copy += value);
90 constexpr registry_storage_iterator &operator-=(
const difference_type value)
noexcept {
91 return (*
this += -value);
94 constexpr registry_storage_iterator operator-(
const difference_type value)
const noexcept {
95 return (*
this + -value);
98 [[nodiscard]]
constexpr reference operator[](
const difference_type value)
const noexcept {
99 return {it[value].first, *it[value].second};
102 [[nodiscard]]
constexpr reference operator*() const noexcept {
103 return operator[](0);
106 [[nodiscard]]
constexpr pointer operator->() const noexcept {
110 template<
typename Lhs,
typename Rhs>
111 friend constexpr std::ptrdiff_t operator-(
const registry_storage_iterator<Lhs> &,
const registry_storage_iterator<Rhs> &)
noexcept;
113 template<
typename Lhs,
typename Rhs>
114 friend constexpr bool operator==(
const registry_storage_iterator<Lhs> &,
const registry_storage_iterator<Rhs> &)
noexcept;
116 template<
typename Lhs,
typename Rhs>
117 friend constexpr bool operator<(
const registry_storage_iterator<Lhs> &,
const registry_storage_iterator<Rhs> &)
noexcept;
123template<
typename Lhs,
typename Rhs>
124[[nodiscard]]
constexpr std::ptrdiff_t operator-(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
125 return lhs.it - rhs.it;
128template<
typename Lhs,
typename Rhs>
129[[nodiscard]]
constexpr bool operator==(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
130 return lhs.it == rhs.it;
133template<
typename Lhs,
typename Rhs>
134[[nodiscard]]
constexpr bool operator!=(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
135 return !(lhs == rhs);
138template<
typename Lhs,
typename Rhs>
139[[nodiscard]]
constexpr bool operator<(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
140 return lhs.it < rhs.it;
143template<
typename Lhs,
typename Rhs>
144[[nodiscard]]
constexpr bool operator>(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
148template<
typename Lhs,
typename Rhs>
149[[nodiscard]]
constexpr bool operator<=(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
153template<
typename Lhs,
typename Rhs>
154[[nodiscard]]
constexpr bool operator>=(
const registry_storage_iterator<Lhs> &lhs,
const registry_storage_iterator<Rhs> &rhs)
noexcept {
158template<
typename Allocator>
159class registry_context {
160 using alloc_traits = std::allocator_traits<Allocator>;
161 using allocator_type =
typename alloc_traits::template rebind_alloc<std::pair<const id_type, basic_any<0u>>>;
164 explicit registry_context(
const allocator_type &allocator)
167 template<
typename Type,
typename... Args>
168 Type &emplace_as(
const id_type
id, Args &&...args) {
169 return any_cast<Type &>(ctx.try_emplace(
id, std::in_place_type<Type>, std::forward<Args>(args)...).first->second);
172 template<
typename Type,
typename... Args>
173 Type &emplace(Args &&...args) {
174 return emplace_as<Type>(type_id<Type>().hash(), std::forward<Args>(args)...);
177 template<
typename Type>
178 Type &insert_or_assign(
const id_type
id, Type &&value) {
179 return any_cast<std::remove_cv_t<std::remove_reference_t<Type>> &>(ctx.insert_or_assign(
id, std::forward<Type>(value)).first->second);
182 template<
typename Type>
183 Type &insert_or_assign(Type &&value) {
184 return insert_or_assign(type_id<Type>().hash(), std::forward<Type>(value));
187 template<
typename Type>
188 bool erase(
const id_type
id = type_id<Type>().hash()) {
189 const auto it = ctx.find(
id);
190 return it != ctx.end() && it->second.type() == type_id<Type>() ? (ctx.erase(it),
true) : false;
193 template<
typename Type>
194 [[nodiscard]]
const Type &
get(
const id_type
id = type_id<Type>().hash())
const {
195 return any_cast<const Type &>(ctx.at(
id));
198 template<
typename Type>
199 [[nodiscard]] Type &
get(
const id_type
id = type_id<Type>().hash()) {
200 return any_cast<Type &>(ctx.at(
id));
203 template<
typename Type>
204 [[nodiscard]]
const Type *find(
const id_type
id = type_id<Type>().hash())
const {
205 const auto it = ctx.find(
id);
206 return it != ctx.cend() ? any_cast<const Type>(&it->second) : nullptr;
209 template<
typename Type>
210 [[nodiscard]] Type *find(
const id_type
id = type_id<Type>().hash()) {
211 const auto it = ctx.find(
id);
212 return it != ctx.end() ? any_cast<Type>(&it->second) : nullptr;
215 template<
typename Type>
216 [[nodiscard]]
bool contains(
const id_type
id = type_id<Type>().hash())
const {
217 const auto it = ctx.find(
id);
218 return it != ctx.cend() && it->second.type() == type_id<Type>();
222 dense_map<id_type, basic_any<0u>, identity, std::equal_to<>, allocator_type> ctx;
233template<
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>) {
258 using alloc_type =
typename storage_type::allocator_type;
261 if constexpr(std::is_void_v<Type> && !std::is_constructible_v<alloc_type, allocator_type>) {
275 template<
typename Type>
277 static_assert(std::is_same_v<Type, std::decay_t<Type>>,
"Non-decayed types not allowed");
279 if constexpr(std::is_same_v<Type, entity_type>) {
283 if(
const auto it = pools.
find(
id);
it != pools.
cend()) {
293 entities.bind(*
this);
295 for(
auto &&
curr: pools) {
296 curr.second->bind(*
this);
312 using context = internal::registry_context<allocator_type>;
322 template<
typename Type>
358 : vars{std::move(
other.vars)},
359 pools{std::move(
other.pools)},
360 groups{std::move(
other.groups)},
361 entities{std::move(
other.entities)} {
405 return entities.get_allocator();
431 return const_cast<common_type *
>(std::as_const(*this).storage(
id));
440 const auto it = pools.
find(
id);
450 template<
typename Type>
461 template<
typename Type>
473 return !(pools.
erase(
id) == 0
u);
482 return static_cast<size_type>(entities.find(
entt).index()) < entities.free_list();
492 return entities.current(
entt);
500 return entities.emplace();
513 return entities.emplace(
hint);
525 template<
typename It>
527 entities.insert(std::move(first), std::move(last));
545 entities.erase(
entt);
546 return entities.current(
entt);
576 template<
typename It>
578 const auto to = entities.sort_as(first, last);
579 const auto from = entities.cend() - entities.free_list();
581 for(
auto &&
curr: pools) {
603 template<
typename Type,
typename...
Args>
605 ENTT_ASSERT(
valid(
entt),
"Invalid entity");
620 template<
typename Type,
typename It>
622 ENTT_ASSERT(std::all_of(first, last, [
this](
const auto entt) {
return valid(
entt); }),
"Invalid entity");
623 assure<Type>().insert(std::move(first), std::move(last), value);
640 ENTT_ASSERT(std::all_of(first, last, [
this](
const auto entt) {
return valid(
entt); }),
"Invalid entity");
656 template<
typename Type,
typename...
Args>
659 ENTT_ASSERT(
valid(
entt),
"Invalid entity");
682 template<
typename Type,
typename... Func>
702 template<
typename Type,
typename...
Args>
704 return patch<Type>(
entt, [&
args...](
auto &...curr) { ((curr = Type{std::forward<Args>(args)...}), ...); });
714 template<
typename Type,
typename... Other>
716 return (assure<Type>().remove(
entt) + ... + assure<Other>().remove(
entt));
731 template<
typename Type,
typename... Other,
typename It>
735 if constexpr(std::is_same_v<It, typename common_type::iterator>) {
736 std::array cpools{
static_cast<common_type *
>(&assure<Type>()),
static_cast<common_type *
>(&assure<Other>())...};
738 for(
auto from = cpools.begin(), to = cpools.end(); from != to; ++from) {
739 if constexpr(
sizeof...(Other) != 0u) {
740 if((*from)->data() == first.data()) {
741 std::swap((*from), cpools.back());
745 count += (*from)->remove(first, last);
749 for(
auto cpools = std::forward_as_tuple(assure<Type>(), assure<Other>()...); first != last; ++first) {
750 count += std::apply([
entt = *first](
auto &...curr) {
return (curr.remove(
entt) + ... + 0u); }, cpools);
768 template<
typename Type,
typename... Other>
770 (assure<Type>().erase(
entt), (assure<Other>().erase(
entt), ...));
784 template<
typename Type,
typename... Other,
typename It>
786 if constexpr(std::is_same_v<It, typename common_type::iterator>) {
787 std::array cpools{
static_cast<common_type *
>(&assure<Type>()),
static_cast<common_type *
>(&assure<Other>())...};
789 for(
auto from = cpools.begin(), to = cpools.end(); from != to; ++from) {
790 if constexpr(
sizeof...(Other) != 0u) {
791 if((*from)->data() == first.data()) {
792 std::swap(*from, cpools.back());
796 (*from)->erase(first, last);
799 for(
auto cpools = std::forward_as_tuple(assure<Type>(), assure<Other>()...); first != last; ++first) {
800 std::apply([
entt = *first](
auto &...curr) { (curr.erase(
entt), ...); }, cpools);
820 template<
typename Func>
822 for(
auto [
id, cpool]:
storage()) {
823 if(cpool.contains(
entt) && func(
id, std::as_const(cpool))) {
834 template<
typename... Type>
836 if constexpr(
sizeof...(Type) == 0u) {
837 for(
auto &&curr: pools) {
838 curr.second->compact();
841 (assure<Type>().compact(), ...);
851 template<
typename... Type>
853 if constexpr(
sizeof...(Type) == 1u) {
854 auto *cpool = assure<std::remove_const_t<Type>...>();
855 return cpool && cpool->contains(
entt);
857 return (all_of<Type>(
entt) && ...);
868 template<
typename... Type>
870 return (all_of<Type>(
entt) || ...);
884 template<
typename... Type>
886 if constexpr(
sizeof...(Type) == 1u) {
887 return (assure<std::remove_const_t<Type>>()->get(
entt), ...);
889 return std::forward_as_tuple(get<Type>(
entt)...);
894 template<
typename... Type>
896 if constexpr(
sizeof...(Type) == 1u) {
899 return std::forward_as_tuple(get<Type>(
entt)...);
918 template<
typename Type,
typename... Args>
920 auto &cpool = assure<Type>();
921 ENTT_ASSERT(valid(
entt),
"Invalid entity");
922 return cpool.contains(
entt) ? cpool.get(
entt) : cpool.emplace(
entt, std::forward<Args>(args)...);
935 template<
typename... Type>
937 if constexpr(
sizeof...(Type) == 1u) {
938 const auto *cpool = assure<std::remove_const_t<Type>...>();
939 return (cpool && cpool->contains(
entt)) ? std::addressof(cpool->get(
entt)) :
nullptr;
941 return std::make_tuple(try_get<Type>(
entt)...);
946 template<
typename... Type>
948 if constexpr(
sizeof...(Type) == 1u) {
949 return (
const_cast<Type *
>(std::as_const(*this).template try_get<Type>(
entt)), ...);
951 return std::make_tuple(try_get<Type>(
entt)...);
959 template<
typename... Type>
961 if constexpr(
sizeof...(Type) == 0u) {
962 for(
size_type pos = pools.size(); pos; --pos) {
963 pools.begin()[pos - 1u].second->clear();
966 const auto elem = entities.each();
967 entities.erase(elem.begin().base(), elem.end().base());
969 (assure<Type>().clear(), ...);
979 return std::none_of(pools.cbegin(), pools.cend(), [
entt](
auto &&curr) { return curr.second->contains(entt); });
1001 template<
typename Type>
1003 return assure<Type>(
id).on_construct();
1025 template<
typename Type>
1027 return assure<Type>(
id).on_update();
1049 template<
typename Type>
1051 return assure<Type>(
id).on_destroy();
1061 template<
typename Type,
typename... Other,
typename... Exclude>
1065 [&elem](
const auto *...curr) { ((curr ? elem.storage(*curr) : void()), ...); }(assure<std::remove_const_t<Exclude>>()..., assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Type>>());
1070 template<
typename Type,
typename... Other,
typename... Exclude>
1071 [[nodiscard]] basic_view<get_t<storage_for_type<Type>, storage_for_type<Other>...>, exclude_t<storage_for_type<Exclude>...>>
1073 return {assure<std::remove_const_t<Type>>(), assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Exclude>>()...};
1083 template<
typename... Owned,
typename... Get,
typename... Exclude>
1084 basic_group<owned_t<storage_for_type<Owned>...>, get_t<storage_for_type<Get>...>, exclude_t<storage_for_type<Exclude>...>>
1086 using group_type = basic_group<owned_t<storage_for_type<Owned>...>, get_t<storage_for_type<Get>...>, exclude_t<storage_for_type<Exclude>...>>;
1087 using handler_type =
typename group_type::handler;
1089 if(
auto it = groups.find(group_type::group_id()); it != groups.cend()) {
1090 return {*std::static_pointer_cast<handler_type>(it->second)};
1093 std::shared_ptr<handler_type> handler{};
1095 if constexpr(
sizeof...(Owned) == 0u) {
1096 handler = std::allocate_shared<handler_type>(get_allocator(), get_allocator(), std::forward_as_tuple(assure<std::remove_const_t<Get>>()...), std::forward_as_tuple(assure<std::remove_const_t<Exclude>>()...));
1098 handler = std::allocate_shared<handler_type>(get_allocator(), std::forward_as_tuple(assure<std::remove_const_t<Owned>>()..., assure<std::remove_const_t<Get>>()...), std::forward_as_tuple(assure<std::remove_const_t<Exclude>>()...));
1099 ENTT_ASSERT(std::all_of(groups.cbegin(), groups.cend(), [](
const auto &data) { return !(data.second->owned(type_id<Owned>().hash()) || ...); }),
"Conflicting groups");
1102 groups.emplace(group_type::group_id(), handler);
1107 template<
typename... Owned,
typename... Get,
typename... Exclude>
1108 [[nodiscard]] basic_group<owned_t<storage_for_type<const Owned>...>, get_t<storage_for_type<const Get>...>, exclude_t<storage_for_type<const Exclude>...>>
1110 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>...>>;
1111 using handler_type =
typename group_type::handler;
1113 if(
auto it = groups.find(group_type::group_id()); it != groups.cend()) {
1114 return {*std::static_pointer_cast<handler_type>(it->second)};
1126 template<
typename... Type>
1128 return std::any_of(groups.cbegin(), groups.cend(), [](
auto &&data) { return (data.second->owned(type_id<Type>().hash()) || ...); });
1164 template<
typename Type,
typename Compare,
typename Sort =
std_sort,
typename... Args>
1165 void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
1166 ENTT_ASSERT(!owned<Type>(),
"Cannot sort owned storage");
1167 auto &cpool = assure<Type>();
1169 if constexpr(std::is_invocable_v<Compare,
decltype(cpool.get({})),
decltype(cpool.get({}))>) {
1170 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))); };
1171 cpool.sort(std::move(comp), std::move(algo), std::forward<Args>(args)...);
1173 cpool.sort(std::move(compare), std::move(algo), std::forward<Args>(args)...);
1190 template<
typename To,
typename From>
1192 ENTT_ASSERT(!owned<To>(),
"Cannot sort owned storage");
1193 const base_type &cpool = assure<From>();
1194 assure<To>().sort_as(cpool.
begin(), cpool.
end());
1212 pool_container_type pools;
1213 group_container_type groups;
1214 storage_for_type<entity_type> entities;
static constexpr value_type construct(const entity_type entity, const version_type version) noexcept
Constructs an identifier from its parts.
static constexpr value_type next(const value_type value) noexcept
Returns the successor of a given identifier.
static constexpr entity_type to_entity(const value_type value) noexcept
Returns the entity part once converted to the underlying type.
typename Traits::value_type value_type
Value type.
typename Traits::version_type version_type
Underlying version type.
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 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.
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.
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.
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 elements 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 elements.
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.
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 elements for an entity.
typename storage_for< Type, Entity, typename alloc_traits::template rebind_alloc< std::remove_const_t< Type > > >::type storage_for_type
void erase(It first, It last)
Erases the given elements 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 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.
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.
typename traits_type::value_type entity_type
Underlying entity identifier.
decltype(auto) get(const entity_type entt) const
Returns references to the given elements 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 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.
void insert(It first, It last, const Type &value={})
Assigns each entity in a range the given element.
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(EIt first, EIt last, CIt from)
Assigns each entity in a range the given elements.
basic_registry(const basic_registry &)=delete
Default copy constructor, deleted on purpose.
internal::registry_context< allocator_type > context
Context type.
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 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.
std::shared_ptr< base_type > mapped_type
Mapped type of the container.
iterator erase(const_iterator pos)
Removes an element from a given position.
std::pair< iterator, bool > emplace(Args &&...args)
Constructs an element in-place, if the key does not exist.
const_iterator end() const noexcept
Returns an iterator to the end.
constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args)
Uses-allocator construction utility (waiting for C++20).
constexpr tombstone_t tombstone
Compile-time constant for tombstone entities.
std::uint32_t id_type
Alias declaration for type identifiers.
constexpr get_t< Type... > get
Variable template for lists of observed elements.
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.
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 elements.
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.