AUI Framework  develop
Cross-platform base for C++ UI apps
Loading...
Searching...
No Matches
AVector.h
1/*
2 * AUI Framework - Declarative UI toolkit for modern C++20
3 * Copyright (C) 2020-2024 Alex2772 and Contributors
4 *
5 * SPDX-License-Identifier: MPL-2.0
6 *
7 * This Source Code Form is subject to the terms of the Mozilla Public
8 * License, v. 2.0. If a copy of the MPL was not distributed with this
9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 */
11
12#pragma once
13
14#include <AUI/Core.h>
15#include <vector>
16#include <cassert>
17#include "SharedPtrTypes.h"
18#include <algorithm>
19#include <ostream>
20#include "ASet.h"
21#include <AUI/Traits/containers.h>
22#include <AUI/Traits/iterators.h>
23#include "AUI/Traits/bit.h"
24#include "AContainerPrototypes.h"
25#include "AUI/Traits/concepts.h"
26#include <concepts>
27
28
29namespace aui::impl {
30 API_AUI_CORE void outOfBoundsException();
31}
32
37template <class StoredType, class Allocator>
38class AVector: public std::vector<StoredType, Allocator>
39{
40protected:
41 using super = std::vector<StoredType, Allocator>;
42 using self = AVector<StoredType, Allocator>;
43
44public:
45 using super::super;
46 using iterator = typename super::iterator;
47
48 template<typename Iterator>
49 explicit AVector(aui::range<Iterator> range): AVector(range.begin(), range.end()) {}
50
51 explicit AVector(std::vector<StoredType, Allocator>&& rhs) noexcept: super(std::move(rhs)) {}
52
53
60 template<typename OtherContainer>
61 iterator insertAll(const OtherContainer& c) noexcept {
62 return insertAll(super::end(), c);
63 }
64
65
72 template<typename OtherContainer>
73 iterator insertAll(OtherContainer&& c) noexcept {
74 return insertAll(super::end(), std::forward<OtherContainer>(c));
75 }
76
77
85 template<typename OtherContainer>
86 iterator insertAll(iterator at, const OtherContainer& c) noexcept {
87 return super::insert(at, c.begin(), c.end());
88 }
89
90
98 template<typename OtherContainer>
99 iterator insertAll(iterator at, OtherContainer&& c) noexcept {
100 return super::insert(at, std::make_move_iterator(c.begin()), std::make_move_iterator(c.end()));
101 }
102
103
108 void removeAll(const StoredType& item) noexcept
109 {
110 aui::container::remove_all(*this, item);
111 }
112
119 template<typename T, aui::mapper<const StoredType&, const T&> Projection>
120 void removeAll(const T& item, Projection projection) noexcept
121 {
122 aui::container::remove_all(*this, item, projection);
123 }
124
130 AOptional<std::size_t> removeFirst(const StoredType& item) noexcept
131 {
132 return aui::container::remove_first(*this, item);
133 }
134
135
139 template<typename OtherContainer>
140 bool isSubsetOf(const OtherContainer& c) const noexcept
141 {
142 return aui::container::is_subset(*this, c);
143 }
144
148 bool contains(const StoredType& value) const noexcept {
149 return aui::container::contains(*this, value);
150 }
151
152 [[nodiscard]]
153 std::size_t sizeInBytes() const noexcept {
154 return super::size() * sizeof(StoredType);
155 }
156
157 [[nodiscard]]
158 StoredType& at(std::size_t index) {
159 if (index >= super::size()) {
160 aui::impl::outOfBoundsException();
161 }
162 return super::operator[](index);
163 }
164
165 [[nodiscard]]
166 const StoredType& at(std::size_t index) const {
167 if (index >= super::size()) {
168 aui::impl::outOfBoundsException();
169 }
170 return super::operator[](index);
171 }
172
173
179 self& operator<<(const StoredType& rhs) noexcept
180 {
181 super::push_back(rhs);
182 return *this;
183 }
184
190 self& operator<<(StoredType&& rhs) noexcept
191 {
192 super::push_back(std::move(rhs));
193 return *this;
194 }
195
201 template<typename OtherContainer, std::enable_if_t<!std::is_convertible_v<OtherContainer, StoredType>, bool> = true>
202 self& operator<<(const OtherContainer& c) noexcept
203 {
204 insertAll(c);
205 return *this;
206 }
207
213 template<typename OtherContainer, std::enable_if_t<!std::is_convertible_v<OtherContainer, StoredType>, bool> = true>
214 self& operator<<(OtherContainer&& c) noexcept
215 {
216 insertAll(std::forward<OtherContainer>(c));
217 return *this;
218 }
219
220
228 [[nodiscard]]
229 StoredType& first() noexcept
230 {
231 AUI_ASSERTX(!super::empty(), "empty container could not have the first element");
232 return super::front();
233 }
234
242 [[nodiscard]]
243 const StoredType& first() const noexcept
244 {
245 AUI_ASSERTX(!super::empty(), "empty container could not have the first element");
246 return super::front();
247 }
248
256 [[nodiscard]]
257 StoredType& last() noexcept
258 {
259 AUI_ASSERTX(!super::empty(), "empty container could not have the last element");
260 return super::back();
261 }
262
270 [[nodiscard]]
271 const StoredType& last() const noexcept
272 {
273 AUI_ASSERTX(!super::empty(), "empty container could not have the last element");
274 return super::back();
275 }
276
281 [[nodiscard]]
282 [[nodiscard]]
283 AOptional<size_t> indexOf(const StoredType& value) const noexcept
284 {
285 return aui::container::index_of(*this, value);
286 }
287
288
289 AVector<StoredType>& sort() noexcept {
290 std::sort(super::begin(), super::end());
291 return *this;
292 }
293
294 template<typename Comparator>
295 AVector<StoredType>& sort(Comparator&& comparator) noexcept {
296 std::sort(super::begin(), super::end(), std::forward<Comparator>(comparator));
297 return *this;
298 }
299
305 template<aui::predicate<StoredType> Predicate>
306 [[nodiscard]]
307 StoredType* findIf(Predicate&& predicate) noexcept
308 {
309 if (auto i = std::find_if(super::begin(), super::end(), std::forward<Predicate>(predicate)); i != super::end()) {
310 return &*i;
311 }
312 return nullptr;
313 }
314
315
324 void removeAt(size_t index) noexcept
325 {
326 aui::container::remove_at(*this, index);
327 }
328
333 template<aui::predicate<StoredType> Predicate>
334 void removeIf(Predicate&& predicate) noexcept
335 {
336 super::erase(std::remove_if(super::begin(), super::end(), std::forward<Predicate>(predicate)), super::end());
337 }
338
343 template<aui::predicate<StoredType> Predicate>
344 void removeIfFirst(Predicate&& predicate) noexcept
345 {
346 auto i = std::find_if(super::begin(), super::end(), std::forward<Predicate>(predicate));
347 if (i == super::end()) {
348 return;
349 }
350 super::erase(i);
351 }
352
353 template<aui::mapper<std::size_t, StoredType> Callable>
354 [[nodiscard]]
355 inline static AVector<StoredType, Allocator> generate(size_t size, Callable&& callable) noexcept {
357 s.reserve(size);
358 for (size_t i = 0; i < size; ++i) {
359 s << callable(i);
360 }
361 return s;
362 }
363
364 [[nodiscard]]
365 ASet<StoredType> toSet() const noexcept {
366 return ASet<StoredType>(super::begin(), super::end());
367 }
368
375 template<aui::incrementable Iterator, aui::invocable<decltype(*std::declval<Iterator>())> UnaryOperation>
376 [[nodiscard]]
377 static auto fromRange(aui::range<Iterator> range, UnaryOperation&& transformer) -> AVector<decltype(transformer(range.first()))> {
378 AVector<decltype(transformer(range.first()))> result;
379 result.reserve(range.size());
380 std::transform(range.begin(), range.end(), std::back_inserter(result), std::forward<UnaryOperation>(transformer));
381 return result;
382 }
383
384 template<aui::invocable<StoredType&> UnaryOperation>
385 [[nodiscard]]
386 auto map(UnaryOperation&& transformer) -> AVector<decltype(transformer(std::declval<StoredType&>()))> {
388 result.reserve(super::size());
389 std::transform(super::begin(), super::end(), std::back_inserter(result), std::forward<UnaryOperation>(transformer));
390 return result;
391 }
392
393 template<aui::invocable<const StoredType&> UnaryOperation>
394 [[nodiscard]]
395 auto map(UnaryOperation&& transformer) const -> AVector<decltype(transformer(std::declval<StoredType>()))> {
396 AVector<decltype(transformer(std::declval<StoredType>()))> result;
397 result.reserve(super::size());
398 std::transform(super::begin(), super::end(), std::back_inserter(result), std::forward<UnaryOperation>(transformer));
399 return result;
400 }
401
402 template<aui::invocable<const StoredType&> UnaryOperation>
403 [[nodiscard]]
404 auto toMap(UnaryOperation&& transformer) const -> AMap<decltype(transformer(std::declval<StoredType>()).first),
405 decltype(transformer(std::declval<StoredType>()).second)> {
406 return aui::container::to_map(super::begin(), super::end(), transformer);
407 }
408
409 template<aui::invocable<StoredType&> UnaryOperation>
410 [[nodiscard]]
411 auto toMap(UnaryOperation&& transformer) -> AMap<decltype(transformer(std::declval<StoredType>()).first),
412 decltype(transformer(std::declval<StoredType>()).second)> {
413 return aui::container::to_map(super::begin(), super::end(), transformer);
414 }
415
416 template<aui::predicate<const StoredType&> Predicate>
417 [[nodiscard]]
418 self filter(Predicate&& predicate) {
419 self result;
420 result.reserve(super::size());
421 for (const auto& element : *this) {
422 if (predicate(element)) {
423 result.push_back(element);
424 }
425 }
426 return result;
427 }
428};
429
430
431template<typename T>
432inline std::ostream& operator<<(std::ostream& o, const AVector<T>& v) {
433 if (v.empty()) {
434 o << "[empty]";
435 } else {
436 o << "[ " << v.first();
437 for (auto it = v.begin() + 1; it != v.end(); ++it) {
438 o << ", " << *it;
439 }
440 o << " ]";
441 }
442
443 return o;
444}
445
Utility wrapper implementing the stack-allocated (fast) optional idiom.
Definition AOptional.h:32
A std::vector with AUI extensions.
Definition AVector.h:39
const StoredType & first() const noexcept
Definition AVector.h:243
self & operator<<(StoredType &&rhs) noexcept
Definition AVector.h:190
AOptional< size_t > indexOf(const StoredType &value) const noexcept
Definition AVector.h:283
bool contains(const StoredType &value) const noexcept
Definition AVector.h:148
iterator insertAll(iterator at, const OtherContainer &c) noexcept
Definition AVector.h:86
self & operator<<(OtherContainer &&c) noexcept
Definition AVector.h:214
void removeIf(Predicate &&predicate) noexcept
Definition AVector.h:334
StoredType * findIf(Predicate &&predicate) noexcept
Finds element by predicate.
Definition AVector.h:307
static auto fromRange(aui::range< Iterator > range, UnaryOperation &&transformer) -> AVector< decltype(transformer(range.first()))>
Constructs a new vector of transformed items of the range.
Definition AVector.h:377
self & operator<<(const StoredType &rhs) noexcept
Definition AVector.h:179
iterator insertAll(iterator at, OtherContainer &&c) noexcept
Definition AVector.h:99
void removeAll(const T &item, Projection projection) noexcept
Definition AVector.h:120
const StoredType & last() const noexcept
Definition AVector.h:271
StoredType & first() noexcept
Definition AVector.h:229
StoredType & last() noexcept
Definition AVector.h:257
bool isSubsetOf(const OtherContainer &c) const noexcept
Definition AVector.h:140
AOptional< std::size_t > removeFirst(const StoredType &item) noexcept
Definition AVector.h:130
void removeIfFirst(Predicate &&predicate) noexcept
Definition AVector.h:344
self & operator<<(const OtherContainer &c) noexcept
Definition AVector.h:202
void removeAt(size_t index) noexcept
Definition AVector.h:324
iterator insertAll(const OtherContainer &c) noexcept
Definition AVector.h:61
iterator insertAll(OtherContainer &&c) noexcept
Definition AVector.h:73
void removeAll(const StoredType &item) noexcept
Definition AVector.h:108
bool is_subset(LContainer &l, RContainer &r) noexcept
Definition containers.h:204
AOptional< size_t > index_of(const Container &c, const typename Container::const_reference value) noexcept
Finds the index of the first occurrence of the value.
Definition containers.h:112
bool contains(const Container &c, const typename Container::const_reference value) noexcept
Definition containers.h:124
AOptional< std::size_t > remove_first(Container &container, typename Container::const_reference value) noexcept
Removes first occurrence of value.
Definition containers.h:171
auto to_map(Iterator begin, Iterator end, UnaryOperation &&transformer)
Transforms sequence to map.
Definition AMap.h:237
void remove_at(Container &c, size_t index) noexcept
Removes element at the specified index.
Definition containers.h:98
void remove_all(Container &container, typename Container::const_reference value) noexcept
Removes all occurrences of value.
Definition containers.h:143
#define AUI_ASSERTX(condition, what)
Asserts that the passed condition evaluates to true. Adds extra message string.
Definition Assert.h:74
Definition iterators.h:50