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"
14#include "gaia/mem/raw_data_holder.h"
19 namespace darr_ext_detail {
29 template <
typename T, darr_ext_detail::
size_type N,
typename Allocator = mem::DefaultAllocatorAdaptor>
67 mem::raw_data_holder<T, allocated_bytes> m_data;
78 const auto cnt =
size();
82 if GAIA_LIKELY (cnt <
cap)
87 m_cap = (
cap * 3 + 1) / 2;
89 if GAIA_UNLIKELY (m_pDataHeap ==
nullptr) {
92 GAIA_MEM_SANI_ADD_BLOCK(
value_size, m_pDataHeap, m_cap, cnt);
93 mem::move_elements<T, false>(m_pDataHeap, m_data, cnt, 0, m_cap,
cap);
98 GAIA_MEM_SANI_ADD_BLOCK(
value_size, m_pDataHeap, m_cap, cnt);
99 mem::move_elements<T, false>(m_pDataHeap,
pDataOld, cnt, 0, m_cap,
cap);
103 m_pData = m_pDataHeap;
107 darr_ext() noexcept = default;
128 template <
typename InputIt>
130 const auto count = (
size_type)core::distance(first, last);
133 if constexpr (std::is_pointer_v<InputIt>) {
135 operator[](
i) = first[
i];
136 }
else if constexpr (std::is_same_v<typename InputIt::iterator_category, core::random_access_iterator_tag>) {
138 operator[](
i) = *(first[
i]);
141 for (
auto it = first;
it != last; ++
it)
142 operator[](++
i) = *
it;
157 GAIA_ASSERT(core::addressof(other) !=
this);
160 if (other.m_pDataHeap ==
nullptr) {
162 mem::move_elements<T, false>(m_data, other.m_data, other.size(), 0,
extent, other.extent);
164 m_pDataHeap =
nullptr;
167 m_pDataHeap = other.m_pDataHeap;
168 m_pData = m_pDataHeap;
174 other.m_pDataHeap =
nullptr;
175 other.m_pData = other.m_data;
192 GAIA_ASSERT(core::addressof(other) !=
this);
195 mem::copy_elements<T, false>(
205 GAIA_ASSERT(core::addressof(other) !=
this);
208 if (m_pDataHeap !=
nullptr)
214 if (other.m_pDataHeap ==
nullptr) {
216 mem::move_elements<T, false>(m_data, other.m_data, other.size(), 0,
extent, other.extent);
218 m_pDataHeap =
nullptr;
221 m_pDataHeap = other.m_pDataHeap;
222 m_pData = m_pDataHeap;
228 other.m_pDataHeap =
nullptr;
229 other.m_pData = other.m_data;
237 if (m_pDataHeap !=
nullptr)
243 GAIA_CLANG_WARNING_PUSH()
245 GAIA_CLANG_WARNING_DISABLE("-Wcast-align")
250 return reinterpret_cast<pointer>(m_pData);
270 GAIA_NODISCARD
decltype(
auto)
operator[](
size_type pos)
const noexcept {
275 GAIA_CLANG_WARNING_POP()
285 GAIA_MEM_SANI_ADD_BLOCK(
value_size, m_pDataHeap,
cap, m_cnt);
287 mem::move_elements<T, false>(m_pDataHeap,
pDataOld, m_cnt, 0,
cap, m_cap);
290 mem::move_elements<T, false>(m_pDataHeap, m_data, m_cnt, 0,
cap, m_cap);
291 GAIA_MEM_SANI_DEL_BLOCK(
value_size, m_data, m_cap, m_cnt);
295 m_pData = m_pDataHeap;
307 core::call_dtor_n(&
data()[count], m_cnt - count);
308 GAIA_MEM_SANI_POP_N(
value_size,
data(), m_cap, m_cnt, m_cnt - count);
315 if (count <= m_cap) {
317 GAIA_MEM_SANI_PUSH_N(
value_size,
data(), m_cap, m_cnt, count - m_cnt);
318 core::call_ctor_n(&
data()[m_cnt], count - m_cnt);
326 GAIA_MEM_SANI_ADD_BLOCK(
value_size, m_pDataHeap, count, count);
329 mem::move_elements<T, false>(m_pDataHeap,
pDataOld, m_cnt, 0, count, m_cap);
330 core::call_ctor_n(&
pDataNew[m_cnt], count - m_cnt);
333 mem::move_elements<T, false>(m_pDataHeap, m_data, m_cnt, 0, count, m_cap);
334 GAIA_MEM_SANI_DEL_BLOCK(
value_size, m_data, m_cap, m_cnt);
339 m_pData = m_pDataHeap;
349 if constexpr (std::is_copy_constructible_v<value_type>) {
355 operator[](
i) = value;
365 auto* ptr = &
data()[m_cnt++];
366 core::call_ctor(ptr,
arg);
375 auto* ptr = &
data()[m_cnt++];
376 core::call_ctor(ptr, GAIA_MOV(
arg));
383 template <
typename...
Args>
388 auto* ptr = &
data()[m_cnt++];
389 core::call_ctor(ptr, GAIA_FWD(
args)...);
395 GAIA_ASSERT(!
empty());
397 auto* ptr = &
data()[m_cnt - 1];
398 core::call_dtor(ptr);
417 mem::shift_elements_right<T, false>(m_pData,
idxDst,
idxSrc, m_cap);
419 core::call_ctor(ptr,
arg);
439 mem::shift_elements_right<T, false>(m_pData,
idxDst,
idxSrc, m_cap);
441 core::call_ctor(ptr, GAIA_MOV(
arg));
461 mem::shift_elements_left<T, false>(m_pData,
idxDst,
idxSrc, m_cap);
463 auto* ptr = &
data()[m_cnt - 1];
464 core::call_dtor(ptr);
477 GAIA_ASSERT(first >=
data())
479 GAIA_ASSERT(last > first);
487 const auto cnt = (
size_type)(last - first);
489 mem::shift_elements_left_fast<T, false>(m_pData,
idxDst,
idxSrc, cnt, m_cap);
491 core::call_dtor_n(&
data()[m_cnt - cnt], cnt);
507 const auto cnt =
size();
512 if (m_pDataHeap !=
nullptr) {
516 mem::move_elements<T, false>(m_data,
pDataOld, cnt, 0);
521 GAIA_MEM_SANI_ADD_BLOCK(
value_size, m_pDataHeap, m_cap, m_cnt);
522 mem::move_elements<T, false>(m_pDataHeap,
pDataOld, cnt, 0);
523 m_pData = m_pDataHeap;
536 template <
typename Func>
543 if (func(
operator[](
idxSrc))) {
546 mem::move_element<T, false>(ptr, ptr,
idxDst,
idxSrc, m_cap, m_cap);
548 core::call_dtor(
ptr2);
553 core::call_dtor(ptr);
593 GAIA_ASSERT(!
empty());
600 GAIA_ASSERT(!
empty());
607 GAIA_ASSERT(!
empty());
614 GAIA_ASSERT(!
empty());
694 if (m_cnt != other.m_cnt)
698 if (!(
operator[](
i) == other[
i]))
713 template <
typename T, uint32_t N, uint32_t... I>
714 darr_ext<std::remove_cv_t<T>, N> to_sarray_impl(T (&a)[N], std::index_sequence<I...> ) {
725 template <
typename T, u
int32_t N>
726 darr_ext<std::remove_cv_t<T>, N> to_sarray(T (&a)[N]) {
727 return detail::to_sarray_impl(a, std::make_index_sequence<N>{});
Array of elements of type.
Definition darray_ext_impl.h:30
void pop_back() noexcept
Removes the last element.
Definition darray_ext_impl.h:394
GAIA_NODISCARD auto end() const noexcept
Returns an iterator one past the last element.
Definition darray_ext_impl.h:662
void resize(size_type count, const_reference value)
Changes the size and initializes new elements from a value.
Definition darray_ext_impl.h:345
GAIA_NODISCARD size_type size() const noexcept
Returns the number of elements.
Definition darray_ext_impl.h:568
GAIA_NODISCARD decltype(auto) front() const noexcept
Accesses the first element.
Definition darray_ext_impl.h:599
darr_ext(darr_ext &&other) noexcept
Move-constructs a container.
Definition darray_ext_impl.h:156
darr_ext & operator=(darr_ext &&other) noexcept
Move-assigns the container.
Definition darray_ext_impl.h:204
darr_ext(size_type count)
Constructs a container with the requested number of value-initialized elements.
Definition darray_ext_impl.h:120
darr_ext & operator=(std::initializer_list< T > il)
Replaces the elements from an initializer list.
Definition darray_ext_impl.h:183
GAIA_NODISCARD size_type max_size() const noexcept
Returns the maximum number of elements supported by this container.
Definition darray_ext_impl.h:586
iterator insert(iterator pos, T &&arg)
Insert the element to the position given by iterator pos.
Definition darray_ext_impl.h:430
void shrink_to_fit()
Reduces allocated storage to match the current size when possible.
Definition darray_ext_impl.h:505
GAIA_NODISCARD auto rbegin() noexcept
Returns a reverse traversal iterator to the last element.
Definition darray_ext_impl.h:638
GAIA_NODISCARD auto rend() noexcept
Returns the reverse traversal sentinel preceding the first element.
Definition darray_ext_impl.h:674
GAIA_NODISCARD auto crbegin() const noexcept
Returns a read-only reverse traversal iterator to the last element.
Definition darray_ext_impl.h:650
const_pointer const_iterator
Read-only random-access iterator type.
Definition darray_ext_impl.h:54
pointer iterator
Mutable random-access iterator type.
Definition darray_ext_impl.h:52
iterator insert(iterator pos, const T &arg)
Insert the element to the position given by iterator pos.
Definition darray_ext_impl.h:408
GAIA_NODISCARD auto rend() const noexcept
Returns the reverse traversal sentinel preceding the first element.
Definition darray_ext_impl.h:680
darr_ext(size_type count, const_reference value)
Constructs a container with copies of a value.
Definition darray_ext_impl.h:114
GAIA_NODISCARD auto cbegin() const noexcept
Returns a read-only iterator to the first element.
Definition darray_ext_impl.h:632
GAIA_NODISCARD decltype(auto) front() noexcept
Accesses the first element.
Definition darray_ext_impl.h:592
void reserve(size_type cap)
Ensures storage for at least the requested number of elements.
Definition darray_ext_impl.h:279
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first element.
Definition darray_ext_impl.h:620
iterator erase(iterator first, iterator last) noexcept
Removes the elements in the range [first, last)
Definition darray_ext_impl.h:476
darr_ext(InputIt first, InputIt last)
Constructs a container from an iterator range.
Definition darray_ext_impl.h:129
GAIA_NODISCARD auto rbegin() const noexcept
Returns a reverse traversal iterator to the last element.
Definition darray_ext_impl.h:644
void push_back(const T &arg)
Appends an element.
Definition darray_ext_impl.h:361
GAIA_NODISCARD auto end() noexcept
Returns an iterator one past the last element.
Definition darray_ext_impl.h:656
GAIA_NODISCARD constexpr bool operator!=(const darr_ext &other) const noexcept
Checks whether two containers differ.
Definition darray_ext_impl.h:706
darr_ext_detail::size_type size_type
Unsigned type used for sizes and indices.
Definition darray_ext_impl.h:49
static constexpr size_t value_size
Size of one element in bytes.
Definition darray_ext_impl.h:59
darr_ext(std::initializer_list< T > il)
Constructs a container from an initializer list.
Definition darray_ext_impl.h:148
GAIA_NODISCARD auto cend() const noexcept
Returns a read-only iterator one past the last element.
Definition darray_ext_impl.h:668
GAIA_NODISCARD auto crend() const noexcept
Returns the read-only reverse traversal sentinel preceding the first element.
Definition darray_ext_impl.h:686
auto retain(Func &&func) noexcept
Removes all elements that fail the predicate.
Definition darray_ext_impl.h:537
T * pointer
Mutable element pointer type.
Definition darray_ext_impl.h:41
darr_ext(const darr_ext &other)
Copy-constructs a container.
Definition darray_ext_impl.h:152
void clear() noexcept
Removes all elements.
Definition darray_ext_impl.h:500
static constexpr size_type extent
Fixed capacity of the container.
Definition darray_ext_impl.h:61
darr_ext & operator=(const darr_ext &other)
Copy-assigns the container.
Definition darray_ext_impl.h:191
darr_ext_detail::difference_type difference_type
Type used for iterator differences.
Definition darray_ext_impl.h:47
GAIA_NODISCARD decltype(auto) back() noexcept
Accesses the last element.
Definition darray_ext_impl.h:606
GAIA_NODISCARD const_pointer data() const noexcept
Returns a pointer to the element storage.
Definition darray_ext_impl.h:255
GAIA_NODISCARD decltype(auto) operator[](size_type pos) noexcept
Accesses an element without bounds checking in optimized builds.
Definition darray_ext_impl.h:262
iterator erase(iterator pos) noexcept
Removes the element at pos.
Definition darray_ext_impl.h:451
decltype(auto) emplace_back(Args &&... args)
Constructs and appends an element.
Definition darray_ext_impl.h:384
GAIA_NODISCARD auto begin() const noexcept
Returns an iterator to the first element.
Definition darray_ext_impl.h:626
GAIA_NODISCARD decltype(auto) back() const noexcept
Accesses the last element.
Definition darray_ext_impl.h:613
const T * const_pointer
Read-only element pointer type.
Definition darray_ext_impl.h:43
void push_back(T &&arg)
Appends an element.
Definition darray_ext_impl.h:371
GAIA_NODISCARD bool operator==(const darr_ext &other) const noexcept
Compares two containers element by element.
Definition darray_ext_impl.h:693
GAIA_NODISCARD pointer data() noexcept
Returns a pointer to the element storage.
Definition darray_ext_impl.h:249
static constexpr uint32_t allocated_bytes
Number of bytes reserved by the inline storage.
Definition darray_ext_impl.h:63
void resize(size_type count)
Changes the number of elements.
Definition darray_ext_impl.h:300
GAIA_NODISCARD bool empty() const noexcept
Checks whether the container has no elements.
Definition darray_ext_impl.h:574
GAIA_NODISCARD size_type capacity() const noexcept
Returns the number of elements that fit without reallocation.
Definition darray_ext_impl.h:580
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 size_type size() const noexcept
Returns the number of elements.
Definition darray_impl.h:504
GAIA_NODISCARD auto begin() noexcept
Returns an iterator to the first element.
Definition darray_impl.h:556
darr_detail::difference_type difference_type
Type used for iterator differences.
Definition darray_impl.h:42
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 AoS way. Good for random access and when accessing ...
Definition data_layout_policy.h:162
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:175
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