2#include "gaia/config/config.h"
6#include <initializer_list>
10#include "gaia/cnt/bitset.h"
11#include "gaia/cnt/darray.h"
12#include "gaia/core/iterator.h"
13#include "gaia/core/utility.h"
14#include "gaia/mem/data_layout_policy.h"
15#include "gaia/mem/mem_alloc.h"
16#include "gaia/mem/mem_utils.h"
17#include "gaia/mem/paged_allocator.h"
18#include "gaia/mem/raw_data_holder.h"
23 using page_storage_id = uint32_t;
27 using difference_type = uint32_t;
28 using size_type = uint32_t;
30 constexpr static page_storage_id InvalidPageStorageId = (page_storage_id)-1;
34 template <
typename T,
typename Allocator>
51 "Sparse_storage items require a conversion function to be defined in gaia::cnt namespace");
52 return detail::InvalidPageStorageId;
58 template <
typename T,
typename Allocator,
bool IsFwd>
59 struct mem_page_iterator {
63 using difference_type = detail::difference_type;
64 using size_type = detail::size_type;
65 using iterator = mem_page_iterator;
69 using page_data_type = detail::mem_page_data<T>;
70 using page_type = detail::mem_page<T, Allocator>;
71 using bit_set_iter_type = std::conditional_t<
72 IsFwd,
typename page_data_type::bit_set::iter,
typename page_data_type::bit_set::iter_rev>;
74 page_type* m_pPage =
nullptr;
75 bit_set_iter_type m_it;
78 mem_page_iterator() =
default;
79 mem_page_iterator(page_type* pPage): m_pPage(pPage) {}
80 mem_page_iterator(page_type* pPage, bit_set_iter_type it): m_pPage(pPage), m_it(it) {}
82 reference operator*()
const {
83 return m_pPage->set_data(*m_it);
85 pointer operator->()
const {
86 return &m_pPage->set_data(*m_it);
89 iterator& operator++() {
93 iterator operator++(
int) {
99 GAIA_NODISCARD
bool operator==(
const iterator& other)
const {
100 return m_pPage == other.m_pPage && m_it == other.m_it;
102 GAIA_NODISCARD
bool operator!=(
const iterator& other)
const {
103 return m_pPage != other.m_pPage && m_it != other.m_it;
107 template <
typename T,
typename Allocator,
bool IsFwd>
108 struct mem_page_iterator_soa {
109 using value_type = T;
112 using difference_type = detail::difference_type;
113 using size_type = detail::size_type;
114 using iterator = mem_page_iterator_soa;
115 using iterator_category = core::bidirectional_iterator_tag;
118 using page_data_type = detail::mem_page_data<T>;
119 using page_type = detail::mem_page<T, Allocator>;
120 using bit_set_iter_type = std::conditional_t<
121 IsFwd,
typename page_data_type::bit_set::iter,
typename page_data_type::bit_set::iter_rev>;
124 bit_set_iter_type m_it;
127 mem_page_iterator_soa(page_type* pPage, bit_set_iter_type it): m_pPage(pPage), m_it(it) {}
129 value_type operator*()
const {
130 return m_pPage->set_data(*m_it);
132 value_type operator->()
const {
133 return &m_pPage->set_data(*m_it);
136 iterator& operator++() {
140 iterator operator++(
int) {
141 iterator temp(*
this);
145 iterator& operator--() {
149 iterator operator--(
int) {
150 iterator temp(*
this);
155 GAIA_NODISCARD
bool operator==(
const iterator& other)
const {
156 return m_pPage == other.m_pPage && m_it == other.m_it;
158 GAIA_NODISCARD
bool operator!=(
const iterator& other)
const {
159 return m_pPage != other.m_pPage && m_it != other.m_it;
163 template <
typename T>
164 struct mem_page_data {
165 static constexpr uint32_t PageCapacity = 4096;
167 using view_policy = mem::auto_view_policy<T>;
168 using bit_set = cnt::bitset<PageCapacity>;
169 static constexpr uint32_t AllocatedBytes = view_policy::get_min_byte_size(0, PageCapacity);
173 size_type cnt = size_type(0);
181 mem::raw_data_holder<T, AllocatedBytes> data;
184 template <
typename T,
typename Allocator>
186 static_assert(!std::is_empty_v<T>,
"It only makes sense to use page storage for data types with non-zero size");
189 using value_type = T;
190 using reference = T&;
191 using const_reference =
const T&;
193 using const_pointer =
const T*;
194 using view_policy = mem::auto_view_policy<T>;
195 using difference_type = detail::difference_type;
196 using size_type = detail::size_type;
198 template <
bool IsFwd>
199 using iterator_base = mem_page_iterator<T, Allocator, IsFwd>;
200 using iterator = iterator_base<true>;
201 using iterator_reverse = iterator_base<false>;
203 template <
bool IsFwd>
204 using iterator_soa_base = mem_page_iterator_soa<T, Allocator, IsFwd>;
205 using iterator_soa = iterator_soa_base<true>;
206 using iterator_soa_reverse = iterator_soa_base<false>;
208 using PageData = mem_page_data<T>;
209 static constexpr uint32_t PageCapacity = PageData::PageCapacity;
213 PageData* m_pData =
nullptr;
216 if GAIA_LIKELY (m_pData !=
nullptr)
220 m_pData = mem::AllocHelper::alloc<PageData, Allocator>(1);
221 (
void)new (m_pData) PageData{};
223 core::call_ctor_raw_n(data(), PageCapacity);
226 void dtr_data_inter(uint32_t idx)
noexcept {
227 GAIA_ASSERT(!empty());
229 if constexpr (!mem::is_soa_layout_v<T>) {
230 auto* ptr = &data()[idx];
231 core::call_dtor(ptr);
234 m_pData->header.mask.set(idx,
false);
235 --m_pData->header.cnt;
238 void dtr_active_data() noexcept {
239 if constexpr (!mem::is_soa_layout_v<T>) {
240 for (
auto i: m_pData->header.mask) {
241 auto* ptr = &data()[i];
242 core::call_dtor(ptr);
248 if (m_pData ==
nullptr)
255 m_pData->~PageData();
256 mem::AllocHelper::free<Allocator>(m_pData);
261 mem_page() =
default;
263 mem_page(
const mem_page& other) {
265 if (other.m_pData ==
nullptr) {
270 m_pData->header.mask = other.m_pData->header.mask;
271 m_pData->header.cnt = other.m_pData->header.cnt;
274 for (
auto i: other.m_pData->header.mask)
275 add_data(i, other.get_data(i));
279 mem_page& operator=(
const mem_page& other) {
280 GAIA_ASSERT(core::addressof(other) !=
this);
283 if (other.m_pData ==
nullptr) {
289 if (m_pData !=
nullptr)
292 m_pData->header.mask = other.m_pData->header.mask;
293 m_pData->header.cnt = other.m_pData->header.cnt;
296 for (
auto i: other.m_pData->header.mask)
297 add_data(i, other.get_data(i));
303 mem_page(mem_page&& other)
noexcept {
304 m_pData = other.m_pData;
305 other.m_pData =
nullptr;
308 mem_page& operator=(mem_page&& other)
noexcept {
309 GAIA_ASSERT(core::addressof(other) !=
this);
313 m_pData = other.m_pData;
314 other.m_pData =
nullptr;
323 GAIA_CLANG_WARNING_PUSH()
325 GAIA_CLANG_WARNING_DISABLE("-Wcast-align")
327 GAIA_NODISCARD pointer data() noexcept {
328 return GAIA_ACC((pointer)&m_pData->data[0]);
331 GAIA_NODISCARD const_pointer data() const noexcept {
332 return GAIA_ACC((const_pointer)&m_pData->data[0]);
335 GAIA_NODISCARD
decltype(
auto) set_data(size_type pos)
noexcept {
336 GAIA_ASSERT(m_pData->header.mask.test(pos));
337 return view_policy::set(
338 {GAIA_ACC((
typename view_policy::TargetCastType) & m_pData->data[0]), PageCapacity}, pos);
341 GAIA_NODISCARD
decltype(
auto)
operator[](size_type pos)
noexcept {
342 GAIA_ASSERT(m_pData->header.mask.test(pos));
343 return view_policy::set(
344 {GAIA_ACC((
typename view_policy::TargetCastType) & m_pData->data[0]), PageCapacity}, pos);
347 GAIA_NODISCARD
decltype(
auto) get_data(size_type pos)
const noexcept {
348 GAIA_ASSERT(m_pData->header.mask.test(pos));
349 return view_policy::get(
350 {GAIA_ACC((
typename view_policy::TargetCastType) & m_pData->data[0]), PageCapacity}, pos);
353 GAIA_NODISCARD
decltype(
auto)
operator[](size_type pos)
const noexcept {
354 GAIA_ASSERT(m_pData->header.mask.test(pos));
355 return view_policy::get(
356 {GAIA_ACC((
typename view_policy::TargetCastType) & m_pData->data[0]), PageCapacity}, pos);
359 GAIA_CLANG_WARNING_POP()
363 ++m_pData->header.cnt;
366 decltype(
auto) add_data(uint32_t idx,
const T& arg) {
367 m_pData->header.mask.set(idx);
369 if constexpr (mem::is_soa_layout_v<T>) {
372 auto* ptr = &set_data(idx);
373 core::call_ctor(ptr, arg);
374 return (reference)(*ptr);
378 decltype(
auto) add_data(uint32_t idx, T&& arg) {
379 m_pData->header.mask.set(idx);
381 if constexpr (mem::is_soa_layout_v<T>) {
382 set_data(idx) = GAIA_MOV(arg);
384 auto* ptr = &set_data(idx);
385 core::call_ctor(ptr, GAIA_MOV(arg));
386 return (reference)(*ptr);
390 template <
typename... Args>
391 decltype(
auto) emplace_data(uint32_t idx, Args&&... args) {
392 m_pData->header.used.set(idx);
394 if constexpr (mem::is_soa_layout_v<T>) {
395 set_data(idx) = T(GAIA_FWD(args)...);
397 auto* ptr = &set_data(idx);
398 core::call_ctor(ptr, GAIA_FWD(args)...);
399 return (reference)(*ptr);
403 void del_data(uint32_t idx)
noexcept {
407 if (m_pData->header.cnt == 0)
411 GAIA_NODISCARD
bool has_data(uint32_t idx)
const noexcept {
412 return m_pData ? m_pData->header.mask.test(idx) :
false;
415 GAIA_NODISCARD size_type size() const noexcept {
416 return m_pData ? m_pData->header.cnt : 0;
419 GAIA_NODISCARD
bool empty() const noexcept {
423 GAIA_NODISCARD
decltype(
auto) front() noexcept {
424 GAIA_ASSERT(!empty());
425 if constexpr (mem::is_soa_layout_v<T>)
428 return (reference)*begin();
431 GAIA_NODISCARD
decltype(
auto) front() const noexcept {
432 GAIA_ASSERT(!empty());
433 if constexpr (mem::is_soa_layout_v<T>)
436 return (const_reference)*begin();
439 GAIA_NODISCARD
decltype(
auto) back() noexcept {
440 GAIA_ASSERT(!empty());
441 const auto idx = *m_pData->header.mask.rbegin();
442 if constexpr (mem::is_soa_layout_v<T>)
443 return set_data(idx);
445 return (reference)(set_data(idx));
448 GAIA_NODISCARD
decltype(
auto) back() const noexcept {
449 GAIA_ASSERT(!empty());
450 const auto idx = *m_pData->header.mask.rbegin();
451 if constexpr (mem::is_soa_layout_v<T>)
452 return set_data(idx);
454 return (const_reference)set_data(idx);
457 static constexpr typename PageData::bit_set s_dummyBitSet{};
459 GAIA_NODISCARD
auto begin() const noexcept {
460 if constexpr (mem::is_soa_layout_v<T>)
461 return iterator_soa((mem_page*)
this, m_pData ? m_pData->header.mask.begin() : s_dummyBitSet.begin());
463 return iterator((mem_page*)
this, m_pData ? m_pData->header.mask.begin() : s_dummyBitSet.begin());
466 GAIA_NODISCARD
auto end() const noexcept {
467 if constexpr (mem::is_soa_layout_v<T>)
468 return iterator_soa((mem_page*)
this, m_pData ? m_pData->header.mask.end() : s_dummyBitSet.end());
470 return iterator((mem_page*)
this, m_pData ? m_pData->header.mask.end() : s_dummyBitSet.end());
473 GAIA_NODISCARD
auto rbegin() const noexcept {
474 if constexpr (mem::is_soa_layout_v<T>)
475 return iterator_soa_reverse(
476 (mem_page*)
this, m_pData ? m_pData->header.mask.rbegin() : s_dummyBitSet.rbegin());
478 return iterator_reverse((mem_page*)
this, m_pData ? m_pData->header.mask.rbegin() : s_dummyBitSet.rbegin());
481 GAIA_NODISCARD
auto rend() const noexcept {
482 if constexpr (mem::is_soa_layout_v<T>)
483 return iterator_soa_reverse((mem_page*)
this, m_pData ? m_pData->header.mask.rend() : s_dummyBitSet.rend());
485 return iterator_reverse((mem_page*)
this, m_pData ? m_pData->header.mask.rend() : s_dummyBitSet.rend());
488 GAIA_NODISCARD
bool operator==(
const mem_page& other)
const noexcept {
490 GAIA_ASSERT(m_pData !=
nullptr);
491 GAIA_ASSERT(other.m_pData !=
nullptr);
493 if (m_pData->header.cnt != other.m_pData->header.cnt)
495 if (m_pData->header.mask != other.m_pData->header.mask)
497 for (
auto i: m_pData->header.mask)
498 if (!(get_data(i) == other[i]))
503 GAIA_NODISCARD
bool operator!=(
const mem_page& other)
const noexcept {
504 return !operator==(other);
514 template <
typename T,
typename Allocator,
bool IsFwd>
532 using page_type = detail::mem_page<T, Allocator>;
535 page_type* m_pPageLast;
548 if constexpr (!
IsFwd) {
549 m_it = m_pPage->rbegin();
550 while (m_it == m_pPage->rend()) {
552 if (m_pPage == m_pPageLast) {
556 m_it = m_pPage->rbegin();
559 m_it = m_pPage->begin();
560 while (m_it == m_pPage->end()) {
562 if (m_pPage == m_pPageLast) {
566 m_it = m_pPage->begin();
574 return m_it.operator*();
579 return m_it.operator->();
585 if constexpr (!
IsFwd) {
587 if (m_it == m_pPage->rend()) {
589 if (m_pPage == m_pPageLast) {
597 if (m_it == m_pPage->end()) {
599 if (m_pPage == m_pPageLast) {
603 m_it = m_pPage->
begin();
620 return m_pPage == other.m_pPage && m_it == other.m_it;
626 return m_pPage != other.m_pPage || m_it != other.m_it;
634 template <
typename T,
typename Allocator,
bool IsFwd>
652 using page_type = detail::mem_page<T, Allocator>;
654 const page_type* m_pPage;
655 const page_type* m_pPageLast;
668 if constexpr (!
IsFwd) {
669 m_it = m_pPage->rbegin();
670 while (m_it == m_pPage->rend()) {
672 if (m_pPage == m_pPageLast) {
676 m_it = m_pPage->rbegin();
679 m_it = m_pPage->begin();
680 while (m_it == m_pPage->end()) {
682 if (m_pPage == m_pPageLast) {
686 m_it = m_pPage->begin();
694 return m_it.operator*();
699 return m_it.operator->();
705 if constexpr (!
IsFwd) {
707 if (m_it == m_pPage->rend()) {
709 if (m_pPage == m_pPageLast) {
717 if (m_it == m_pPage->end()) {
719 if (m_pPage == m_pPageLast) {
723 m_it = m_pPage->
begin();
740 return m_pPage == other.m_pPage && m_it == other.m_it;
746 return m_pPage != other.m_pPage || m_it != other.m_it;
754 template <
typename T,
typename Allocator,
bool IsFwd>
770 using page_type = detail::mem_page<T, Allocator>;
773 page_type* m_pPageLast;
786 if constexpr (!
IsFwd) {
787 m_it = m_pPage->rbegin();
788 while (m_it == m_pPage->rend()) {
789 if (m_pPage == m_pPageLast)
792 m_it = m_pPage->rbegin();
795 m_it = m_pPage->begin();
796 while (m_it == m_pPage->end()) {
797 if (m_pPage == m_pPageLast)
800 m_it = m_pPage->begin();
808 return m_it.operator*();
813 return m_it.operator->();
819 if constexpr (!
IsFwd) {
821 while (m_it == m_pPage->rend()) {
827 while (m_it == m_pPage->end()) {
829 m_it = m_pPage->
begin();
846 return m_pPage == other.m_pPage && m_it == other.m_it;
852 return m_pPage != other.m_pPage || m_it != other.m_it;
860 template <
typename T,
typename Allocator,
bool IsFwd>
876 using page_type = detail::mem_page<T, Allocator>;
878 const page_type* m_pPage;
879 const page_type* m_pPageLast;
893 if constexpr (!
IsFwd) {
894 m_it = m_pPage->rbegin();
895 while (m_it == m_pPage->rend()) {
896 if (m_pPage == m_pPageLast)
899 m_it = m_pPage->rbegin();
902 m_it = m_pPage->begin();
903 while (m_it == m_pPage->end()) {
904 if (m_pPage == m_pPageLast)
907 m_it = m_pPage->begin();
915 return m_it.operator*();
920 return m_it.operator->();
926 if constexpr (!
IsFwd) {
928 while (m_it == m_pPage->rend()) {
934 while (m_it == m_pPage->end()) {
936 m_it = m_pPage->
begin();
953 return m_pPage == other.m_pPage && m_it == other.m_it;
959 return m_pPage != other.m_pPage || m_it != other.m_it;
965 template <
typename T>
1018 constexpr static uint32_t ToPageIndex = core::count_bits(PageMask);
1040 m_pages = other.m_pages;
1041 m_itemCnt = other.m_itemCnt;
1048 GAIA_ASSERT(core::addressof(other) !=
this);
1050 m_pages = other.m_pages;
1051 m_itemCnt = other.m_itemCnt;
1058 m_pages = GAIA_MOV(other.m_pages);
1059 m_itemCnt = other.m_itemCnt;
1068 GAIA_ASSERT(core::addressof(other) !=
this);
1070 m_pages = GAIA_MOV(other.m_pages);
1071 m_itemCnt = other.m_itemCnt;
1080 GAIA_CLANG_WARNING_PUSH()
1082 GAIA_CLANG_WARNING_DISABLE("-
Wcast-align")
1088 GAIA_ASSERT(
has(
id));
1099 GAIA_ASSERT(
has(
id));
1106 GAIA_CLANG_WARNING_POP()
1117 const auto val = page_data_type::bit_set::BitCount;
1118 return did < val && m_pages[
pid].has_data(
did);
1124 GAIA_NODISCARD
bool has(
const T&
arg)
const noexcept {
1126 GAIA_ASSERT(
id != detail::InvalidPageStorageId);
1134 template <
typename TType>
1138 if constexpr (mem::is_soa_layout_v<TType>)
1154 if constexpr (mem::is_soa_layout_v<TType>)
1164 GAIA_ASSERT(
has(
id));
1176 GAIA_ASSERT(!
empty());
1177 GAIA_ASSERT(
id != detail::InvalidPageStorageId);
1212 return m_itemCnt == 0;
1218 GAIA_ASSERT(!
empty());
1225 GAIA_ASSERT(!
empty());
1232 GAIA_ASSERT(!
empty());
1239 GAIA_ASSERT(!
empty());
1246 GAIA_ASSERT(!
empty());
1253 GAIA_ASSERT(!
empty());
1260 GAIA_ASSERT(!
empty());
1267 GAIA_ASSERT(!
empty());
1274 GAIA_ASSERT(!
empty());
1281 GAIA_ASSERT(!
empty());
1288 GAIA_ASSERT(!
empty());
1295 GAIA_ASSERT(!
empty());
1302 GAIA_ASSERT(!
empty());
1309 GAIA_ASSERT(!
empty());
1316 GAIA_ASSERT(!
empty());
1323 GAIA_ASSERT(!
empty());
1331 return m_pages == other.m_pages;
Array with variable size of elements of type.
Definition darray_impl.h:27
GAIA_NODISCARD auto rbegin() noexcept
Returns a reverse traversal iterator to the last element.
Definition darray_impl.h:574
GAIA_NODISCARD size_type size() const noexcept
Returns the number of elements.
Definition darray_impl.h:504
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first element.
Definition darray_impl.h:556
void resize(size_type count)
Changes the number of elements.
Definition darray_impl.h:240
GAIA_NODISCARD pointer data() noexcept
Returns a pointer to the element storage.
Definition darray_impl.h:193
Heap-allocated paged storage for elements of type T.
Definition paged_storage.h:966
GAIA_NODISCARD bool operator==(const page_storage &other) const noexcept
Checks whether two storages contain equal elements.
Definition paged_storage.h:1330
detail::mem_page< T, Allocator > page_type
Page type used by the storage.
Definition paged_storage.h:993
const_page_iterator< T, Allocator, false > const_iterator_reverse
Reverse read-only iterator.
Definition paged_storage.h:1008
GAIA_NODISCARD auto end() noexcept
Returns an iterator past the last stored element.
Definition paged_storage.h:1266
GAIA_NODISCARD auto rbegin() const noexcept
Returns a reverse iterator to the last stored element.
Definition paged_storage.h:1294
GAIA_NODISCARD decltype(auto) front() const noexcept
Accesses the first stored element.
Definition paged_storage.h:1224
GAIA_NODISCARD auto crend() const noexcept
Returns a read-only reverse iterator before the first stored element.
Definition paged_storage.h:1322
GAIA_NODISCARD auto cbegin() const noexcept
Returns a read-only iterator to the first stored element.
Definition paged_storage.h:1259
decltype(auto) add(TType &&arg)
Inserts the item arg into the storage.
Definition paged_storage.h:1135
GAIA_NODISCARD decltype(auto) back() const noexcept
Accesses the last stored element.
Definition paged_storage.h:1238
void clear()
Clears the storage.
Definition paged_storage.h:1198
page_iterator< T, Allocator, true > iterator
Forward mutable iterator.
Definition paged_storage.h:998
void del(const T &arg) noexcept
Removes the item arg from the storage.
Definition paged_storage.h:1192
const_page_iterator< T, Allocator, true > const_iterator
Forward read-only iterator.
Definition paged_storage.h:1006
static constexpr uint32_t AllocatorBlockSize
Size in bytes of one allocator block.
Definition paged_storage.h:986
GAIA_NODISCARD auto rend() noexcept
Returns a reverse iterator before the first stored element.
Definition paged_storage.h:1308
decltype(auto) set(page_storage_id id)
Accesses the record at the index id for update.
Definition paged_storage.h:1163
page_storage & operator=(page_storage &&other) noexcept
Move-assigns a storage.
Definition paged_storage.h:1067
page_iterator< T, Allocator, false > iterator_reverse
Reverse mutable iterator.
Definition paged_storage.h:1000
GAIA_NODISCARD size_type size() const noexcept
Returns the number of items inserted into the storage.
Definition paged_storage.h:1205
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first stored element.
Definition paged_storage.h:1245
detail::difference_type difference_type
Type used for iterator distances.
Definition paged_storage.h:981
static constexpr uint32_t PageCapacity
Maximum number of elements addressable in one page.
Definition paged_storage.h:995
GAIA_NODISCARD auto rend() const noexcept
Returns a reverse iterator before the first stored element.
Definition paged_storage.h:1315
GAIA_NODISCARD auto rbegin() noexcept
Returns a reverse iterator to the last stored element.
Definition paged_storage.h:1287
detail::mem_page_data< T > page_data_type
Raw page-data type.
Definition paged_storage.h:991
GAIA_NODISCARD bool empty() const noexcept
Checks if the storage is empty (no items inserted).
Definition paged_storage.h:1211
GAIA_NODISCARD bool has(const T &arg) const noexcept
Checks if an item arg exists within the storage.
Definition paged_storage.h:1124
GAIA_NODISCARD auto begin() const noexcept
Returns an iterator to the first stored element.
Definition paged_storage.h:1252
GAIA_NODISCARD decltype(auto) front() noexcept
Accesses the first stored element.
Definition paged_storage.h:1217
void del(page_storage_id id) noexcept
Removes the item at the index id from the storage.
Definition paged_storage.h:1175
GAIA_NODISCARD auto cend() const noexcept
Returns a read-only iterator past the last stored element.
Definition paged_storage.h:1280
GAIA_NODISCARD auto end() const noexcept
Returns an iterator past the last stored element.
Definition paged_storage.h:1273
GAIA_NODISCARD bool operator!=(const page_storage &other) const noexcept
Checks whether two storages differ.
Definition paged_storage.h:1337
detail::size_type size_type
Type used for sizes and indices.
Definition paged_storage.h:983
GAIA_NODISCARD auto crbegin() const noexcept
Returns a read-only reverse iterator to the last stored element.
Definition paged_storage.h:1301
GAIA_NODISCARD decltype(auto) back() noexcept
Accesses the last stored element.
Definition paged_storage.h:1231
page_storage & operator=(const page_storage &other)
Copy-assigns a storage.
Definition paged_storage.h:1047
page_storage(page_storage &&other) noexcept
Move-constructs a storage.
Definition paged_storage.h:1057
GAIA_NODISCARD bool has(page_storage_id id) const noexcept
Checks if an item with a given page id exists.
Definition paged_storage.h:1111
Gaia-ECS is a header-only library which means we want to avoid using global static variables because ...
Definition dyn_singleton.h:29
Read-only iterator over structure-of-arrays elements in paged storage.
Definition paged_storage.h:861
const_page_iterator_soa(const page_type *pPage)
Constructs an end iterator at a page boundary.
Definition paged_storage.h:885
iterator operator++(int)
Advances to the next element.
Definition paged_storage.h:943
detail::difference_type difference_type
Type used for iterator distances.
Definition paged_storage.h:867
detail::size_type size_type
Type used for sizes and indices.
Definition paged_storage.h:869
iterator & operator++()
Advances to the next element.
Definition paged_storage.h:925
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators have the same position.
Definition paged_storage.h:952
value_type operator*() const
Accesses the current element view.
Definition paged_storage.h:914
value_type operator->() const
Accesses the current element view through arrow syntax.
Definition paged_storage.h:919
const_page_iterator_soa(const page_type *pPage, const page_type *pPageLast)
Constructs a read-only iterator over a page range.
Definition paged_storage.h:890
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators have different positions.
Definition paged_storage.h:958
Read-only iterator over elements in paged storage.
Definition paged_storage.h:635
iterator operator++(int)
Advances to the next element.
Definition paged_storage.h:730
reference operator*() const
Accesses the current element.
Definition paged_storage.h:693
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators have the same position.
Definition paged_storage.h:739
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators have different positions.
Definition paged_storage.h:745
detail::difference_type difference_type
Type used for iterator distances.
Definition paged_storage.h:643
const_page_iterator(const page_type *pPage)
Constructs an end iterator at a page boundary.
Definition paged_storage.h:661
detail::size_type size_type
Type used for sizes and indices.
Definition paged_storage.h:645
const_page_iterator(const page_type *pPage, const page_type *pPageLast)
Constructs a read-only iterator over a page range.
Definition paged_storage.h:666
pointer operator->() const
Accesses the current element through a pointer.
Definition paged_storage.h:698
iterator & operator++()
Advances to the next element.
Definition paged_storage.h:704
Iterator over structure-of-arrays elements in paged storage.
Definition paged_storage.h:755
iterator & operator++()
Advances to the next element.
Definition paged_storage.h:818
detail::size_type size_type
Type used for sizes and indices.
Definition paged_storage.h:763
detail::difference_type difference_type
Type used for iterator distances.
Definition paged_storage.h:761
iterator operator++(int)
Advances to the next element.
Definition paged_storage.h:836
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators have different positions.
Definition paged_storage.h:851
value_type operator*() const
Accesses the current element view.
Definition paged_storage.h:807
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators have the same position.
Definition paged_storage.h:845
value_type operator->() const
Accesses the current element view through arrow syntax.
Definition paged_storage.h:812
page_iterator_soa(page_type *pPage)
Constructs an end iterator at a page boundary.
Definition paged_storage.h:779
page_iterator_soa(page_type *pPage, page_type *pPageLast)
Constructs an iterator over a page range.
Definition paged_storage.h:784
Iterator over elements in paged storage.
Definition paged_storage.h:515
detail::size_type size_type
Type used for sizes and indices.
Definition paged_storage.h:525
detail::difference_type difference_type
Type used for iterator distances.
Definition paged_storage.h:523
iterator & operator++()
Advances to the next element.
Definition paged_storage.h:584
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators have the same position.
Definition paged_storage.h:619
iterator operator++(int)
Advances to the next element.
Definition paged_storage.h:610
page_iterator(page_type *pPage)
Constructs an end iterator at a page boundary.
Definition paged_storage.h:541
pointer operator->() const
Accesses the current element through a pointer.
Definition paged_storage.h:578
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators have different positions.
Definition paged_storage.h:625
reference operator*() const
Accesses the current element.
Definition paged_storage.h:573
page_iterator(page_type *pPage, page_type *pPageLast)
Constructs an iterator over a page range.
Definition paged_storage.h:546
Customization point for converting a value to its paged-storage identifier. The default implementatio...
Definition paged_storage.h:43
static page_storage_id get(const T &item) noexcept
Applies the default conversion for an item.
Definition paged_storage.h:47
Storage policy for a selected layout and item type.
Definition data_layout_policy.h:123