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 !(*
this == other);
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>;
123 page_type* m_pPage =
nullptr;
124 bit_set_iter_type m_it;
128 mem_page_iterator_soa() =
default;
133 mem_page_iterator_soa(page_type* pPage, bit_set_iter_type it): m_pPage(pPage), m_it(it) {}
135 value_type operator*()
const {
136 return m_pPage->set_data(*m_it);
138 value_type operator->()
const {
139 return m_pPage->set_data(*m_it);
142 iterator& operator++() {
146 iterator operator++(
int) {
147 iterator temp(*
this);
151 iterator& operator--() {
155 iterator operator--(
int) {
156 iterator temp(*
this);
161 GAIA_NODISCARD
bool operator==(
const iterator& other)
const {
162 return m_pPage == other.m_pPage && m_it == other.m_it;
164 GAIA_NODISCARD
bool operator!=(
const iterator& other)
const {
165 return !(*
this == other);
169 template <
typename T>
170 struct mem_page_data {
171 static constexpr uint32_t PageCapacity = 4096;
173 using view_policy = mem::auto_view_policy<T>;
174 using bit_set = cnt::bitset<PageCapacity>;
175 static constexpr uint32_t AllocatedBytes = view_policy::get_min_byte_size(0, PageCapacity);
179 size_type cnt = size_type(0);
187 mem::raw_data_holder<T, AllocatedBytes> data;
190 template <
typename T,
typename Allocator>
192 static_assert(!std::is_empty_v<T>,
"It only makes sense to use page storage for data types with non-zero size");
195 using value_type = T;
196 using reference = T&;
197 using const_reference =
const T&;
199 using const_pointer =
const T*;
200 using view_policy = mem::auto_view_policy<T>;
201 using difference_type = detail::difference_type;
202 using size_type = detail::size_type;
204 template <
bool IsFwd>
205 using iterator_base = mem_page_iterator<T, Allocator, IsFwd>;
206 using iterator = iterator_base<true>;
207 using iterator_reverse = iterator_base<false>;
209 template <
bool IsFwd>
210 using iterator_soa_base = mem_page_iterator_soa<T, Allocator, IsFwd>;
211 using iterator_soa = iterator_soa_base<true>;
212 using iterator_soa_reverse = iterator_soa_base<false>;
214 using PageData = mem_page_data<T>;
215 static constexpr uint32_t PageCapacity = PageData::PageCapacity;
219 PageData* m_pData =
nullptr;
222 if GAIA_LIKELY (m_pData !=
nullptr)
226 m_pData = mem::AllocHelper::alloc<PageData, Allocator>(1);
227 (
void)new (m_pData) PageData{};
229 core::call_ctor_raw_n(data(), PageCapacity);
232 void dtr_data_inter(uint32_t idx)
noexcept {
233 GAIA_ASSERT(!empty());
235 if constexpr (!mem::is_soa_layout_v<T>) {
236 auto* ptr = &data()[idx];
237 core::call_dtor(ptr);
240 m_pData->header.mask.set(idx,
false);
241 --m_pData->header.cnt;
244 void dtr_active_data() noexcept {
245 if constexpr (!mem::is_soa_layout_v<T>) {
246 for (
auto i: m_pData->header.mask) {
247 auto* ptr = &data()[i];
248 core::call_dtor(ptr);
254 if (m_pData ==
nullptr)
261 m_pData->~PageData();
262 mem::AllocHelper::free<Allocator>(m_pData);
267 mem_page() =
default;
269 mem_page(
const mem_page& other) {
271 if (other.m_pData ==
nullptr) {
276 m_pData->header.mask = other.m_pData->header.mask;
277 m_pData->header.cnt = other.m_pData->header.cnt;
280 for (
auto i: other.m_pData->header.mask)
281 add_data(i, other.get_data(i));
285 mem_page& operator=(
const mem_page& other) {
286 GAIA_ASSERT(core::addressof(other) !=
this);
289 if (other.m_pData ==
nullptr) {
295 if (m_pData !=
nullptr)
298 m_pData->header.mask = other.m_pData->header.mask;
299 m_pData->header.cnt = other.m_pData->header.cnt;
302 for (
auto i: other.m_pData->header.mask)
303 add_data(i, other.get_data(i));
309 mem_page(mem_page&& other)
noexcept {
310 m_pData = other.m_pData;
311 other.m_pData =
nullptr;
314 mem_page& operator=(mem_page&& other)
noexcept {
315 GAIA_ASSERT(core::addressof(other) !=
this);
319 m_pData = other.m_pData;
320 other.m_pData =
nullptr;
329 GAIA_CLANG_WARNING_PUSH()
331 GAIA_CLANG_WARNING_DISABLE("-Wcast-align")
333 GAIA_NODISCARD pointer data() noexcept {
334 return GAIA_ACC((pointer)&m_pData->data[0]);
337 GAIA_NODISCARD const_pointer data() const noexcept {
338 return GAIA_ACC((const_pointer)&m_pData->data[0]);
341 GAIA_NODISCARD
decltype(
auto) set_data(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)
operator[](size_type pos)
noexcept {
348 GAIA_ASSERT(m_pData->header.mask.test(pos));
349 return view_policy::set(
350 {GAIA_ACC((
typename view_policy::TargetCastType) & m_pData->data[0]), PageCapacity}, pos);
353 GAIA_NODISCARD
decltype(
auto) get_data(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_NODISCARD
decltype(
auto)
operator[](size_type pos)
const noexcept {
360 GAIA_ASSERT(m_pData->header.mask.test(pos));
361 return view_policy::get(
362 {GAIA_ACC((
typename view_policy::TargetCastType) & m_pData->data[0]), PageCapacity}, pos);
365 GAIA_CLANG_WARNING_POP()
369 ++m_pData->header.cnt;
372 decltype(
auto) add_data(uint32_t idx,
const T& arg) {
373 m_pData->header.mask.set(idx);
375 if constexpr (mem::is_soa_layout_v<T>) {
378 auto* ptr = &set_data(idx);
379 core::call_ctor(ptr, arg);
380 return (reference)(*ptr);
384 decltype(
auto) add_data(uint32_t idx, T&& arg) {
385 m_pData->header.mask.set(idx);
387 if constexpr (mem::is_soa_layout_v<T>) {
388 set_data(idx) = GAIA_MOV(arg);
390 auto* ptr = &set_data(idx);
391 core::call_ctor(ptr, GAIA_MOV(arg));
392 return (reference)(*ptr);
396 template <
typename... Args>
397 decltype(
auto) emplace_data(uint32_t idx, Args&&... args) {
398 m_pData->header.used.set(idx);
400 if constexpr (mem::is_soa_layout_v<T>) {
401 set_data(idx) = T(GAIA_FWD(args)...);
403 auto* ptr = &set_data(idx);
404 core::call_ctor(ptr, GAIA_FWD(args)...);
405 return (reference)(*ptr);
409 void del_data(uint32_t idx)
noexcept {
413 if (m_pData->header.cnt == 0)
417 GAIA_NODISCARD
bool has_data(uint32_t idx)
const noexcept {
418 return m_pData ? m_pData->header.mask.test(idx) :
false;
421 GAIA_NODISCARD size_type size() const noexcept {
422 return m_pData ? m_pData->header.cnt : 0;
425 GAIA_NODISCARD
bool empty() const noexcept {
429 GAIA_NODISCARD
decltype(
auto) front() noexcept {
430 GAIA_ASSERT(!empty());
431 if constexpr (mem::is_soa_layout_v<T>)
434 return (reference)*begin();
437 GAIA_NODISCARD
decltype(
auto) front() const noexcept {
438 GAIA_ASSERT(!empty());
439 if constexpr (mem::is_soa_layout_v<T>)
442 return (const_reference)*begin();
445 GAIA_NODISCARD
decltype(
auto) back() noexcept {
446 GAIA_ASSERT(!empty());
447 const auto idx = *m_pData->header.mask.rbegin();
448 if constexpr (mem::is_soa_layout_v<T>)
449 return set_data(idx);
451 return (reference)(set_data(idx));
454 GAIA_NODISCARD
decltype(
auto) back() const noexcept {
455 GAIA_ASSERT(!empty());
456 const auto idx = *m_pData->header.mask.rbegin();
457 if constexpr (mem::is_soa_layout_v<T>)
458 return set_data(idx);
460 return (const_reference)set_data(idx);
463 static constexpr typename PageData::bit_set s_dummyBitSet{};
465 GAIA_NODISCARD
auto begin() const noexcept {
466 if constexpr (mem::is_soa_layout_v<T>)
467 return iterator_soa((mem_page*)
this, m_pData ? m_pData->header.mask.begin() : s_dummyBitSet.begin());
469 return iterator((mem_page*)
this, m_pData ? m_pData->header.mask.begin() : s_dummyBitSet.begin());
472 GAIA_NODISCARD
auto end() const noexcept {
473 if constexpr (mem::is_soa_layout_v<T>)
474 return iterator_soa((mem_page*)
this, m_pData ? m_pData->header.mask.end() : s_dummyBitSet.end());
476 return iterator((mem_page*)
this, m_pData ? m_pData->header.mask.end() : s_dummyBitSet.end());
479 GAIA_NODISCARD
auto rbegin() const noexcept {
480 if constexpr (mem::is_soa_layout_v<T>)
481 return iterator_soa_reverse(
482 (mem_page*)
this, m_pData ? m_pData->header.mask.rbegin() : s_dummyBitSet.rbegin());
484 return iterator_reverse((mem_page*)
this, m_pData ? m_pData->header.mask.rbegin() : s_dummyBitSet.rbegin());
487 GAIA_NODISCARD
auto rend() const noexcept {
488 if constexpr (mem::is_soa_layout_v<T>)
489 return iterator_soa_reverse((mem_page*)
this, m_pData ? m_pData->header.mask.rend() : s_dummyBitSet.rend());
491 return iterator_reverse((mem_page*)
this, m_pData ? m_pData->header.mask.rend() : s_dummyBitSet.rend());
494 GAIA_NODISCARD
bool operator==(
const mem_page& other)
const noexcept {
496 GAIA_ASSERT(m_pData !=
nullptr);
497 GAIA_ASSERT(other.m_pData !=
nullptr);
499 if (m_pData->header.cnt != other.m_pData->header.cnt)
501 if (m_pData->header.mask != other.m_pData->header.mask)
503 for (
auto i: m_pData->header.mask)
504 if (!(get_data(i) == other[i]))
509 GAIA_NODISCARD
bool operator!=(
const mem_page& other)
const noexcept {
510 return !operator==(other);
520 template <
typename T,
typename Allocator,
bool IsFwd>
538 using page_type = detail::mem_page<T, Allocator>;
541 page_type* m_pPageLast;
554 if constexpr (!
IsFwd) {
555 m_it = m_pPage->rbegin();
556 while (m_it == m_pPage->rend()) {
557 if (m_pPage == m_pPageLast) {
562 m_it = m_pPage->rbegin();
565 m_it = m_pPage->begin();
566 while (m_it == m_pPage->end()) {
568 if (m_pPage == m_pPageLast) {
572 m_it = m_pPage->begin();
580 return m_it.operator*();
585 return m_it.operator->();
591 if constexpr (!
IsFwd) {
593 if (m_it == m_pPage->rend()) {
595 if (m_pPage == m_pPageLast) {
601 }
while (m_it == m_pPage->rend());
605 if (m_it == m_pPage->end()) {
608 if (m_pPage == m_pPageLast) {
612 m_it = m_pPage->
begin();
613 }
while (m_it == m_pPage->end());
630 return m_pPage ==
other.m_pPage && m_it ==
other.m_it;
636 return m_pPage !=
other.m_pPage || m_it !=
other.m_it;
644 template <
typename T,
typename Allocator,
bool IsFwd>
662 using page_type = detail::mem_page<T, Allocator>;
664 const page_type* m_pPage;
665 const page_type* m_pPageLast;
678 if constexpr (!
IsFwd) {
679 m_it = m_pPage->rbegin();
680 while (m_it == m_pPage->rend()) {
681 if (m_pPage == m_pPageLast) {
686 m_it = m_pPage->rbegin();
689 m_it = m_pPage->begin();
690 while (m_it == m_pPage->end()) {
692 if (m_pPage == m_pPageLast) {
696 m_it = m_pPage->begin();
704 return m_it.operator*();
709 return m_it.operator->();
715 if constexpr (!
IsFwd) {
717 if (m_it == m_pPage->rend()) {
719 if (m_pPage == m_pPageLast) {
725 }
while (m_it == m_pPage->rend());
729 if (m_it == m_pPage->end()) {
732 if (m_pPage == m_pPageLast) {
736 m_it = m_pPage->
begin();
737 }
while (m_it == m_pPage->end());
754 return m_pPage ==
other.m_pPage && m_it ==
other.m_it;
760 return m_pPage !=
other.m_pPage || m_it !=
other.m_it;
771 template <
typename T,
typename Allocator,
bool IsFwd>
787 using page_type = detail::mem_page<T, Allocator>;
790 page_type* m_pPageLast;
803 if constexpr (!
IsFwd) {
804 m_it = m_pPage->rbegin();
805 while (m_it == m_pPage->rend()) {
806 if (m_pPage == m_pPageLast) {
811 m_it = m_pPage->rbegin();
814 m_it = m_pPage->begin();
815 while (m_it == m_pPage->end()) {
817 if (m_pPage == m_pPageLast) {
821 m_it = m_pPage->begin();
829 return m_it.operator*();
834 return m_it.operator->();
840 if constexpr (!
IsFwd) {
842 if (m_it == m_pPage->rend()) {
844 if (m_pPage == m_pPageLast) {
850 }
while (m_it == m_pPage->rend());
854 if (m_it == m_pPage->end()) {
857 if (m_pPage == m_pPageLast) {
861 m_it = m_pPage->
begin();
862 }
while (m_it == m_pPage->end());
879 return m_pPage ==
other.m_pPage && m_it ==
other.m_it;
885 return m_pPage !=
other.m_pPage || m_it !=
other.m_it;
896 template <
typename T,
typename Allocator,
bool IsFwd>
912 using page_type = detail::mem_page<T, Allocator>;
914 const page_type* m_pPage;
915 const page_type* m_pPageLast;
929 if constexpr (!
IsFwd) {
930 m_it = m_pPage->rbegin();
931 while (m_it == m_pPage->rend()) {
932 if (m_pPage == m_pPageLast) {
937 m_it = m_pPage->rbegin();
940 m_it = m_pPage->begin();
941 while (m_it == m_pPage->end()) {
943 if (m_pPage == m_pPageLast) {
947 m_it = m_pPage->begin();
955 return m_it.operator*();
960 return m_it.operator->();
966 if constexpr (!
IsFwd) {
968 if (m_it == m_pPage->rend()) {
970 if (m_pPage == m_pPageLast) {
976 }
while (m_it == m_pPage->rend());
980 if (m_it == m_pPage->end()) {
983 if (m_pPage == m_pPageLast) {
987 m_it = m_pPage->
begin();
988 }
while (m_it == m_pPage->end());
1005 return m_pPage ==
other.m_pPage && m_it ==
other.m_it;
1011 return m_pPage !=
other.m_pPage || m_it !=
other.m_it;
1017 template <
typename T>
1080 constexpr static uint32_t ToPageIndex = core::count_bits(PageMask);
1090 m_pages.
resize(
pid + 1, ResizePolicy::Scale);
1102 m_pages =
other.m_pages;
1103 m_itemCnt =
other.m_itemCnt;
1110 GAIA_ASSERT(core::addressof(
other) !=
this);
1112 m_pages =
other.m_pages;
1113 m_itemCnt =
other.m_itemCnt;
1120 m_pages = GAIA_MOV(
other.m_pages);
1121 m_itemCnt =
other.m_itemCnt;
1130 GAIA_ASSERT(core::addressof(
other) !=
this);
1132 m_pages = GAIA_MOV(
other.m_pages);
1133 m_itemCnt =
other.m_itemCnt;
1142 GAIA_CLANG_WARNING_PUSH()
1144 GAIA_CLANG_WARNING_DISABLE("-
Wcast-align")
1150 GAIA_ASSERT(
has(
id));
1161 GAIA_ASSERT(
has(
id));
1168 GAIA_CLANG_WARNING_POP()
1179 const auto val = page_data_type::bit_set::BitCount;
1180 return did < val && m_pages[
pid].has_data(
did);
1186 GAIA_NODISCARD
bool has(
const T&
arg)
const noexcept {
1188 GAIA_ASSERT(
id != detail::InvalidPageStorageId);
1196 template <
typename TType>
1200 if constexpr (mem::is_soa_layout_v<T>)
1216 if constexpr (mem::is_soa_layout_v<T>)
1226 GAIA_ASSERT(
has(
id));
1238 GAIA_ASSERT(!
empty());
1239 GAIA_ASSERT(
id != detail::InvalidPageStorageId);
1274 return m_itemCnt == 0;
1280 GAIA_ASSERT(!
empty());
1287 GAIA_ASSERT(!
empty());
1294 GAIA_ASSERT(!
empty());
1301 GAIA_ASSERT(!
empty());
1308 GAIA_ASSERT(!
empty());
1315 GAIA_ASSERT(!
empty());
1322 GAIA_ASSERT(!
empty());
1329 GAIA_ASSERT(!
empty());
1336 GAIA_ASSERT(!
empty());
1343 GAIA_ASSERT(!
empty());
1350 GAIA_ASSERT(!
empty());
1357 GAIA_ASSERT(!
empty());
1364 GAIA_ASSERT(!
empty());
1371 GAIA_ASSERT(!
empty());
1378 GAIA_ASSERT(!
empty());
1385 GAIA_ASSERT(!
empty());
1393 return m_pages ==
other.m_pages;
Array of elements of type.
Definition darray_ext_impl.h:31
GAIA_NODISCARD size_type size() const noexcept
Returns the number of elements.
Definition darray_ext_impl.h:561
GAIA_NODISCARD auto rbegin() noexcept
Returns a reverse traversal iterator to the last element.
Definition darray_ext_impl.h:631
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first element.
Definition darray_ext_impl.h:613
void resize(size_type count, ResizePolicy policy=ResizePolicy::Exact)
Changes the number of elements.
Definition darray_ext_impl.h:289
GAIA_NODISCARD pointer data() noexcept
Returns a pointer to the element storage.
Definition darray_ext_impl.h:236
Heap-allocated paged storage for elements of type T.
Definition paged_storage.h:1018
GAIA_NODISCARD bool operator==(const page_storage &other) const noexcept
Checks whether two storages contain equal elements.
Definition paged_storage.h:1392
detail::mem_page< T, Allocator > page_type
Page type used by the storage.
Definition paged_storage.h:1045
GAIA_NODISCARD auto end() noexcept
Returns an iterator past the last stored element.
Definition paged_storage.h:1328
GAIA_NODISCARD auto rbegin() const noexcept
Returns a reverse iterator to the last stored element.
Definition paged_storage.h:1356
GAIA_NODISCARD decltype(auto) front() const noexcept
Accesses the first stored element.
Definition paged_storage.h:1286
GAIA_NODISCARD auto crend() const noexcept
Returns a read-only reverse iterator before the first stored element.
Definition paged_storage.h:1384
GAIA_NODISCARD auto cbegin() const noexcept
Returns a read-only iterator to the first stored element.
Definition paged_storage.h:1321
decltype(auto) add(TType &&arg)
Inserts the item arg into the storage.
Definition paged_storage.h:1197
GAIA_NODISCARD decltype(auto) back() const noexcept
Accesses the last stored element.
Definition paged_storage.h:1300
void clear()
Clears the storage.
Definition paged_storage.h:1260
void del(const T &arg) noexcept
Removes the item arg from the storage.
Definition paged_storage.h:1254
static constexpr uint32_t AllocatorBlockSize
Size in bytes of one allocator block.
Definition paged_storage.h:1038
GAIA_NODISCARD auto rend() noexcept
Returns a reverse iterator before the first stored element.
Definition paged_storage.h:1370
decltype(auto) set(page_storage_id id)
Accesses the record at the index id for update.
Definition paged_storage.h:1225
page_storage & operator=(page_storage &&other) noexcept
Move-assigns a storage.
Definition paged_storage.h:1129
page_iterator_soa< T, Allocator, false > iterator_soa_reverse
Reverse mutable iterator for SoA elements.
Definition paged_storage.h:1056
GAIA_NODISCARD size_type size() const noexcept
Returns the number of items inserted into the storage.
Definition paged_storage.h:1267
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first stored element.
Definition paged_storage.h:1307
detail::difference_type difference_type
Type used for iterator distances.
Definition paged_storage.h:1033
static constexpr uint32_t PageCapacity
Maximum number of elements addressable in one page.
Definition paged_storage.h:1047
GAIA_NODISCARD auto rend() const noexcept
Returns a reverse iterator before the first stored element.
Definition paged_storage.h:1377
GAIA_NODISCARD auto rbegin() noexcept
Returns a reverse iterator to the last stored element.
Definition paged_storage.h:1349
detail::mem_page_data< T > page_data_type
Raw page-data type.
Definition paged_storage.h:1043
GAIA_NODISCARD bool empty() const noexcept
Checks if the storage is empty (no items inserted).
Definition paged_storage.h:1273
const_page_iterator_soa< T, Allocator, false > const_iterator_soa_reverse
Reverse read-only iterator for SoA elements.
Definition paged_storage.h:1064
std::conditional_t< mem::is_soa_layout_v< T >, const_iterator_soa, const_iterator_aos > const_iterator
Forward read-only iterator matching the element data layout.
Definition paged_storage.h:1071
std::conditional_t< mem::is_soa_layout_v< T >, iterator_soa_reverse, iterator_aos_reverse > iterator_reverse
Reverse mutable iterator matching the element data layout.
Definition paged_storage.h:1069
std::conditional_t< mem::is_soa_layout_v< T >, iterator_soa, iterator_aos > iterator
Forward mutable iterator matching the element data layout.
Definition paged_storage.h:1066
GAIA_NODISCARD bool has(const T &arg) const noexcept
Checks if an item arg exists within the storage.
Definition paged_storage.h:1186
GAIA_NODISCARD auto begin() const noexcept
Returns an iterator to the first stored element.
Definition paged_storage.h:1314
GAIA_NODISCARD decltype(auto) front() noexcept
Accesses the first stored element.
Definition paged_storage.h:1279
void del(page_storage_id id) noexcept
Removes the item at the index id from the storage.
Definition paged_storage.h:1237
std::conditional_t< mem::is_soa_layout_v< T >, const_iterator_soa_reverse, const_iterator_aos_reverse > const_iterator_reverse
Reverse read-only iterator matching the element data layout.
Definition paged_storage.h:1074
GAIA_NODISCARD auto cend() const noexcept
Returns a read-only iterator past the last stored element.
Definition paged_storage.h:1342
GAIA_NODISCARD auto end() const noexcept
Returns an iterator past the last stored element.
Definition paged_storage.h:1335
GAIA_NODISCARD bool operator!=(const page_storage &other) const noexcept
Checks whether two storages differ.
Definition paged_storage.h:1399
detail::size_type size_type
Type used for sizes and indices.
Definition paged_storage.h:1035
GAIA_NODISCARD auto crbegin() const noexcept
Returns a read-only reverse iterator to the last stored element.
Definition paged_storage.h:1363
page_iterator_soa< T, Allocator, true > iterator_soa
Forward mutable iterator for SoA elements.
Definition paged_storage.h:1054
GAIA_NODISCARD decltype(auto) back() noexcept
Accesses the last stored element.
Definition paged_storage.h:1293
page_storage & operator=(const page_storage &other)
Copy-assigns a storage.
Definition paged_storage.h:1109
const_page_iterator_soa< T, Allocator, true > const_iterator_soa
Forward read-only iterator for SoA elements.
Definition paged_storage.h:1062
page_storage(page_storage &&other) noexcept
Move-constructs a storage.
Definition paged_storage.h:1119
GAIA_NODISCARD bool has(page_storage_id id) const noexcept
Checks if an item with a given page id exists.
Definition paged_storage.h:1173
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 SoA elements in paged storage. SoA pages keep each member in a separate array...
Definition paged_storage.h:897
const_page_iterator_soa(const page_type *pPage)
Constructs an end iterator at a page boundary.
Definition paged_storage.h:921
iterator operator++(int)
Advances to the next element.
Definition paged_storage.h:995
detail::difference_type difference_type
Type used for iterator distances.
Definition paged_storage.h:903
detail::size_type size_type
Type used for sizes and indices.
Definition paged_storage.h:905
iterator & operator++()
Advances to the next element.
Definition paged_storage.h:965
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators have the same position.
Definition paged_storage.h:1004
value_type operator*() const
Accesses the current element view.
Definition paged_storage.h:954
value_type operator->() const
Accesses the current element view through arrow syntax.
Definition paged_storage.h:959
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:926
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators have different positions.
Definition paged_storage.h:1010
Read-only iterator over elements in paged storage.
Definition paged_storage.h:645
iterator operator++(int)
Advances to the next element.
Definition paged_storage.h:744
reference operator*() const
Accesses the current element.
Definition paged_storage.h:703
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators have the same position.
Definition paged_storage.h:753
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators have different positions.
Definition paged_storage.h:759
detail::difference_type difference_type
Type used for iterator distances.
Definition paged_storage.h:653
const_page_iterator(const page_type *pPage)
Constructs an end iterator at a page boundary.
Definition paged_storage.h:671
detail::size_type size_type
Type used for sizes and indices.
Definition paged_storage.h:655
const_page_iterator(const page_type *pPage, const page_type *pPageLast)
Constructs a read-only iterator over a page range.
Definition paged_storage.h:676
pointer operator->() const
Accesses the current element through a pointer.
Definition paged_storage.h:708
iterator & operator++()
Advances to the next element.
Definition paged_storage.h:714
Iterator over SoA elements in paged storage. SoA pages keep each member in a separate array,...
Definition paged_storage.h:772
iterator & operator++()
Advances to the next element.
Definition paged_storage.h:839
detail::size_type size_type
Type used for sizes and indices.
Definition paged_storage.h:780
detail::difference_type difference_type
Type used for iterator distances.
Definition paged_storage.h:778
iterator operator++(int)
Advances to the next element.
Definition paged_storage.h:869
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators have different positions.
Definition paged_storage.h:884
value_type operator*() const
Accesses the current element view.
Definition paged_storage.h:828
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators have the same position.
Definition paged_storage.h:878
value_type operator->() const
Accesses the current element view through arrow syntax.
Definition paged_storage.h:833
page_iterator_soa(page_type *pPage)
Constructs an end iterator at a page boundary.
Definition paged_storage.h:796
page_iterator_soa(page_type *pPage, page_type *pPageLast)
Constructs an iterator over a page range.
Definition paged_storage.h:801
Iterator over elements in paged storage.
Definition paged_storage.h:521
detail::size_type size_type
Type used for sizes and indices.
Definition paged_storage.h:531
detail::difference_type difference_type
Type used for iterator distances.
Definition paged_storage.h:529
iterator & operator++()
Advances to the next element.
Definition paged_storage.h:590
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators have the same position.
Definition paged_storage.h:629
iterator operator++(int)
Advances to the next element.
Definition paged_storage.h:620
page_iterator(page_type *pPage)
Constructs an end iterator at a page boundary.
Definition paged_storage.h:547
pointer operator->() const
Accesses the current element through a pointer.
Definition paged_storage.h:584
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators have different positions.
Definition paged_storage.h:635
reference operator*() const
Accesses the current element.
Definition paged_storage.h:579
page_iterator(page_type *pPage, page_type *pPageLast)
Constructs an iterator over a page range.
Definition paged_storage.h:552
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:121