Gaia-ECS v1.0.0
A simple and powerful entity component system
Loading...
Searching...
No Matches
data_layout_policy.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include <tuple>
5#include <type_traits>
6#include <utility>
7
8#include "gaia/core/span.h"
9#include "gaia/core/utility.h"
10#include "gaia/mem/mem_alloc.h"
11#include "gaia/mem/mem_sani.h"
12#include "gaia/meta/reflection.h"
13
14namespace gaia {
15 namespace mem {
17 enum class DataLayout : uint8_t {
18 AoS = 0,
19 SoA = 1,
20 SoA8 = 2,
21 SoA16 = 3,
22
23 Count = 4
24 };
25
26#define GAIA_LAYOUT(layout_name) static constexpr auto gaia_Data_Layout = ::gaia::mem::DataLayout::layout_name
27
28 // Helper templates
30 namespace detail {
31 template <typename T>
32 constexpr uint32_t get_alignment() {
33 if constexpr (std::is_empty_v<T>)
34 // Always consider 0 for empty types
35 return 0U;
36 else
37 return (uint32_t)alignof(T);
38 }
39
46 constexpr size_t get_aligned_byte_offset(uintptr_t address, size_t alig, size_t itemSize, size_t cnt) {
47 const auto padding = mem::padding(address, alig);
48 address += padding + itemSize * cnt;
49 return address;
50 }
51
58 template <typename T, size_t Alignment>
59 constexpr size_t get_aligned_byte_offset(uintptr_t address, size_t cnt) {
60 const auto padding = mem::padding<Alignment>(address);
61 address += padding + sizeof(T) * cnt;
62 return address;
63 }
64 } // namespace detail
66
70 template <DataLayout TDataLayout, typename TItem>
74 template <typename TItem>
75 struct data_layout_properties<DataLayout::AoS, TItem> {
77 constexpr static DataLayout Layout = DataLayout::AoS;
79 constexpr static size_t PackSize = 1;
81 constexpr static size_t Alignment = detail::get_alignment<TItem>();
82 };
85 template <typename TItem>
86 struct data_layout_properties<DataLayout::SoA, TItem> {
88 constexpr static DataLayout Layout = DataLayout::SoA;
90 constexpr static size_t PackSize = 4;
92 constexpr static size_t Alignment = PackSize * 4;
93 };
96 template <typename TItem>
97 struct data_layout_properties<DataLayout::SoA8, TItem> {
99 constexpr static DataLayout Layout = DataLayout::SoA8;
101 constexpr static size_t PackSize = 8;
103 constexpr static size_t Alignment = PackSize * 4;
104 };
107 template <typename TItem>
108 struct data_layout_properties<DataLayout::SoA16, TItem> {
110 constexpr static DataLayout Layout = DataLayout::SoA16;
112 constexpr static size_t PackSize = 16;
114 constexpr static size_t Alignment = PackSize * 4;
115 };
116
120 template <DataLayout TDataLayout, typename TItem>
122
126 template <DataLayout TDataLayout, typename TItem>
131 template <DataLayout TDataLayout, typename TItem>
133
138 template <DataLayout TDataLayout, typename TItem, size_t Ids>
144 template <DataLayout TDataLayout, typename TItem, size_t Ids>
146
159 template <typename ValueType>
162 using TargetCastType = std::add_pointer_t<ValueType>;
163
168
173 GAIA_NODISCARD static constexpr uint32_t get_min_byte_size(uintptr_t addr, size_t cnt) noexcept {
174 const auto offset = detail::get_aligned_byte_offset<ValueType, Alignment>(addr, cnt);
175 return (uint32_t)(offset - addr);
176 }
177
182 template <typename Allocator>
183 GAIA_NODISCARD static uint8_t* alloc(size_t cnt) noexcept {
184 const auto bytes = get_min_byte_size(0, cnt);
185 return mem::AllocHelper::alloc<uint8_t, Allocator>(bytes);
186 }
187
193 template <typename Allocator>
194 static void free(void* pData, size_t cap, size_t cnt) noexcept {
195 if (pData == nullptr)
196 return;
197 core::call_dtor_n((ValueType*)pData, cnt);
198 GAIA_MEM_SANI_DEL_BLOCK(sizeof(ValueType), pData, cap, cnt);
199 return mem::AllocHelper::free<Allocator>(pData);
200 }
201
206 template <typename Allocator>
207 static void free(void* pData, size_t cnt) noexcept {
208 if (pData == nullptr)
209 return;
210 core::call_dtor_n((ValueType*)pData, cnt);
211 return mem::AllocHelper::free<Allocator>(pData);
212 }
213
218 GAIA_NODISCARD constexpr static ValueType get_value(std::span<const ValueType> s, size_t idx) noexcept {
219 return s[idx];
220 }
221
226 GAIA_NODISCARD constexpr static const ValueType& get(std::span<const ValueType> s, size_t idx) noexcept {
227 return s[idx];
228 }
229
234 GAIA_NODISCARD constexpr static ValueType& set(std::span<ValueType> s, size_t idx) noexcept {
235 return s[idx];
236 }
237 };
238
239 template <typename ValueType>
240 struct data_view_policy<DataLayout::AoS, ValueType>: data_view_policy_aos<ValueType> {};
241
244 template <typename ValueType>
248
250 std::span<const uint8_t> m_data;
251
254 data_view_policy_aos_get(std::span<uint8_t> data): m_data({(const uint8_t*)data.data(), data.size()}) {}
257 data_view_policy_aos_get(std::span<const uint8_t> data): m_data({(const uint8_t*)data.data(), data.size()}) {}
261 template <typename C>
262 data_view_policy_aos_get(const C& c): m_data({(const uint8_t*)c.data(), c.size()}) {
263 static_assert(!std::is_same_v<C, data_view_policy_aos_get>);
264 }
265
269 GAIA_NODISCARD const ValueType& operator[](size_t idx) const noexcept {
270 GAIA_ASSERT(idx < m_data.size());
271 return ((const ValueType*)(const void*)m_data.data())[idx];
272 }
273
276 GAIA_NODISCARD decltype(auto) data() const noexcept {
277 return (const uint8_t*)m_data.data();
278 }
279
282 GAIA_NODISCARD auto size() const noexcept {
283 return m_data.size();
284 }
285 };
286
287 template <typename ValueType>
288 struct data_view_policy_get<DataLayout::AoS, ValueType>: data_view_policy_aos_get<ValueType> {};
289
292 template <typename ValueType>
296
298 std::span<uint8_t> m_data;
299
302 data_view_policy_aos_set(std::span<uint8_t> data): m_data({(uint8_t*)data.data(), data.size()}) {}
305 data_view_policy_aos_set(std::span<const uint8_t> data): m_data({(uint8_t*)data.data(), data.size()}) {}
309 template <typename C>
310 data_view_policy_aos_set(const C& c): m_data({(uint8_t*)c.data(), c.size()}) {
311 static_assert(!std::is_same_v<C, data_view_policy_aos_set>);
312 }
313
317 GAIA_NODISCARD ValueType& operator[](size_t idx) noexcept {
318 GAIA_ASSERT(idx < m_data.size());
319 return ((ValueType*)(void*)m_data.data())[idx];
320 }
321
325 GAIA_NODISCARD const ValueType& operator[](size_t idx) const noexcept {
326 GAIA_ASSERT(idx < m_data.size());
327 return ((const ValueType*)(const void*)m_data.data())[idx];
328 }
329
332 GAIA_NODISCARD auto data() const noexcept {
333 return m_data.data();
334 }
335
338 GAIA_NODISCARD auto size() const noexcept {
339 return m_data.size();
340 }
341 };
342
343 template <typename ValueType>
344 struct data_view_policy_set<DataLayout::AoS, ValueType>: data_view_policy_aos_set<ValueType> {};
345
357 GAIA_NODISCARD static const uint8_t*
358 get(const void* pData, uint32_t alignment, std::span<const uint8_t> fieldSizes, uint32_t fieldIdx, uint32_t row,
359 uint32_t capacity) noexcept {
360 GAIA_ASSERT(pData != nullptr);
361 GAIA_ASSERT(alignment != 0 && fieldIdx < fieldSizes.size() && row < capacity);
362
363 auto address = (uintptr_t)pData;
364 GAIA_FOR(fieldIdx) {
365 address = detail::get_aligned_byte_offset(address, alignment, fieldSizes[i], capacity);
366 }
367 address += mem::padding(address, alignment);
368 return (const uint8_t*)address + ((uintptr_t)fieldSizes[fieldIdx] * row);
369 }
370
379 GAIA_NODISCARD static uint8_t*
380 set(void* pData, uint32_t alignment, std::span<const uint8_t> fieldSizes, uint32_t fieldIdx, uint32_t row,
381 uint32_t capacity) noexcept {
382 return const_cast<uint8_t*>(get(pData, alignment, fieldSizes, fieldIdx, row, capacity));
383 }
384 };
385
397 template <DataLayout TDataLayout, typename ValueType>
399 static_assert(std::is_copy_assignable_v<ValueType>);
400
402 using TTuple = decltype(meta::struct_to_tuple(std::declval<ValueType>()));
404 using TargetCastType = uint8_t*;
405
411 constexpr static size_t TTupleItems = std::tuple_size<TTuple>::value;
412 static_assert(Alignment > 0U, "SoA data can't be zero-aligned");
413
416 template <size_t Item>
417 using value_type = typename std::tuple_element<Item, TTuple>::type;
420 template <size_t Item>
421 using const_value_type = typename std::add_const<value_type<Item>>::type;
422
427 GAIA_NODISCARD constexpr static uint32_t get_min_byte_size(uintptr_t addr, size_t cnt) noexcept {
428 const auto offset = get_aligned_byte_offset<TTupleItems>(addr, cnt);
429 return (uint32_t)(offset - addr);
430 }
431
436 template <typename Allocator>
437 GAIA_NODISCARD static uint8_t* alloc(size_t cnt) noexcept {
438 const auto bytes = get_min_byte_size(0, cnt);
439 return mem::AllocHelper::alloc_alig<uint8_t, Allocator>(Alignment, bytes);
440 }
441
447 template <typename Allocator>
448 static void free(void* pData, size_t cap, size_t cnt) noexcept {
449 if (pData == nullptr)
450 return;
451
452 mem_del_block(pData, cap, cnt);
453 return mem::AllocHelper::free_alig<Allocator>(pData);
454 }
455
460 static void mem_add_block(void* pData, size_t cap, size_t count) {
461 meta::each_member(ValueType{}, [&](auto&&... item) {
462 auto address = mem::align<Alignment>((uintptr_t)pData);
463 ((
464 //
465 GAIA_MEM_SANI_ADD_BLOCK(sizeof(item), (void*)address, cap, count),
466 // Skip towards the next element and make sure the address is aligned properly
467 address = mem::align<Alignment>(address + (sizeof(item) * cap))),
468 ...);
469 });
470 }
471
476 static void mem_del_block(void* pData, size_t cap, size_t count) {
477 meta::each_member(ValueType{}, [&](auto&&... item) {
478 auto address = mem::align<Alignment>((uintptr_t)pData);
479 ((
480 //
481 GAIA_MEM_SANI_DEL_BLOCK(sizeof(item), (void*)address, cap, count),
482 // Skip towards the next element and make sure the address is aligned properly
483 address = mem::align<Alignment>(address + (sizeof(item) * cap))),
484 ...);
485 });
486 }
487
493 static void mem_push_block(void* pData, size_t cap, size_t count, size_t n) {
494 meta::each_member(ValueType{}, [&](auto&&... item) {
495 auto address = mem::align<Alignment>((uintptr_t)pData);
496 ((
497 //
498 GAIA_MEM_SANI_PUSH_N(sizeof(item), (void*)address, cap, count, n),
499 // Skip towards the next element and make sure the address is aligned properly
500 address = mem::align<Alignment>(address + (sizeof(item) * cap))),
501 ...);
502 });
503 }
504
510 static void mem_pop_block(void* pData, size_t cap, size_t count, size_t n) {
511 meta::each_member(ValueType{}, [&](auto&&... item) {
512 auto address = mem::align<Alignment>((uintptr_t)pData);
513 ((
514 //
515 GAIA_MEM_SANI_POP_N(sizeof(item), (void*)address, cap, count, n),
516 // Skip towards the next element and make sure the address is aligned properly
517 address = mem::align<Alignment>(address + (sizeof(item) * cap))),
518 ...);
519 });
520 }
521
526 GAIA_NODISCARD constexpr static ValueType get(std::span<const uint8_t> s, size_t idx) noexcept {
527 return get_inter(meta::struct_to_tuple(ValueType{}), s, idx, std::make_index_sequence<TTupleItems>());
528 }
529
535 template <size_t Item>
536 GAIA_NODISCARD constexpr static auto get(std::span<const uint8_t> s, size_t idx = 0) noexcept {
537 const auto offset = get_aligned_byte_offset<Item>((uintptr_t)s.data(), s.size());
538 const auto& ref = get_ref<const value_type<Item>>(reinterpret_cast<const uint8_t*>(offset), idx);
539 return std::span{&ref, s.size() - idx};
540 }
541
543 class accessor {
544 std::span<uint8_t> m_data;
545 size_t m_idx;
546
547 public:
551 constexpr accessor(std::span<uint8_t> data, size_t idx): m_data(data), m_idx(idx) {}
552
555 constexpr void operator=(const ValueType& val) noexcept {
556 set_inter(meta::struct_to_tuple(val), m_data, m_idx, std::make_index_sequence<TTupleItems>());
557 }
558
561 constexpr void operator=(ValueType&& val) noexcept {
562 set_inter(meta::struct_to_tuple(GAIA_MOV(val)), m_data, m_idx, std::make_index_sequence<TTupleItems>());
563 }
564
567 GAIA_NODISCARD constexpr operator ValueType() const noexcept {
568 return get_inter(
569 meta::struct_to_tuple(ValueType{}), {(const uint8_t*)m_data.data(), m_data.size()}, m_idx,
570 std::make_index_sequence<TTupleItems>());
571 }
572 };
573
578 GAIA_NODISCARD constexpr static auto set(std::span<uint8_t> s, size_t idx) noexcept {
579 return accessor(s, idx);
580 }
581
587 template <size_t Item>
588 GAIA_NODISCARD constexpr static auto set(std::span<uint8_t> s, size_t idx = 0) noexcept {
589 const auto offset = get_aligned_byte_offset<Item>((uintptr_t)s.data(), s.size());
590 auto& ref = get_ref<value_type<Item>>((const uint8_t*)offset, idx);
591 return std::span{&ref, s.size() - idx};
592 }
593
594 private:
595 template <size_t... Ids>
596 GAIA_NODISCARD constexpr static size_t get_aligned_byte_offset_seq(
597 uintptr_t address, [[maybe_unused]] size_t cnt, std::index_sequence<Ids...> /*no_name*/) {
598 ((address = detail::get_aligned_byte_offset(address, Alignment, sizeof(value_type<Ids>), cnt)), ...);
599 address += mem::padding(address, Alignment);
600 return address;
601 }
602
603 template <uint32_t N>
604 GAIA_NODISCARD constexpr static size_t get_aligned_byte_offset(uintptr_t address, size_t cnt) {
605 return get_aligned_byte_offset_seq(address, cnt, std::make_index_sequence<N>());
606 }
607
608 template <typename TMemberType>
609 GAIA_NODISCARD constexpr static TMemberType& get_ref(const uint8_t* data, size_t idx) noexcept {
610 // Write the value directly to the memory address.
611 // Usage of unaligned_ref is not necessary because the memory is aligned.
612 auto* pCastData = (TMemberType*)(void*)data;
613 return pCastData[idx];
614 }
615
616 template <typename Tup, size_t... Ids>
617 GAIA_NODISCARD constexpr static ValueType
618 get_inter(Tup&& t, std::span<const uint8_t> s, size_t idx, std::index_sequence<Ids...> /*no_name*/) noexcept {
619 auto address = mem::align<Alignment>((uintptr_t)s.data());
620 ((
621 // Put the value at the address into our tuple. Data is aligned so we can read directly.
622 std::get<Ids>(t) = get_ref<value_type<Ids>>((const uint8_t*)address, idx),
623 // Skip towards the next element and make sure the address is aligned properly
624 address = mem::align<Alignment>(address + (sizeof(value_type<Ids>) * s.size()))),
625 ...);
626 return meta::tuple_to_struct<ValueType, TTuple>(GAIA_FWD(t));
627 }
628
629 template <typename Tup, size_t... Ids>
630 constexpr static void
631 set_inter(Tup&& t, std::span<uint8_t> s, size_t idx, std::index_sequence<Ids...> /*no_name*/) noexcept {
632 auto address = mem::align<Alignment>((uintptr_t)s.data());
633 ((
634 // Set the tuple value. Data is aligned so we can write directly.
635 get_ref<value_type<Ids>>((uint8_t*)address, idx) = std::get<Ids>(t),
636 // Skip towards the next element and make sure the address is aligned properly
637 address = mem::align<Alignment>(address + (sizeof(value_type<Ids>) * s.size()))),
638 ...);
639 }
640 };
641
642 template <typename ValueType>
643 struct data_view_policy<DataLayout::SoA, ValueType>: //
644 data_view_policy_soa<DataLayout::SoA, ValueType> {};
645 template <typename ValueType>
646 struct data_view_policy<DataLayout::SoA8, ValueType>: //
647 data_view_policy_soa<DataLayout::SoA8, ValueType> {};
648 template <typename ValueType>
649 struct data_view_policy<DataLayout::SoA16, ValueType>: //
650 data_view_policy_soa<DataLayout::SoA16, ValueType> {};
651
655 template <DataLayout TDataLayout, typename ValueType>
657 static_assert(std::is_copy_assignable_v<ValueType>);
658
661
664 template <size_t Item>
667 using const_value_type = typename view_policy::template const_value_type<Item>;
668 };
669
671 std::span<const uint8_t> m_data;
672
675 data_view_policy_soa_get(std::span<uint8_t> data): m_data({(const uint8_t*)data.data(), data.size()}) {}
678 data_view_policy_soa_get(std::span<const uint8_t> data): m_data({(const uint8_t*)data.data(), data.size()}) {}
682 template <typename C>
683 data_view_policy_soa_get(const C& c): m_data({(const uint8_t*)c.data(), c.size()}) {
684 static_assert(!std::is_same_v<C, data_view_policy_soa_get>);
685 }
686
690 GAIA_NODISCARD constexpr decltype(auto) operator[](size_t idx) const noexcept {
691 return view_policy::get(m_data, idx);
692 }
693
697 template <size_t Item>
698 GAIA_NODISCARD constexpr auto get() const noexcept {
699 auto s = view_policy::template get<Item>(m_data);
700 return std::span(s.data(), s.size());
701 }
702
705 GAIA_NODISCARD decltype(auto) data() const noexcept {
706 return (const uint8_t*)m_data.data();
707 }
708
711 GAIA_NODISCARD auto size() const noexcept {
712 return m_data.size();
713 }
714 };
715
716 template <typename ValueType>
717 struct data_view_policy_get<DataLayout::SoA, ValueType>: //
718 data_view_policy_soa_get<DataLayout::SoA, ValueType> {};
719 template <typename ValueType>
720 struct data_view_policy_get<DataLayout::SoA8, ValueType>: //
721 data_view_policy_soa_get<DataLayout::SoA8, ValueType> {};
722 template <typename ValueType>
723 struct data_view_policy_get<DataLayout::SoA16, ValueType>: //
724 data_view_policy_soa_get<DataLayout::SoA16, ValueType> {};
725
729 template <DataLayout TDataLayout, typename ValueType>
731 static_assert(std::is_copy_assignable_v<ValueType>);
732
735
738 template <size_t Item>
741 using value_type = typename view_policy::template value_type<Item>;
743 using const_value_type = typename view_policy::template const_value_type<Item>;
744 };
745
747 std::span<uint8_t> m_data;
748
751 data_view_policy_soa_set(std::span<uint8_t> data): m_data({(uint8_t*)data.data(), data.size()}) {}
754 data_view_policy_soa_set(std::span<const uint8_t> data): m_data({(uint8_t*)data.data(), data.size()}) {}
758 template <typename C>
759 data_view_policy_soa_set(const C& c): m_data({(uint8_t*)c.data(), c.size()}) {
760 static_assert(!std::is_same_v<C, data_view_policy_soa_set>);
761 }
762
764 struct accessor {
766 std::span<uint8_t> m_data;
768 size_t m_idx;
769
772 constexpr void operator=(const ValueType& val) noexcept {
774 }
777 constexpr void operator=(ValueType&& val) noexcept {
778 view_policy::set(m_data, m_idx) = GAIA_FWD(val);
779 }
780 };
781
785 GAIA_NODISCARD constexpr decltype(auto) operator[](size_t idx) const noexcept {
786 return view_policy::get({(const uint8_t*)m_data.data(), m_data.size()}, idx);
787 }
791 GAIA_NODISCARD constexpr auto operator[](size_t idx) noexcept {
792 return accessor{m_data, idx};
793 }
794
798 template <size_t Item>
799 GAIA_NODISCARD constexpr auto get() const noexcept {
800 auto s = view_policy::template get<Item>(m_data);
801 return std::span(s.data(), s.size());
802 }
803
807 template <size_t Item>
808 GAIA_NODISCARD constexpr auto set() noexcept {
809 auto s = view_policy::template set<Item>(m_data);
810 return std::span(s.data(), s.size());
811 }
812
815 GAIA_NODISCARD auto data() const noexcept {
816 return m_data.data();
817 }
818
821 GAIA_NODISCARD auto size() const noexcept {
822 return m_data.size();
823 }
824 };
825
826 template <typename ValueType>
827 struct data_view_policy_set<DataLayout::SoA, ValueType>: //
828 data_view_policy_soa_set<DataLayout::SoA, ValueType> {};
829 template <typename ValueType>
830 struct data_view_policy_set<DataLayout::SoA8, ValueType>: //
831 data_view_policy_soa_set<DataLayout::SoA8, ValueType> {};
832 template <typename ValueType>
833 struct data_view_policy_set<DataLayout::SoA16, ValueType>: //
834 data_view_policy_soa_set<DataLayout::SoA16, ValueType> {};
835
836 //----------------------------------------------------------------------
837 // Helpers
838 //----------------------------------------------------------------------
839
841 namespace detail {
842 template <typename, typename = void>
843 struct auto_view_policy_inter {
844 static constexpr DataLayout data_layout_type = DataLayout::AoS;
845 };
846 template <typename T>
847 struct auto_view_policy_inter<T, std::void_t<decltype(T::gaia_Data_Layout)>> {
848 static constexpr DataLayout data_layout_type = T::gaia_Data_Layout;
849 };
850
851 template <typename, typename = void>
852 struct is_soa_layout: std::false_type {};
853 template <typename T>
854 struct is_soa_layout<T, std::void_t<decltype(T::gaia_Data_Layout)>>:
855 std::bool_constant<!std::is_empty_v<T> && (T::gaia_Data_Layout != DataLayout::AoS)> {};
856 } // namespace detail
858
861 template <typename T>
862 using auto_view_policy = data_view_policy<detail::auto_view_policy_inter<T>::data_layout_type, T>;
865 template <typename T>
866 using auto_view_policy_get = data_view_policy_get<detail::auto_view_policy_inter<T>::data_layout_type, T>;
869 template <typename T>
870 using auto_view_policy_set = data_view_policy_set<detail::auto_view_policy_inter<T>::data_layout_type, T>;
871
874 template <typename T>
875 inline constexpr bool is_soa_layout_v = detail::is_soa_layout<T>::value;
876
877 } // namespace mem
878} // namespace gaia
Proxy used to read or assign one complete SoA value.
Definition data_layout_policy.h:543
constexpr void operator=(const ValueType &val) noexcept
Assigns a copied value to the selected SoA fields.
Definition data_layout_policy.h:555
constexpr accessor(std::span< uint8_t > data, size_t idx)
Creates a value proxy.
Definition data_layout_policy.h:551
constexpr void operator=(ValueType &&val) noexcept
Assigns a moved value to the selected SoA fields.
Definition data_layout_policy.h:561
Compile-time properties of a data layout.
Definition data_layout_policy.h:71
Read-only byte view over AoS values.
Definition data_layout_policy.h:245
std::span< const uint8_t > m_data
Raw data pointed to by the view policy.
Definition data_layout_policy.h:250
data_view_policy_aos_get(std::span< uint8_t > data)
Creates a read-only view over mutable bytes.
Definition data_layout_policy.h:254
GAIA_NODISCARD auto size() const noexcept
Returns the backing span size.
Definition data_layout_policy.h:282
GAIA_NODISCARD const ValueType & operator[](size_t idx) const noexcept
Returns a value by index.
Definition data_layout_policy.h:269
data_view_policy_aos_get(const C &c)
Creates a read-only view over a contiguous container.
Definition data_layout_policy.h:262
data_view_policy_aos_get(std::span< const uint8_t > data)
Creates a read-only view over bytes.
Definition data_layout_policy.h:257
GAIA_NODISCARD decltype(auto) data() const noexcept
Returns the backing byte address.
Definition data_layout_policy.h:276
Mutable byte view over AoS values.
Definition data_layout_policy.h:293
data_view_policy_aos_set(std::span< const uint8_t > data)
Creates a mutable view from a byte span.
Definition data_layout_policy.h:305
GAIA_NODISCARD ValueType & operator[](size_t idx) noexcept
Returns a mutable value by index.
Definition data_layout_policy.h:317
GAIA_NODISCARD auto size() const noexcept
Returns the backing span size.
Definition data_layout_policy.h:338
std::span< uint8_t > m_data
Raw data pointed to by the view policy.
Definition data_layout_policy.h:298
data_view_policy_aos_set(const C &c)
Creates a mutable view over a contiguous container.
Definition data_layout_policy.h:310
GAIA_NODISCARD const ValueType & operator[](size_t idx) const noexcept
Returns a read-only value by index.
Definition data_layout_policy.h:325
GAIA_NODISCARD auto data() const noexcept
Returns the backing byte address.
Definition data_layout_policy.h:332
data_view_policy_aos_set(std::span< uint8_t > data)
Creates a mutable view over bytes.
Definition data_layout_policy.h:302
View policy for accessing and storing data in the AoS way. Good for random access and when accessing ...
Definition data_layout_policy.h:160
static constexpr size_t Alignment
Required byte alignment.
Definition data_layout_policy.h:167
static GAIA_NODISCARD constexpr uint32_t get_min_byte_size(uintptr_t addr, size_t cnt) noexcept
Calculates the bytes required for a value range.
Definition data_layout_policy.h:173
static GAIA_NODISCARD uint8_t * alloc(size_t cnt) noexcept
Allocates raw AoS capacity. The caller constructs the live values.
Definition data_layout_policy.h:183
static void free(void *pData, size_t cnt) noexcept
Destroys and releases an AoS value range.
Definition data_layout_policy.h:207
GAIA_NODISCARD static constexpr ValueType get_value(std::span< const ValueType > s, size_t idx) noexcept
Copies a value from an AoS span.
Definition data_layout_policy.h:218
std::add_pointer_t< ValueType > TargetCastType
Pointer type used to address stored values.
Definition data_layout_policy.h:162
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:234
static void free(void *pData, size_t cap, size_t cnt) noexcept
Destroys and releases an instrumented AoS value range.
Definition data_layout_policy.h:194
static constexpr DataLayout Layout
Physical layout.
Definition data_layout_policy.h:165
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:226
Indexed read-only view metadata.
Definition data_layout_policy.h:139
Read-only view for a selected layout and item type.
Definition data_layout_policy.h:127
Indexed mutable view metadata.
Definition data_layout_policy.h:145
Mutable view for a selected layout and item type.
Definition data_layout_policy.h:132
Type-erased policy for addressing one field value in SoA storage. The field arrays use the same align...
Definition data_layout_policy.h:348
static GAIA_NODISCARD const uint8_t * get(const void *pData, uint32_t alignment, std::span< const uint8_t > fieldSizes, uint32_t fieldIdx, uint32_t row, uint32_t capacity) noexcept
Returns one read-only field value from type-erased SoA storage.
Definition data_layout_policy.h:358
static GAIA_NODISCARD uint8_t * set(void *pData, uint32_t alignment, std::span< const uint8_t > fieldSizes, uint32_t fieldIdx, uint32_t row, uint32_t capacity) noexcept
Returns one mutable field value from type-erased SoA storage.
Definition data_layout_policy.h:380
Metadata for a selected field.
Definition data_layout_policy.h:665
typename view_policy::template const_value_type< Item > const_value_type
Const-qualified field type.
Definition data_layout_policy.h:667
Read-only byte view over SoA values.
Definition data_layout_policy.h:656
data_view_policy_soa_get(std::span< const uint8_t > data)
Creates a read-only view over bytes.
Definition data_layout_policy.h:678
data_view_policy_soa_get(std::span< uint8_t > data)
Creates a read-only view over mutable bytes.
Definition data_layout_policy.h:675
std::span< const uint8_t > m_data
Raw data pointed to by the view policy.
Definition data_layout_policy.h:671
GAIA_NODISCARD decltype(auto) data() const noexcept
Returns the backing byte address.
Definition data_layout_policy.h:705
GAIA_NODISCARD auto size() const noexcept
Returns the backing span size.
Definition data_layout_policy.h:711
data_view_policy_soa_get(const C &c)
Creates a read-only view over a contiguous container.
Definition data_layout_policy.h:683
GAIA_NODISCARD constexpr auto get() const noexcept
Returns a read-only span over one field.
Definition data_layout_policy.h:698
Proxy used to assign one complete value.
Definition data_layout_policy.h:764
constexpr void operator=(ValueType &&val) noexcept
Assigns a moved value.
Definition data_layout_policy.h:777
constexpr void operator=(const ValueType &val) noexcept
Assigns a copied value.
Definition data_layout_policy.h:772
size_t m_idx
Value index.
Definition data_layout_policy.h:768
std::span< uint8_t > m_data
Backing byte span.
Definition data_layout_policy.h:766
Metadata for a selected field.
Definition data_layout_policy.h:739
typename view_policy::template const_value_type< Item > const_value_type
Const-qualified field type.
Definition data_layout_policy.h:743
typename view_policy::template value_type< Item > value_type
Mutable field type.
Definition data_layout_policy.h:741
Mutable byte view over SoA values.
Definition data_layout_policy.h:730
GAIA_NODISCARD constexpr auto set() noexcept
Returns a mutable span over one field.
Definition data_layout_policy.h:808
data_view_policy_soa_set(std::span< uint8_t > data)
Creates a mutable view over bytes.
Definition data_layout_policy.h:751
data_view_policy_soa_set(const C &c)
Creates a mutable view over a contiguous container.
Definition data_layout_policy.h:759
std::span< uint8_t > m_data
Raw data pointed to by the view policy.
Definition data_layout_policy.h:747
GAIA_NODISCARD constexpr auto operator[](size_t idx) noexcept
Returns a mutable proxy by index.
Definition data_layout_policy.h:791
data_view_policy_soa_set(std::span< const uint8_t > data)
Creates a mutable view from a byte span.
Definition data_layout_policy.h:754
GAIA_NODISCARD auto size() const noexcept
Returns the backing span size.
Definition data_layout_policy.h:821
GAIA_NODISCARD constexpr auto get() const noexcept
Returns a read-only span over one field.
Definition data_layout_policy.h:799
GAIA_NODISCARD auto data() const noexcept
Returns the backing byte address.
Definition data_layout_policy.h:815
View policy for accessing and storing data in the SoA way. Good for SIMD processing.
Definition data_layout_policy.h:398
GAIA_NODISCARD static constexpr ValueType get(std::span< const uint8_t > s, size_t idx) noexcept
Reconstructs a value from its SoA fields.
Definition data_layout_policy.h:526
static void mem_pop_block(void *pData, size_t cap, size_t count, size_t n)
Poisons removed SoA values for the memory sanitizer.
Definition data_layout_policy.h:510
static void mem_add_block(void *pData, size_t cap, size_t count)
Registers a newly allocated SoA range with the memory sanitizer.
Definition data_layout_policy.h:460
uint8_t * TargetCastType
Pointer type used to address SoA storage.
Definition data_layout_policy.h:404
static constexpr DataLayout Layout
Physical layout.
Definition data_layout_policy.h:407
static constexpr size_t Alignment
Required byte alignment.
Definition data_layout_policy.h:409
typename std::add_const< value_type< Item > >::type const_value_type
Const-qualified type of a reflected field.
Definition data_layout_policy.h:421
static GAIA_NODISCARD uint8_t * alloc(size_t cnt) noexcept
Allocates an SoA value range.
Definition data_layout_policy.h:437
decltype(meta::struct_to_tuple(std::declval< ValueType >())) TTuple
Tuple representation of the reflected value fields.
Definition data_layout_policy.h:402
GAIA_NODISCARD static constexpr uint32_t get_min_byte_size(uintptr_t addr, size_t cnt) noexcept
Calculates the bytes required for an SoA value range.
Definition data_layout_policy.h:427
static void mem_del_block(void *pData, size_t cap, size_t count)
Unregisters an SoA range from the memory sanitizer.
Definition data_layout_policy.h:476
GAIA_NODISCARD static constexpr auto set(std::span< uint8_t > s, size_t idx) noexcept
Returns a mutable proxy for one complete value.
Definition data_layout_policy.h:578
static void mem_push_block(void *pData, size_t cap, size_t count, size_t n)
Makes newly appended SoA values addressable by the memory sanitizer.
Definition data_layout_policy.h:493
static void free(void *pData, size_t cap, size_t cnt) noexcept
Releases an instrumented SoA value range.
Definition data_layout_policy.h:448
GAIA_NODISCARD static constexpr auto set(std::span< uint8_t > s, size_t idx=0) noexcept
Returns a mutable span over one SoA field.
Definition data_layout_policy.h:588
static constexpr size_t TTupleItems
Number of reflected fields.
Definition data_layout_policy.h:411
GAIA_NODISCARD static constexpr auto get(std::span< const uint8_t > s, size_t idx=0) noexcept
Returns a read-only span over one SoA field.
Definition data_layout_policy.h:536
typename std::tuple_element< Item, TTuple >::type value_type
Type of a reflected field.
Definition data_layout_policy.h:417
Storage policy for a selected layout and item type.
Definition data_layout_policy.h:121