Gaia-ECS v1.0.0
A simple and powerful entity component system
Loading...
Searching...
No Matches
darray_soa_impl.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include <cstddef>
5#include <initializer_list>
6#include <type_traits>
7#include <utility>
8
9#include "gaia/cnt/impl/array_utils.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_sani.h"
14#include "gaia/mem/mem_utils.h"
15
16namespace gaia {
17 namespace cnt {
19 namespace darr_soa_detail {
20 using difference_type = int32_t;
21 using size_type = uint32_t;
22 } // namespace darr_soa_detail
24
26 template <typename T>
27 struct darr_soa_iterator {
29 using value_type = T;
30 // using pointer = T*; not supported
31 // using reference = T&; not supported
33 using difference_type = darr_soa_detail::difference_type;
35 using size_type = darr_soa_detail::size_type;
36
37 using iterator = darr_soa_iterator;
39 using iterator_category = core::random_access_iterator_tag;
40
41 private:
42 uint8_t* m_ptr;
43 size_type m_cnt;
44 size_type m_idx;
45
46 public:
47 darr_soa_iterator(uint8_t* ptr, size_type cnt, size_type idx): m_ptr(ptr), m_cnt(cnt), m_idx(idx) {}
48
49 T operator*() const {
50 return mem::data_view_policy<T::gaia_Data_Layout, T>::get({m_ptr, m_cnt}, m_idx);
51 }
52 T operator->() const {
53 return mem::data_view_policy<T::gaia_Data_Layout, T>::get({m_ptr, m_cnt}, m_idx);
54 }
55 iterator operator[](difference_type offset) const {
56 return iterator(m_ptr, m_cnt, (size_type)((difference_type)m_idx + offset));
57 }
58
59 iterator& operator+=(difference_type diff) {
60 m_idx = (size_type)((difference_type)m_idx + diff);
61 return *this;
62 }
63 iterator& operator-=(difference_type diff) {
64 m_idx = (size_type)((difference_type)m_idx - diff);
65 return *this;
66 }
67 iterator& operator++() {
68 ++m_idx;
69 return *this;
70 }
71 iterator operator++(int) {
72 iterator temp(*this);
73 ++*this;
74 return temp;
75 }
76 iterator& operator--() {
77 --m_idx;
78 return *this;
79 }
80 iterator operator--(int) {
81 iterator temp(*this);
82 --*this;
83 return temp;
84 }
85
86 iterator operator+(difference_type offset) const {
87 return iterator(m_ptr, m_cnt, (size_type)((difference_type)m_idx + offset));
88 }
89 iterator operator-(difference_type offset) const {
90 return iterator(m_ptr, m_cnt, (size_type)((difference_type)m_idx - offset));
91 }
92 difference_type operator-(const iterator& other) const {
93 GAIA_ASSERT(m_ptr == other.m_ptr);
94 return (difference_type)(m_idx - other.m_idx);
95 }
96
97 GAIA_NODISCARD bool operator==(const iterator& other) const {
98 GAIA_ASSERT(m_ptr == other.m_ptr);
99 return m_idx == other.m_idx;
100 }
101 GAIA_NODISCARD bool operator!=(const iterator& other) const {
102 GAIA_ASSERT(m_ptr == other.m_ptr);
103 return m_idx != other.m_idx;
104 }
105 GAIA_NODISCARD bool operator>(const iterator& other) const {
106 GAIA_ASSERT(m_ptr == other.m_ptr);
107 return m_idx > other.m_idx;
108 }
109 GAIA_NODISCARD bool operator>=(const iterator& other) const {
110 GAIA_ASSERT(m_ptr == other.m_ptr);
111 return m_idx >= other.m_idx;
112 }
113 GAIA_NODISCARD bool operator<(const iterator& other) const {
114 GAIA_ASSERT(m_ptr == other.m_ptr);
115 return m_idx < other.m_idx;
116 }
117 GAIA_NODISCARD bool operator<=(const iterator& other) const {
118 GAIA_ASSERT(m_ptr == other.m_ptr);
119 return m_idx <= other.m_idx;
120 }
121 };
122
123 template <typename T>
124 struct const_darr_soa_iterator {
125 using value_type = T;
126 // using pointer = T*; not supported
127 // using reference = T&; not supported
128 using difference_type = darr_soa_detail::difference_type;
129 using size_type = darr_soa_detail::size_type;
130
131 using iterator = const_darr_soa_iterator;
132 using iterator_category = core::random_access_iterator_tag;
133
134 private:
135 const uint8_t* m_ptr;
136 size_type m_cnt;
137 size_type m_idx;
138
139 public:
140 const_darr_soa_iterator(const uint8_t* ptr, size_type cnt, size_type idx): m_ptr(ptr), m_cnt(cnt), m_idx(idx) {}
141
142 T operator*() const {
143 return mem::data_view_policy<T::gaia_Data_Layout, T>::get({m_ptr, m_cnt}, m_idx);
144 }
145 T operator->() const {
146 return mem::data_view_policy<T::gaia_Data_Layout, T>::get({m_ptr, m_cnt}, m_idx);
147 }
148 iterator operator[](difference_type offset) const {
149 return iterator(m_ptr, m_cnt, (size_type)((difference_type)m_idx + offset));
150 }
151
152 iterator& operator+=(difference_type diff) {
153 m_idx = (size_type)((difference_type)m_idx + diff);
154 return *this;
155 }
156 iterator& operator-=(difference_type diff) {
157 m_idx = (size_type)((difference_type)m_idx - diff);
158 return *this;
159 }
160 iterator& operator++() {
161 ++m_idx;
162 return *this;
163 }
164 iterator operator++(int) {
165 iterator temp(*this);
166 ++*this;
167 return temp;
168 }
169 iterator& operator--() {
170 --m_idx;
171 return *this;
172 }
173 iterator operator--(int) {
174 iterator temp(*this);
175 --*this;
176 return temp;
177 }
178
179 iterator operator+(difference_type offset) const {
180 return iterator(m_ptr, m_cnt, (size_type)((difference_type)m_idx + offset));
181 }
182 iterator operator-(difference_type offset) const {
183 return iterator(m_ptr, m_cnt, (size_type)((difference_type)m_idx - offset));
184 }
185 difference_type operator-(const iterator& other) const {
186 GAIA_ASSERT(m_ptr == other.m_ptr);
187 return (difference_type)(m_idx - other.m_idx);
188 }
189
190 GAIA_NODISCARD bool operator==(const iterator& other) const {
191 GAIA_ASSERT(m_ptr == other.m_ptr);
192 return m_idx == other.m_idx;
193 }
194 GAIA_NODISCARD bool operator!=(const iterator& other) const {
195 GAIA_ASSERT(m_ptr == other.m_ptr);
196 return m_idx != other.m_idx;
197 }
198 GAIA_NODISCARD bool operator>(const iterator& other) const {
199 GAIA_ASSERT(m_ptr == other.m_ptr);
200 return m_idx > other.m_idx;
201 }
202 GAIA_NODISCARD bool operator>=(const iterator& other) const {
203 GAIA_ASSERT(m_ptr == other.m_ptr);
204 return m_idx >= other.m_idx;
205 }
206 GAIA_NODISCARD bool operator<(const iterator& other) const {
207 GAIA_ASSERT(m_ptr == other.m_ptr);
208 return m_idx < other.m_idx;
209 }
210 GAIA_NODISCARD bool operator<=(const iterator& other) const {
211 GAIA_ASSERT(m_ptr == other.m_ptr);
212 return m_idx <= other.m_idx;
213 }
214 };
216
220 template <typename T, typename Allocator = mem::DefaultAllocatorAdaptor>
221 class darr_soa {
222 static_assert(mem::is_soa_layout_v<T>, "darr_soa can be used only with soa types");
223
224 public:
226 using value_type = T;
228 using reference = T&;
230 using const_reference = const T&;
232 using pointer = T*;
234 using const_pointer = const T*;
238 using difference_type = darr_soa_detail::difference_type;
240 using size_type = darr_soa_detail::size_type;
241
252
253 private:
254 uint8_t* m_pData = nullptr;
255 size_type m_cnt = size_type(0);
256 size_type m_cap = size_type(0);
257
258 void try_grow() {
259 const auto cnt = size();
260 const auto cap = capacity();
261
262 // Unless we reached the capacity don't do anything
263 if GAIA_LIKELY (cap != 0 && cnt < cap)
264 return;
265
266 // If no data is allocated go with at least 4 elements
267 if GAIA_UNLIKELY (m_pData == nullptr) {
268 m_pData = view_policy::template alloc<Allocator>(m_cap = 4);
269 return;
270 }
271
272 // We increase the capacity in multiples of 1.5 which is about the golden ratio (1.618).
273 // This effectively means we prefer more frequent allocations over memory fragmentation.
274 m_cap = (cap * 3 + 1) / 2;
275
276 auto* pDataOld = m_pData;
277 m_pData = view_policy::template alloc<Allocator>(m_cap);
278 view_policy::mem_add_block(m_pData, m_cap, cnt);
279 mem::move_elements<T, true>(m_pData, pDataOld, cnt, 0, m_cap, cap);
280 view_policy::template free<Allocator>(pDataOld, cap, cnt);
281 }
282
283 public:
284 darr_soa() noexcept = default;
286 darr_soa(core::zero_t) noexcept {}
287
292 resize(count, value);
293 }
294
298 resize(count);
299 }
300
305 template <typename InputIt>
306 darr_soa(InputIt first, InputIt last) {
307 const auto count = (size_type)core::distance(first, last);
308 resize(count);
309
310 if constexpr (std::is_pointer_v<InputIt>) {
311 for (size_type i = 0; i < count; ++i)
312 operator[](i) = first[i];
313 } else if constexpr (std::is_same_v<typename InputIt::iterator_category, core::random_access_iterator_tag>) {
314 for (size_type i = 0; i < count; ++i)
315 operator[](i) = *(first[i]);
316 } else {
317 size_type i = 0;
318 for (auto it = first; it != last; ++it)
319 operator[](i++) = *it;
320 }
321 }
322
325 darr_soa(std::initializer_list<T> il): darr_soa(il.begin(), il.end()) {}
326
330
333 darr_soa(darr_soa&& other) noexcept {
334 // This is a newly constructed object.
335 // It can't have any memory allocated, yet.
336 GAIA_ASSERT(m_pData == nullptr);
337
338 m_pData = other.m_pData;
339 m_cnt = other.m_cnt;
340 m_cap = other.m_cap;
341
342 other.m_cnt = size_type(0);
343 other.m_cap = size_type(0);
344 other.m_pData = nullptr;
345 }
346
350 darr_soa& operator=(std::initializer_list<T> il) {
351 *this = darr_soa(il.begin(), il.end());
352 return *this;
353 }
354
359 GAIA_ASSERT(core::addressof(other) != this);
360
361 resize(other.size());
362 mem::copy_elements<T, true>(
363 (uint8_t*)m_pData, (const uint8_t*)other.m_pData, other.size(), 0, capacity(), other.capacity());
364
365 return *this;
366 }
367
372 GAIA_ASSERT(core::addressof(other) != this);
373
374 // Release previously allocated memory if there was anything
375 view_policy::template free<Allocator>(m_pData, m_cap, m_cnt);
376
377 m_pData = other.m_pData;
378 m_cnt = other.m_cnt;
379 m_cap = other.m_cap;
380
381 other.m_pData = nullptr;
382 other.m_cnt = size_type(0);
383 other.m_cap = size_type(0);
384
385 return *this;
386 }
387
388 ~darr_soa() {
389 view_policy::template free<Allocator>(m_pData, m_cap, m_cnt);
390 }
391
392 GAIA_CLANG_WARNING_PUSH()
393 // Memory is aligned so we can silence this warning
394 GAIA_CLANG_WARNING_DISABLE("-Wcast-align")
395
398 GAIA_NODISCARD pointer data() noexcept {
399 return reinterpret_cast<pointer>(m_pData);
400 }
401
404 GAIA_NODISCARD const_pointer data() const noexcept {
405 return reinterpret_cast<const_pointer>(m_pData);
406 }
407
411 GAIA_NODISCARD decltype(auto) operator[](size_type pos) noexcept {
412 GAIA_ASSERT(pos < size());
413 return view_policy::set({(typename view_policy::TargetCastType)m_pData, capacity()}, pos);
414 }
415
419 GAIA_NODISCARD decltype(auto) operator[](size_type pos) const noexcept {
420 GAIA_ASSERT(pos < size());
421 return view_policy::get({(typename view_policy::TargetCastType)m_pData, capacity()}, pos);
422 }
423
424 GAIA_CLANG_WARNING_POP()
425
426
429 if (cap <= m_cap)
430 return;
431
432 auto* pDataOld = m_pData;
433 m_pData = view_policy::template alloc<Allocator>(cap);
434
435 if (pDataOld != nullptr) {
436 view_policy::mem_add_block(m_pData, cap, m_cnt);
437 mem::move_elements<T, true>(m_pData, pDataOld, m_cnt, 0, cap, m_cap);
438 view_policy::template free<Allocator>(pDataOld, m_cap, m_cnt);
439 }
440
441 m_cap = cap;
442 }
443
447 void resize(size_type count, ResizePolicy policy = ResizePolicy::Exact) {
448 if (count == m_cnt)
449 return;
450
451 // Fresh allocation
452 if (m_pData == nullptr) {
453 if (count > 0) {
454 m_pData = view_policy::template alloc<Allocator>(count);
455 view_policy::mem_add_block(m_pData, count, count);
456 m_cap = count;
457 m_cnt = count;
458 }
459 return;
460 }
461
462 // Resizing to a smaller size
463 if (count < m_cnt) {
464 view_policy::mem_pop_block(m_pData, m_cap, m_cnt, m_cnt - count);
465
466 m_cnt = count;
467 return;
468 }
469
470 // Resizing to a bigger size but still within allocated capacity
471 if (count <= m_cap) {
472 view_policy::mem_push_block(m_pData, m_cap, m_cnt, count - m_cnt);
473
474 m_cnt = count;
475 return;
476 }
477
478 const auto cap = detail::resize_capacity(policy, m_cap, count);
479 auto* pDataOld = m_pData;
480 m_pData = view_policy::template alloc<Allocator>(cap);
481 view_policy::mem_add_block(m_pData, cap, count);
482 // Move old data to the new location
483 mem::move_elements<T, true>(m_pData, pDataOld, m_cnt, 0, cap, m_cap);
484 // Release old memory
485 view_policy::template free<Allocator>(pDataOld, m_cap, m_cnt);
486
487 m_cap = cap;
488 m_cnt = count;
489 }
490
495 void resize(size_type count, const_reference value, ResizePolicy policy = ResizePolicy::Exact) {
496 const auto oldCount = m_cnt;
497 resize(count, policy);
498
499 if constexpr (std::is_copy_constructible_v<value_type>) {
500 const value_type valueCopy = value;
501 for (size_type i = oldCount; i < m_cnt; ++i)
502 operator[](i) = valueCopy;
503 } else {
504 for (size_type i = oldCount; i < m_cnt; ++i)
505 operator[](i) = value;
506 }
507 }
508
511 void push_back(const T& arg) {
512 try_grow();
513
514 view_policy::mem_push_block(m_pData, m_cap, m_cnt, 1);
515 operator[](m_cnt++) = arg;
516 }
517
520 void push_back(T&& arg) {
521 try_grow();
522
523 view_policy::mem_push_block(m_pData, m_cap, m_cnt, 1);
524 operator[](m_cnt++) = GAIA_MOV(arg);
525 }
526
531 template <typename... Args>
532 decltype(auto) emplace_back(Args&&... args) {
533 T value(GAIA_FWD(args)...);
534 try_grow();
535
536 view_policy::mem_push_block(m_pData, m_cap, m_cnt, 1);
537 operator[](m_cnt++) = GAIA_MOV(value);
538 }
539
542 GAIA_ASSERT(!empty());
543
544 view_policy::mem_pop_block(m_pData, m_cap, m_cnt, 1);
545
546 --m_cnt;
547 }
548
554 GAIA_ASSERT(pos >= begin());
555 GAIA_ASSERT(pos <= end());
556
557 const auto idxSrc = (size_type)(pos - begin());
558 try_grow();
559 const auto idxDst = size();
560
561 view_policy::mem_push_block(m_pData, m_cap, m_cnt, 1);
562 mem::shift_elements_right<T, true>(m_pData, idxDst, idxSrc, m_cap);
563
564 ++m_cnt;
566
567 return iterator(m_pData, capacity(), idxSrc);
568 }
569
575 GAIA_ASSERT(pos >= begin());
576 GAIA_ASSERT(pos <= end());
577
578 const auto idxSrc = (size_type)(pos - begin());
579 try_grow();
580 const auto idxDst = size();
581
582 view_policy::mem_push_block(m_pData, m_cap, m_cnt, 1);
583 mem::shift_elements_right<T, true>(m_pData, idxDst, idxSrc, m_cap);
584
585 ++m_cnt;
586 operator[](idxSrc) = GAIA_MOV(arg);
587
588 return iterator(m_pData, capacity(), idxSrc);
589 }
590
595 GAIA_ASSERT(empty() || (pos >= begin() && pos < end()));
596
597 if (empty())
598 return end();
599
600 const auto idxSrc = (size_type)(pos - begin());
601 const auto idxDst = size() - 1;
602
603 mem::shift_elements_left<T, true>(m_pData, idxDst, idxSrc, m_cap);
604 view_policy::mem_pop_block(m_pData, m_cap, m_cnt, 1);
605
606 --m_cnt;
607
608 return iterator(m_pData, capacity(), idxSrc);
609 }
610
615 iterator erase(iterator first, iterator last) noexcept {
616 GAIA_ASSERT(empty() || (first >= begin() && first < end()));
617 GAIA_ASSERT(last > first);
618 GAIA_ASSERT(last <= end());
619
620 if (empty())
621 return end();
622
623 const auto idxSrc = (size_type)(first - begin());
624 const auto idxDst = size();
625 const auto cnt = (size_type)(last - first);
626
627 mem::shift_elements_left_fast<T, true>(m_pData, idxDst, idxSrc, cnt, m_cap);
628 view_policy::mem_pop_block(m_pData, m_cap, m_cnt, cnt);
629
630 m_cnt -= cnt;
631
632 return iterator(m_pData, capacity(), idxSrc);
633 }
634
637 resize(0);
638 }
639
642 const auto cap = capacity();
643 const auto cnt = size();
644 if (cap == cnt)
645 return;
646
647 auto* pDataOld = m_pData;
648 m_pData = cnt != 0 ? view_policy::template alloc<Allocator>(cnt) : nullptr;
649 if (cnt != 0) {
650 view_policy::mem_add_block(m_pData, cnt, cnt);
651 mem::move_elements<T, true>(m_pData, pDataOld, cnt, 0, cnt, cap);
652 }
653 view_policy::template free<Allocator>(pDataOld, cap, cnt);
654 m_cap = cnt;
655 }
656
662 template <typename Func>
663 auto retain(Func&& func) noexcept {
664 const auto oldCount = m_cnt;
665 const auto newSize = detail::retain_array<true>(*this, m_cnt, func);
667 return newSize;
668 }
669
672 GAIA_NODISCARD size_type size() const noexcept {
673 return m_cnt;
674 }
675
678 GAIA_NODISCARD bool empty() const noexcept {
679 return size() == 0;
680 }
681
684 GAIA_NODISCARD size_type capacity() const noexcept {
685 return m_cap;
686 }
687
690 GAIA_NODISCARD size_type max_size() const noexcept {
691 return static_cast<size_type>(-1);
692 }
693
696 GAIA_NODISCARD decltype(auto) front() noexcept {
697 GAIA_ASSERT(!empty());
698 return *begin();
699 }
700
703 GAIA_NODISCARD decltype(auto) front() const noexcept {
704 GAIA_ASSERT(!empty());
705 return *begin();
706 }
707
710 GAIA_NODISCARD decltype(auto) back() noexcept {
711 GAIA_ASSERT(!empty());
712 return operator[](m_cnt - 1);
713 }
714
717 GAIA_NODISCARD decltype(auto) back() const noexcept {
718 GAIA_ASSERT(!empty());
719 return operator[](m_cnt - 1);
720 }
721
724 GAIA_NODISCARD auto begin() noexcept {
725 return iterator(m_pData, capacity(), 0);
726 }
727
730 GAIA_NODISCARD auto begin() const noexcept {
731 return const_iterator(m_pData, capacity(), 0);
732 }
733
736 GAIA_NODISCARD auto cbegin() const noexcept {
737 return const_iterator(m_pData, capacity(), 0);
738 }
739
742 GAIA_NODISCARD auto rbegin() noexcept {
743 return reverse_iterator(end());
744 }
745
748 GAIA_NODISCARD auto rbegin() const noexcept {
749 return const_reverse_iterator(end());
750 }
751
754 GAIA_NODISCARD auto crbegin() const noexcept {
756 }
757
760 GAIA_NODISCARD auto end() noexcept {
761 return iterator(m_pData, capacity(), size());
762 }
763
766 GAIA_NODISCARD auto end() const noexcept {
767 return const_iterator(m_pData, capacity(), size());
768 }
769
772 GAIA_NODISCARD auto cend() const noexcept {
773 return const_iterator(m_pData, capacity(), size());
774 }
775
778 GAIA_NODISCARD auto rend() noexcept {
779 return reverse_iterator(begin());
780 }
781
784 GAIA_NODISCARD auto rend() const noexcept {
786 }
787
790 GAIA_NODISCARD auto crend() const noexcept {
792 }
793
797 GAIA_NODISCARD bool operator==(const darr_soa& other) const noexcept {
798 if (m_cnt != other.m_cnt)
799 return false;
800 const size_type n = size();
801 for (size_type i = 0; i < n; ++i)
802 if (!(operator[](i) == other[i]))
803 return false;
804 return true;
805 }
806
810 GAIA_NODISCARD constexpr bool operator!=(const darr_soa& other) const noexcept {
811 return !operator==(other);
812 }
813
817 template <size_t Item>
820 std::span<uint8_t>{GAIA_ACC((uint8_t*)m_pData), capacity()});
821 }
822
826 template <size_t Item>
829 std::span<const uint8_t>{GAIA_ACC((const uint8_t*)m_pData), capacity()});
830 }
831 };
832 } // namespace cnt
833
834} // namespace gaia
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
pointer iterator
Mutable random-access iterator type.
Definition darray_ext_impl.h:53
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first element.
Definition darray_ext_impl.h:613
GAIA_NODISCARD auto end() noexcept
Returns an iterator one past the last element.
Definition darray_ext_impl.h:649
GAIA_NODISCARD constexpr bool operator!=(const darr_ext &other) const noexcept
Checks whether two containers differ.
Definition darray_ext_impl.h:699
darr_ext_detail::size_type size_type
Unsigned type used for sizes and indices.
Definition darray_ext_impl.h:50
core::random_access_iterator_tag iterator_category
Iterator category exposed by the container.
Definition darray_ext_impl.h:61
darr_ext_detail::difference_type difference_type
Type used for iterator differences.
Definition darray_ext_impl.h:48
T value_type
Element type stored by the container.
Definition darray_ext_impl.h:36
GAIA_NODISCARD decltype(auto) operator[](size_type pos) noexcept
Accesses an element without bounds checking in optimized builds.
Definition darray_ext_impl.h:249
GAIA_NODISCARD bool operator==(const darr_ext &other) const noexcept
Compares two containers element by element.
Definition darray_ext_impl.h:686
GAIA_NODISCARD size_type capacity() const noexcept
Returns the number of elements that fit without reallocation.
Definition darray_ext_impl.h:573
Array with variable size of elements of type.
Definition darray_soa_impl.h:221
iterator insert(iterator pos, T &&arg)
Insert the element to the position given by iterator pos.
Definition darray_soa_impl.h:574
void resize(size_type count, ResizePolicy policy=ResizePolicy::Exact)
Changes the number of elements.
Definition darray_soa_impl.h:447
auto view_mut() noexcept
Returns a mutable view of one structure-of-arrays member.
Definition darray_soa_impl.h:818
GAIA_NODISCARD const_pointer data() const noexcept
Returns a pointer to the element storage.
Definition darray_soa_impl.h:404
GAIA_NODISCARD bool empty() const noexcept
Checks whether the container has no elements.
Definition darray_soa_impl.h:678
void reserve(size_type cap)
Ensures storage for at least the requested number of elements.
Definition darray_soa_impl.h:428
void push_back(T &&arg)
Appends an element.
Definition darray_soa_impl.h:520
core::reverse_iterator< iterator, difference_type > reverse_iterator
Mutable reverse random-access iterator type.
Definition darray_soa_impl.h:247
void resize(size_type count, const_reference value, ResizePolicy policy=ResizePolicy::Exact)
Changes the size and initializes new elements from a value.
Definition darray_soa_impl.h:495
decltype(auto) emplace_back(Args &&... args)
Constructs and appends an element.
Definition darray_soa_impl.h:532
auto view() const noexcept
Returns a read-only view of one structure-of-arrays member.
Definition darray_soa_impl.h:827
GAIA_NODISCARD auto rbegin() const noexcept
Returns a reverse traversal iterator to the last element.
Definition darray_soa_impl.h:748
darr_soa(const darr_soa &other)
Copy-constructs a container.
Definition darray_soa_impl.h:329
GAIA_NODISCARD auto crbegin() const noexcept
Returns a read-only reverse traversal iterator to the last element.
Definition darray_soa_impl.h:754
GAIA_NODISCARD auto rend() const noexcept
Returns the reverse traversal sentinel preceding the first element.
Definition darray_soa_impl.h:784
void clear() noexcept
Removes all elements.
Definition darray_soa_impl.h:636
GAIA_NODISCARD bool operator==(const darr_soa &other) const noexcept
Compares two containers element by element.
Definition darray_soa_impl.h:797
GAIA_NODISCARD auto cend() const noexcept
Returns a read-only iterator one past the last element.
Definition darray_soa_impl.h:772
const_darr_soa_iterator< T > const_iterator
Read-only random-access iterator type.
Definition darray_soa_impl.h:245
darr_soa_detail::size_type size_type
Unsigned type used for sizes and indices.
Definition darray_soa_impl.h:240
darr_soa_detail::difference_type difference_type
Type used for iterator differences.
Definition darray_soa_impl.h:238
auto retain(Func &&func) noexcept
Removes all elements that fail the predicate. The predicate may modify its element but must not chang...
Definition darray_soa_impl.h:663
GAIA_NODISCARD decltype(auto) operator[](size_type pos) noexcept
Accesses an element without bounds checking in optimized builds.
Definition darray_soa_impl.h:411
darr_soa & operator=(darr_soa &&other) noexcept
Move-assigns the container.
Definition darray_soa_impl.h:371
GAIA_NODISCARD size_type capacity() const noexcept
Returns the number of elements that fit without reallocation.
Definition darray_soa_impl.h:684
GAIA_NODISCARD auto end() const noexcept
Returns an iterator one past the last element.
Definition darray_soa_impl.h:766
iterator erase(iterator first, iterator last) noexcept
Removes the elements in the range [first, last)
Definition darray_soa_impl.h:615
GAIA_NODISCARD decltype(auto) front() const noexcept
Accesses the first element.
Definition darray_soa_impl.h:703
GAIA_NODISCARD auto cbegin() const noexcept
Returns a read-only iterator to the first element.
Definition darray_soa_impl.h:736
darr_soa(size_type count, const_reference value)
Constructs a container with copies of a value.
Definition darray_soa_impl.h:291
GAIA_NODISCARD decltype(auto) back() const noexcept
Accesses the last element.
Definition darray_soa_impl.h:717
GAIA_NODISCARD constexpr bool operator!=(const darr_soa &other) const noexcept
Checks whether two containers differ.
Definition darray_soa_impl.h:810
GAIA_NODISCARD decltype(auto) front() noexcept
Accesses the first element.
Definition darray_soa_impl.h:696
darr_soa(size_type count)
Constructs a container with the requested number of value-initialized elements.
Definition darray_soa_impl.h:297
void push_back(const T &arg)
Appends an element.
Definition darray_soa_impl.h:511
iterator erase(iterator pos) noexcept
Removes the element at pos.
Definition darray_soa_impl.h:594
darr_soa_iterator< T > iterator
Mutable random-access iterator type.
Definition darray_soa_impl.h:243
GAIA_NODISCARD auto crend() const noexcept
Returns the read-only reverse traversal sentinel preceding the first element.
Definition darray_soa_impl.h:790
darr_soa(darr_soa &&other) noexcept
Move-constructs a container.
Definition darray_soa_impl.h:333
GAIA_NODISCARD decltype(auto) back() noexcept
Accesses the last element.
Definition darray_soa_impl.h:710
GAIA_NODISCARD auto rend() noexcept
Returns the reverse traversal sentinel preceding the first element.
Definition darray_soa_impl.h:778
darr_soa & operator=(const darr_soa &other)
Copy-assigns the container.
Definition darray_soa_impl.h:358
void shrink_to_fit()
Reduces allocated storage to match the current size when possible.
Definition darray_soa_impl.h:641
GAIA_NODISCARD size_type max_size() const noexcept
Returns the maximum number of elements supported by this container.
Definition darray_soa_impl.h:690
GAIA_NODISCARD auto rbegin() noexcept
Returns a reverse traversal iterator to the last element.
Definition darray_soa_impl.h:742
GAIA_NODISCARD size_type size() const noexcept
Returns the number of elements.
Definition darray_soa_impl.h:672
darr_soa(std::initializer_list< T > il)
Constructs a container from an initializer list.
Definition darray_soa_impl.h:325
core::reverse_iterator< const_iterator, difference_type > const_reverse_iterator
Read-only reverse random-access iterator type.
Definition darray_soa_impl.h:249
GAIA_NODISCARD auto begin() const noexcept
Returns an iterator to the first element.
Definition darray_soa_impl.h:730
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first element.
Definition darray_soa_impl.h:724
GAIA_NODISCARD auto end() noexcept
Returns an iterator one past the last element.
Definition darray_soa_impl.h:760
darr_soa(InputIt first, InputIt last)
Constructs a container from an iterator range.
Definition darray_soa_impl.h:306
iterator insert(iterator pos, const T &arg)
Insert the element to the position given by iterator pos.
Definition darray_soa_impl.h:553
void pop_back() noexcept
Removes the last element.
Definition darray_soa_impl.h:541
darr_soa & operator=(std::initializer_list< T > il)
Replaces the elements from an initializer list.
Definition darray_soa_impl.h:350
GAIA_NODISCARD pointer data() noexcept
Returns a pointer to the element storage.
Definition darray_soa_impl.h:398
Random-access iterator that traverses an underlying iterator in reverse. The stored iterator denotes ...
Definition iterator.h:24
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
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
Storage policy for a selected layout and item type.
Definition data_layout_policy.h:121