2#include "gaia/config/config.h"
5#include <initializer_list>
9#include "gaia/core/iterator.h"
10#include "gaia/core/utility.h"
11#include "gaia/mem/data_layout_policy.h"
12#include "gaia/mem/mem_sani.h"
13#include "gaia/mem/mem_utils.h"
18 namespace darr_soa_detail {
26 struct darr_soa_iterator {
34 using size_type = darr_soa_detail::size_type;
46 darr_soa_iterator(uint8_t* ptr, uint32_t cnt, uint32_t idx): m_ptr(ptr), m_cnt(cnt), m_idx(idx) {}
49 return mem::data_view_policy<T::gaia_Data_Layout, T>::get({m_ptr, m_cnt}, m_idx);
51 T operator->()
const {
52 return mem::data_view_policy<T::gaia_Data_Layout, T>::get({m_ptr, m_cnt}, m_idx);
55 return iterator(m_ptr, m_cnt, m_idx + offset);
86 return iterator(m_ptr, m_cnt, m_idx + offset);
89 return iterator(m_ptr, m_cnt, m_idx + offset);
92 GAIA_ASSERT(m_ptr == other.m_ptr);
97 GAIA_ASSERT(m_ptr == other.m_ptr);
98 return m_idx == other.m_idx;
101 GAIA_ASSERT(m_ptr == other.m_ptr);
102 return m_idx != other.m_idx;
104 GAIA_NODISCARD
bool operator>(
const iterator& other)
const {
105 GAIA_ASSERT(m_ptr == other.m_ptr);
106 return m_idx > other.m_idx;
108 GAIA_NODISCARD
bool operator>=(
const iterator& other)
const {
109 GAIA_ASSERT(m_ptr == other.m_ptr);
110 return m_idx >= other.m_idx;
112 GAIA_NODISCARD
bool operator<(
const iterator& other)
const {
113 GAIA_ASSERT(m_ptr == other.m_ptr);
114 return m_idx < other.m_idx;
116 GAIA_NODISCARD
bool operator<=(
const iterator& other)
const {
117 GAIA_ASSERT(m_ptr == other.m_ptr);
118 return m_idx <= other.m_idx;
122 template <
typename T>
123 struct const_darr_soa_iterator {
128 using size_type = darr_soa_detail::size_type;
130 using iterator = const_darr_soa_iterator;
134 const uint8_t* m_ptr;
139 const_darr_soa_iterator(
const uint8_t* ptr, uint32_t cnt, uint32_t idx): m_ptr(ptr), m_cnt(cnt), m_idx(idx) {}
141 T operator*()
const {
142 return mem::data_view_policy<T::gaia_Data_Layout, T>::get({m_ptr, m_cnt}, m_idx);
144 T operator->()
const {
145 return mem::data_view_policy<T::gaia_Data_Layout, T>::get({m_ptr, m_cnt}, m_idx);
148 return iterator(m_ptr, m_cnt, m_idx + offset);
179 return iterator(m_ptr, m_cnt, m_idx + offset);
182 return iterator(m_ptr, m_cnt, m_idx + offset);
185 GAIA_ASSERT(m_ptr == other.m_ptr);
190 GAIA_ASSERT(m_ptr == other.m_ptr);
191 return m_idx == other.m_idx;
194 GAIA_ASSERT(m_ptr == other.m_ptr);
195 return m_idx != other.m_idx;
197 GAIA_NODISCARD
bool operator>(
const iterator& other)
const {
198 GAIA_ASSERT(m_ptr == other.m_ptr);
199 return m_idx > other.m_idx;
201 GAIA_NODISCARD
bool operator>=(
const iterator& other)
const {
202 GAIA_ASSERT(m_ptr == other.m_ptr);
203 return m_idx >= other.m_idx;
205 GAIA_NODISCARD
bool operator<(
const iterator& other)
const {
206 GAIA_ASSERT(m_ptr == other.m_ptr);
207 return m_idx < other.m_idx;
209 GAIA_NODISCARD
bool operator<=(
const iterator& other)
const {
210 GAIA_ASSERT(m_ptr == other.m_ptr);
211 return m_idx <= other.m_idx;
219 template <
typename T,
typename Allocator = mem::DefaultAllocatorAdaptor>
221 static_assert(mem::is_soa_layout_v<T>,
"darr_soa can be used only with soa types");
254 const auto cnt =
size();
258 if GAIA_LIKELY (
cap != 0 && cnt <
cap)
262 if GAIA_UNLIKELY (m_pData ==
nullptr) {
269 m_cap = (
cap * 3 + 1) / 2;
274 mem::move_elements<T, true>(m_pData,
pDataOld, cnt, 0, m_cap,
cap);
279 darr_soa() noexcept = default;
300 template <
typename InputIt>
302 const auto count = (
size_type)core::distance(first, last);
305 if constexpr (std::is_pointer_v<InputIt>) {
307 operator[](
i) = first[
i];
308 }
else if constexpr (std::is_same_v<typename InputIt::iterator_category, core::random_access_iterator_tag>) {
310 operator[](
i) = *(first[
i]);
313 for (
auto it = first;
it != last; ++
it)
314 operator[](++
i) = *
it;
331 GAIA_ASSERT(m_pData ==
nullptr);
333 m_pData = other.m_pData;
339 other.m_pData =
nullptr;
354 GAIA_ASSERT(core::addressof(other) !=
this);
357 mem::copy_elements<T, true>(
367 GAIA_ASSERT(core::addressof(other) !=
this);
372 m_pData = other.m_pData;
376 other.m_pData =
nullptr;
387 GAIA_CLANG_WARNING_PUSH()
389 GAIA_CLANG_WARNING_DISABLE("-Wcast-align")
394 return reinterpret_cast<pointer>(m_pData);
414 GAIA_NODISCARD
decltype(
auto)
operator[](
size_type pos)
const noexcept {
419 GAIA_CLANG_WARNING_POP()
432 mem::move_elements<T, true>(m_pData,
pDataOld, m_cnt, 0,
cap, m_cap);
446 if (m_pData ==
nullptr) {
465 if (count <= m_cap) {
476 mem::move_elements<T, true>(m_pData,
pDataOld, m_cnt, 0, count, m_cap);
491 if constexpr (std::is_copy_constructible_v<value_type>) {
497 operator[](
i) = value;
522 template <
typename...
Args>
532 GAIA_ASSERT(!
empty());
552 mem::shift_elements_right<T, true>(m_pData,
idxDst,
idxSrc, m_cap);
574 mem::shift_elements_right<T, true>(m_pData,
idxDst,
idxSrc, m_cap);
596 mem::shift_elements_left<T, true>(m_pData,
idxDst,
idxSrc, m_cap);
609 GAIA_ASSERT(first >=
data())
611 GAIA_ASSERT(last > first);
619 const auto cnt = (
size_type)(last - first);
621 mem::shift_elements_left_fast<T, true>(m_pData,
idxDst,
idxSrc, cnt, m_cap);
637 const auto cnt =
size();
645 mem::move_elements<T, true>(m_pData,
pDataOld, cnt, 0);
653 template <
typename Func>
660 if (func(
operator[](
idxSrc))) {
662 mem::move_element<T, true>(m_pData, m_pData,
idxDst,
idxSrc, m_cap, m_cap);
664 core::call_dtor(ptr);
669 core::call_dtor(ptr);
709 GAIA_ASSERT(!
empty());
716 GAIA_ASSERT(!
empty());
723 GAIA_ASSERT(!
empty());
730 GAIA_ASSERT(!
empty());
810 if (m_cnt != other.m_cnt)
814 if (!(
operator[](
i) == other[
i]))
829 template <
size_t Item>
838 template <
size_t Item>
841 std::span<const uint8_t>{GAIA_ACC((
const uint8_t*)m_pData),
capacity()});
Array with variable size of elements of type.
Definition darray_soa_impl.h:220
iterator insert(iterator pos, T &&arg)
Insert the element to the position given by iterator pos.
Definition darray_soa_impl.h:565
auto view_mut() noexcept
Returns a mutable view of one structure-of-arrays member.
Definition darray_soa_impl.h:830
GAIA_NODISCARD const_pointer data() const noexcept
Returns a pointer to the element storage.
Definition darray_soa_impl.h:399
GAIA_NODISCARD bool empty() const noexcept
Checks whether the container has no elements.
Definition darray_soa_impl.h:690
void reserve(size_type cap)
Ensures storage for at least the requested number of elements.
Definition darray_soa_impl.h:423
void push_back(T &&arg)
Appends an element.
Definition darray_soa_impl.h:511
decltype(auto) emplace_back(Args &&... args)
Constructs and appends an element.
Definition darray_soa_impl.h:523
auto view() const noexcept
Returns a read-only view of one structure-of-arrays member.
Definition darray_soa_impl.h:839
GAIA_NODISCARD auto rbegin() const noexcept
Returns a reverse traversal iterator to the last element.
Definition darray_soa_impl.h:760
darr_soa(const darr_soa &other)
Copy-constructs a container.
Definition darray_soa_impl.h:324
GAIA_NODISCARD auto crbegin() const noexcept
Returns a read-only reverse traversal iterator to the last element.
Definition darray_soa_impl.h:766
GAIA_NODISCARD auto rend() const noexcept
Returns the reverse traversal sentinel preceding the first element.
Definition darray_soa_impl.h:796
void clear() noexcept
Removes all elements.
Definition darray_soa_impl.h:630
GAIA_NODISCARD bool operator==(const darr_soa &other) const noexcept
Compares two containers element by element.
Definition darray_soa_impl.h:809
GAIA_NODISCARD auto cend() const noexcept
Returns a read-only iterator one past the last element.
Definition darray_soa_impl.h:784
const_darr_soa_iterator< T > const_iterator
Read-only random-access iterator type.
Definition darray_soa_impl.h:244
darr_soa_detail::size_type size_type
Unsigned type used for sizes and indices.
Definition darray_soa_impl.h:239
darr_soa_detail::difference_type difference_type
Type used for iterator differences.
Definition darray_soa_impl.h:237
auto retain(Func &&func) noexcept
Removes all elements that fail the predicate.
Definition darray_soa_impl.h:654
GAIA_NODISCARD decltype(auto) operator[](size_type pos) noexcept
Accesses an element without bounds checking in optimized builds.
Definition darray_soa_impl.h:406
void resize(size_type count, const_reference value)
Changes the size and initializes new elements from a value.
Definition darray_soa_impl.h:487
darr_soa & operator=(darr_soa &&other) noexcept
Move-assigns the container.
Definition darray_soa_impl.h:366
void resize(size_type count)
Changes the number of elements.
Definition darray_soa_impl.h:441
GAIA_NODISCARD size_type capacity() const noexcept
Returns the number of elements that fit without reallocation.
Definition darray_soa_impl.h:696
GAIA_NODISCARD auto end() const noexcept
Returns an iterator one past the last element.
Definition darray_soa_impl.h:778
iterator erase(iterator first, iterator last) noexcept
Removes the elements in the range [first, last)
Definition darray_soa_impl.h:608
GAIA_NODISCARD decltype(auto) front() const noexcept
Accesses the first element.
Definition darray_soa_impl.h:715
GAIA_NODISCARD auto cbegin() const noexcept
Returns a read-only iterator to the first element.
Definition darray_soa_impl.h:748
darr_soa(size_type count, const_reference value)
Constructs a container with copies of a value.
Definition darray_soa_impl.h:286
GAIA_NODISCARD decltype(auto) back() const noexcept
Accesses the last element.
Definition darray_soa_impl.h:729
GAIA_NODISCARD constexpr bool operator!=(const darr_soa &other) const noexcept
Checks whether two containers differ.
Definition darray_soa_impl.h:822
GAIA_NODISCARD decltype(auto) front() noexcept
Accesses the first element.
Definition darray_soa_impl.h:708
darr_soa(size_type count)
Constructs a container with the requested number of value-initialized elements.
Definition darray_soa_impl.h:292
void push_back(const T &arg)
Appends an element.
Definition darray_soa_impl.h:503
iterator erase(iterator pos) noexcept
Removes the element at pos.
Definition darray_soa_impl.h:586
darr_soa_iterator< T > iterator
Mutable random-access iterator type.
Definition darray_soa_impl.h:242
GAIA_NODISCARD auto crend() const noexcept
Returns the read-only reverse traversal sentinel preceding the first element.
Definition darray_soa_impl.h:802
darr_soa(darr_soa &&other) noexcept
Move-constructs a container.
Definition darray_soa_impl.h:328
GAIA_NODISCARD decltype(auto) back() noexcept
Accesses the last element.
Definition darray_soa_impl.h:722
GAIA_NODISCARD auto rend() noexcept
Returns the reverse traversal sentinel preceding the first element.
Definition darray_soa_impl.h:790
darr_soa & operator=(const darr_soa &other)
Copy-assigns the container.
Definition darray_soa_impl.h:353
void shrink_to_fit()
Reduces allocated storage to match the current size when possible.
Definition darray_soa_impl.h:635
GAIA_NODISCARD size_type max_size() const noexcept
Returns the maximum number of elements supported by this container.
Definition darray_soa_impl.h:702
GAIA_NODISCARD auto rbegin() noexcept
Returns a reverse traversal iterator to the last element.
Definition darray_soa_impl.h:754
GAIA_NODISCARD size_type size() const noexcept
Returns the number of elements.
Definition darray_soa_impl.h:684
darr_soa(std::initializer_list< T > il)
Constructs a container from an initializer list.
Definition darray_soa_impl.h:320
GAIA_NODISCARD auto begin() const noexcept
Returns an iterator to the first element.
Definition darray_soa_impl.h:742
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first element.
Definition darray_soa_impl.h:736
GAIA_NODISCARD auto end() noexcept
Returns an iterator one past the last element.
Definition darray_soa_impl.h:772
darr_soa(InputIt first, InputIt last)
Constructs a container from an iterator range.
Definition darray_soa_impl.h:301
iterator insert(iterator pos, const T &arg)
Insert the element to the position given by iterator pos.
Definition darray_soa_impl.h:543
void pop_back() noexcept
Removes the last element.
Definition darray_soa_impl.h:531
darr_soa & operator=(std::initializer_list< T > il)
Replaces the elements from an initializer list.
Definition darray_soa_impl.h:345
GAIA_NODISCARD pointer data() noexcept
Returns a pointer to the element storage.
Definition darray_soa_impl.h:393
Array with variable size of elements of type.
Definition darray_impl.h:27
darr_detail::size_type size_type
Unsigned type used for sizes and indices.
Definition darray_impl.h:44
GAIA_NODISCARD decltype(auto) operator[](size_type pos) noexcept
Accesses an element without bounds checking in optimized builds.
Definition darray_impl.h:206
core::random_access_iterator_tag iterator_category
Iterator category exposed by the container.
Definition darray_impl.h:51
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first element.
Definition darray_impl.h:556
GAIA_NODISCARD bool operator==(const darr &other) const noexcept
Compares two containers element by element.
Definition darray_impl.h:629
T value_type
Element type stored by the container.
Definition darray_impl.h:30
pointer iterator
Mutable random-access iterator type.
Definition darray_impl.h:47
darr_detail::difference_type difference_type
Type used for iterator differences.
Definition darray_impl.h:42
GAIA_NODISCARD constexpr bool operator!=(const darr &other) const noexcept
Checks whether two containers differ.
Definition darray_impl.h:642
GAIA_NODISCARD auto end() noexcept
Returns an iterator one past the last element.
Definition darray_impl.h:592
View policy for accessing and storing data in the SoA way. Good for SIMD processing.
Definition data_layout_policy.h:402
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:530
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:514
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:464
uint8_t * TargetCastType
Pointer type used to address SoA storage.
Definition data_layout_policy.h:408
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:582
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:497
Storage policy for a selected layout and item type.
Definition data_layout_policy.h:123