Iros
 
Loading...
Searching...
No Matches
zip_transform_view.h
Go to the documentation of this file.
1#pragma once
2
8
9namespace di::container {
10template<concepts::MoveConstructible F, concepts::InputContainer... Views>
11requires((concepts::View<Views> && ...) && sizeof...(Views) > 0 &&
12 concepts::Invocable<F&, meta::ContainerReference<Views>...> &&
13 concepts::CanReference<meta::InvokeResult<F&, meta::ContainerReference<Views>...>>)
14class ZipTransformView : public ViewInterface<ZipTransformView<F, Views...>> {
15private:
16 using InnerView = ZipView<Views...>;
17
18 template<bool is_const>
20
21 template<bool is_const>
23
24 template<bool is_const>
25 class Sentinel;
26
27 template<bool is_const>
28 class Iterator;
29
30 template<bool is_const>
31 class Sentinel
32 : public SentinelExtension<Sentinel<is_const>, Zentinel<is_const>, Iterator<is_const>, Ziperator<is_const>> {
33 private:
34 using Base = SentinelExtension<Sentinel<is_const>, Zentinel<is_const>, Iterator<is_const>, Ziperator<is_const>>;
35
36 friend class ZipTransformView;
37
38 constexpr explicit Sentinel(Zentinel<is_const> sentinel) : Base(sentinel) {}
39
40 public:
41 constexpr Sentinel() = default;
42
43 constexpr Sentinel(Sentinel<!is_const> other)
44 requires(is_const && concepts::ConvertibleTo<Zentinel<is_const>, Zentinel<!is_const>>)
45 : Base(other.base()) {}
46 };
47
48 template<bool is_const>
49 class Iterator
50 : public IteratorExtension<
51 Iterator<is_const>, Ziperator<is_const>,
52 meta::RemoveCVRef<meta::InvokeResult<meta::MaybeConst<is_const, F>&,
53 meta::ContainerReference<meta::MaybeConst<is_const, Views>>...>>> {
54 using Base = IteratorExtension<
55 Iterator<is_const>, Ziperator<is_const>,
58
59 friend class ZipTransformView;
60
61 constexpr explicit Iterator(meta::MaybeConst<is_const, ZipTransformView>& parent, Ziperator<is_const> iterator)
62 : Base(util::move(iterator)), m_parent(util::addressof(parent)) {}
63
64 public:
65 Iterator()
67 = default;
68
69 constexpr Iterator(Iterator<!is_const> other)
70 requires(is_const && concepts::ConvertibleTo<Ziperator<is_const>, Ziperator<!is_const>>)
71 : Base(util::move(other).base()), m_parent(other.m_parent) {}
72
73 constexpr auto operator*() const -> decltype(auto) {
74 return apply(
75 [&](auto const&... iters) -> decltype(auto) {
76 return function::invoke(m_parent->m_function.value(), *iters...);
77 },
78 this->base().iterators());
79 }
80
81 private:
82 template<bool>
83 friend class Iterator;
84
85 constexpr friend auto tag_invoke(types::Tag<iterator_move>, Iterator const& self) -> decltype(auto) {
86 if constexpr (concepts::LValueReference<decltype(*self)>) {
87 return util::move(*self);
88 } else {
89 return *self;
90 }
91 }
92
94 };
95
96public:
97 ZipTransformView() = default;
98
99 constexpr explicit ZipTransformView(F function, Views... views)
100 : m_function(util::move(function)), m_zip(util::move(views)...) {}
101
102 constexpr auto begin() { return Iterator<false>(*this, m_zip.begin()); }
103
104 constexpr auto begin() const
105 requires(concepts::Container<InnerView const> &&
106 concepts::Invocable<F const&, meta::ContainerReference<Views const>...>)
107 {
108 return Iterator<true>(*this, m_zip.begin());
109 }
110
111 constexpr auto end() {
113 return Iterator<false>(*this, m_zip.end());
114 } else {
115 return Sentinel<false>(m_zip.end());
116 }
117 }
118
119 constexpr auto end() const
120 requires(concepts::Container<InnerView const> &&
121 concepts::Invocable<F const&, meta::ContainerReference<Views const>...>)
122 {
124 return Iterator<true>(*this, m_zip.end());
125 } else {
126 return Sentinel<true>(m_zip.end());
127 }
128 }
129
130 constexpr auto size()
132 {
133 return m_zip.size();
134 }
135
136 constexpr auto size() const
137 requires(concepts::SizedContainer<InnerView const>)
138 {
139 return m_zip.size();
140 }
141
142private:
143 util::RebindableBox<F> m_function;
144 ZipView<Views...> m_zip;
145};
146
147template<class F, class... Cons>
149}
Definition iterator_extension.h:19
Definition sentinel_extension.h:10
constexpr auto base() const -> Sent
Definition sentinel_extension.h:16
Definition view_interface.h:26
Definition zip_transform_view.h:14
constexpr auto end() const
Definition zip_transform_view.h:119
constexpr ZipTransformView(F function, Views... views)
Definition zip_transform_view.h:99
constexpr auto begin()
Definition zip_transform_view.h:102
constexpr auto end()
Definition zip_transform_view.h:111
constexpr auto size() const
Definition zip_transform_view.h:136
constexpr auto begin() const
Definition zip_transform_view.h:104
constexpr auto size()
Definition zip_transform_view.h:130
Definition zip_view.h:24
Definition rebindable_box.h:42
Definition common_container.h:10
Definition operations.h:99
Definition operations.h:27
Definition language.h:30
Definition sized_container.h:8
Definition any_storable.h:9
concept F
Definition zip_transform.h:12
Definition sequence.h:12
constexpr auto move
Definition move.h:38
ZipTransformView(F, Cons &&...) -> ZipTransformView< F, meta::AsView< Cons >... >
auto tag_invoke(types::Tag< util::deduce_create >, InPlaceTemplate< NodeHashMap >, Con &&) -> NodeHashMap< meta::TupleElement< T, 0 >, meta::TupleElement< T, 1 > >
Definition as_bool.h:8
constexpr auto invoke
Definition invoke.h:100
Definition merge_interfaces.h:6
decltype(container::end(util::declval< T & >())) ContainerSentinel
Definition container_sentinel.h:8
RemoveCV< RemoveReference< T > > RemoveCVRef
Definition core.h:74
IteratorReference< ContainerIterator< T > > ContainerReference
Definition container_reference.h:8
Conditional< is_const, T const, T > MaybeConst
Definition util.h:9
decltype(container::begin(util::declval< T & >())) ContainerIterator
Definition container_iterator.h:8
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition vocab.h:96
constexpr auto apply(F &&f, Tup &&tuple) -> decltype(detail::apply_impl(meta::MakeIndexSequence< meta::TupleSize< Tup > > {}, util::forward< F >(f), util::forward< Tup >(tuple)))
Definition apply.h:22