1#ifndef ENTT_ENTITY_STORAGE_HPP
2#define ENTT_ENTITY_STORAGE_HPP
11#include "../config/config.h"
12#include "../core/bit.hpp"
13#include "../core/iterator.hpp"
14#include "../core/memory.hpp"
15#include "../core/type_info.hpp"
16#include "component.hpp"
19#include "sparse_set.hpp"
26template<
typename Container, auto Page>
27class storage_iterator final {
28 friend storage_iterator<const Container, Page>;
30 using container_type = std::remove_const_t<Container>;
31 using alloc_traits = std::allocator_traits<typename container_type::allocator_type>;
33 using iterator_traits = std::iterator_traits<std::conditional_t<
34 std::is_const_v<Container>,
35 typename alloc_traits::template rebind_traits<typename std::pointer_traits<typename container_type::value_type>::element_type>::const_pointer,
36 typename alloc_traits::template rebind_traits<typename std::pointer_traits<typename container_type::value_type>::element_type>::pointer>>;
39 using value_type =
typename iterator_traits::value_type;
40 using pointer =
typename iterator_traits::pointer;
41 using reference =
typename iterator_traits::reference;
42 using difference_type =
typename iterator_traits::difference_type;
43 using iterator_category = std::random_access_iterator_tag;
45 constexpr storage_iterator() noexcept = default;
47 constexpr storage_iterator(Container *ref, const difference_type idx) noexcept
51 template<
bool Const = std::is_const_v<Container>,
typename = std::enable_if_t<Const>>
52 constexpr storage_iterator(
const storage_iterator<std::remove_const_t<Container>, Page> &other) noexcept
53 : storage_iterator{other.payload, other.offset} {}
55 constexpr storage_iterator &operator++() noexcept {
56 return --offset, *
this;
59 constexpr storage_iterator operator++(
int)
noexcept {
60 const storage_iterator orig = *
this;
61 return ++(*this), orig;
64 constexpr storage_iterator &operator--() noexcept {
65 return ++offset, *
this;
68 constexpr storage_iterator operator--(
int)
noexcept {
69 const storage_iterator orig = *
this;
70 return operator--(), orig;
73 constexpr storage_iterator &operator+=(
const difference_type value)
noexcept {
78 constexpr storage_iterator
operator+(
const difference_type value)
const noexcept {
79 storage_iterator copy = *
this;
80 return (copy += value);
83 constexpr storage_iterator &operator-=(
const difference_type value)
noexcept {
84 return (*
this += -value);
87 constexpr storage_iterator operator-(
const difference_type value)
const noexcept {
88 return (*
this + -value);
91 [[nodiscard]]
constexpr reference operator[](
const difference_type value)
const noexcept {
92 const auto pos =
static_cast<typename Container::size_type
>(index() - value);
93 return (*payload)[pos / Page][
fast_mod(
static_cast<std::size_t
>(pos), Page)];
96 [[nodiscard]]
constexpr pointer operator->() const noexcept {
97 return std::addressof(
operator[](0));
100 [[nodiscard]]
constexpr reference operator*() const noexcept {
101 return operator[](0);
104 [[nodiscard]]
constexpr difference_type index() const noexcept {
110 difference_type offset;
113template<
typename Lhs,
typename Rhs, auto Page>
114[[nodiscard]]
constexpr std::ptrdiff_t operator-(
const storage_iterator<Lhs, Page> &lhs,
const storage_iterator<Rhs, Page> &rhs)
noexcept {
115 return rhs.index() - lhs.index();
118template<
typename Lhs,
typename Rhs, auto Page>
119[[nodiscard]]
constexpr bool operator==(
const storage_iterator<Lhs, Page> &lhs,
const storage_iterator<Rhs, Page> &rhs)
noexcept {
120 return lhs.index() == rhs.index();
123template<
typename Lhs,
typename Rhs, auto Page>
124[[nodiscard]]
constexpr bool operator!=(
const storage_iterator<Lhs, Page> &lhs,
const storage_iterator<Rhs, Page> &rhs)
noexcept {
125 return !(lhs == rhs);
128template<
typename Lhs,
typename Rhs, auto Page>
129[[nodiscard]]
constexpr bool operator<(
const storage_iterator<Lhs, Page> &lhs,
const storage_iterator<Rhs, Page> &rhs)
noexcept {
130 return lhs.index() > rhs.index();
133template<
typename Lhs,
typename Rhs, auto Page>
134[[nodiscard]]
constexpr bool operator>(
const storage_iterator<Lhs, Page> &lhs,
const storage_iterator<Rhs, Page> &rhs)
noexcept {
138template<
typename Lhs,
typename Rhs, auto Page>
139[[nodiscard]]
constexpr bool operator<=(
const storage_iterator<Lhs, Page> &lhs,
const storage_iterator<Rhs, Page> &rhs)
noexcept {
143template<
typename Lhs,
typename Rhs, auto Page>
144[[nodiscard]]
constexpr bool operator>=(
const storage_iterator<Lhs, Page> &lhs,
const storage_iterator<Rhs, Page> &rhs)
noexcept {
148template<
typename It,
typename... Other>
149class extended_storage_iterator final {
150 template<
typename Iter,
typename... Args>
151 friend class extended_storage_iterator;
154 using iterator_type = It;
155 using value_type =
decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::forward_as_tuple(*std::declval<Other>()...)));
156 using pointer = input_iterator_pointer<value_type>;
157 using reference = value_type;
158 using difference_type = std::ptrdiff_t;
159 using iterator_category = std::input_iterator_tag;
160 using iterator_concept = std::forward_iterator_tag;
162 constexpr extended_storage_iterator()
165 constexpr extended_storage_iterator(iterator_type base, Other... other)
166 : it{base, other...} {}
168 template<
typename... Args,
typename = std::enable_if_t<(!std::is_same_v<Other, Args> && ...) && (std::is_constructible_v<Other, Args> && ...)>>
169 constexpr extended_storage_iterator(
const extended_storage_iterator<It, Args...> &other)
172 constexpr extended_storage_iterator &operator++() noexcept {
173 return ++std::get<It>(it), (++std::get<Other>(it), ...), *
this;
176 constexpr extended_storage_iterator operator++(
int)
noexcept {
177 const extended_storage_iterator orig = *
this;
178 return ++(*this), orig;
181 [[nodiscard]]
constexpr pointer operator->() const noexcept {
185 [[nodiscard]]
constexpr reference operator*() const noexcept {
186 return {*std::get<It>(it), *std::get<Other>(it)...};
189 [[nodiscard]]
constexpr iterator_type base() const noexcept {
190 return std::get<It>(it);
193 template<
typename... Lhs,
typename... Rhs>
194 friend constexpr bool operator==(
const extended_storage_iterator<Lhs...> &,
const extended_storage_iterator<Rhs...> &)
noexcept;
197 std::tuple<It, Other...> it;
200template<
typename... Lhs,
typename... Rhs>
201[[nodiscard]]
constexpr bool operator==(
const extended_storage_iterator<Lhs...> &lhs,
const extended_storage_iterator<Rhs...> &rhs)
noexcept {
202 return std::get<0>(lhs.it) == std::get<0>(rhs.it);
205template<
typename... Lhs,
typename... Rhs>
206[[nodiscard]]
constexpr bool operator!=(
const extended_storage_iterator<Lhs...> &lhs,
const extended_storage_iterator<Rhs...> &rhs)
noexcept {
207 return !(lhs == rhs);
228template<
typename Type,
typename Entity,
typename Allocator,
typename>
230 using alloc_traits = std::allocator_traits<Allocator>;
231 static_assert(std::is_same_v<typename alloc_traits::value_type, Type>,
"Invalid value type");
232 using container_type = std::vector<typename alloc_traits::pointer, typename alloc_traits::template rebind_alloc<typename alloc_traits::pointer>>;
237 [[nodiscard]]
auto &element_at(
const std::size_t pos)
const {
241 auto assure_at_least(
const std::size_t pos) {
244 if(!(idx < payload.size())) {
245 auto curr = payload.size();
247 payload.resize(idx + 1u,
nullptr);
250 for(
const auto last = payload.size(); curr < last; ++curr) {
255 payload.resize(curr);
263 template<
typename... Args>
264 auto emplace_element(
const Entity
entt,
const bool force_back, Args &&...args) {
279 void shrink_to_size(
const std::size_t sz) {
286 alloc_traits::destroy(allocator, std::addressof(element_at(pos)));
289 alloc_traits::destroy(allocator, std::addressof(element_at(pos)));
293 for(
auto pos = from, last = payload.size(); pos < last; ++pos) {
297 payload.resize(from);
298 payload.shrink_to_fit();
301 void swap_at(
const std::size_t lhs,
const std::size_t rhs) {
303 swap(element_at(lhs), element_at(rhs));
306 void move_to(
const std::size_t lhs,
const std::size_t rhs) {
307 auto &elem = element_at(lhs);
310 alloc_traits::destroy(allocator, std::addressof(elem));
314 [[nodiscard]]
const void *get_at(
const std::size_t pos)
const final {
315 return std::addressof(element_at(pos));
318 void swap_or_move([[maybe_unused]]
const std::size_t from, [[maybe_unused]]
const std::size_t to)
override {
319 static constexpr bool is_pinned_type = !(std::is_move_constructible_v<Type> && std::is_move_assignable_v<Type>);
321 ENTT_ASSERT((from + 1u) && !is_pinned_type,
"Pinned type");
323 if constexpr(!is_pinned_type) {
338 void pop(underlying_iterator first, underlying_iterator last)
override {
345 alloc_traits::destroy(allocator, std::addressof(elem));
349 [[maybe_unused]]
auto unused = std::exchange(elem, std::move(other));
350 alloc_traits::destroy(allocator, std::addressof(other));
364 alloc_traits::destroy(allocator, std::addressof(element_at(
static_cast<size_type>(first.index()))));
368 alloc_traits::destroy(allocator, std::addressof(element_at(
static_cast<size_type>(first.index()))));
380 underlying_iterator
try_emplace([[maybe_unused]]
const Entity
entt, [[maybe_unused]]
const bool force_back,
const void *
value)
override {
381 if(
value !=
nullptr) {
382 if constexpr(std::is_copy_constructible_v<element_type>) {
388 if constexpr(std::is_default_constructible_v<element_type>) {
389 return emplace_element(
entt, force_back);
412 using pointer =
typename container_type::pointer;
414 using const_pointer =
typename alloc_traits::template rebind_traits<typename alloc_traits::const_pointer>::const_pointer;
416 using iterator = internal::storage_iterator<container_type, traits_type::page_size>;
418 using const_iterator = internal::storage_iterator<const container_type, traits_type::page_size>;
444 payload{allocator} {}
456 payload{std::move(other.payload)} {}
466 :
base_type{std::move(other), allocator},
467 payload{std::move(other.payload), allocator} {
468 ENTT_ASSERT(alloc_traits::is_always_equal::value ||
get_allocator() == other.get_allocator(),
"Copying a storage is not allowed");
490 ENTT_ASSERT(alloc_traits::is_always_equal::value ||
get_allocator() == other.get_allocator(),
"Copying a storage is not allowed");
501 swap(payload, other.payload);
510 return payload.get_allocator();
524 assure_at_least(cap - 1u);
548 return payload.data();
553 return payload.data();
606 return std::make_reverse_iterator(
cend());
616 return std::make_reverse_iterator(
end());
625 return std::make_reverse_iterator(
cbegin());
635 return std::make_reverse_iterator(
begin());
663 return std::forward_as_tuple(
get(
entt));
668 return std::forward_as_tuple(
get(
entt));
683 template<
typename... Args>
685 if constexpr(std::is_aggregate_v<value_type> && (
sizeof...(Args) != 0u || !std::is_default_constructible_v<value_type>)) {
686 const auto it = emplace_element(
entt,
false, Type{std::forward<Args>(args)...});
687 return element_at(
static_cast<size_type>(it.index()));
689 const auto it = emplace_element(
entt,
false, std::forward<Args>(args)...);
690 return element_at(
static_cast<size_type>(it.index()));
701 template<
typename... Func>
704 auto &elem = element_at(idx);
705 (std::forward<Func>(func)(elem), ...);
723 template<
typename It>
725 for(; first != last; ++first) {
726 emplace_element(*first,
true,
value);
745 template<typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<CIt>::value_type,
value_type>>>
747 for(; first != last; ++first, ++from) {
748 emplace_element(*first,
true, *from);
788 container_type payload;
792template<
typename Type,
typename Entity,
typename Allocator>
793class basic_storage<Type, Entity, Allocator, std::enable_if_t<component_traits<Type, Entity>::page_size == 0u>>
794 :
public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
795 using alloc_traits = std::allocator_traits<Allocator>;
796 static_assert(std::is_same_v<typename alloc_traits::value_type, Type>,
"Invalid value type");
851 :
base_type{std::move(other), allocator} {}
875 if constexpr(std::is_void_v<element_type> && !std::is_constructible_v<allocator_type, typename base_type::allocator_type>) {
915 template<
typename... Args>
927 template<
typename... Func>
930 (std::forward<Func>(func)(), ...);
940 template<
typename It,
typename... Args>
942 void insert(It first, It last, Args &&...) {
943 for(; first != last; ++first) {
986template<
typename Entity,
typename Allocator>
989 using alloc_traits = std::allocator_traits<Allocator>;
990 static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>,
"Invalid value type");
994 auto from_placeholder()
noexcept {
996 ENTT_ASSERT(
entt !=
null,
"No more entities available");
1001 auto next()
noexcept {
1005 entt = from_placeholder();
1023 underlying_iterator
try_emplace(
const Entity hint,
const bool,
const void *)
override {
1075 placeholder{other.placeholder} {}
1085 :
base_type{std::move(other), allocator},
1086 placeholder{other.placeholder} {}
1104 placeholder = other.placeholder;
1129 return std::tuple{};
1167 template<
typename It>
1173 for(; first != last; ++first) {
1205 template<
typename... Func>
1208 (std::forward<Func>(func)(), ...);
1217 template<
typename It>
1218 [[deprecated(
"use ::generate(first, last) instead")]]
void insert(It first, It last) {
1219 generate(std::move(first), std::move(last));
1230 return std::as_const(*this).each();
1248 return std::as_const(*this).reach();
typename Traits::entity_type entity_type
Underlying entity type.
static constexpr value_type construct(const entity_type entity, const version_type version) noexcept
Constructs an identifier from its parts.
static constexpr entity_type to_entity(const value_type value) noexcept
Returns the entity part once converted to the underlying type.
static constexpr value_type combine(const entity_type lhs, const entity_type rhs) noexcept
Combines two identifiers in a single one.
static constexpr version_type to_version(const value_type value) noexcept
Returns the version part once converted to the underlying type.
iterator begin() const noexcept
const_iterator cbegin() const noexcept
virtual basic_iterator try_emplace(const Entity entt, const bool force_back, const void *=nullptr)
void swap_and_pop(const basic_iterator it)
iterator end() const noexcept
reverse_iterator rend() const noexcept
pointer data() const noexcept
virtual void reserve(const size_type cap)
size_type size() const noexcept
basic_sparse_set & operator=(const basic_sparse_set &)=delete
virtual void shrink_to_fit()
void swap(basic_sparse_set &other) noexcept
const_iterator find(const entity_type entt) const noexcept
virtual void pop(basic_iterator first, basic_iterator last)
version_type current(const entity_type entt) const noexcept
Returns the contained version for an identifier.
bool contains(const entity_type entt) const noexcept
const_iterator cend() const noexcept
void in_place_pop(const basic_iterator it)
const_reverse_iterator crend() const noexcept
constexpr allocator_type get_allocator() const noexcept
const void * value(const entity_type entt) const noexcept
reverse_iterator rbegin() const noexcept
entity_type operator[](const size_type pos) const noexcept
size_type free_list() const noexcept
Returns data on the free list whose meaning depends on the mode.
internal::sparse_set_iterator< packed_container_type > basic_iterator
const_reverse_iterator crbegin() const noexcept
size_type index(const entity_type entt) const noexcept
const_reverse_iterable reach() const noexcept
Returns a reverse iterable object to use to visit a storage.
std::size_t size_type
Unsigned integer type.
iterable_adaptor< internal::extended_storage_iterator< typename base_type::reverse_iterator > > reverse_iterable
Extended reverse iterable storage proxy.
static constexpr deletion_policy storage_policy
Storage deletion policy.
void get(const entity_type entt) const noexcept
Returns the object assigned to an entity, that is void.
void value_type
Type of the objects assigned to entities.
entity_type generate(const entity_type hint)
Creates a new identifier or recycles a destroyed one.
iterable_adaptor< internal::extended_storage_iterator< typename base_type::const_iterator > > const_iterable
Constant extended iterable storage proxy.
void insert(It first, It last)
Assigns each element in a range an identifier.
Entity entity_type
Underlying entity identifier.
void pop_all() override
Erases all entities of a storage.
entity_type emplace(const entity_type hint)
Creates a new identifier or recycles a destroyed one.
~basic_storage() override=default
Default destructor.
underlying_iterator try_emplace(const Entity hint, const bool, const void *) override
Assigns an entity to a storage.
basic_storage & operator=(basic_storage &&other) noexcept
Move assignment operator.
entity_type generate()
Creates a new identifier or recycles a destroyed one.
reverse_iterable reach() noexcept
Returns a reverse iterable object to use to visit a storage.
basic_storage(basic_storage &&other, const allocator_type &allocator)
Allocator-extended move constructor.
std::ptrdiff_t difference_type
Signed integer type.
Entity element_type
Element type.
const_iterable each() const noexcept
Returns an iterable object to use to visit a storage.
basic_storage(const allocator_type &allocator)
Constructs an empty container with a given allocator.
void generate(It first, It last)
Assigns each element in a range an identifier.
Allocator allocator_type
Allocator type.
iterable_adaptor< internal::extended_storage_iterator< typename base_type::const_reverse_iterator > > const_reverse_iterable
Constant extended reverse iterable storage proxy.
iterable_adaptor< internal::extended_storage_iterator< typename base_type::iterator > > iterable
Extended iterable storage proxy.
basic_sparse_set< Entity, Allocator > base_type
Base type.
basic_storage(basic_storage &&other) noexcept
Move constructor.
entity_type emplace()
Creates a new identifier or recycles a destroyed one.
iterable each() noexcept
Returns an iterable object to use to visit a storage.
basic_storage(const basic_storage &)=delete
Default copy constructor, deleted on purpose.
void patch(const entity_type entt, Func &&...func)
Updates a given identifier.
basic_storage()
Default constructor.
void start_from(const entity_type hint)
Sets the starting identifier for generation.
basic_storage & operator=(const basic_storage &)=delete
Default copy assignment operator, deleted on purpose.
std::tuple get_as_tuple(const entity_type entt) const noexcept
Returns an empty tuple.
~basic_storage() override=default
Default destructor.
void insert(It first, It last, Args &&...)
Assigns entities to a storage.
void value_type
Type of the objects assigned to entities.
basic_storage & operator=(const basic_storage &)=delete
Default copy assignment operator, deleted on purpose.
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
basic_sparse_set< Entity, typename alloc_traits::template rebind_alloc< Entity > > base_type
Base type.
Type element_type
Element type.
static constexpr deletion_policy storage_policy
Storage deletion policy.
std::tuple get_as_tuple(const entity_type entt) const noexcept
Returns an empty tuple.
void patch(const entity_type entt, Func &&...func)
Updates the instance assigned to a given entity in-place.
reverse_iterable reach() noexcept
Returns a reverse iterable object to use to visit a storage.
basic_storage()
Default constructor.
basic_storage(const allocator_type &allocator)
Constructs an empty container with a given allocator.
basic_storage(basic_storage &&other, const allocator_type &allocator)
Allocator-extended move constructor.
iterable_adaptor< internal::extended_storage_iterator< typename base_type::iterator > > iterable
Extended iterable storage proxy.
iterable_adaptor< internal::extended_storage_iterator< typename base_type::reverse_iterator > > reverse_iterable
Extended reverse iterable storage proxy.
basic_storage(basic_storage &&other) noexcept=default
Move constructor.
iterable_adaptor< internal::extended_storage_iterator< typename base_type::const_iterator > > const_iterable
Constant extended iterable storage proxy.
basic_storage(const basic_storage &)=delete
Default copy constructor, deleted on purpose.
void get(const entity_type entt) const noexcept
Returns the object assigned to an entity, that is void.
std::size_t size_type
Unsigned integer type.
std::ptrdiff_t difference_type
Signed integer type.
const_iterable each() const noexcept
Returns an iterable object to use to visit a storage.
const_reverse_iterable reach() const noexcept
Returns a reverse iterable object to use to visit a storage.
basic_storage & operator=(basic_storage &&other) noexcept=default
Move assignment operator.
iterable_adaptor< internal::extended_storage_iterator< typename base_type::const_reverse_iterator > > const_reverse_iterable
Constant extended reverse iterable storage proxy.
Allocator allocator_type
Allocator type.
void emplace(const entity_type entt, Args &&...)
Assigns an entity to a storage and constructs its object.
iterable each() noexcept
Returns an iterable object to use to visit a storage.
Entity entity_type
Underlying entity identifier.
iterator end() noexcept
Returns an iterator to the end.
~basic_storage() override
Default destructor.
basic_storage()
Default constructor.
iterator insert(EIt first, EIt last, CIt from)
Assigns one or more entities to a storage and constructs their objects from a given range.
const_reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the beginning.
const_iterator end() const noexcept
Returns an iterator to the end.
const_pointer raw() const noexcept
Direct access to the array of objects.
void pop_all() override
Erases all entities of a storage.
basic_storage(basic_storage &&other) noexcept
Move constructor.
const value_type & get(const entity_type entt) const noexcept
Returns the object assigned to an entity.
const_iterator cend() const noexcept
Returns an iterator to the end.
size_type capacity() const noexcept override
Returns the number of elements that a storage has currently allocated space for.
iterable_adaptor< internal::extended_storage_iterator< typename base_type::const_reverse_iterator, const_reverse_iterator > > const_reverse_iterable
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
typename alloc_traits::template rebind_traits< typename alloc_traits::const_pointer >::const_pointer const_pointer
const_iterable each() const noexcept
Returns an iterable object to use to visit a storage.
void swap(basic_storage &other) noexcept
Exchanges the contents with those of a given storage.
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the beginning.
internal::storage_iterator< container_type, traits_type::page_size > iterator
const_iterator begin() const noexcept
Returns an iterator to the beginning.
underlying_type base_type
reverse_iterator rend() noexcept
Returns a reverse iterator to the end.
basic_storage & operator=(basic_storage &&other) noexcept
Move assignment operator.
const_reverse_iterator rend() const noexcept
Returns a reverse iterator to the end.
underlying_iterator try_emplace(const Entity entt, const bool force_back, const void *value) override
Assigns an entity to a storage.
const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
std::reverse_iterator< const_iterator > const_reverse_iterator
value_type & patch(const entity_type entt, Func &&...func)
Updates the instance assigned to a given entity in-place.
std::reverse_iterator< iterator > reverse_iterator
std::size_t size_type
Unsigned integer type.
iterator insert(It first, It last, const value_type &value={})
Assigns one or more entities to a storage and constructs their objects from a given instance.
void pop(underlying_iterator first, underlying_iterator last) override
Erases entities from a storage.
typename container_type::pointer pointer
reverse_iterable reach() noexcept
Returns a reverse iterable object to use to visit a storage.
iterable_adaptor< internal::extended_storage_iterator< typename base_type::reverse_iterator, reverse_iterator > > reverse_iterable
iterable_adaptor< internal::extended_storage_iterator< typename base_type::iterator, iterator > > iterable
pointer raw() noexcept
Direct access to the array of objects.
std::tuple< value_type & > get_as_tuple(const entity_type entt) noexcept
Returns the object assigned to an entity as a tuple.
std::ptrdiff_t difference_type
value_type & get(const entity_type entt) noexcept
Returns the object assigned to an entity.
const_reverse_iterator crend() const noexcept
Returns a reverse iterator to the end.
const_reverse_iterable reach() const noexcept
Returns a reverse iterable object to use to visit a storage.
iterable each() noexcept
Returns an iterable object to use to visit a storage.
basic_storage & operator=(const basic_storage &)=delete
Default copy assignment operator, deleted on purpose.
void reserve(const size_type cap) override
Increases the capacity of a storage.
basic_storage(const allocator_type &allocator)
Constructs an empty storage with a given allocator.
value_type & emplace(const entity_type entt, Args &&...args)
Assigns an entity to a storage and constructs its object.
std::tuple< const value_type & > get_as_tuple(const entity_type entt) const noexcept
Returns the object assigned to an entity as a tuple.
void shrink_to_fit() override
Requests the removal of unused capacity.
const_reverse_iterator crbegin() const noexcept
Returns a reverse iterator to the beginning.
internal::storage_iterator< const container_type, traits_type::page_size > const_iterator
basic_storage(basic_storage &&other, const allocator_type &allocator)
Allocator-extended move constructor.
iterable_adaptor< internal::extended_storage_iterator< typename base_type::const_iterator, const_iterator > > const_iterable
basic_storage(const basic_storage &)=delete
Default copy constructor, deleted on purpose.
iterator begin() noexcept
Returns an iterator to the beginning.
static constexpr deletion_policy storage_policy
Allocator allocator_type
Allocator type.
constexpr std::enable_if_t< std::is_unsigned_v< Type >, Type > fast_mod(const Type value, const std::size_t mod) noexcept
Fast module utility function (powers of two only).
constexpr null_t null
Compile-time constant for null entities.
constexpr tombstone_t tombstone
Compile-time constant for tombstone entities.
constexpr Type * uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args)
Uses-allocator construction utility (waiting for C++20).
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.
deletion_policy
Storage deletion policy.
@ swap_only
Swap-only deletion policy.
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.
const type_info & type_id() noexcept
Returns the type info object associated to a given type.
@ ref
Aliasing mode, the object points to a non-const element.
constexpr bool operator>(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr auto to_address(Type &&ptr) noexcept
Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Common way to access various properties of components.
static constexpr bool in_place_delete
static constexpr std::size_t page_size
Utility class to create an iterable object from a pair of iterators.