AUI Framework  master
Cross-platform module-based framework for developing C++20 desktop applications
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 "AContainerPrototypes.h"
24#include "AUI/Traits/concepts.h"
25#include <concepts>
26
27
28namespace aui::impl {
29 API_AUI_CORE void outOfBoundsException();
30}
31
36template <class StoredType, class Allocator>
37class AVector: public std::vector<StoredType, Allocator>
38{
39protected:
40 using super = std::vector<StoredType, Allocator>;
42
43public:
44 using super::super;
45 using iterator = typename super::iterator;
46
47 template<typename Iterator>
48 explicit AVector(aui::range<Iterator> range): AVector(range.begin(), range.end()) {}
49
50 explicit AVector(std::vector<StoredType, Allocator>&& rhs) noexcept: super(std::move(rhs)) {}
51
52
59 template<typename OtherContainer>
60 iterator insertAll(const OtherContainer& c) noexcept {
61 return insertAll(super::end(), c);
62 }
63
64
71 template<typename OtherContainer>
72 iterator insertAll(OtherContainer&& c) noexcept {
73 return insertAll(super::end(), std::forward<OtherContainer>(c));
74 }
75
76
84 template<typename OtherContainer>
85 iterator insertAll(iterator at, const OtherContainer& c) noexcept {
86 return super::insert(at, c.begin(), c.end());
87 }
88
89
97 template<typename OtherContainer>
98 iterator insertAll(iterator at, OtherContainer&& c) noexcept {
99 return super::insert(at, std::make_move_iterator(c.begin()), std::make_move_iterator(c.end()));
100 }
101
102
107 void removeAll(const StoredType& item) noexcept
108 {
109 aui::container::remove_all(*this, item);
110 }
111
118 template<typename T, aui::mapper<const StoredType&, const T&> Projection>
119 void removeAll(const T& item, Projection projection) noexcept
120 {
121 aui::container::remove_all(*this, item, projection);
122 }
123
129 AOptional<std::size_t> removeFirst(const StoredType& item) noexcept
130 {
131 return aui::container::remove_first(*this, item);
132 }
133
134
138 template<typename OtherContainer>
139 bool isSubsetOf(const OtherContainer& c) const noexcept
140 {
141 return aui::container::is_subset(*this, c);
142 }
143
147 bool contains(const StoredType& value) const noexcept {
148 return aui::container::contains(*this, value);
149 }
150
151 [[nodiscard]]
152 std::size_t sizeInBytes() const noexcept {
153 return super::size() * sizeof(StoredType);
154 }
155
156 [[nodiscard]]
157 StoredType& at(std::size_t index) {
158 if (index >= super::size()) {
159 aui::impl::outOfBoundsException();
160 }
161 return super::operator[](index);
162 }
163
164 [[nodiscard]]
165 const StoredType& at(std::size_t index) const {
166 if (index >= super::size()) {
167 aui::impl::outOfBoundsException();
168 }
169 return super::operator[](index);
170 }
171
172
178 self& operator<<(const StoredType& rhs) noexcept
179 {
180 super::push_back(rhs);
181 return *this;
182 }
183
189 self& operator<<(StoredType&& rhs) noexcept
190 {
191 super::push_back(std::move(rhs));
192 return *this;
193 }
194
200 template<typename OtherContainer, std::enable_if_t<!std::is_convertible_v<OtherContainer, StoredType>, bool> = true>
201 self& operator<<(const OtherContainer& c) noexcept
202 {
203 insertAll(c);
204 return *this;
205 }
206
212 template<typename OtherContainer, std::enable_if_t<!std::is_convertible_v<OtherContainer, StoredType>, bool> = true>
213 self& operator<<(OtherContainer&& c) noexcept
214 {
215 insertAll(std::forward<OtherContainer>(c));
216 return *this;
217 }
218
219
227 [[nodiscard]]
228 StoredType& first() noexcept
229 {
230 AUI_ASSERTX(!super::empty(), "empty container could not have the first element");
231 return super::front();
232 }
233
241 [[nodiscard]]
242 const StoredType& first() const noexcept
243 {
244 AUI_ASSERTX(!super::empty(), "empty container could not have the first element");
245 return super::front();
246 }
247
255 [[nodiscard]]
256 StoredType& last() noexcept
257 {
258 AUI_ASSERTX(!super::empty(), "empty container could not have the last element");
259 return super::back();
260 }
261
269 [[nodiscard]]
270 const StoredType& last() const noexcept
271 {
272 AUI_ASSERTX(!super::empty(), "empty container could not have the last element");
273 return super::back();
274 }
275
280 [[nodiscard]]
281 [[nodiscard]]
282 size_t indexOf(const StoredType& value) const noexcept
283 {
284 return aui::container::index_of(*this, value);
285 }
286
287
288 AVector<StoredType>& sort() noexcept {
289 std::sort(super::begin(), super::end());
290 return *this;
291 }
292
293 template<typename Comparator>
294 AVector<StoredType>& sort(Comparator&& comparator) noexcept {
295 std::sort(super::begin(), super::end(), std::forward<Comparator>(comparator));
296 return *this;
297 }
298
304 template<aui::predicate<StoredType> Predicate>
305 [[nodiscard]]
306 StoredType* findIf(Predicate&& predicate) noexcept
307 {
308 if (auto i = std::find_if(super::begin(), super::end(), std::forward<Predicate>(predicate)); i != super::end()) {
309 return &*i;
310 }
311 return nullptr;
312 }
313
314
323 void removeAt(size_t index) noexcept
324 {
325 aui::container::remove_at(*this, index);
326 }
327
332 template<aui::predicate<StoredType> Predicate>
333 void removeIf(Predicate&& predicate) noexcept
334 {
335 super::erase(std::remove_if(super::begin(), super::end(), std::forward<Predicate>(predicate)), super::end());
336 }
337
342 template<aui::predicate<StoredType> Predicate>
343 void removeIfFirst(Predicate&& predicate) noexcept
344 {
345 auto i = std::find_if(super::begin(), super::end(), std::forward<Predicate>(predicate));
346 if (i == super::end()) {
347 return;
348 }
349 super::erase(i);
350 }
351
352 template<aui::mapper<std::size_t, StoredType> Callable>
353 [[nodiscard]]
354 inline static AVector<StoredType, Allocator> generate(size_t size, Callable&& callable) noexcept {
356 s.reserve(size);
357 for (size_t i = 0; i < size; ++i) {
358 s << callable(i);
359 }
360 return s;
361 }
362
363 [[nodiscard]]
364 ASet<StoredType> toSet() const noexcept {
365 return ASet<StoredType>(super::begin(), super::end());
366 }
367
374 template<aui::incrementable Iterator, aui::invocable<decltype(*std::declval<Iterator>())> UnaryOperation>
375 [[nodiscard]]
376 static auto fromRange(aui::range<Iterator> range, UnaryOperation&& transformer) -> AVector<decltype(transformer(range.first()))> {
377 AVector<decltype(transformer(range.first()))> result;
378 result.reserve(range.size());
379 std::transform(range.begin(), range.end(), std::back_inserter(result), std::forward<UnaryOperation>(transformer));
380 return result;
381 }
382
383 template<aui::invocable<StoredType&> UnaryOperation>
384 [[nodiscard]]
385 auto map(UnaryOperation&& transformer) -> AVector<decltype(transformer(std::declval<StoredType&>()))> {
387 result.reserve(super::size());
388 std::transform(super::begin(), super::end(), std::back_inserter(result), std::forward<UnaryOperation>(transformer));
389 return result;
390 }
391
392 template<aui::invocable<const StoredType&> UnaryOperation>
393 [[nodiscard]]
394 auto map(UnaryOperation&& transformer) const -> AVector<decltype(transformer(std::declval<StoredType>()))> {
396 result.reserve(super::size());
397 std::transform(super::begin(), super::end(), std::back_inserter(result), std::forward<UnaryOperation>(transformer));
398 return result;
399 }
400
401 template<aui::invocable<const StoredType&> UnaryOperation>
402 [[nodiscard]]
403 auto toMap(UnaryOperation&& transformer) const -> AMap<decltype(transformer(std::declval<StoredType>()).first),
404 decltype(transformer(std::declval<StoredType>()).second)> {
405 return aui::container::to_map(super::begin(), super::end(), transformer);
406 }
407
408 template<aui::invocable<StoredType&> UnaryOperation>
409 [[nodiscard]]
410 auto toMap(UnaryOperation&& transformer) -> AMap<decltype(transformer(std::declval<StoredType>()).first),
411 decltype(transformer(std::declval<StoredType>()).second)> {
412 return aui::container::to_map(super::begin(), super::end(), transformer);
413 }
414
415 template<aui::predicate<const StoredType&> Predicate>
416 [[nodiscard]]
417 self filter(Predicate&& predicate) {
418 self result;
419 result.reserve(super::size());
420 for (const auto& element : *this) {
421 if (predicate(element)) {
422 result.push_back(element);
423 }
424 }
425 return result;
426 }
427};
428
429
430template<typename T>
431inline std::ostream& operator<<(std::ostream& o, const AVector<T>& v) {
432 if (v.empty()) {
433 o << "[empty]";
434 } else {
435 o << "[ " << v.first();
436 for (auto it = v.begin() + 1; it != v.end(); ++it) {
437 o << ", " << *it;
438 }
439 o << " ]";
440 }
441
442 return o;
443}
444
A std::map with AUI extensions.
Definition: AMap.h:218
Utility wrapper implementing the stack-allocated (fast) optional idiom.
Definition: AOptional.h:32
A std::set with AUI extensions.
Definition: ASet.h:25
A std::vector with AUI extensions.
Definition: AVector.h:38
const StoredType & first() const noexcept
Definition: AVector.h:242
self & operator<<(StoredType &&rhs) noexcept
Definition: AVector.h:189
bool contains(const StoredType &value) const noexcept
Definition: AVector.h:147
iterator insertAll(iterator at, const OtherContainer &c) noexcept
Definition: AVector.h:85
self & operator<<(OtherContainer &&c) noexcept
Definition: AVector.h:213
void removeIf(Predicate &&predicate) noexcept
Definition: AVector.h:333
StoredType * findIf(Predicate &&predicate) noexcept
Finds element by predicate.
Definition: AVector.h:306
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:376
self & operator<<(const StoredType &rhs) noexcept
Definition: AVector.h:178
iterator insertAll(iterator at, OtherContainer &&c) noexcept
Definition: AVector.h:98
void removeAll(const T &item, Projection projection) noexcept
Definition: AVector.h:119
const StoredType & last() const noexcept
Definition: AVector.h:270
StoredType & first() noexcept
Definition: AVector.h:228
StoredType & last() noexcept
Definition: AVector.h:256
bool isSubsetOf(const OtherContainer &c) const noexcept
Definition: AVector.h:139
AOptional< std::size_t > removeFirst(const StoredType &item) noexcept
Definition: AVector.h:129
void removeIfFirst(Predicate &&predicate) noexcept
Definition: AVector.h:343
self & operator<<(const OtherContainer &c) noexcept
Definition: AVector.h:201
void removeAt(size_t index) noexcept
Definition: AVector.h:323
iterator insertAll(const OtherContainer &c) noexcept
Definition: AVector.h:60
iterator insertAll(OtherContainer &&c) noexcept
Definition: AVector.h:72
void removeAll(const StoredType &item) noexcept
Definition: AVector.h:107
size_t indexOf(const StoredType &value) const noexcept
Definition: AVector.h:282
bool is_subset(LContainer &l, RContainer &r) noexcept
Definition: containers.h:233
bool contains(const Container &c, const typename Container::const_reference value) noexcept
Definition: containers.h:153
AOptional< std::size_t > remove_first(Container &container, typename Container::const_reference value) noexcept
Removes first occurrence of value.
Definition: containers.h:200
auto to_map(Iterator begin, Iterator end, UnaryOperation &&transformer)
Transforms sequence to map.
Definition: AMap.h:237
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:141
void remove_at(Container &c, size_t index) noexcept
Removes element at the specified index.
Definition: containers.h:128
void remove_all(Container &container, typename Container::const_reference value) noexcept
Removes all occurrences of value.
Definition: containers.h:172
#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