Aria 2.0.0
C++23 MVVM framework (C++20 minimum) — reactive, coroutine-first, ABI-layered
Loading...
Searching...
No Matches
list_source.hpp
Go to the documentation of this file.
1#pragma once
2
3// list_source.hpp — concept describing the "list-like source" surface.
4//
5// Adapter layer (Qt6 / AppKit / UIKit list bridges) wants to consume any
6// of the observable list types uniformly:
7//
8// * `aria::ObservableList<T>`
9// * `aria::FilteredList<T>`
10// * `aria::SortedList<T>`
11// * `aria::MappedList<S, T>` (the element type is T = Target)
12// * `aria::DistinctList<T, Key>`
13// * `aria::PagedList<T>`
14// * `aria::GroupedList<T, Key>` (the element type is T = Group<T, Key>)
15//
16// They all ship the same observation vocabulary (`ListChange<T>` events
17// via `.observe(...)`) — supplied uniformly by `detail::ListSignalMixin`
18// — plus a small read surface (`size()`, `at(i)`, `snapshot()`). Rather
19// than introducing an abstract `IDerivedList<T>` base class — which
20// would require either virtual dispatch or a type-erased wrapper — we
21// express the requirement as a concept and let adapter templates accept
22// the source by reference.
23//
24// Rationale (no-premature-abstraction principle):
25// * No new abstraction surface is introduced until a real demand
26// pulls one. The concept is the *minimum* contract every adapter
27// bridge needs.
28// * The four list types remain unchanged — they already satisfy the
29// concept by construction.
30// * Test code can supply tiny fakes that satisfy the concept without
31// pulling in `ObservableList` machinery.
32
34#include "aria/subscription.hpp"
35
36#include <concepts>
37#include <cstddef>
38#include <functional>
39#include <memory>
40#include <type_traits>
41#include <vector>
42
43namespace aria {
44
55
56namespace detail {
57
58template<typename L>
59 requires (requires { typename L::value_type; } ||
60 requires { typename L::element_type; })
61struct list_source_value_impl {
62 template<typename U>
63 static auto probe(int) -> typename U::value_type;
64 template<typename U>
65 static auto probe(...) -> typename U::element_type;
66 using type = decltype(probe<L>(0));
67};
68
69} // namespace detail
70
75template<typename L>
76using list_source_value_t = typename detail::list_source_value_impl<
77 std::remove_cvref_t<L>>::type;
78
79template<typename L, typename T>
80concept ListSourceOf = requires(L& l,
81 std::function<void(const ListChange<T>&)> fn,
82 std::size_t i) {
83 { l.observe(std::move(fn)) } -> std::same_as<Subscription>;
84 { l.size() } -> std::convertible_to<std::size_t>;
85 { l.at(i) } -> std::convertible_to<std::shared_ptr<T>>;
86 { l.snapshot() } -> std::convertible_to<std::vector<std::shared_ptr<T>>>;
87};
88
89template<typename L>
93
94} // namespace aria
Definition list_source.hpp:90
Definition list_source.hpp:80
Definition signal.hpp:12
typename detail::list_source_value_impl< std::remove_cvref_t< L > >::type list_source_value_t
Element type for a list source.
Definition list_source.hpp:76
An owning event in a sequential list edit stream.
Definition list_change.hpp:16