33 using const_reference =
const T&;
35 using const_pointer =
const T*;
37 using difference_type = sarr_ext_detail::difference_type;
38 using size_type = sarr_ext_detail::size_type;
40 using iterator = pointer;
41 using const_iterator = const_pointer;
44 static constexpr size_t value_size =
sizeof(T);
45 static constexpr size_type extent = N;
46 static constexpr uint32_t allocated_bytes = view_policy::get_min_byte_size(0, N);
50 size_type m_cnt = size_type(0);
53 constexpr sarr_ext()
noexcept =
default;
57 core::call_dtor_n(data(), m_cnt);
60 constexpr sarr_ext(size_type count, const_reference value)
noexcept {
66 constexpr sarr_ext(size_type count)
noexcept {
70 template <
typename InputIt>
71 constexpr sarr_ext(InputIt first, InputIt last)
noexcept {
72 const auto count = (size_type)core::distance(first, last);
75 if constexpr (std::is_pointer_v<InputIt>) {
76 for (size_type i = 0; i < count; ++i)
77 operator[](i) = first[i];
78 }
else if constexpr (std::is_same_v<typename InputIt::iterator_category, core::random_access_iterator_tag>) {
79 for (size_type i = 0; i < count; ++i)
80 operator[](i) = *(first[i]);
83 for (
auto it = first; it != last; ++it)
84 operator[](++i) = *it;
88 constexpr sarr_ext(std::initializer_list<T> il):
sarr_ext(il.begin(), il.end()) {}
93 GAIA_ASSERT(core::addressof(other) !=
this);
95 core::call_ctor_raw_n(data(), extent);
96 mem::move_elements<T, false>(m_data, other.m_data, other.size(), 0, extent, other.extent);
98 other.m_cnt = size_type(0);
101 sarr_ext& operator=(std::initializer_list<T> il) {
102 *
this =
sarr_ext(il.begin(), il.end());
107 GAIA_ASSERT(core::addressof(other) !=
this);
109 resize(other.size());
110 mem::copy_elements<T, false>(
111 GAIA_ACC((uint8_t*)&m_data[0]), GAIA_ACC((
const uint8_t*)&other.m_data[0]), other.size(), 0, extent,
118 GAIA_ASSERT(core::addressof(other) !=
this);
121 mem::move_elements<T, false>(
122 GAIA_ACC((uint8_t*)&m_data[0]), GAIA_ACC((uint8_t*)&other.m_data[0]), other.size(), 0, extent,
125 other.m_cnt = size_type(0);
130 GAIA_CLANG_WARNING_PUSH()
132 GAIA_CLANG_WARNING_DISABLE(
"-Wcast-align")
134 GAIA_NODISCARD
constexpr pointer data()
noexcept {
135 return GAIA_ACC((pointer)&m_data[0]);
138 GAIA_NODISCARD
constexpr const_pointer data()
const noexcept {
139 return GAIA_ACC((const_pointer)&m_data[0]);
142 GAIA_NODISCARD
constexpr decltype(
auto)
operator[](size_type pos)
noexcept {
143 GAIA_ASSERT(pos < size());
144 return view_policy::set({GAIA_ACC((
typename view_policy::TargetCastType) & m_data[0]), extent}, pos);
147 GAIA_NODISCARD
constexpr decltype(
auto)
operator[](size_type pos)
const noexcept {
148 GAIA_ASSERT(pos < size());
149 return view_policy::get({GAIA_ACC((
typename view_policy::TargetCastType) & m_data[0]), extent}, pos);
152 GAIA_CLANG_WARNING_POP()
154 constexpr void push_back(
const T& arg)
noexcept {
155 GAIA_ASSERT(size() < N);
157 auto* ptr = &data()[m_cnt++];
158 core::call_ctor(ptr, arg);
161 constexpr void push_back(T&& arg)
noexcept {
162 GAIA_ASSERT(size() < N);
164 auto* ptr = &data()[m_cnt++];
165 core::call_ctor(ptr, GAIA_MOV(arg));
168 template <
typename... Args>
169 constexpr decltype(
auto) emplace_back(Args&&... args)
noexcept {
170 GAIA_ASSERT(size() < N);
172 auto* ptr = &data()[m_cnt++];
173 core::call_ctor(ptr, GAIA_FWD(args)...);
174 return (reference)*ptr;
177 constexpr void pop_back()
noexcept {
178 GAIA_ASSERT(!empty());
180 auto* ptr = &data()[m_cnt];
181 core::call_dtor(ptr);
189 iterator
insert(iterator pos,
const T& arg)
noexcept {
190 GAIA_ASSERT(size() < N);
191 GAIA_ASSERT(pos >= data());
192 GAIA_ASSERT(empty() || (pos < iterator(data() + size())));
194 const auto idxSrc = (size_type)core::distance(begin(), pos);
195 const auto idxDst = (size_type)core::distance(begin(), end());
197 mem::shift_elements_right<T, false>(m_data, idxDst, idxSrc, extent);
199 auto* ptr = &data()[idxSrc];
200 core::call_ctor(ptr, arg);
204 return iterator(&data()[idxSrc]);
210 iterator
insert(iterator pos, T&& arg)
noexcept {
211 GAIA_ASSERT(size() < N);
212 GAIA_ASSERT(pos >= data());
213 GAIA_ASSERT(empty() || (pos < iterator(data() + size())));
215 const auto idxSrc = (size_type)core::distance(begin(), pos);
216 const auto idxDst = (size_type)core::distance(begin(), end());
218 mem::shift_elements_right<T, false>(m_data, idxDst, idxSrc, extent);
220 auto* ptr = &data()[idxSrc];
221 core::call_ctor(ptr, GAIA_MOV(arg));
225 return iterator(&data()[idxSrc]);
230 constexpr iterator
erase(iterator pos)
noexcept {
231 GAIA_ASSERT(pos >= data());
232 GAIA_ASSERT(empty() || (pos < iterator(data() + size())));
237 const auto idxSrc = (size_type)core::distance(begin(), pos);
238 const auto idxDst = (size_type)core::distance(begin(), end()) - 1;
240 mem::shift_elements_left<T, false>(m_data, idxDst, idxSrc, extent);
242 auto* ptr = &data()[m_cnt - 1];
243 core::call_dtor(ptr);
247 return iterator(&data()[idxSrc]);
253 iterator
erase(iterator first, iterator last)
noexcept {
254 GAIA_ASSERT(first >= data())
255 GAIA_ASSERT(empty() || (first < iterator(data() + size())));
256 GAIA_ASSERT(last > first);
257 GAIA_ASSERT(last <= (data() + size()));
262 const auto idxSrc = (size_type)core::distance(begin(), first);
263 const auto idxDst = size();
264 const auto cnt = (size_type)(last - first);
266 mem::shift_elements_left_fast<T, false>(m_data, idxDst, idxSrc, cnt, extent);
268 core::call_dtor_n(&data()[m_cnt - cnt], cnt);
272 return iterator(&data()[idxSrc]);
277 GAIA_ASSERT(pos < size());
279 const auto idxSrc = pos;
280 const auto idxDst = (size_type)core::distance(begin(), end()) - 1;
282 mem::shift_elements_left<T, false>(m_data, idxDst, idxSrc, extent);
284 auto* ptr = &data()[m_cnt - 1];
285 core::call_dtor(ptr);
289 return iterator(&data()[idxSrc]);
292 constexpr void clear() noexcept {
296 constexpr void resize(size_type count)
noexcept {
297 GAIA_ASSERT(count <= max_size());
300 if (count <= m_cnt) {
302 core::call_dtor_n(&data()[count], size() - count);
307 core::call_ctor_n(&data()[size()], count - size());
316 template <
typename Func>
318 size_type erased = 0;
319 size_type idxDst = 0;
320 size_type idxSrc = 0;
322 while (idxSrc < m_cnt) {
323 if (func(
operator[](idxSrc))) {
324 if (idxDst < idxSrc) {
325 auto* ptr = (uint8_t*)data();
326 mem::move_element<T, false>(ptr, ptr, idxDst, idxSrc, max_size(), max_size());
327 auto* ptr2 = &data()[idxSrc];
328 core::call_dtor(ptr2);
332 auto* ptr = &data()[idxSrc];
333 core::call_dtor(ptr);
344 GAIA_NODISCARD
constexpr size_type size() const noexcept {
348 GAIA_NODISCARD
constexpr bool empty() const noexcept {
352 GAIA_NODISCARD
constexpr size_type capacity() const noexcept {
356 GAIA_NODISCARD
constexpr size_type max_size() const noexcept {
360 GAIA_NODISCARD
constexpr decltype(
auto) front() noexcept {
361 GAIA_ASSERT(!empty());
362 return (reference)*begin();
365 GAIA_NODISCARD
constexpr decltype(
auto) front() const noexcept {
366 GAIA_ASSERT(!empty());
367 return (const_reference)*begin();
370 GAIA_NODISCARD
constexpr decltype(
auto) back() noexcept {
371 GAIA_ASSERT(!empty());
372 return (reference) operator[](m_cnt - 1);
375 GAIA_NODISCARD
constexpr decltype(
auto) back() const noexcept {
376 GAIA_ASSERT(!empty());
377 return (const_reference) operator[](m_cnt - 1);
380 GAIA_NODISCARD
constexpr auto begin() noexcept {
381 return iterator(data());
384 GAIA_NODISCARD
constexpr auto begin() const noexcept {
385 return const_iterator(data());
388 GAIA_NODISCARD
constexpr auto cbegin() const noexcept {
389 return const_iterator(data());
392 GAIA_NODISCARD
constexpr auto rbegin() noexcept {
393 return iterator((pointer)&back());
396 GAIA_NODISCARD
constexpr auto rbegin() const noexcept {
397 return const_iterator((pointer)&back());
400 GAIA_NODISCARD
constexpr auto crbegin() const noexcept {
401 return const_iterator((pointer)&back());
404 GAIA_NODISCARD
constexpr auto end() noexcept {
405 return iterator(GAIA_ACC((pointer)&m_data[0]) + size());
408 GAIA_NODISCARD
constexpr auto end() const noexcept {
409 return const_iterator(GAIA_ACC((const_pointer)&m_data[0]) + size());
412 GAIA_NODISCARD
constexpr auto cend() const noexcept {
413 return const_iterator(GAIA_ACC((const_pointer)&m_data[0]) + size());
416 GAIA_NODISCARD
constexpr auto rend() noexcept {
417 return iterator(GAIA_ACC((pointer)&m_data[0]) - 1);
420 GAIA_NODISCARD
constexpr auto rend() const noexcept {
421 return const_iterator(GAIA_ACC((const_pointer)&m_data[0]) - 1);
424 GAIA_NODISCARD
constexpr auto crend() const noexcept {
425 return const_iterator(GAIA_ACC((const_pointer)&m_data[0]) - 1);
428 GAIA_NODISCARD
constexpr bool operator==(
const sarr_ext& other)
const noexcept {
429 if (m_cnt != other.m_cnt)
431 const size_type n = size();
432 for (size_type i = 0; i < n; ++i)
433 if (!(
operator[](i) == other[i]))
438 GAIA_NODISCARD
constexpr bool operator!=(
const sarr_ext& other)
const noexcept {
439 return !operator==(other);