37 using self = ADynamicVector;
38 using super = ADynamicVector;
39 using iterator = StoredType*;
40 using const_iterator =
const StoredType*;
41 using reference = StoredType&;
42 using const_reference =
const StoredType&;
43 using value = StoredType;
45 constexpr ADynamicVector()
noexcept {}
46 constexpr ADynamicVector(
const ADynamicVector& rhs): ADynamicVector() {
47 insert(mBegin, rhs.begin(), rhs.end());
49 constexpr ADynamicVector(ADynamicVector&& rhs)
noexcept: ADynamicVector() {
50 operator=(std::move(rhs));
52 constexpr ~ADynamicVector() {
57 constexpr StoredType* data()
noexcept {
61 constexpr const StoredType* data()
const noexcept {
66 constexpr iterator begin()
noexcept {
70 constexpr const_iterator begin()
const noexcept {
75 constexpr iterator end()
noexcept {
80 constexpr const_iterator end()
const noexcept {
85 constexpr StoredType& front()
noexcept {
90 constexpr StoredType& back()
noexcept {
91 return *std::prev(end());
95 constexpr const StoredType& front()
const noexcept {
100 constexpr const StoredType& back()
const noexcept {
101 return *std::prev(end());
104 constexpr void push_back(StoredType value)
noexcept {
105 insert(end(), std::move(value));
108 constexpr void push_front(StoredType value)
noexcept {
109 insert(begin(), std::move(value));
112 constexpr void pop_back()
noexcept {
113 AUI_ASSERTX(size() > 0,
"ADynamicVector is empty");
114 erase(std::prev(end()));
116 constexpr void pop_front()
noexcept {
117 AUI_ASSERTX(size() > 0,
"ADynamicVector is empty");
122 constexpr StoredType& operator[](std::size_t index)
noexcept {
124 return *(data() + index);
128 constexpr StoredType& operator[](std::size_t index)
const noexcept {
129 return const_cast<ADynamicVector*
>(
this)->
operator[](index);
133 constexpr bool empty()
const noexcept {
134 return begin() == end();
137 constexpr void clear()
noexcept {
139 mBegin = mEnd = mBufferEnd =
nullptr;
143 for (
auto& v : *
this) {
146 operator delete[](mBegin);
150 constexpr std::size_t size()
const noexcept {
151 return mEnd - mBegin;
155 constexpr std::size_t reserved()
const noexcept {
156 return mBufferEnd - mBegin;
159 template<
typename OtherIterator>
160 constexpr iterator insert(iterator at, OtherIterator begin, OtherIterator end) {
161 AUI_ASSERT_MY_ITERATOR(at);
162 auto distance = std::distance(begin, end);
164 if (size() + distance <= reserved()) {
165 return aui::container::vector_impl::insert_no_growth(mEnd, at, begin, end);
168 temp.reserve(aui::bit_ceil(distance + size()));
169 aui::container::vector_impl::insert_no_growth(temp.mEnd, temp.mEnd,
170 std::make_move_iterator(mBegin), std::make_move_iterator(at));
172 auto result = aui::container::vector_impl::insert_no_growth(temp.mEnd, temp.mEnd,
175 aui::container::vector_impl::insert_no_growth(temp.mEnd, temp.mEnd,
176 std::make_move_iterator(at), std::make_move_iterator(mEnd));
177 operator=(std::move(temp));
183 constexpr iterator insert(iterator at, StoredType value) {
184 AUI_ASSERT_MY_ITERATOR(at);
185 return insert(at, std::make_move_iterator(&value), std::make_move_iterator(&value + 1));
188 constexpr iterator erase(iterator at) {
189 return erase(at, std::next(at));
192 constexpr iterator erase(iterator begin, iterator end) {
193 AUI_ASSERT_MY_ITERATOR(begin);
194 AUI_ASSERT_MY_ITERATOR(end);
196 return aui::container::vector_impl::erase(mBegin, mEnd, begin, end);
199 void reserve(std::size_t newSize) {
200 if (reserved() == newSize) {
204 auto newBuffer =
static_cast<StoredType*
>(
operator new[](newSize *
sizeof(StoredType)));
205 auto newBufferEnd = newBuffer;
207 auto elementsToMove = std::min(newSize, size());
208 auto moveFrom = begin();
209 for (std::size_t i = 0; i < elementsToMove; ++newBufferEnd, ++moveFrom) {
210 new (newBufferEnd) StoredType(std::move(*moveFrom));
215 mBufferEnd = newBuffer + newSize;
222 ADynamicVector& operator=(ADynamicVector&& rhs)
noexcept {
226 mBufferEnd = rhs.mBufferEnd;
228 rhs.mBegin =
nullptr;
230 rhs.mBufferEnd =
nullptr;
244 template<
typename OtherContainer>
256 template<
typename OtherContainer>
258 return insertAll(super::end(), std::forward<OtherContainer>(c));
269 template<
typename OtherContainer>
270 iterator
insertAll(iterator at,
const OtherContainer& c)
noexcept {
271 return super::insert(at, c.begin(), c.end());
282 template<
typename OtherContainer>
283 iterator
insertAll(iterator at, OtherContainer&& c)
noexcept {
284 return super::insert(at, std::make_move_iterator(c.begin()), std::make_move_iterator(c.end()));
310 template<
typename OtherContainer>
319 bool contains(
const StoredType& value)
const noexcept {
324 std::size_t sizeInBytes() const noexcept {
325 return super::size() *
sizeof(StoredType);
329 StoredType& at(std::size_t index) {
330 if (index >= super::size()) {
331 aui::impl::outOfBoundsException();
333 return super::operator[](index);
337 const StoredType& at(std::size_t index)
const {
338 if (index >= super::size()) {
339 aui::impl::outOfBoundsException();
341 return super::operator[](index);
352 super::push_back(rhs);
363 super::push_back(std::forward<StoredType>(rhs));
372 template<
typename OtherContainer, std::enable_if_t<!std::is_convertible_v<OtherContainer, StoredType>,
bool> = true>
384 template<
typename OtherContainer, std::enable_if_t<!std::is_convertible_v<OtherContainer, StoredType>,
bool> = true>
387 insertAll(std::forward<OtherContainer>(c));
401 AUI_ASSERTX(!super::empty(),
"empty container could not have the first element");
402 return super::front();
412 const StoredType&
first() const noexcept
414 AUI_ASSERTX(!super::empty(),
"empty container could not have the first element");
415 return super::front();
427 AUI_ASSERTX(!super::empty(),
"empty container could not have the last element");
428 return super::back();
438 const StoredType&
last() const noexcept
440 AUI_ASSERTX(!super::empty(),
"empty container could not have the last element");
441 return super::back();
455 void sort() noexcept {
456 std::sort(super::begin(), super::end());
459 template<
typename Comparator>
460 void sort(Comparator&& comparator)
noexcept {
461 std::sort(super::begin(), super::end(), std::forward<Comparator>(comparator));
481 template<
typename Predicate>
484 super::erase(std::remove_if(super::begin(), super::end(), std::forward<Predicate>(predicate)), super::end());
497 template<aui::incrementable Iterator, aui::invocable<decltype(*std::declval<Iterator>())> UnaryOperation>
499 AVector<
decltype(transformer(range.first()))> result;
500 result.reserve(range.size());
501 std::transform(range.begin(), range.end(), std::back_inserter(result), std::forward<UnaryOperation>(transformer));
505 template<aui::invocable<const StoredType&> UnaryOperation>
508 result.reserve(super::size());
509 std::transform(super::begin(), super::end(), std::back_inserter(result), std::forward<UnaryOperation>(transformer));
513 template<aui::invocable<const StoredType&> UnaryOperation>
515 auto toMap(UnaryOperation&& transformer)
const -> AMap<decltype(transformer(std::declval<StoredType>()).
first),
516 decltype(transformer(std::declval<StoredType>()).second)> {
520 template<aui::invocable<StoredType&> UnaryOperation>
522 auto toMap(UnaryOperation&& transformer) -> AMap<decltype(transformer(std::declval<StoredType>()).
first),
523 decltype(transformer(std::declval<StoredType>()).second)> {
527 template<aui::predicate<const StoredType&> Predicate>
528 self filter(Predicate&& predicate) {
530 result.reserve(super::size());
531 for (
const auto& element : *
this) {
532 if (predicate(element)) {
533 result.push_back(element);
540 iterator mBegin =
nullptr;
541 iterator mEnd =
nullptr;
542 iterator mBufferEnd =
nullptr;