2#include "gaia/config/config.h"
5#include <initializer_list>
9#include "gaia/cnt/darray.h"
10#include "gaia/core/iterator.h"
11#include "gaia/core/utility.h"
12#include "gaia/mem/data_layout_policy.h"
13#include "gaia/mem/mem_utils.h"
18 using sparse_id = uint64_t;
22 using difference_type = uint32_t;
23 using size_type = uint32_t;
25 constexpr static sparse_id InvalidSparseId = (sparse_id)-1;
26 constexpr static size_type InvalidDenseId = BadIndex - 1;
27 inline constexpr sparse_id EmptyDenseId = InvalidSparseId;
34 template <
typename Dense>
35 GAIA_NODISCARD
auto sparse_dense_data(Dense& dense)
noexcept {
36 auto* pData = dense.
data();
37 return pData !=
nullptr ? pData : &EmptyDenseId;
41 template <
typename T, u
int32_t PageCapacity,
typename Allocator,
typename>
57 "Sparse_storage items require a conversion function to be defined in gaia::cnt namespace");
58 return detail::InvalidSparseId;
62 template <
typename T, u
int32_t PageCapacity,
typename Allocator,
typename =
void>
77 static_assert((PageCapacity & (PageCapacity - 1)) == 0,
"PageCapacity of sparse_iterator must be a power of 2");
78 constexpr static sparse_id page_mask = PageCapacity - 1;
79 constexpr static sparse_id to_page_index = core::count_bits(page_mask);
81 using page_type = detail::sparse_page<T, PageCapacity, Allocator, void>;
83 const sparse_id* m_pDense;
95 const auto sid = *m_pDense;
104 const auto sid = *m_pDense;
114 return {m_pDense + offset, m_pPages};
162 return {m_pDense + offset, m_pPages};
168 return {m_pDense - offset, m_pPages};
181 return m_pDense == other.m_pDense;
187 return m_pDense != other.m_pDense;
193 return m_pDense > other.m_pDense;
199 return m_pDense >= other.m_pDense;
205 return m_pDense < other.m_pDense;
211 return m_pDense <= other.m_pDense;
215 template <
typename T, u
int32_t PageCapacity,
typename Allocator,
typename =
void>
230 static_assert((PageCapacity & (PageCapacity - 1)) == 0,
"PageCapacity of sparse_iterator must be a power of 2");
231 constexpr static sparse_id page_mask = PageCapacity - 1;
232 constexpr static sparse_id to_page_index = core::count_bits(page_mask);
234 using page_type = detail::sparse_page<T, PageCapacity, Allocator, void>;
236 const sparse_id* m_pDense;
237 const page_type* m_pPages;
248 const auto sid = *m_pDense;
257 const auto sid = *m_pDense;
267 return {m_pDense + offset, m_pPages};
315 return {m_pDense + offset, m_pPages};
321 return {m_pDense - offset, m_pPages};
334 return m_pDense == other.m_pDense;
340 return m_pDense != other.m_pDense;
346 return m_pDense > other.m_pDense;
352 return m_pDense >= other.m_pDense;
358 return m_pDense < other.m_pDense;
364 return m_pDense <= other.m_pDense;
368 template <
typename T, u
int32_t PageCapacity,
typename Allocator>
383 static_assert((PageCapacity & (PageCapacity - 1)) == 0,
"PageCapacity of sparse_iterator must be a power of 2");
384 constexpr static sparse_id page_mask = PageCapacity - 1;
385 constexpr static sparse_id to_page_index = core::count_bits(page_mask);
387 using page_type = detail::sparse_page<T, PageCapacity, Allocator, std::enable_if_t<std::is_empty_v<T>>>;
399 const auto sid = *m_pDense;
405 const auto sid = *m_pDense;
412 return {m_pDense + offset};
460 return {m_pDense + offset};
466 return {m_pDense - offset};
479 return m_pDense == other.m_pDense;
485 return m_pDense != other.m_pDense;
491 return m_pDense > other.m_pDense;
497 return m_pDense >= other.m_pDense;
503 return m_pDense < other.m_pDense;
509 return m_pDense <= other.m_pDense;
513 template <
typename T, u
int32_t PageCapacity,
typename Allocator>
528 static_assert((PageCapacity & (PageCapacity - 1)) == 0,
"PageCapacity of sparse_iterator must be a power of 2");
529 constexpr static sparse_id page_mask = PageCapacity - 1;
530 constexpr static sparse_id to_page_index = core::count_bits(page_mask);
532 using page_type = detail::sparse_page<T, PageCapacity, Allocator, std::enable_if_t<std::is_empty_v<T>>>;
544 const auto sid = *m_pDense;
550 const auto sid = *m_pDense;
557 return {m_pDense + offset};
605 return {m_pDense + offset};
611 return {m_pDense - offset};
624 return m_pDense == other.m_pDense;
630 return m_pDense != other.m_pDense;
636 return m_pDense > other.m_pDense;
642 return m_pDense >= other.m_pDense;
648 return m_pDense < other.m_pDense;
654 return m_pDense <= other.m_pDense;
660 template <
typename T, u
int32_t PageCapacity,
typename Allocator,
typename =
void>
663 using value_type = T;
664 using reference = T&;
665 using const_reference =
const T&;
667 using const_pointer =
const T*;
669 using difference_type = detail::difference_type;
670 using size_type = detail::size_type;
672 using iterator = sparse_iterator<T, PageCapacity, Allocator>;
673 using const_iterator = const_sparse_iterator<T, PageCapacity, Allocator>;
676 size_type* m_pSparse =
nullptr;
677 uint8_t* m_pData =
nullptr;
681 if (m_pSparse !=
nullptr)
686 m_pSparse = mem::AllocHelper::alloc<size_type>(
"SparsePage", PageCapacity);
687 GAIA_FOR(PageCapacity) m_pSparse[i] = detail::InvalidDenseId;
690 m_pData = view_policy::template alloc<Allocator>(PageCapacity);
693 void dtr_data_inter(uint32_t idx)
noexcept {
694 GAIA_ASSERT(!empty());
696 auto* ptr = &data()[idx];
697 core::call_dtor(ptr);
700 void dtr_active_data() noexcept {
701 GAIA_ASSERT(m_pSparse !=
nullptr);
703 for (uint32_t i = 0; m_cnt != 0 && i != PageCapacity; ++i) {
704 if (m_pSparse[i] == detail::InvalidDenseId)
707 auto* ptr = &data()[i];
708 core::call_dtor(ptr);
713 if (m_pSparse ==
nullptr)
721 mem::AllocHelper::free(
"SparsePage", m_pSparse);
722 view_policy::template free<Allocator>(m_pData, m_cnt);
730 sparse_page() =
default;
732 sparse_page(
const sparse_page& other) {
734 if (other.m_pSparse ==
nullptr) {
739 for (uint32_t i = 0; i < PageCapacity; ++i) {
741 m_pSparse[i] = other.m_pSparse[i];
742 if (other.m_pSparse[i] == detail::InvalidDenseId)
746 add_data(i, other.set_data(i));
753 sparse_page& operator=(
const sparse_page& other) {
754 GAIA_ASSERT(core::addressof(other) !=
this);
756 if (other.m_pSparse ==
nullptr) {
763 if (m_pSparse !=
nullptr)
767 for (uint32_t i = 0; i < PageCapacity; ++i) {
769 m_pSparse[i] = other.m_pSparse[i];
770 if (other.m_pSparse[i] == detail::InvalidDenseId)
774 add_data(i, other.get_data(i));
783 sparse_page(sparse_page&& other)
noexcept {
784 m_pSparse = other.m_pSparse;
785 m_pData = other.m_pData;
788 other.m_pSparse =
nullptr;
789 other.m_pData =
nullptr;
790 other.m_cnt = size_type(0);
793 sparse_page& operator=(sparse_page&& other)
noexcept {
794 GAIA_ASSERT(core::addressof(other) !=
this);
798 m_pSparse = other.m_pSparse;
799 m_pData = other.m_pData;
802 other.m_pSparse =
nullptr;
803 other.m_pData =
nullptr;
804 other.m_cnt = size_type(0);
813 GAIA_CLANG_WARNING_PUSH()
815 GAIA_CLANG_WARNING_DISABLE("-Wcast-align")
817 GAIA_NODISCARD pointer data() noexcept {
818 return reinterpret_cast<pointer
>(m_pData);
821 GAIA_NODISCARD const_pointer data() const noexcept {
822 return reinterpret_cast<const_pointer
>(m_pData);
825 GAIA_NODISCARD
auto& set_id(size_type pos)
noexcept {
826 return m_pSparse[pos];
829 GAIA_NODISCARD
auto get_id(size_type pos)
const noexcept {
830 return m_pSparse[pos];
833 GAIA_NODISCARD
decltype(
auto) set_data(size_type pos)
noexcept {
834 return view_policy::set({(
typename view_policy::TargetCastType)m_pData, PageCapacity}, pos);
837 GAIA_NODISCARD
decltype(
auto) get_data(size_type pos)
const noexcept {
838 return view_policy::get({(
typename view_policy::TargetCastType)m_pData, PageCapacity}, pos);
841 GAIA_CLANG_WARNING_POP()
843 GAIA_NODISCARD
bool allocated() const noexcept {
844 return m_pSparse !=
nullptr;
852 decltype(
auto) add_data(uint32_t idx,
const T& arg) {
853 auto* ptr = &set_data(idx);
854 core::call_ctor(ptr, arg);
855 return (reference)(*ptr);
858 decltype(
auto) add_data(uint32_t idx, T&& arg) {
859 auto* ptr = &set_data(idx);
860 core::call_ctor(ptr, GAIA_MOV(arg));
861 return (reference)(*ptr);
864 void del_data(uint32_t idx)
noexcept {
867 GAIA_ASSERT(m_cnt > 0);
875 GAIA_NODISCARD size_type size() const noexcept {
879 GAIA_NODISCARD
bool empty() const noexcept {
883 GAIA_NODISCARD
decltype(
auto) front() noexcept {
884 GAIA_ASSERT(!empty());
885 return (reference)*begin();
888 GAIA_NODISCARD
decltype(
auto) front() const noexcept {
889 GAIA_ASSERT(!empty());
890 return (const_reference)*begin();
893 GAIA_NODISCARD
decltype(
auto) back() noexcept {
894 GAIA_ASSERT(!empty());
895 return (reference)(set_data(m_cnt - 1));
898 GAIA_NODISCARD
decltype(
auto) back() const noexcept {
899 GAIA_ASSERT(!empty());
900 return (const_reference)set_data(m_cnt - 1);
903 GAIA_NODISCARD
auto begin() noexcept {
904 return iterator(data());
907 GAIA_NODISCARD
auto begin() const noexcept {
908 return const_iterator(data());
911 GAIA_NODISCARD
auto cbegin() const noexcept {
912 return const_iterator(data());
915 GAIA_NODISCARD
auto rbegin() noexcept {
916 return iterator((pointer)&back());
919 GAIA_NODISCARD
auto rbegin() const noexcept {
920 return const_iterator((pointer)&back());
923 GAIA_NODISCARD
auto crbegin() const noexcept {
924 return const_iterator((pointer)&back());
927 GAIA_NODISCARD
auto end() noexcept {
928 return iterator(data() + size());
931 GAIA_NODISCARD
auto end() const noexcept {
932 return const_iterator(data() + size());
935 GAIA_NODISCARD
auto cend() const noexcept {
936 return const_iterator(data() + size());
939 GAIA_NODISCARD
auto rend() noexcept {
940 return iterator(data() - 1);
943 GAIA_NODISCARD
auto rend() const noexcept {
944 return const_iterator(data() - 1);
947 GAIA_NODISCARD
auto crend() const noexcept {
948 return const_iterator(data() - 1);
951 GAIA_NODISCARD
bool operator==(
const sparse_page& other)
const {
952 if (m_cnt != other.m_cnt)
954 const size_type n = size();
955 for (size_type i = 0; i < n; ++i)
956 if (!(get_data(i) == other[i]))
961 GAIA_NODISCARD
constexpr bool operator!=(
const sparse_page& other)
const {
962 return !operator==(other);
967 template <
typename T, u
int32_t PageCapacity,
typename Allocator>
968 class sparse_page<T, PageCapacity, Allocator, std::enable_if_t<std::is_empty_v<T>>> {
970 using value_type = T;
974 using const_pointer =
const T*;
975 using view_policy = mem::data_view_policy_aos<T>;
976 using difference_type = detail::difference_type;
977 using size_type = detail::size_type;
979 using iterator = sparse_iterator<T, PageCapacity, Allocator, std::enable_if_t<std::is_empty_v<T>>>;
980 using const_iterator = const_sparse_iterator<T, PageCapacity, Allocator, std::enable_if_t<std::is_empty_v<T>>>;
983 size_type* m_pSparse =
nullptr;
987 if (m_pSparse ==
nullptr) {
990 m_pSparse = mem::AllocHelper::alloc<size_type>(
"SparsePage", PageCapacity);
991 GAIA_FOR(PageCapacity) m_pSparse[i] = detail::InvalidDenseId;
995 void dtr_data_inter([[maybe_unused]] uint32_t idx)
noexcept {
996 GAIA_ASSERT(!empty());
999 void dtr_active_data() noexcept {
1000 GAIA_ASSERT(m_pSparse !=
nullptr);
1004 if (m_pSparse ==
nullptr)
1008 mem::AllocHelper::free(
"SparsePage", m_pSparse);
1010 m_pSparse =
nullptr;
1015 sparse_page() =
default;
1017 sparse_page(
const sparse_page& other) {
1019 if (other.m_pSparse ==
nullptr) {
1022 for (uint32_t i = 0; i < PageCapacity; ++i) {
1024 m_pSparse[i] = other.m_pSparse[i];
1025 if (m_pSparse[i] == detail::InvalidDenseId)
1029 m_cnt = other.m_cnt;
1033 sparse_page& operator=(
const sparse_page& other) {
1034 GAIA_ASSERT(core::addressof(other) !=
this);
1036 if (m_pSparse ==
nullptr && other.m_pSparse !=
nullptr)
1040 if (other.m_pSparse ==
nullptr) {
1044 if (m_pSparse !=
nullptr)
1048 for (uint32_t i = 0; i < PageCapacity; ++i)
1049 m_pSparse[i] = other.m_pSparse[i];
1051 m_cnt = other.m_cnt;
1057 sparse_page(sparse_page&& other)
noexcept {
1060 GAIA_ASSERT(m_pSparse ==
nullptr);
1062 m_pSparse = other.m_pSparse;
1063 m_cnt = other.m_cnt;
1065 other.m_pSparse =
nullptr;
1066 other.m_cnt = size_type(0);
1069 sparse_page& operator=(sparse_page&& other)
noexcept {
1070 GAIA_ASSERT(core::addressof(other) !=
this);
1074 m_pSparse = other.m_pSparse;
1075 m_cnt = other.m_cnt;
1077 other.m_pSparse =
nullptr;
1078 other.m_cnt = size_type(0);
1087 GAIA_CLANG_WARNING_PUSH()
1089 GAIA_CLANG_WARNING_DISABLE("-Wcast-align")
1091 GAIA_NODISCARD pointer data() noexcept {
1092 return reinterpret_cast<pointer
>(m_pSparse);
1095 GAIA_NODISCARD const_pointer data() const noexcept {
1096 return reinterpret_cast<const_pointer
>(m_pSparse);
1099 GAIA_CLANG_WARNING_POP()
1101 GAIA_NODISCARD
bool allocated() const noexcept {
1102 return m_pSparse !=
nullptr;
1110 GAIA_NODISCARD
auto& set_id(size_type pos)
noexcept {
1111 return m_pSparse[pos];
1114 GAIA_NODISCARD
auto get_id(size_type pos)
const noexcept {
1115 return m_pSparse[pos];
1118 void del_id(uint32_t idx)
noexcept {
1119 dtr_data_inter(idx);
1121 GAIA_ASSERT(m_cnt > 0);
1129 GAIA_NODISCARD size_type size() const noexcept {
1133 GAIA_NODISCARD
bool empty() const noexcept {
1137 GAIA_NODISCARD
auto front() const noexcept {
1138 GAIA_ASSERT(!empty());
1142 GAIA_NODISCARD
auto back() const noexcept {
1143 GAIA_ASSERT(!empty());
1144 return get_id(m_cnt - 1);
1147 GAIA_NODISCARD
auto begin() noexcept {
1148 return iterator(data());
1151 GAIA_NODISCARD
auto begin() const noexcept {
1152 return const_iterator(data());
1155 GAIA_NODISCARD
auto cbegin() const noexcept {
1156 return const_iterator(data());
1159 GAIA_NODISCARD
auto rbegin() noexcept {
1160 return iterator((pointer)&back());
1163 GAIA_NODISCARD
auto rbegin() const noexcept {
1164 return const_iterator((pointer)&back());
1167 GAIA_NODISCARD
auto crbegin() const noexcept {
1168 return const_iterator((pointer)&back());
1171 GAIA_NODISCARD
auto end() noexcept {
1172 return iterator(data() + size());
1175 GAIA_NODISCARD
auto end() const noexcept {
1176 return const_iterator(data() + size());
1179 GAIA_NODISCARD
auto cend() const noexcept {
1180 return const_iterator(data() + size());
1183 GAIA_NODISCARD
auto rend() noexcept {
1184 return iterator(data() - 1);
1187 GAIA_NODISCARD
auto rend() const noexcept {
1188 return const_iterator(data() - 1);
1191 GAIA_NODISCARD
auto crend() const noexcept {
1192 return const_iterator(data() - 1);
1195 GAIA_NODISCARD
bool operator==(
const sparse_page& other)
const {
1196 if (m_cnt != other.m_cnt)
1198 const size_type n = size();
1199 for (size_type i = 0; i < n; ++i)
1200 if (!(get_id(i) == other.get_id(i)))
1205 GAIA_NODISCARD
constexpr bool operator!=(
const sparse_page& other)
const {
1206 return !operator==(other);
1219 typename T, uint32_t PageCapacity = 4096,
typename Allocator = mem::DefaultAllocatorAdaptor,
typename =
void>
1233 using page_type = detail::sparse_page<T, PageCapacity, Allocator>;
1236 static_assert((PageCapacity & (PageCapacity - 1)) == 0,
"PageCapacity of sparse_storage must be a power of 2");
1237 constexpr static sparse_id page_mask = PageCapacity - 1;
1238 constexpr static sparse_id to_page_index = core::count_bits(page_mask);
1265 constexpr sparse_storage() noexcept = default;
1270 GAIA_ASSERT(core::addressof(other) !=
this);
1272 m_dense = other.m_dense;
1273 m_pages = other.m_pages;
1274 m_cnt = other.m_cnt;
1281 GAIA_ASSERT(core::addressof(other) !=
this);
1283 m_dense = other.m_dense;
1284 m_pages = other.m_pages;
1285 m_cnt = other.m_cnt;
1295 GAIA_ASSERT(m_dense.
data() ==
nullptr);
1297 m_dense = GAIA_MOV(other.m_dense);
1298 m_pages = GAIA_MOV(other.m_pages);
1299 m_cnt = other.m_cnt;
1310 GAIA_ASSERT(core::addressof(other) !=
this);
1312 m_dense = GAIA_MOV(other.m_dense);
1313 m_pages = GAIA_MOV(other.m_pages);
1314 m_cnt = other.m_cnt;
1325 GAIA_CLANG_WARNING_PUSH()
1327 GAIA_CLANG_WARNING_DISABLE("-
Wcast-align")
1344 GAIA_NODISCARD
decltype(
auto)
operator[](sparse_id
sid)
const noexcept {
1353 GAIA_CLANG_WARNING_POP()
1358 GAIA_NODISCARD
bool has(sparse_id
sid)
const {
1359 if (
sid == detail::InvalidSparseId)
1367 const auto&
page = m_pages[
pid];
1370 if (!
page.allocated())
1373 const auto id =
page.get_id(
did);
1374 return id != detail::InvalidDenseId;
1382 GAIA_ASSERT(
sid != detail::InvalidSparseId);
1389 template <
typename TType>
1404 m_dense[m_cnt] =
sid;
1427 GAIA_ASSERT(!
empty());
1428 GAIA_ASSERT(
sid != detail::InvalidSparseId);
1436 const auto sidPrev = std::as_const(m_dense)[m_cnt - 1];
1441 const auto id =
page.get_id(
did);
1445 page.set_id(
did) = detail::InvalidDenseId;
1448 m_dense.
resize(m_cnt - 1);
1450 GAIA_ASSERT(m_cnt > 0);
1483 GAIA_ASSERT(!
empty());
1490 GAIA_ASSERT(!
empty());
1497 GAIA_ASSERT(!
empty());
1499 const auto sid = m_dense[m_cnt - 1];
1509 GAIA_ASSERT(!
empty());
1511 const auto sid = m_dense[m_cnt - 1];
1521 return iterator(detail::sparse_dense_data(m_dense), m_pages.
data());
1539 return iterator(detail::sparse_dense_data(m_dense) +
size(), m_pages.
data());
1559 if (m_cnt != other.m_cnt)
1565 if (m_dense != other.m_dense)
1572 for (
size_type i = 0, cnt = 0;
i <
n && cnt < m_cnt; ++
i, ++cnt) {
1573 const auto sid = m_dense[
i];
1601 template <
typename T, u
int32_t PageCapacity,
typename Allocator>
1619 detail::sparse_page<T, PageCapacity, Allocator, std::enable_if_t<std::is_empty_v<T>>>;
1623 static_assert((PageCapacity & (PageCapacity - 1)) == 0,
"PageCapacity of sparse_storage must be a power of 2");
1624 constexpr static sparse_id page_mask = PageCapacity - 1;
1625 constexpr static sparse_id to_page_index = core::count_bits(page_mask);
1652 constexpr sparse_storage() noexcept = default;
1657 GAIA_ASSERT(core::addressof(other) !=
this);
1659 m_dense = other.m_dense;
1660 m_pages = other.m_pages;
1661 m_cnt = other.m_cnt;
1668 GAIA_ASSERT(core::addressof(other) !=
this);
1670 m_dense = other.m_dense;
1671 m_pages = other.m_pages;
1672 m_cnt = other.m_cnt;
1682 GAIA_ASSERT(m_dense.
data() ==
nullptr);
1684 m_dense = GAIA_MOV(other.m_dense);
1685 m_pages = GAIA_MOV(other.m_pages);
1686 m_cnt = other.m_cnt;
1697 GAIA_ASSERT(core::addressof(other) !=
this);
1699 m_dense = GAIA_MOV(other.m_dense);
1700 m_pages = GAIA_MOV(other.m_pages);
1701 m_cnt = other.m_cnt;
1715 GAIA_NODISCARD
bool has(sparse_id
sid)
const {
1716 GAIA_ASSERT(
sid != detail::InvalidSparseId);
1720 return has_internal(
pid,
did);
1728 const auto&
page = m_pages[
pid];
1729 if (!
page.allocated())
1732 const auto id =
page.get_id(
did);
1733 return id != detail::InvalidDenseId;
1740 GAIA_ASSERT(
sid != detail::InvalidSparseId);
1745 if (has_internal(
pid,
did))
1749 m_dense[m_cnt] =
sid;
1758 GAIA_ASSERT(!
empty());
1759 GAIA_ASSERT(
sid != detail::InvalidSparseId);
1764 if (!has_internal(
pid,
did))
1767 const auto sidPrev = std::as_const(m_dense)[m_cnt - 1];
1772 const auto id =
page.get_id(
did);
1776 page.set_id(
did) = detail::InvalidDenseId;
1778 m_dense.
resize(m_cnt - 1);
1780 GAIA_ASSERT(m_cnt > 0);
1806 GAIA_ASSERT(!
empty());
1813 GAIA_ASSERT(!
empty());
1820 GAIA_ASSERT(!
empty());
1822 const auto sid = m_dense[m_cnt - 1];
1832 GAIA_ASSERT(!
empty());
1834 const auto sid = m_dense[m_cnt - 1];
1844 return iterator(detail::sparse_dense_data(m_dense));
1862 return iterator(detail::sparse_dense_data(m_dense) +
size());
1882 if (m_cnt != other.m_cnt)
1888 if (m_dense != other.m_dense)
Array with variable size of elements of type.
Definition darray_impl.h:27
GAIA_NODISCARD size_type capacity() const noexcept
Returns the number of elements that fit without reallocation.
Definition darray_impl.h:516
void reserve(size_type cap)
Ensures storage for at least the requested number of elements.
Definition darray_impl.h:223
GAIA_NODISCARD size_type size() const noexcept
Returns the number of elements.
Definition darray_impl.h:504
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
GAIA_NODISCARD decltype(auto) back() const noexcept
Returns the last registered sparse identifier.
Definition sparse_storage.h:1831
sparse_storage(sparse_storage &&other) noexcept
Move-constructs the storage.
Definition sparse_storage.h:1679
GAIA_NODISCARD auto end() noexcept
Returns an iterator past the last sparse identifier.
Definition sparse_storage.h:1861
void del(sparse_id sid) noexcept
Removes a sparse id from storage.
Definition sparse_storage.h:1757
GAIA_NODISCARD bool has(sparse_id sid) const
Checks whether a sparse identifier is registered.
Definition sparse_storage.h:1715
detail::size_type size_type
Type used for sizes and offsets.
Definition sparse_storage.h:1611
sparse_storage & operator=(sparse_storage &&other) noexcept
Move-assigns the storage.
Definition sparse_storage.h:1696
GAIA_NODISCARD auto cbegin() const noexcept
Returns a constant iterator to the first sparse identifier.
Definition sparse_storage.h:1855
detail::difference_type difference_type
Type used for iterator distances.
Definition sparse_storage.h:1610
detail::sparse_page< T, PageCapacity, Allocator, std::enable_if_t< std::is_empty_v< T > > > page_type
Internal sparse-page type.
Definition sparse_storage.h:1620
GAIA_NODISCARD bool empty() const noexcept
Checks if the storage is empty (no items inserted).
Definition sparse_storage.h:1799
GAIA_NODISCARD auto end() const noexcept
Returns an iterator past the last sparse identifier.
Definition sparse_storage.h:1867
GAIA_NODISCARD decltype(auto) back() noexcept
Returns the last registered sparse identifier.
Definition sparse_storage.h:1819
void clear()
Clears the storage.
Definition sparse_storage.h:1785
GAIA_NODISCARD decltype(auto) front() const noexcept
Returns the first registered sparse identifier.
Definition sparse_storage.h:1812
sparse_storage & operator=(const sparse_storage &other)
Copy-assigns the storage.
Definition sparse_storage.h:1667
GAIA_NODISCARD decltype(auto) front() noexcept
Returns the first registered sparse identifier.
Definition sparse_storage.h:1805
GAIA_NODISCARD constexpr bool operator!=(const sparse_storage &other) const
Checks whether two storages differ.
Definition sparse_storage.h:1897
void add(sparse_id sid)
Registers a new sparse id.
Definition sparse_storage.h:1739
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first sparse identifier.
Definition sparse_storage.h:1843
GAIA_NODISCARD auto cend() const noexcept
Returns a constant iterator past the last sparse identifier.
Definition sparse_storage.h:1873
GAIA_NODISCARD size_type size() const noexcept
Returns the number of identifiers registered in the storage.
Definition sparse_storage.h:1793
GAIA_NODISCARD auto begin() const noexcept
Returns an iterator to the first sparse identifier.
Definition sparse_storage.h:1849
GAIA_NODISCARD bool operator==(const sparse_storage &other) const
Checks whether two storages contain the same sparse identifiers.
Definition sparse_storage.h:1880
Array with variable size of elements of type T allocated on heap. Allocates enough memory to support ...
Definition sparse_storage.h:1220
sparse_storage & operator=(sparse_storage &&other) noexcept
Move-assigns the storage.
Definition sparse_storage.h:1309
detail::size_type size_type
Type used for sizes and offsets.
Definition sparse_storage.h:1229
GAIA_NODISCARD size_type size() const noexcept
Returns the number of items inserted into the storage.
Definition sparse_storage.h:1470
GAIA_NODISCARD auto cend() const noexcept
Returns a constant iterator past the last value.
Definition sparse_storage.h:1550
GAIA_NODISCARD decltype(auto) front() const noexcept
Returns the first stored value.
Definition sparse_storage.h:1489
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first value.
Definition sparse_storage.h:1520
decltype(auto) set(sparse_id sid)
Update the record at the index sid.
Definition sparse_storage.h:1414
detail::difference_type difference_type
Type used for iterator distances.
Definition sparse_storage.h:1228
detail::sparse_page< T, PageCapacity, Allocator > page_type
Internal sparse-page type.
Definition sparse_storage.h:1233
sparse_storage(sparse_storage &&other) noexcept
Move-constructs the storage.
Definition sparse_storage.h:1292
GAIA_NODISCARD bool empty() const noexcept
Checks if the storage is empty (no items inserted).
Definition sparse_storage.h:1476
GAIA_NODISCARD bool has(sparse_id sid) const
Checks whether an item with a sparse identifier exists.
Definition sparse_storage.h:1358
const_sparse_iterator< T, PageCapacity, Allocator > const_iterator
Constant iterator type.
Definition sparse_storage.h:1232
GAIA_NODISCARD bool has(const T &arg) const
Checks if an item arg exists within the storage.
Definition sparse_storage.h:1380
void del(sparse_id sid) noexcept
Removes the item at the index sid from the storage.
Definition sparse_storage.h:1426
GAIA_NODISCARD auto begin() const noexcept
Returns an iterator to the first value.
Definition sparse_storage.h:1526
void clear()
Clears the storage.
Definition sparse_storage.h:1462
GAIA_NODISCARD auto end() noexcept
Returns an iterator past the last value.
Definition sparse_storage.h:1538
GAIA_NODISCARD bool operator==(const sparse_storage &other) const
Checks whether two storages contain equal values at equal sparse identifiers.
Definition sparse_storage.h:1557
GAIA_NODISCARD constexpr bool operator!=(const sparse_storage &other) const
Checks whether two storages differ.
Definition sparse_storage.h:1589
GAIA_NODISCARD decltype(auto) back() const noexcept
Returns the last stored value.
Definition sparse_storage.h:1508
GAIA_NODISCARD decltype(auto) front() noexcept
Returns the first stored value.
Definition sparse_storage.h:1482
GAIA_NODISCARD auto cbegin() const noexcept
Returns a constant iterator to the first value.
Definition sparse_storage.h:1532
GAIA_NODISCARD decltype(auto) back() noexcept
Returns the last stored value.
Definition sparse_storage.h:1496
decltype(auto) add(TType &&arg)
Inserts the item arg into the storage.
Definition sparse_storage.h:1391
sparse_iterator< T, PageCapacity, Allocator > iterator
Mutable iterator type.
Definition sparse_storage.h:1231
sparse_storage & operator=(const sparse_storage &other)
Copy-assigns the storage.
Definition sparse_storage.h:1280
void del(const T &arg) noexcept
Removes the item arg from the storage.
Definition sparse_storage.h:1456
GAIA_NODISCARD auto end() const noexcept
Returns an iterator past the last value.
Definition sparse_storage.h:1544
value_type operator*() const
Returns the sparse identifier at the current position.
Definition sparse_storage.h:543
GAIA_NODISCARD bool operator<=(const iterator &other) const
Checks whether this iterator does not follow another iterator.
Definition sparse_storage.h:653
iterator operator++(int)
Advances to the next sparse identifier.
Definition sparse_storage.h:582
const_sparse_iterator(const value_type *pDense)
Constructs a constant iterator for a dense sparse-id position.
Definition sparse_storage.h:539
GAIA_NODISCARD bool operator>(const iterator &other) const
Checks whether this iterator follows another iterator.
Definition sparse_storage.h:635
detail::difference_type difference_type
Type used for iterator distances.
Definition sparse_storage.h:523
iterator & operator+=(size_type diff)
Advances the iterator.
Definition sparse_storage.h:563
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators refer to different positions.
Definition sparse_storage.h:629
difference_type operator-(const iterator &other) const
Returns the distance from another iterator.
Definition sparse_storage.h:616
iterator operator--(int)
Moves to the previous sparse identifier.
Definition sparse_storage.h:595
GAIA_NODISCARD bool operator<(const iterator &other) const
Checks whether this iterator precedes another iterator.
Definition sparse_storage.h:647
iterator & operator--()
Moves to the previous sparse identifier.
Definition sparse_storage.h:589
sparse_id value_type
Sparse identifier value type.
Definition sparse_storage.h:520
iterator operator[](size_type offset) const
Returns an iterator at an offset from the current position.
Definition sparse_storage.h:556
detail::size_type size_type
Type used for iterator offsets.
Definition sparse_storage.h:524
GAIA_NODISCARD bool operator>=(const iterator &other) const
Checks whether this iterator does not precede another iterator.
Definition sparse_storage.h:641
iterator operator-(size_type offset) const
Returns an iterator moved backward by an offset.
Definition sparse_storage.h:610
iterator & operator-=(size_type diff)
Moves the iterator backward.
Definition sparse_storage.h:570
iterator operator+(size_type offset) const
Returns an iterator advanced by an offset.
Definition sparse_storage.h:604
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators refer to the same position.
Definition sparse_storage.h:623
value_type operator->() const
Returns the sparse identifier at the current position.
Definition sparse_storage.h:549
iterator & operator++()
Advances to the next sparse identifier.
Definition sparse_storage.h:576
Constant random-access iterator over sparse-storage values.
Definition sparse_storage.h:220
iterator & operator-=(size_type diff)
Moves the iterator backward.
Definition sparse_storage.h:280
iterator operator--(int)
Moves to the previous value.
Definition sparse_storage.h:305
pointer operator->() const
Returns a pointer to the value at the current position.
Definition sparse_storage.h:256
GAIA_NODISCARD bool operator>=(const iterator &other) const
Checks whether this iterator does not precede another iterator.
Definition sparse_storage.h:351
const_sparse_iterator(const sparse_id *pDense, const page_type *pPages)
Constructs a constant iterator for a dense position and sparse-page array.
Definition sparse_storage.h:243
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators refer to the same position.
Definition sparse_storage.h:333
iterator operator-(size_type offset) const
Returns an iterator moved backward by an offset.
Definition sparse_storage.h:320
detail::difference_type difference_type
Type used for iterator distances.
Definition sparse_storage.h:225
iterator operator++(int)
Advances to the next value.
Definition sparse_storage.h:292
iterator operator[](size_type offset) const
Returns an iterator at an offset from the current position.
Definition sparse_storage.h:266
detail::size_type size_type
Type used for iterator offsets.
Definition sparse_storage.h:226
difference_type operator-(const iterator &other) const
Returns the distance from another iterator.
Definition sparse_storage.h:326
reference operator*() const
Returns the value at the current position.
Definition sparse_storage.h:247
iterator operator+(size_type offset) const
Returns an iterator advanced by an offset.
Definition sparse_storage.h:314
iterator & operator++()
Advances to the next value.
Definition sparse_storage.h:286
GAIA_NODISCARD bool operator<(const iterator &other) const
Checks whether this iterator precedes another iterator.
Definition sparse_storage.h:357
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators refer to different positions.
Definition sparse_storage.h:339
iterator & operator+=(size_type diff)
Advances the iterator.
Definition sparse_storage.h:273
iterator & operator--()
Moves to the previous value.
Definition sparse_storage.h:299
GAIA_NODISCARD bool operator>(const iterator &other) const
Checks whether this iterator follows another iterator.
Definition sparse_storage.h:345
GAIA_NODISCARD bool operator<=(const iterator &other) const
Checks whether this iterator does not follow another iterator.
Definition sparse_storage.h:363
Mutable random-access iterator over sparse identifiers for empty stored types.
Definition sparse_storage.h:373
value_type operator*() const
Returns the sparse identifier at the current position.
Definition sparse_storage.h:398
iterator & operator++()
Advances to the next sparse identifier.
Definition sparse_storage.h:431
iterator operator[](size_type offset) const
Returns an iterator at an offset from the current position.
Definition sparse_storage.h:411
iterator operator--(int)
Moves to the previous sparse identifier.
Definition sparse_storage.h:450
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators refer to different positions.
Definition sparse_storage.h:484
GAIA_NODISCARD bool operator>(const iterator &other) const
Checks whether this iterator follows another iterator.
Definition sparse_storage.h:490
detail::size_type size_type
Type used for iterator offsets.
Definition sparse_storage.h:379
iterator operator+(size_type offset) const
Returns an iterator advanced by an offset.
Definition sparse_storage.h:459
value_type operator->() const
Returns the sparse identifier at the current position.
Definition sparse_storage.h:404
iterator & operator--()
Moves to the previous sparse identifier.
Definition sparse_storage.h:444
GAIA_NODISCARD bool operator<=(const iterator &other) const
Checks whether this iterator does not follow another iterator.
Definition sparse_storage.h:508
iterator & operator+=(size_type diff)
Advances the iterator.
Definition sparse_storage.h:418
GAIA_NODISCARD bool operator<(const iterator &other) const
Checks whether this iterator precedes another iterator.
Definition sparse_storage.h:502
GAIA_NODISCARD bool operator>=(const iterator &other) const
Checks whether this iterator does not precede another iterator.
Definition sparse_storage.h:496
iterator & operator-=(size_type diff)
Moves the iterator backward.
Definition sparse_storage.h:425
difference_type operator-(const iterator &other) const
Returns the distance from another iterator.
Definition sparse_storage.h:471
sparse_iterator(const value_type *pDense)
Constructs an iterator for a dense sparse-id position.
Definition sparse_storage.h:394
iterator operator++(int)
Advances to the next sparse identifier.
Definition sparse_storage.h:437
sparse_id value_type
Sparse identifier value type.
Definition sparse_storage.h:375
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators refer to the same position.
Definition sparse_storage.h:478
iterator operator-(size_type offset) const
Returns an iterator moved backward by an offset.
Definition sparse_storage.h:465
detail::difference_type difference_type
Type used for iterator distances.
Definition sparse_storage.h:378
Mutable random-access iterator over sparse-storage values.
Definition sparse_storage.h:67
iterator operator-(size_type offset) const
Returns an iterator moved backward by an offset.
Definition sparse_storage.h:167
GAIA_NODISCARD bool operator<=(const iterator &other) const
Checks whether this iterator does not follow another iterator.
Definition sparse_storage.h:210
GAIA_NODISCARD bool operator>=(const iterator &other) const
Checks whether this iterator does not precede another iterator.
Definition sparse_storage.h:198
detail::difference_type difference_type
Type used for iterator distances.
Definition sparse_storage.h:72
iterator operator[](size_type offset) const
Returns an iterator at an offset from the current position.
Definition sparse_storage.h:113
reference operator*() const
Returns the value at the current position.
Definition sparse_storage.h:94
sparse_iterator(const sparse_id *pDense, page_type *pPages)
Constructs an iterator for a dense position and sparse-page array.
Definition sparse_storage.h:90
iterator & operator-=(size_type diff)
Moves the iterator backward.
Definition sparse_storage.h:127
iterator & operator++()
Advances to the next value.
Definition sparse_storage.h:133
GAIA_NODISCARD bool operator<(const iterator &other) const
Checks whether this iterator precedes another iterator.
Definition sparse_storage.h:204
iterator & operator--()
Moves to the previous value.
Definition sparse_storage.h:146
difference_type operator-(const iterator &other) const
Returns the distance from another iterator.
Definition sparse_storage.h:173
iterator operator++(int)
Advances to the next value.
Definition sparse_storage.h:139
pointer operator->() const
Returns a pointer to the value at the current position.
Definition sparse_storage.h:103
GAIA_NODISCARD bool operator>(const iterator &other) const
Checks whether this iterator follows another iterator.
Definition sparse_storage.h:192
GAIA_NODISCARD bool operator==(const iterator &other) const
Checks whether two iterators refer to the same position.
Definition sparse_storage.h:180
detail::size_type size_type
Type used for iterator offsets.
Definition sparse_storage.h:73
iterator operator--(int)
Moves to the previous value.
Definition sparse_storage.h:152
GAIA_NODISCARD bool operator!=(const iterator &other) const
Checks whether two iterators refer to different positions.
Definition sparse_storage.h:186
iterator operator+(size_type offset) const
Returns an iterator advanced by an offset.
Definition sparse_storage.h:161
iterator & operator+=(size_type diff)
Advances the iterator.
Definition sparse_storage.h:120
Converts an item to the sparse identifier used by sparse_storage.
Definition sparse_storage.h:49
static sparse_id get(const T &item) noexcept
Returns the sparse identifier for an item.
Definition sparse_storage.h:53
View policy for accessing and storing data in the AoS way. Good for random access and when accessing ...
Definition data_layout_policy.h:162
std::add_pointer_t< ValueType > TargetCastType
Pointer type used to address stored values.
Definition data_layout_policy.h:164
GAIA_NODISCARD static constexpr ValueType & set(std::span< ValueType > s, size_t idx) noexcept
Returns a mutable value reference from an AoS span.
Definition data_layout_policy.h:238
GAIA_NODISCARD static constexpr const ValueType & get(std::span< const ValueType > s, size_t idx) noexcept
Returns a read-only value reference from an AoS span.
Definition data_layout_policy.h:230