Skip to content

aui::any_view#

RTTI-wrapped range.

Header:#include <AUI/Traits/any_view.h>
CMake:aui_link(my_target PUBLIC aui::core)

Detailed Description#

Experimental Feature

This API is experimental. Experimental APIs are likely to contain bugs, might be changed or removed in the future.

aui::any_view is a dynamic range class that mimics the behavior of C++20 ranges/range-v3 using type-erased interfaces. It allows for the creation of runtime-checked, polymorphic ranges with input iterators.

Alternative implementation of ranges::views::any_view.

The general idea is to preserve lazy nature of C++20 ranges/range-v3 and flexibility between compilation modules.

Keep in mind that type erasure can lead to performance overhead due to dynamic dispatch.

aui::any_view initialized with an lvalue reference will contain a reference to the container; thus the container can be modified.

1
2
3
4
5
AVector<int> elements{1,2,3};
aui::any_view<int> ints = elements;
EXPECT_EQ(ints | ranges::to_vector, std::vector({1, 2, 3 }));
elements << 4;
EXPECT_EQ(ints | ranges::to_vector, std::vector({1, 2, 3, 4 }));

aui::any_view initialized with an rvalue reference will move the container into itself; thus it acquires ownership.

1
2
3
4
5
AVector<int> elements{1,2,3};
aui::any_view<int> ints = std::move(elements);
EXPECT_EQ(ints | ranges::to_vector, std::vector({1, 2, 3 }));
elements << 4;
EXPECT_EQ(ints | ranges::to_vector, std::vector({1, 2, 3 }));

Using aui::any_view::iterator acquired before modification of the referenced container may lead to undefined behaviour; it all depends on the referenced container.

aui::any_view follows the same principle as std::function for functors.

Public Types#


iterator#

struct aui::any_view::iterator

Examples:

examples/app/notes/src/main.cpp

Notes App - Note taking app that demonstrates usage of AListModel, AProperty, user data saving and loading.

                      },
                      /// [scrollarea]
                      AScrollArea::Builder()
                          .withContents(
                          AUI_DECLARATIVE_FOR(note, *mNotes, AVerticalLayout) {
                              observeChangesForDirty(note);
                              return notePreview(note) AUI_LET {
                                  connect(it->clicked, [this, note] { mCurrentNote = note; });
                                  it& mCurrentNote > [note](AView& view, const _<Note>& currentNote) {
                                      ALOG_DEBUG(LOG_TAG) << "currentNote == note " << currentNote << " == " << note;
examples/ui/contacts/src/main.cpp

AUI Contacts - Usage of AUI_DECLARATIVE_FOR to make a contacts-like application.

        mSelectedContact = nullptr;
    }

    _<AView> indexedList() {
        return AUI_DECLARATIVE_FOR(group, *mContacts | ranges::views::chunk_by([](const _<Contact>& lhs, const _<Contact>& rhs) {
                                return groupLetter(lhs->displayName) == groupLetter(rhs->displayName);
                            }), AVerticalLayout) {
            auto firstContact = *ranges::begin(group);
            auto firstLetter = groupLetter(firstContact->displayName);
            ALogger::info("Test") << "Computing view for group " << AString(1, firstLetter);
examples/ui/views/src/ExampleWindow.cpp

Views Example - All-in-one views building example.

                                    }
                                }),
                            _new<ASpacerExpanding>(),
                          } AUI_WITH_STYLE { LayoutSpacing { 4_dp } },
                          AUI_DECLARATIVE_FOR(i, *state->colors, AWordWrappingLayout) {
                              return Horizontal {
                                  _new<ALabel>(i.toString()) AUI_WITH_STYLE {
                                      TextColor { i.readableBlackOrWhite() },
                                  }
                              } AUI_WITH_STYLE {
examples/ui/infinite_lazy_list/src/main.cpp

Infinite Lazy List - Usage of AUI_DECLARATIVE_FOR to make an infinite lazy list.

        };
    });

    return Vertical {
        AUI_DECLARATIVE_FOR(i, *state->items, AVerticalLayout) { return Label{} & i->value; },
        Centered {
          _new<ASpinnerV2>() AUI_LET {
                  AObject::connect(it->redrawn, AObject::GENERIC_OBSERVER, [state] {
                      // when a spinner appears, we indicate that we need more items.
                      state->needMore = true;
examples/7guis/crud/src/main.cpp

7GUIs CRUD - Create/Read/Update/Delete example.

                Label { "Filter prefix:" },
                _new<ATextField>() AUI_WITH_STYLE { Expanding(1, 0) } && mFilterPrefix,
              } AUI_WITH_STYLE { LayoutSpacing { 4_dp } },
              AScrollArea::Builder().withExpanding().withContents(
                  AUI_DECLARATIVE_FOR(i, *mUsers | FILTER_VIEW, AVerticalLayout) {
                    auto view = _new<ALabel>();
                    view & i->displayName;
                    connect(mSelectedUser, view, [this, &view = *view, i] {
                        view.setAssName("selected", mSelectedUser == i);
                    });

Empty structure.

Public Methods#

begin#


iterator any_view::begin()
Returns
polymorphic begin iterator.

Examples:

examples/app/minesweeper/src/NewGameWindow.cpp

Minesweeper Game - Minesweeper game implementation driven by ass.

      Horizontal {
        _new<ASpacerExpanding>(),
        _new<AButton>("Start game") AUI_LET {
                it->setDefault();
                connect(it->clicked, me::begin);
            },
        _new<AButton>("Cancel").connect(&AButton::clicked, me::close),
      } AUI_WITH_STYLE { LayoutSpacing { 4_dp } },
    } AUI_WITH_STYLE { LayoutSpacing { 4_dp } });
examples/app/minesweeper/src/NewGameWindow.h

Minesweeper Game - Minesweeper game implementation driven by ass.

    _<ALabel> mDifficultyLabel;

    void updateMinesMax();
    void updateDifficultyLabel();
    void begin();

};
examples/ui/contacts/src/main.cpp

AUI Contacts - Usage of AUI_DECLARATIVE_FOR to make a contacts-like application.

        mSelectedContact = nullptr;
    }

    _<AView> indexedList() {
        return AUI_DECLARATIVE_FOR(group, *mContacts | ranges::views::chunk_by([](const _<Contact>& lhs, const _<Contact>& rhs) {
                                return groupLetter(lhs->displayName) == groupLetter(rhs->displayName);
                            }), AVerticalLayout) {
            auto firstContact = *ranges::begin(group);
            auto firstLetter = groupLetter(firstContact->displayName);
            ALogger::info("Test") << "Computing view for group " << AString(1, firstLetter);
examples/7guis/circle_drawer/src/main.cpp

7GUIs Circle Drawer - Undo, redo, dialog control.

    Container mStack;

public:
    void undo() {
        if (nextAction == mStack.begin()) {
            return;
        }
        nextAction = std::prev(*nextAction);
        (**nextAction)->undo();
    }
examples/7guis/cells/src/Cell.cpp

7GUIs Cells - Spreadsheet processor (Excel).

}

glm::uvec2 Cell::fromName(const AString& name) {
    glm::uvec2 out{UNDEFINED};
    auto it = name.begin();
    for (;it != name.end() && 'A' <= *it && *it <= 'Z'; ++it) {
        if (out.x == UNDEFINED) { out.x = 0; }
        out.x *= 26;
        out.x += *it - 'A';
    }
examples/7guis/cells/src/AST.cpp

7GUIs Cells - Spreadsheet processor (Excel).

                }
            }
            if (!binaryOperators.empty()) {
                auto root = std::min_element(
                    binaryOperators.begin(), binaryOperators.end(),
                    [](const BinaryOperatorAndItsPriority& lhs, const BinaryOperatorAndItsPriority& rhs) {
                        return lhs.priority < rhs.priority;
                    });
                auto out = std::make_unique<T>();
                AUI_ASSERT(root->owning != nullptr);

end#


iterator any_view::end()
Returns
polymorphic end iterator.

Examples:

examples/app/game_of_life/src/main.cpp

Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.

            }
        }
        return accumulator;
    }
}; /// end

