Iros
 
Loading...
Searching...
No Matches
slide_view.h
Go to the documentation of this file.
1#pragma once
2
11#include "di/math/to_unsigned.h"
13#include "di/util/store_if.h"
14
15namespace di::container {
16namespace detail {
17 template<typename T>
19
20 template<typename T>
23
24 template<typename T>
26}
27
28template<concepts::ForwardContainer View>
32 , public meta::EnableBorrowedContainer<SlideView<View>, concepts::BorrowedContainer<View>> {
33private:
34 template<bool is_const>
36
37 template<bool is_const>
39
40 template<bool is_const>
42
43 template<bool is_const>
45
46 template<bool is_const>
47 using ValueType = decltype(container::reconstruct(
48 in_place_type<Base<is_const>>, util::declval<Iter<is_const> const&>(), util::declval<Iter<is_const> const&>()));
49
50 class Sentinel;
51
52 template<bool is_const>
53 class Iterator
54 : public IteratorBase<Iterator<is_const>,
55 meta::Conditional<concepts::RandomAccessIterator<Iter<is_const>>, RandomAccessIteratorTag,
56 meta::Conditional<concepts::BidirectionalIterator<Iter<is_const>>,
57 BidirectionalIteratorTag, ForwardIteratorTag>>,
58 ValueType<is_const>, SSizeType<is_const>> {
59 private:
60 constexpr Iterator(Iter<is_const> current, SSizeType<is_const> window_size)
62 : m_current(util::move(current)), m_window_size(window_size) {}
63
64 constexpr Iterator(Iter<is_const> current, Iter<is_const> last_element, SSizeType<is_const> window_size)
66 : m_current(util::move(current)), m_last_element(util::move(last_element)), m_window_size(window_size) {}
67
68 public:
69 Iterator() = default;
70
71 constexpr Iterator(Iterator<!is_const> other)
72 requires(is_const && concepts::ConvertibleTo<Iter<false>, Iter<true>>)
73 : m_current(util::move(other.m_current)), m_window_size(other.m_window_size) {}
74
75 constexpr auto operator*() const {
77 return container::reconstruct(in_place_type<Base<is_const>>, m_current,
78 container::next(m_last_element.value));
79 } else {
80 return container::reconstruct(in_place_type<Base<is_const>>, m_current, m_current + m_window_size);
81 }
82 }
83
84 constexpr void advance_one() {
86 ++m_last_element.value;
87 }
88 ++m_current;
89 }
90
91 constexpr void back_one()
93 {
95 --m_last_element.value;
96 }
97 --m_current;
98 }
99
100 constexpr void advance_n(SSizeType<is_const> n)
102 {
104 m_last_element.value += n;
105 }
106 m_current += n;
107 }
108
109 private:
110 template<bool>
111 friend class Iterator;
112
113 friend class Sentinel;
114
115 friend class SlideView;
116
117 constexpr friend auto operator==(Iterator const& a, Iterator const& b) -> bool {
119 return a.m_last_element.value == b.m_last_element.value;
120 } else {
121 return a.m_current == b.m_current;
122 }
123 }
124
125 constexpr friend auto operator<=>(Iterator const& a, Iterator const& b)
127 {
128 return a.m_current <=> b.m_current;
129 }
130
131 constexpr friend auto operator-(Iterator const& a, Iterator const& b)
132 requires(concepts::SizedSentinelFor<Iter<is_const>, Iter<is_const>>)
133 {
135 return a.m_last_element.value - b.m_last_element.value;
136 } else {
137 return a.m_current - b.m_current;
138 }
139 }
140
141 Iter<is_const> m_current {};
142 [[no_unique_address]] util::StoreIf<Iter<is_const>, detail::SlideCachesFirst<Base<is_const>>> m_last_element {};
143 SSizeType<is_const> m_window_size { 0 };
144 };
145
146 class Sentinel : public SentinelBase<Sentinel> {
147 private:
148 constexpr explicit Sentinel(Sent<false> base) : m_base(base) {}
149
150 public:
151 Sentinel() = default;
152
153 constexpr auto equals(Iterator<false> const& other) -> bool { return m_base == other.m_last_element; }
154
155 constexpr auto difference(Iterator<false> const& other)
156 requires(concepts::SizedSentinelFor<Sent<false>, Iter<false>>)
157 {
158 return m_base - other.m_last_element;
159 }
160
161 private:
162 friend class SlideView;
163
164 Sent<false> m_base;
165 };
166
167public:
170 = default;
171
172 constexpr explicit SlideView(View base, SSizeType<false> window_size)
173 : m_base(util::move(base)), m_window_size(window_size) {
175 }
176
177 constexpr auto base() const& -> View
178 requires(concepts::CopyConstructible<View>)
179 {
180 return m_base;
181 }
182 constexpr auto base() && -> View { return util::move(m_base); }
183
184 constexpr auto window_size() const { return m_window_size; }
185
186 constexpr auto begin()
188 {
189 if constexpr (detail::SlideCachesFirst<View>) {
190 if (!m_begin_cache.value) {
191 m_begin_cache.value.emplace(Iterator<false>(
192 container::begin(m_base),
193 container::next(container::begin(m_base), m_window_size - 1, container::end(m_base)),
194 m_window_size));
195 }
196 return m_begin_cache.value.value();
197 } else {
198 return Iterator<false>(container::begin(m_base), m_window_size);
199 }
200 }
201
202 constexpr auto begin() const
203 requires(detail::SlideCachesNothing<View const>)
204 {
205 return Iterator<true>(container::begin(m_base), m_window_size);
206 }
207
208 constexpr auto end()
210 {
211 if constexpr (detail::SlideCachesNothing<View>) {
212 return Iterator<false>(container::begin(m_base) + SSizeType<false>(size()), m_window_size);
213 } else if constexpr (detail::SlideCachesLast<View>) {
214 if (!m_end_cache.value) {
215 m_end_cache.value.emplace(Iterator<false>(
216 container::prev(container::end(m_base), m_window_size - 1, container::begin(m_base)),
217 container::end(m_base), m_window_size));
218 }
219 return m_end_cache.value.value();
220 } else if constexpr (concepts::CommonContainer<View>) {
221 return Iterator<false>(container::end(m_base), container::end(m_base), m_window_size);
222 } else {
223 return Sentinel(container::end(m_base));
224 }
225 }
226
227 constexpr auto end() const
228 requires(detail::SlideCachesNothing<View const>)
229 {
230 return begin() + SSizeType<true>(size());
231 }
232
233 constexpr auto size()
235 {
236 auto size = container::distance(m_base) - m_window_size + 1;
237 if (size < 0) {
238 size = 0;
239 }
240 return math::to_unsigned(size);
241 }
242
243 constexpr auto size() const
244 requires(concepts::SizedContainer<View const>)
245 {
246 auto size = container::distance(m_base) - m_window_size + 1;
247 if (size < 0) {
248 size = 0;
249 }
250 return math::to_unsigned(size);
251 }
252
253private:
254 View m_base;
255 SSizeType<false> m_window_size {};
256 [[no_unique_address]] util::StoreIf<util::NonPropagatingCache<Iterator<false>>, !detail::SlideCachesNothing<View>>
257 m_end_cache;
258 [[no_unique_address]] util::StoreIf<util::NonPropagatingCache<Iterator<false>>, !detail::SlideCachesNothing<View>>
259 m_begin_cache;
260};
261
262template<typename Con>
264}
#define DI_ASSERT(...)
Definition assert_bool.h:7
Definition sentinel_base.h:13
Definition slide_view.h:32
constexpr auto size()
Definition slide_view.h:233
constexpr auto end() const
Definition slide_view.h:227
constexpr auto size() const
Definition slide_view.h:243
constexpr auto end()
Definition slide_view.h:208
constexpr auto window_size() const
Definition slide_view.h:184
constexpr auto base() const &-> View requires(concepts::CopyConstructible< View >)
Definition slide_view.h:177
constexpr auto base() &&-> View
Definition slide_view.h:182
constexpr SlideView(View base, SSizeType< false > window_size)
Definition slide_view.h:172
constexpr auto begin()
Definition slide_view.h:186
constexpr auto begin() const
Definition slide_view.h:202
Definition view_interface.h:26
Definition view.h:35
Definition bidirectional_container.h:8
Definition bidirectional_iterator.h:8
Definition common_container.h:10
Definition operations.h:99
Definition operations.h:27
Definition random_access_container.h:8
Definition random_access_iterator.h:12
Definition simple_view.h:11
Definition sized_container.h:8
Definition sized_sentinel_for.h:9
Definition compare.h:91
Definition view.h:10
Definition slide_view.h:25
Definition slide_view.h:21
Definition any_storable.h:9
Definition sequence.h:13
Definition sequence.h:12
constexpr auto prev
Definition prev.h:28
constexpr auto next
Definition next.h:35
constexpr auto operator<=>(MoveIterator< Iter > const &a, MoveIterator< U > const &b)
Definition move_iterator.h:90
constexpr auto operator-(MoveIterator< Iter > const &a, MoveIterator< U > const &b) -> decltype(a.base() - b.base())
Definition move_iterator.h:95
SlideView(Con &&, meta::ContainerSSizeType< Con >) -> SlideView< meta::AsView< Con > >
constexpr auto reconstruct
Definition reconstruct.h:75
constexpr auto move
Definition move.h:38
constexpr auto operator==(MoveIterator< Iter > const &a, MoveIterator< U > const &b) -> bool
Definition move_iterator.h:85
constexpr auto distance
Definition distance.h:44
constexpr auto size
Definition size.h:54
constexpr auto end
Definition end.h:47
constexpr auto begin
Definition begin.h:44
constexpr auto to_unsigned
Definition to_unsigned.h:16
Definition merge_interfaces.h:6
IteratorSSizeType< ContainerIterator< T > > ContainerSSizeType
Definition container_ssize_type.h:8
decltype(container::end(util::declval< T & >())) ContainerSentinel
Definition container_sentinel.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
Definition vocab.h:96
auto declval() -> meta::AddRValueReference< T >
Definition declval.h:8
constexpr auto in_place_type
Definition in_place_type.h:12
Definition enable_borrowed_container.h:9
Definition iterator_base.h:14
Definition store_if.h:7
T value
Definition store_if.h:8