AUI Framework  master
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-2025 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    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, std::begin(c), std::end(c));
   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 {
  356        AVector<StoredType, Allocator> s;
  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&>()))> {
  387        AVector<decltype(transformer(std::declval<StoredType&>()))> result;
  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:33
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:205
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:172
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