class CellsView : public AView {
public:
    static constexpr auto SCALE = 8_dp;
examples/app/notes/src/main.cpp

Notes App - Note taking app that demonstrates usage of AListModel, AProperty, user data saving and loading.

                      },
                      /// [scrollarea]
                      AScrollArea::Builder()
                          .withContents(
                          AUI_DECLARATIVE_FOR(note, *mNotes, AVerticalLayout) {
                              observeChangesForDirty(note);
                              return notePreview(note) AUI_LET {
                                  connect(it->clicked, [this, note] { mCurrentNote = note; });
                                  it& mCurrentNote > [note](AView& view, const _<Note>& currentNote) {
                                      ALOG_DEBUG(LOG_TAG) << "currentNote == note " << currentNote << " == " << note;
examples/7guis/circle_drawer/src/main.cpp

7GUIs Circle Drawer - Undo, redo, dialog control.

        (**nextAction)->undo();
    }

    void redo() {
        if (nextAction == mStack.end()) {
            return;
        }
        (**nextAction)->redo();
        nextAction = std::next(*nextAction);
    }
examples/7guis/cells/src/Cell.cpp

7GUIs Cells - Spreadsheet processor (Excel).

glm::uvec2 Cell::fromName(const AString& name) {
    glm::uvec2 out{UNDEFINED};
    auto it = name.begin();
    for (;it != name.end() && 'A' <= *it && *it <= 'Z'; ++it) {
        if (out.x == UNDEFINED) { out.x = 0; }
        out.x *= 26;
        out.x += *it - 'A';
    }
    for (;it != name.end() && '0' <= *it && *it <= '9'; ++it) {
examples/7guis/cells/src/AST.cpp

7GUIs Cells - Spreadsheet processor (Excel).

                }
            }
            if (!binaryOperators.empty()) {
                auto root = std::min_element(
                    binaryOperators.begin(), binaryOperators.end(),
                    [](const BinaryOperatorAndItsPriority& lhs, const BinaryOperatorAndItsPriority& rhs) {
                        return lhs.priority < rhs.priority;
                    });
                auto out = std::make_unique<T>();
                AUI_ASSERT(root->owning != nullptr);