36 using self = ASmallVector;
42 using iterator = StoredType*;
43 using const_iterator =
const StoredType*;
44 using reference = StoredType&;
45 using const_reference =
const StoredType&;
46 using value = StoredType;
48 ASmallVector()
noexcept {
49 new (&mBase.inplace) StaticVector();
52 ASmallVector(ASmallVector&& rhs)
noexcept {
53 if (rhs.isInplaceAllocated()) {
54 new (&mBase.inplace) StaticVector(*rhs.inplace());
56 new (&mBase.dynamic) DynamicVector(*rhs.dynamic());
59 new (&rhs.mBase.inplace) StaticVector();
62 ~ASmallVector()
noexcept {
67 constexpr StoredType* data()
noexcept {
68 return reinterpret_cast<StoredType*
>(mBase.common.begin);
71 constexpr const StoredType* data()
const noexcept {
72 return reinterpret_cast<const StoredType*
>(mBase.common.begin);
76 constexpr iterator begin()
noexcept {
77 return mBase.common.begin;
80 constexpr const_iterator begin()
const noexcept {
81 return mBase.common.begin;
85 constexpr iterator end()
noexcept {
86 return mBase.common.end;
90 constexpr const_iterator end()
const noexcept {
91 return mBase.common.end;
95 constexpr StoredType& front()
noexcept {
100 constexpr StoredType& back()
noexcept {
101 return *(begin() + (
size() - 1));
105 constexpr const StoredType& front()
const noexcept {
110 constexpr const StoredType& back()
const noexcept {
111 return *(begin() + (
size() - 1));
114 constexpr void push_back(StoredType value)
noexcept {
115 insert(end(), std::move(value));
118 constexpr void push_front(StoredType value)
noexcept {
119 insert(begin(), std::move(value));
122 constexpr void pop_back()
noexcept {
124 erase(std::prev(end()));
126 constexpr void pop_front()
noexcept {
132 constexpr StoredType& operator[](std::size_t index)
noexcept {
134 return *(data() + index);
138 constexpr StoredType& operator[](std::size_t index)
const noexcept {
139 return const_cast<ASmallVector*
>(
this)->
operator[](index);
143 constexpr bool empty()
const noexcept {
144 return begin() == end();
147 constexpr void clear()
noexcept {
149 new (&mBase.inplace) StaticVector();
156 std::size_t
size() const noexcept {
157 return std::distance(begin(), end());
162 bool isInplaceAllocated() const noexcept {
163 return size() <= StaticVectorSize;
167 template<
typename OtherIterator>
168 constexpr iterator insert(iterator at, OtherIterator begin, OtherIterator end) {
169 AUI_ASSERT_MY_ITERATOR(at);
170 auto distance = std::distance(begin, end);
172 if (distance +
size() <= StaticVectorSize) {
173 return inplace()->insert(at, begin, end);
175 if (!isInplaceAllocated()) {
176 return dynamic()->insert(at, begin, end);
181 temp.reserve(aui::bit_ceil(distance +
size()));
183 aui::container::vector_impl::insert_no_growth(temp.mEnd, temp.mEnd,
184 std::make_move_iterator(this->begin()), std::make_move_iterator(at));
186 auto result = aui::container::vector_impl::insert_no_growth(temp.mEnd, temp.mEnd,
189 aui::container::vector_impl::insert_no_growth(temp.mEnd, temp.mEnd,
190 std::make_move_iterator(at), std::make_move_iterator(this->end()));
192 inplace()->~StaticVector();
193 new (&mBase.dynamic) DynamicVector(std::move(temp));
198 constexpr iterator erase(iterator begin, iterator end)
noexcept {
199 AUI_ASSERT_MY_ITERATOR(begin);
200 AUI_ASSERT_MY_ITERATOR(end);
202 if (isInplaceAllocated()) {
203 return inplace()->erase(begin, end);
206 if (
size() - std::distance(begin, end) > StaticVectorSize) {
207 return dynamic()->erase(begin, end);
210 auto index = std::distance(this->begin(), begin);
213 auto temp = std::move(*dynamic());
214 temp.erase(begin, end);
215 new (inplace()) StaticVector();
216 inplace()->insert(inplace()->end(), std::make_move_iterator(temp.begin()), std::make_move_iterator(temp.end()));
217 return this->begin() + index;
220 constexpr iterator insert(iterator at, StoredType value) {
221 AUI_ASSERT_MY_ITERATOR(at);
222 return insert(at, std::make_move_iterator(&value), std::make_move_iterator(&value + 1));
225 constexpr iterator erase(iterator at) {
226 return erase(at, std::next(at));
239 template<
typename OtherContainer>
251 template<
typename OtherContainer>
253 return insertAll(super::end(), std::forward<OtherContainer>(c));
264 template<
typename OtherContainer>
265 iterator
insertAll(iterator at,
const OtherContainer& c)
noexcept {
266 return super::insert(at, c.begin(), c.end());
277 template<
typename OtherContainer>
278 iterator
insertAll(iterator at, OtherContainer&& c)
noexcept {
279 return super::insert(at, std::make_move_iterator(c.begin()), std::make_move_iterator(c.end()));
298 template<
typename T, aui::mapper<const StoredType&, const T&> Projection>
299 void removeAll(
const T& item, Projection projection)
noexcept
317 template<
typename OtherContainer>
326 bool contains(
const StoredType& value)
const noexcept {
331 std::size_t sizeInBytes() const noexcept {
336 StoredType& at(std::size_t index) {
338 aui::impl::outOfBoundsException();
340 return super::operator[](index);
344 const StoredType& at(std::size_t index)
const {
346 aui::impl::outOfBoundsException();
348 return super::operator[](index);
359 super::push_back(rhs);
370 super::push_back(std::forward<StoredType>(rhs));
379 template<
typename OtherContainer, std::enable_if_t<!std::is_convertible_v<OtherContainer, StoredType>,
bool> = true>
391 template<
typename OtherContainer, std::enable_if_t<!std::is_convertible_v<OtherContainer, StoredType>,
bool> = true>
394 insertAll(std::forward<OtherContainer>(c));
408 AUI_ASSERTX(!super::empty(),
"empty container could not have the first element");
409 return super::front();
419 const StoredType&
first() const noexcept
421 AUI_ASSERTX(!super::empty(),
"empty container could not have the first element");
422 return super::front();
434 AUI_ASSERTX(!super::empty(),
"empty container could not have the last element");
435 return super::back();
445 const StoredType&
last() const noexcept
447 AUI_ASSERTX(!super::empty(),
"empty container could not have the last element");
448 return super::back();
462 void sort() noexcept {
463 std::sort(super::begin(), super::end());
466 template<
typename Comparator>
467 void sort(Comparator&& comparator)
noexcept {
468 std::sort(super::begin(), super::end(), std::forward<Comparator>(comparator));
476 template<aui::predicate<StoredType> Predicate>
477 StoredType*
findIf(Predicate&& predicate)
noexcept
479 if (
auto i = std::find_if(super::begin(), super::end(), std::forward<Predicate>(predicate)); i != super::end()) {
492 template<
typename T, aui::mapper<const StoredType&, const T&> Projection>
493 StoredType*
findIf(
const T& value, Projection&& projection)
noexcept
495 if (
auto i = std::find_if(super::begin(),
497 [&](
const StoredType& s) {
return value == std::invoke(projection, s); }
498 ); i != super::end()) {
521 template<
typename Predicate>
524 super::erase(std::remove_if(super::begin(), super::end(), std::forward<Predicate>(predicate)), super::end());
537 template<aui::incrementable Iterator, aui::invocable<decltype(*std::declval<Iterator>())> UnaryOperation>
539 AVector<
decltype(transformer(range.first()))> result;
540 result.reserve(range.size());
541 std::transform(range.begin(), range.end(), std::back_inserter(result), std::forward<UnaryOperation>(transformer));
545 template<aui::invocable<const StoredType&> UnaryOperation>
549 std::transform(super::begin(), super::end(), std::back_inserter(result), std::forward<UnaryOperation>(transformer));
553 template<aui::invocable<const StoredType&> UnaryOperation>
555 auto toMap(UnaryOperation&& transformer)
const -> AMap<decltype(transformer(std::declval<StoredType>()).
first),
556 decltype(transformer(std::declval<StoredType>()).second)> {
560 template<aui::invocable<StoredType&> UnaryOperation>
562 auto toMap(UnaryOperation&& transformer) -> AMap<decltype(transformer(std::declval<StoredType>()).
first),
563 decltype(transformer(std::declval<StoredType>()).second)> {
567 template<aui::predicate<const StoredType&> Predicate>
568 self filter(Predicate&& predicate) {
570 for (
const auto& element : *
this) {
571 if (predicate(element)) {
572 result.push_back(element);
586 std::aligned_storage_t<
sizeof(StaticVector),
alignof(StaticVector)> inplace;
587 std::aligned_storage_t<
sizeof(DynamicVector),
alignof(DynamicVector)> dynamic;
591 StaticVector* inplace() {
593 return reinterpret_cast<StaticVector*
>(&mBase.inplace);
596 DynamicVector * dynamic() {
598 return reinterpret_cast<DynamicVector*
>(&mBase.dynamic);
602 if (isInplaceAllocated()) {
603 inplace()->~StaticVector();
605 dynamic()->~DynamicVector();