Manifold 1.0
Robust computational geometry
 
Loading...
Searching...
No Matches
iters.h
1// Copyright 2024 The Manifold Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14#pragma once
15
16#include <iterator>
17#include <type_traits>
18
19namespace manifold {
20
21template <typename F, typename Iter>
23 private:
24 Iter iter;
25 F f;
26
27 public:
28 using pointer = void;
29 using reference = std::invoke_result_t<
30 F, typename std::iterator_traits<std::remove_const_t<Iter>>::value_type>;
31 using difference_type =
32 typename std::iterator_traits<std::remove_const_t<Iter>>::difference_type;
33 using value_type = reference;
34 using iterator_category = typename std::iterator_traits<
35 std::remove_const_t<Iter>>::iterator_category;
36
37 constexpr TransformIterator(Iter iter, F f) : iter(iter), f(f) {}
38
39 TransformIterator& operator=(const TransformIterator& other) {
40 if (this == &other) return *this;
41 // don't copy function, should be the same
42 iter = other.iter;
43 return *this;
44 }
45
46 constexpr reference operator*() const { return f(*iter); }
47
48 constexpr reference operator[](size_t i) const { return f(iter[i]); }
49
50 // prefix increment
51 TransformIterator& operator++() {
52 iter += 1;
53 return *this;
54 }
55
56 // postfix
57 TransformIterator operator++(int) {
58 auto old = *this;
59 operator++();
60 return old;
61 }
62
63 // prefix increment
64 TransformIterator& operator--() {
65 iter -= 1;
66 return *this;
67 }
68
69 // postfix
70 TransformIterator operator--(int) {
71 auto old = *this;
72 operator--();
73 return old;
74 }
75
76 constexpr TransformIterator operator+(size_t n) const {
77 return TransformIterator(iter + n, f);
78 }
79
80 TransformIterator& operator+=(size_t n) {
81 iter += n;
82 return *this;
83 }
84
85 constexpr TransformIterator operator-(size_t n) const {
86 return TransformIterator(iter - n, f);
87 }
88
89 TransformIterator& operator-=(size_t n) {
90 iter -= n;
91 return *this;
92 }
93
94 constexpr bool operator==(TransformIterator other) const {
95 return iter == other.iter;
96 }
97
98 constexpr bool operator!=(TransformIterator other) const {
99 return !(iter == other.iter);
100 }
101
102 constexpr bool operator<(TransformIterator other) const {
103 return iter < other.iter;
104 }
105
106 constexpr difference_type operator-(TransformIterator other) const {
107 return iter - other.iter;
108 }
109
110 constexpr operator TransformIterator<F, const Iter>() const {
111 return TransformIterator(f, iter);
112 }
113};
114
115template <typename T>
117 private:
118 T counter;
119
120 public:
121 using pointer = void;
122 using reference = T;
123 using difference_type = std::make_signed_t<T>;
124 using value_type = T;
125 using iterator_category = std::random_access_iterator_tag;
126
127 constexpr CountingIterator(T counter) : counter(counter) {}
128
129 constexpr value_type operator*() const { return counter; }
130 constexpr value_type operator[](T i) const { return counter + i; }
131
132 // prefix increment
133 CountingIterator& operator++() {
134 counter += 1;
135 return *this;
136 }
137
138 // postfix
139 CountingIterator operator++(int) {
140 auto old = *this;
141 operator++();
142 return old;
143 }
144
145 // prefix increment
146 CountingIterator& operator--() {
147 counter -= 1;
148 return *this;
149 }
150
151 // postfix
152 CountingIterator operator--(int) {
153 auto old = *this;
154 operator--();
155 return old;
156 }
157
158 constexpr CountingIterator operator+(T n) const {
159 return CountingIterator(counter + n);
160 }
161
162 CountingIterator& operator+=(T n) {
163 counter += n;
164 return *this;
165 }
166
167 constexpr CountingIterator operator-(T n) const {
168 return CountingIterator(counter - n);
169 }
170
171 CountingIterator& operator-=(T n) {
172 counter -= n;
173 return *this;
174 }
175
176 constexpr friend bool operator==(CountingIterator a, CountingIterator b) {
177 return a.counter == b.counter;
178 }
179
180 constexpr friend bool operator!=(CountingIterator a, CountingIterator b) {
181 return a.counter != b.counter;
182 }
183
184 constexpr friend bool operator<(CountingIterator a, CountingIterator b) {
185 return a.counter < b.counter;
186 }
187
188 constexpr friend difference_type operator-(CountingIterator a,
190 return a.counter - b.counter;
191 }
192
193 constexpr operator CountingIterator<const T>() const {
194 return CountingIterator(counter);
195 }
196};
197
198constexpr CountingIterator<size_t> countAt(size_t i) {
199 return CountingIterator(i);
200}
201
202template <typename Iter>
204 private:
205 struct StridedRangeIter {
206 private:
207 Iter iter;
208 size_t stride;
209
210 public:
211 using pointer =
212 typename std::iterator_traits<std::remove_const_t<Iter>>::pointer;
213 using reference =
214 typename std::iterator_traits<std::remove_const_t<Iter>>::reference;
215 using difference_type = typename std::iterator_traits<
216 std::remove_const_t<Iter>>::difference_type;
217 using value_type =
218 typename std::iterator_traits<std::remove_const_t<Iter>>::value_type;
219 using iterator_category = typename std::iterator_traits<
220 std::remove_const_t<Iter>>::iterator_category;
221
222 constexpr StridedRangeIter(Iter iter, int stride)
223 : iter(iter), stride(stride) {}
224
225 constexpr reference operator*() { return *iter; }
226
227 constexpr std::add_const_t<reference> operator*() const { return *iter; }
228
229 constexpr reference operator[](size_t i) { return iter[i * stride]; }
230
231 constexpr std::add_const_t<reference> operator[](size_t i) const {
232 return iter[i * stride];
233 }
234
235 // prefix increment
236 StridedRangeIter& operator++() {
237 iter += stride;
238 return *this;
239 }
240
241 // postfix
242 StridedRangeIter operator++(int) {
243 auto old = *this;
244 operator++();
245 return old;
246 }
247
248 // prefix increment
249 StridedRangeIter& operator--() {
250 iter -= stride;
251 return *this;
252 }
253
254 // postfix
255 StridedRangeIter operator--(int) {
256 auto old = *this;
257 operator--();
258 return old;
259 }
260
261 constexpr StridedRangeIter operator+(size_t n) const {
262 return StridedRangeIter(iter + n * stride, stride);
263 }
264
265 StridedRangeIter& operator+=(size_t n) {
266 iter += n * stride;
267 return *this;
268 }
269
270 constexpr StridedRangeIter operator-(size_t n) const {
271 return StridedRangeIter(iter - n * stride, stride);
272 }
273
274 StridedRangeIter& operator-=(size_t n) {
275 iter -= n * stride;
276 return *this;
277 }
278
279 constexpr friend bool operator==(StridedRangeIter a, StridedRangeIter b) {
280 return a.iter == b.iter;
281 }
282
283 constexpr friend bool operator!=(StridedRangeIter a, StridedRangeIter b) {
284 return !(a.iter == b.iter);
285 }
286
287 constexpr friend bool operator<(StridedRangeIter a, StridedRangeIter b) {
288 return a.iter < b.iter;
289 }
290
291 constexpr friend difference_type operator-(StridedRangeIter a,
292 StridedRangeIter b) {
293 // note that this is not well-defined if a.stride != b.stride...
294 return (a.iter - b.iter) / a.stride;
295 }
296 };
297 Iter _start, _end;
298 const size_t stride;
299
300 public:
301 constexpr StridedRange(Iter start, Iter end, size_t stride)
302 : _start(start), _end(end), stride(stride) {}
303
304 constexpr StridedRangeIter begin() const {
305 return StridedRangeIter(_start, stride);
306 }
307
308 constexpr StridedRangeIter end() const {
309 return StridedRangeIter(_start, stride) +
310 ((std::distance(_start, _end) + (stride - 1)) / stride);
311 }
312};
313
314} // namespace manifold
Definition common.h:22
Definition iters.h:116
Definition iters.h:203
Definition iters.h:22