Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/manifold/src/iters.h
9913 views
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 <optional>
18
#include <type_traits>
19
20
namespace manifold {
21
22
template <typename F, typename Iter>
23
struct TransformIterator {
24
private:
25
Iter iter;
26
std::optional<F> f;
27
28
public:
29
using pointer = void;
30
using reference = std::invoke_result_t<
31
F, typename std::iterator_traits<std::remove_const_t<Iter>>::value_type>;
32
using difference_type =
33
typename std::iterator_traits<std::remove_const_t<Iter>>::difference_type;
34
using value_type = reference;
35
using iterator_category = typename std::iterator_traits<
36
std::remove_const_t<Iter>>::iterator_category;
37
38
constexpr TransformIterator(Iter iter, F f) : iter(iter), f(f) {}
39
40
TransformIterator(const TransformIterator& other)
41
: iter(other.iter), f(other.f) {}
42
43
TransformIterator(TransformIterator&& other) : iter(other.iter), f(other.f) {}
44
45
TransformIterator& operator=(const TransformIterator& other) {
46
if (this == &other) return *this;
47
iter = other.iter;
48
f.emplace(*other.f);
49
return *this;
50
}
51
52
TransformIterator& operator=(TransformIterator&& other) {
53
if (this == &other) return *this;
54
iter = other.iter;
55
f.emplace(*other.f);
56
return *this;
57
}
58
59
constexpr reference operator*() const { return (*f)(*iter); }
60
61
constexpr reference operator[](size_t i) const { return (*f)(iter[i]); }
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
// prefix increment
77
TransformIterator& operator--() {
78
iter -= 1;
79
return *this;
80
}
81
82
// postfix
83
TransformIterator operator--(int) {
84
auto old = *this;
85
operator--();
86
return old;
87
}
88
89
constexpr TransformIterator operator+(size_t n) const {
90
return TransformIterator(iter + n, *f);
91
}
92
93
TransformIterator& operator+=(size_t n) {
94
iter += n;
95
return *this;
96
}
97
98
constexpr TransformIterator operator-(size_t n) const {
99
return TransformIterator(iter - n, *f);
100
}
101
102
TransformIterator& operator-=(size_t n) {
103
iter -= n;
104
return *this;
105
}
106
107
constexpr bool operator==(TransformIterator other) const {
108
return iter == other.iter;
109
}
110
111
constexpr bool operator!=(TransformIterator other) const {
112
return !(iter == other.iter);
113
}
114
115
constexpr bool operator<(TransformIterator other) const {
116
return iter < other.iter;
117
}
118
119
constexpr difference_type operator-(TransformIterator other) const {
120
return iter - other.iter;
121
}
122
123
constexpr operator TransformIterator<F, const Iter>() const {
124
return TransformIterator(*f, iter);
125
}
126
};
127
128
template <typename T>
129
struct CountingIterator {
130
private:
131
T counter;
132
133
public:
134
using pointer = void;
135
using reference = T;
136
using difference_type = std::make_signed_t<T>;
137
using value_type = T;
138
using iterator_category = std::random_access_iterator_tag;
139
140
constexpr CountingIterator(T counter) : counter(counter) {}
141
142
constexpr value_type operator*() const { return counter; }
143
constexpr value_type operator[](T i) const { return counter + i; }
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
// prefix increment
159
CountingIterator& operator--() {
160
counter -= 1;
161
return *this;
162
}
163
164
// postfix
165
CountingIterator operator--(int) {
166
auto old = *this;
167
operator--();
168
return old;
169
}
170
171
constexpr CountingIterator operator+(T n) const {
172
return CountingIterator(counter + n);
173
}
174
175
CountingIterator& operator+=(T n) {
176
counter += n;
177
return *this;
178
}
179
180
constexpr CountingIterator operator-(T n) const {
181
return CountingIterator(counter - n);
182
}
183
184
CountingIterator& operator-=(T n) {
185
counter -= n;
186
return *this;
187
}
188
189
constexpr friend bool operator==(CountingIterator a, CountingIterator b) {
190
return a.counter == b.counter;
191
}
192
193
constexpr friend bool operator!=(CountingIterator a, CountingIterator b) {
194
return a.counter != b.counter;
195
}
196
197
constexpr friend bool operator<(CountingIterator a, CountingIterator b) {
198
return a.counter < b.counter;
199
}
200
201
constexpr friend difference_type operator-(CountingIterator a,
202
CountingIterator b) {
203
return a.counter - b.counter;
204
}
205
206
constexpr operator CountingIterator<const T>() const {
207
return CountingIterator(counter);
208
}
209
};
210
211
constexpr CountingIterator<size_t> countAt(size_t i) {
212
return CountingIterator(i);
213
}
214
215
template <typename Iter>
216
struct StridedRange {
217
private:
218
struct StridedRangeIter {
219
private:
220
Iter iter;
221
size_t stride;
222
223
public:
224
using pointer =
225
typename std::iterator_traits<std::remove_const_t<Iter>>::pointer;
226
using reference =
227
typename std::iterator_traits<std::remove_const_t<Iter>>::reference;
228
using difference_type = typename std::iterator_traits<
229
std::remove_const_t<Iter>>::difference_type;
230
using value_type =
231
typename std::iterator_traits<std::remove_const_t<Iter>>::value_type;
232
using iterator_category = typename std::iterator_traits<
233
std::remove_const_t<Iter>>::iterator_category;
234
235
constexpr StridedRangeIter(Iter iter, int stride)
236
: iter(iter), stride(stride) {}
237
238
constexpr reference operator*() { return *iter; }
239
240
constexpr std::add_const_t<reference> operator*() const { return *iter; }
241
242
constexpr reference operator[](size_t i) { return iter[i * stride]; }
243
244
constexpr std::add_const_t<reference> operator[](size_t i) const {
245
return iter[i * stride];
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
// prefix increment
262
StridedRangeIter& operator--() {
263
iter -= stride;
264
return *this;
265
}
266
267
// postfix
268
StridedRangeIter operator--(int) {
269
auto old = *this;
270
operator--();
271
return old;
272
}
273
274
constexpr StridedRangeIter operator+(size_t n) const {
275
return StridedRangeIter(iter + n * stride, stride);
276
}
277
278
StridedRangeIter& operator+=(size_t n) {
279
iter += n * stride;
280
return *this;
281
}
282
283
constexpr StridedRangeIter operator-(size_t n) const {
284
return StridedRangeIter(iter - n * stride, stride);
285
}
286
287
StridedRangeIter& operator-=(size_t n) {
288
iter -= n * stride;
289
return *this;
290
}
291
292
constexpr friend bool operator==(StridedRangeIter a, StridedRangeIter b) {
293
return a.iter == b.iter;
294
}
295
296
constexpr friend bool operator!=(StridedRangeIter a, StridedRangeIter b) {
297
return !(a.iter == b.iter);
298
}
299
300
constexpr friend bool operator<(StridedRangeIter a, StridedRangeIter b) {
301
return a.iter < b.iter;
302
}
303
304
constexpr friend difference_type operator-(StridedRangeIter a,
305
StridedRangeIter b) {
306
// note that this is not well-defined if a.stride != b.stride...
307
return (a.iter - b.iter) / a.stride;
308
}
309
};
310
Iter _start, _end;
311
const size_t stride;
312
313
public:
314
constexpr StridedRange(Iter start, Iter end, size_t stride)
315
: _start(start), _end(end), stride(stride) {}
316
317
constexpr StridedRangeIter begin() const {
318
return StridedRangeIter(_start, stride);
319
}
320
321
constexpr StridedRangeIter end() const {
322
return StridedRangeIter(_start, stride) +
323
((std::distance(_start, _end) + (stride - 1)) / stride);
324
}
325
};
326
327
} // namespace manifold
328
329