Iros
 
Loading...
Searching...
No Matches
cycle_view.h
Go to the documentation of this file.
1#pragma once
2
10#include "di/meta/util.h"
12#include "di/util/store_if.h"
13
14namespace di::container {
15template<concepts::ForwardContainer View>
16requires(concepts::View<View>)
18private:
19 template<bool is_const>
21
22 template<bool is_const>
24
25 template<bool is_const>
27
28 template<bool is_const>
30
31 template<bool is_const>
33
34 template<bool is_const>
35 class Iterator
36 : public IteratorBase<Iterator<is_const>,
37 meta::Conditional<concepts::RandomAccessIterator<Iter<is_const>>, RandomAccessIteratorTag,
38 meta::Conditional<concepts::BidirectionalIterator<Iter<is_const>>,
39 BidirectionalIteratorTag, ForwardIteratorTag>>,
40 Value<is_const>, SSizeType<is_const>> {
41 private:
42 friend class CycleView;
43
44 constexpr explicit Iterator(Parent<is_const>* parent, Iter<is_const> base)
45 : m_parent(parent), m_base(util::move(base)) {}
46
47 constexpr auto get_end() {
49 return container::end(m_parent->base_ref());
50 } else {
51 if (!m_parent->m_end_cache) {
52 m_parent->m_end_cache.value.emplace(container::next(m_base, container::end(m_parent->base_ref())));
53 }
54 return m_parent->m_end_cache.value.value();
55 }
56 }
57
58 public:
59 Iterator() = default;
60
61 template<bool other_is_const = !is_const>
62 constexpr Iterator(Iterator<other_is_const> other)
63 requires(is_const && concepts::ConvertibleTo<Iter<false>, Iter<true>>)
64 : m_parent(other.m_parent), m_base(util::move(other.m_base)), m_cycle_number(other.m_cycle_number) {}
65
66 constexpr auto base() const& { return m_base; }
67 constexpr auto base() && { return util::move(m_base); }
68
69 constexpr auto operator*() const -> decltype(auto) { return *m_base; }
70
71 constexpr void advance_one() {
72 if (++m_base == get_end()) {
73 ++m_cycle_number;
74 m_base = container::begin(m_parent->base_ref());
75 }
76 }
77
78 constexpr void back_one()
80 {
81 if (m_base == container::begin(m_parent->base_ref())) {
82 --m_cycle_number;
83 m_base = get_end();
84 }
85 --m_base;
86 }
87
88 constexpr void advance_n(SSizeType<is_const> n)
90 {
91 auto start = container::begin(m_parent->base_ref());
92 auto size = container::distance(start, get_end());
93
94 auto offset = m_base - start;
95 auto new_offset = (offset + n) % size;
96
97 if (new_offset < 0) {
98 new_offset += size;
99 }
100 m_base = start + new_offset;
101 m_cycle_number += (offset + n) / size;
102 }
103
104 private:
105 template<bool>
106 friend class Iterator;
107
108 constexpr friend auto operator==(Iterator const& a, Iterator const& b) -> bool {
109 return a.m_cycle_number == b.m_cycle_number && a.m_base == b.m_base;
110 }
111
112 constexpr friend auto operator<=>(Iterator const& a, Iterator const& b)
114 {
116 if (auto result = a.m_cycle_number <=> b.m_cycle_number; result != 0) {
117 return static_cast<Result>(result);
118 }
119 return a.m_base <=> b.m_base;
120 }
121
122 constexpr friend auto operator-(Iterator const& a, Iterator const& b) -> SSizeType<is_const>
124 {
125 auto start = container::begin(a.m_parent->base_ref());
126 auto size = container::distance(start, container::end(a.m_parent->base_ref()));
127
128 return (a.m_cycle_number - b.m_cycle_number) * size + (a.m_base - b.m_base);
129 }
130
131 Parent<is_const>* m_parent { nullptr };
132 Iter<is_const> m_base {};
133 ssize_t m_cycle_number { 0 };
134 };
135
136public:
139 = default;
140
141 constexpr CycleView(View view) : m_base(util::move(view)) {}
142
143 constexpr auto base() const& -> View
144 requires(concepts::CopyConstructible<View>)
145 {
146 return m_base;
147 }
148
149 constexpr auto base() && -> View
151 {
152 return util::move(m_base);
153 }
154
155 constexpr auto base_ref() -> View& { return m_base; }
156 constexpr auto base_ref() const -> View const& { return m_base; }
157
158 constexpr auto begin()
160 {
161 return Iterator<false>(this, container::begin(m_base));
162 }
163
164 constexpr auto begin() const
165 requires(concepts::CommonContainer<View const>)
166 {
167 return Iterator<true>(this, container::begin(m_base));
168 }
169
170 constexpr auto end() const { return unreachable_sentinel; }
171
172private:
173 View m_base {};
176};
177
178template<typename Con>
180}
Definition cycle_view.h:17
constexpr auto begin()
Definition cycle_view.h:158
constexpr auto base() &&-> View requires(concepts::CopyConstructible< View >)
Definition cycle_view.h:149
constexpr CycleView(View view)
Definition cycle_view.h:141
constexpr auto end() const
Definition cycle_view.h:170
constexpr auto base_ref() const -> View const &
Definition cycle_view.h:156
constexpr auto begin() const
Definition cycle_view.h:164
constexpr auto base() const &-> View requires(concepts::CopyConstructible< View >)
Definition cycle_view.h:143
constexpr auto base_ref() -> View &
Definition cycle_view.h:155
Definition view_interface.h:26
constexpr auto size()
Definition view_interface.h:86
Definition view.h:35
Definition bidirectional_iterator.h:8
Definition common_container.h:10
Definition operations.h:99
Definition operations.h:34
Definition operations.h:27
Definition random_access_iterator.h:12
Definition simple_view.h:11
Definition compare.h:91
Definition any_storable.h:9
Definition adjacent.h:8
Definition sequence.h:12
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
constexpr auto move
Definition move.h:38
CycleView(Con &&) -> CycleView< meta::AsView< Con > >
constexpr auto unreachable_sentinel
Definition unreachable_sentinel.h:11
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 end
Definition end.h:47
constexpr auto begin
Definition begin.h:44
IteratorSSizeType< ContainerIterator< T > > ContainerSSizeType
Definition container_ssize_type.h:8
meta::Type< detail::CompareThreeWayResultHelper< T, U > > CompareThreeWayResult
Definition compare.h:133
Conditional< is_const, T const, T > MaybeConst
Definition util.h:9
IteratorValue< ContainerIterator< T > > ContainerValue
Definition container_value.h:8
decltype(container::begin(util::declval< T & >())) ContainerIterator
Definition container_iterator.h:8
ptrdiff_t ssize_t
Definition ssize_t.h:6
Definition vocab.h:96
Expected< T, Error > Result
Definition result.h:8
Definition iterator_base.h:14
Definition store_if.h:7