Peano
Loading...
Searching...
No Matches
linked_grid_iterator.h
Go to the documentation of this file.
1#pragma once
2
3#include <optional>
4
5#include <lang/assert.h>
6#include <lang/spinlock.h>
7#include <lang/type.h>
8
11};
12
14 EmitEnter = 1 << 0,
15 EmitExit = 1 << 1,
16};
17
18template<typename Spacetree>
23
24template<typename TGrid>
26 using Grid = TGrid;
27
28 Grid *root = nullptr;
29
30 Grid *getFirst(Grid *parent) = delete;
31
32 Grid *getNext(Grid *sibling) = delete;
33
34 explicit IterationOrder(Grid *top) : root(top) {}
35};
36
37template<typename TGrid>
38struct NaturalOrder : public IterationOrder<TGrid> {
41
42 Grid *getFirst(Grid *parent) {
43 return &parent->subtrees[0];
44 }
45
46 Grid *getNext(Grid *node) {
47 return node->getNextSibling();
48 }
49
50 explicit NaturalOrder(Grid *top) : Base(top) {}
51};
52
53template<typename TGrid, typename Derived, typename TIterationOrder = NaturalOrder<TGrid>>
55protected:
56 TIterationOrder iterationOrder;
57
58 TGrid *cell = nullptr;
59
61
62 bool hasEmittedLast = false;
63
67
68 bool enter(TGrid *) {
69 return true;
70 }
71
72 bool exit(TGrid *) {
73 return true;
74 }
75
76 bool hasNext() {
77 auto *SELF = (Derived *) this;
78
79 if (SELF->hasEmittedLast) return false;
80
81 return true;
82 }
83
84public:
85 using Grid = TGrid;
87
89
90 explicit DefaultIteratorCRTP(TIterationOrder order) : iterationOrder(order), cell(order.root) {}
91
92 explicit DefaultIteratorCRTP(Grid *top) : iterationOrder(TIterationOrder(top)), cell(top) {}
93
94 std::optional<Item> next() {
95 auto *SELF = (Derived *) this;
96
97 if (!SELF->hasNext()) return std::nullopt;
98
99 RESTART:
100 if (SELF->state == Direction::Enter) {
101 auto event = Item(Direction::Enter, SELF->cell);
102 auto shouldRecurse = SELF->enter(SELF->cell);
103 if (shouldRecurse & (SELF->cell->subtrees != nullptr)) {
104 SELF->cell = SELF->iterationOrder.getFirst(SELF->cell);
105 SELF->state = Direction::Enter;
106 } else SELF->state = Direction::Exit;
107 if (SELF->emitFlags() & EventEmitFlag::EmitEnter) {
108 return event;
109 } else goto RESTART;
110 } else {
111 auto event = Item(Direction::Exit, SELF->cell);
112 SELF->exit(SELF->cell);
113 if (SELF->cell == SELF->iterationOrder.root) [[unlikely]] {
114 SELF->hasEmittedLast = true;
115 if (SELF->emitFlags() & EventEmitFlag::EmitExit) {
116 return event;
117 } else return std::nullopt;
118 }
119 auto *nextSibling = SELF->iterationOrder.getNext(SELF->cell);
120 if (nextSibling) {
121 SELF->cell = nextSibling;
122 SELF->state = Direction::Enter;
123 } else {
124 SELF->cell = SELF->cell->parent;
125 SELF->state = Direction::Exit;
126 }
127 if (SELF->emitFlags() & EventEmitFlag::EmitExit) {
128 return event;
129 } else goto RESTART;
130 }
131 }
132};
133
134template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
135class DefaultIterator : public DefaultIteratorCRTP<Spacetree, DefaultIterator<Spacetree, TIterationOrder>, TIterationOrder> {
137public:
138 using Base::Base;
139};
140
141template<typename Spacetree, typename Derived, typename TIterationOrder = NaturalOrder<Spacetree>>
142class LeafsIteratorCRTP : public DefaultIteratorCRTP<Spacetree, Derived, TIterationOrder> {
143protected:
145 friend Base;
146
149 }
150
151 bool enter(Spacetree *spacetree) {
152 return true;
153 }
154
155 bool exit(Spacetree *spacetree) {
156 return true;
157 }
158
159public:
161 using Item = Spacetree*;
162
163 using Base::Base;
164
165 std::optional<Item> next() {
166 while (true) {
167 auto next = Base::next();
168 if (!next) [[unlikely]] return std::nullopt;
169 if (next->cell->subtrees) continue;
170 return next->cell;
171 }
172 }
173};
174
175template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
176class LeafsIterator : public LeafsIteratorCRTP<Spacetree, LeafsIterator<Spacetree, TIterationOrder>, TIterationOrder> {
178public:
179 using Base::Base;
180};
181
182template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
184
185template<typename Spacetree, typename Derived, typename TIterationOrder = NaturalOrder<Spacetree>>
186class BoundaryLeafsIteratorCRTP : public LeafsIteratorCRTP<Spacetree, Derived, TIterationOrder> {
187protected:
189 friend Base;
190 friend Base::Base;
191
192 Spacetree::Geo::Region boundary;
193
194 bool enter(Spacetree *spacetree) {
195 auto *SELF = (Derived*) this;
196 if (!SELF->boundary.sharesBoundary(spacetree->range)) return false;
197 return Base::enter(spacetree);
198 }
199
200public:
202 using Item = Spacetree*;
203
204 explicit BoundaryLeafsIteratorCRTP(TIterationOrder order) : BoundaryLeafsIteratorCRTP(order, order.root->range) {}
205
206 BoundaryLeafsIteratorCRTP(TIterationOrder order, Spacetree::Geo::Region boundary) : Base(order), boundary(boundary) {}
207
209
210 BoundaryLeafsIteratorCRTP(Spacetree *top, Spacetree::Geo::Region boundary) : Base(TIterationOrder(top)), boundary(boundary) {}
211
212 std::optional<Item> next() {
213 auto *SELF = (Derived*) this;
214
215 while (true) {
216 auto next = Base::next();
217 if (!next) return std::nullopt;
218 if (!SELF->boundary.sharesBoundary(next.value()->range)) continue;
219 return next;
220 }
221 }
222};
223
224template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
225class BoundaryLeafsIterator : public BoundaryLeafsIteratorCRTP<Spacetree, BoundaryLeafsIterator<Spacetree, TIterationOrder>, TIterationOrder> {
227 using Base::Base;
228};
229
230template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
232
233template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
235
236template<typename Spacetree, typename Derived, typename TIterationOrder = NaturalOrder<Spacetree>>
237class InsideRegionLeafsIteratorCRTP : public LeafsIteratorCRTP<Spacetree, Derived, TIterationOrder> {
238protected:
240 friend Base;
241 friend Base::Base;
242
243 Spacetree::Geo::Region region;
244
245 bool enter(Spacetree *spacetree) {
246 auto *SELF = (Derived*) this;
247
248 if (!SELF->region.overlaps(spacetree->range)) return false;
249 return Base::enter(spacetree);
250 }
251
252public:
254 using Item = Spacetree*;
255
256 InsideRegionLeafsIteratorCRTP(TIterationOrder order, Spacetree::Geo::Region region) : Base(order), region(region) {}
257
258 InsideRegionLeafsIteratorCRTP(Spacetree *top, Spacetree::Geo::Region region) : Base(TIterationOrder(top)), region(region) {}
259
260 std::optional<Item> next() {
261 auto *SELF = (Derived*) this;
262
263 while (true) {
264 auto next = Base::next();
265 if (!next) [[unlikely]] return std::nullopt;
266 if (!SELF->region.overlaps(next.value()->range)) [[unlikely]] continue;
267 return next;
268 }
269 }
270};
271
272template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
273class InsideRegionLeafsIterator : public InsideRegionLeafsIteratorCRTP<Spacetree, InsideRegionLeafsIterator<Spacetree, TIterationOrder>, TIterationOrder> {
275 using Base::Base;
276};
277
278template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
280
281template<typename Spacetree, typename Derived, typename TIterationOrder = NaturalOrder<Spacetree>>
282class OutsideRegionLeafsIteratorCRTP : public LeafsIteratorCRTP<Spacetree, Derived, TIterationOrder> {
283protected:
285 friend Base;
286 friend Base::Base;
287
288 Spacetree::Geo::Region region;
289
290 bool enter(Spacetree *spacetree) {
291 auto *SELF = (Derived*) this;
292
293 if (SELF->region.contains(spacetree->range)) return false;
294 return Base::enter(spacetree);
295 }
296
297public:
299 using Item = Spacetree*;
300
301 OutsideRegionLeafsIteratorCRTP(TIterationOrder order, Spacetree::Geo::Region region) : Base(order), region(region) {}
302
303 OutsideRegionLeafsIteratorCRTP(Spacetree *top, Spacetree::Geo::Region region) : Base(TIterationOrder(top)), region(region) {}
304
305 std::optional<Item> next() {
306 auto *SELF = (Derived*) this;
307
308 while (true) {
309 auto next = Base::next();
310 if (!next) return std::nullopt;
311 if (SELF->region.contains(next.value()->range)) continue;
312 return next;
313 }
314 }
315};
316
317template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
318class OutsideRegionLeafsIterator : public OutsideRegionLeafsIteratorCRTP<Spacetree, OutsideRegionLeafsIterator<Spacetree, TIterationOrder>, TIterationOrder> {
320 using Base::Base;
321};
322
323template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
325
326template<typename Spacetree, int LEVEL = 4, typename TIterationOrder = NaturalOrder<Spacetree>>
327class LeafOrLevelIterator : public DefaultIteratorCRTP<Spacetree, LeafOrLevelIterator<Spacetree, LEVEL, TIterationOrder>, TIterationOrder> {
329 friend Base;
330
331 int level = -1;
332protected:
335 }
336
337 bool enter(Spacetree *spacetree) {
338 this->level++;
339 if (this->level < LEVEL) {
340 return true;
341 }
342 return false;
343 }
344
345 bool exit(Spacetree *spacetree) {
346 this->level--;
347 return true;
348 }
349
350public:
352 using Item = Spacetree*;
353
354 using Base::Base;
355
356 std::optional<Item> next() {
357 while (true) {
358 auto next = Base::next();
359 if (!next) [[unlikely]] return std::nullopt;
360 if (this->level == LEVEL) return next->cell;
361 if (next->cell->subtrees) continue;
362 return next->cell;
363 }
364 }
365};
366
367template<typename Spacetree, int LEVEL = 4, typename TIterationOrder = NaturalOrder<Spacetree>>
369
370template<typename Spacetree, typename Derived, typename TIterationOrder = NaturalOrder<Spacetree>>
371class BottomUpIteratorCRTP : public DefaultIteratorCRTP<Spacetree, Derived, TIterationOrder> {
372protected:
374 friend Base;
375
378 }
379
380 bool enter(Spacetree *spacetree) {
381 return true;
382 }
383
384 bool exit(Spacetree *spacetree) {
385 return true;
386 }
387
388public:
390 using Item = Spacetree*;
391
392 using Base::Base;
393
394 std::optional<Item> next() {
395 while (true) {
396 auto next = Base::next();
397 if (!next) [[unlikely]] return std::nullopt;
398 return next->cell;
399 }
400 }
401};
402
403template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
404class BottomUpIterator : public BottomUpIteratorCRTP<Spacetree, BottomUpIterator<Spacetree, TIterationOrder>, TIterationOrder> {
406public:
407 using Base::Base;
408};
409
410template<typename Spacetree, typename TIterationOrder = NaturalOrder<Spacetree>>
412
413template<typename Spacetree, int LEVEL = 4, typename TIterationOrder = NaturalOrder<Spacetree>>
414class BottomUpLeafOrLevelIterator : public DefaultIteratorCRTP<Spacetree, BottomUpLeafOrLevelIterator<Spacetree, LEVEL, TIterationOrder>, TIterationOrder> {
416 friend Base;
417
418 int level = -1;
419protected:
422 }
423
424 bool enter(Spacetree *spacetree) {
425 this->level++;
426 if (this->level < LEVEL) {
427 return true;
428 }
429 return false;
430 }
431
432 bool exit(Spacetree *spacetree) {
433 this->level--;
434 return true;
435 }
436
437public:
439 using Item = Spacetree*;
440
441 using Base::Base;
442
443 std::optional<Item> next() {
444 while (true) {
445 auto next = Base::next();
446 if (!next) return std::nullopt;
447 return next->cell;
448 }
449 }
450};
451
452template<typename Spacetree, int LEVEL = 4, typename TIterationOrder = NaturalOrder<Spacetree>>
454
455template<typename InnerIterator>
458 InnerIterator *iter;
459
460public:
461 explicit SpinlockedIterator() = default;
462
463 explicit SpinlockedIterator(InnerIterator *inner) {
464 this->iter = inner;
465 }
466
467 std::optional<typename InnerIterator::Item> next() {
468 this->spinLock.lock();
469 auto next = this->iter->next();
470 this->spinLock.unlock();
471 return next;
472 }
473};
bool enter(Spacetree *spacetree)
std::optional< Item > next()
bool exit(Spacetree *spacetree)
constexpr EventEmitFlag emitFlags()
bool exit(Spacetree *spacetree)
bool enter(Spacetree *spacetree)
constexpr EventEmitFlag emitFlags()
BoundaryLeafsIteratorCRTP(Spacetree *top)
Spacetree::Geo::Region boundary
BoundaryLeafsIteratorCRTP(TIterationOrder order)
std::optional< Item > next()
BoundaryLeafsIteratorCRTP(Spacetree *top, Spacetree::Geo::Region boundary)
bool enter(Spacetree *spacetree)
BoundaryLeafsIteratorCRTP(TIterationOrder order, Spacetree::Geo::Region boundary)
DefaultIteratorCRTP()=default
DefaultIteratorCRTP(TIterationOrder order)
std::optional< Item > next()
constexpr EventEmitFlag emitFlags()
TIterationOrder iterationOrder
InsideRegionLeafsIteratorCRTP(Spacetree *top, Spacetree::Geo::Region region)
bool enter(Spacetree *spacetree)
InsideRegionLeafsIteratorCRTP(TIterationOrder order, Spacetree::Geo::Region region)
constexpr EventEmitFlag emitFlags()
bool enter(Spacetree *spacetree)
std::optional< Item > next()
bool exit(Spacetree *spacetree)
std::optional< Item > next()
DefaultIteratorCRTP< Spacetree, Derived, TIterationOrder > Base
constexpr EventEmitFlag emitFlags()
bool enter(Spacetree *spacetree)
bool exit(Spacetree *spacetree)
Geo::Region range
Definition linked_grid.h:51
bool enter(Spacetree *spacetree)
OutsideRegionLeafsIteratorCRTP(TIterationOrder order, Spacetree::Geo::Region region)
OutsideRegionLeafsIteratorCRTP(Spacetree *top, Spacetree::Geo::Region region)
void lock()
Definition spinlock.h:12
void unlock()
Definition spinlock.h:27
std::optional< typename InnerIterator::Item > next()
SpinlockedIterator()=default
SpinlockedIterator(InnerIterator *inner)
OutsideRegionLeafsIterator(Spacetree *, typename Spacetree::Geo::Region region) -> OutsideRegionLeafsIterator< Spacetree, TIterationOrder >
BottomUpIterator(Spacetree *) -> BottomUpIterator< Spacetree, TIterationOrder >
BottomUpLeafOrLevelIterator(Spacetree *) -> BottomUpLeafOrLevelIterator< Spacetree, LEVEL, TIterationOrder >
InsideRegionLeafsIterator(Spacetree *, typename Spacetree::Geo::Region region) -> InsideRegionLeafsIterator< Spacetree, TIterationOrder >
LeafOrLevelIterator(Spacetree *) -> LeafOrLevelIterator< Spacetree, LEVEL, TIterationOrder >
BoundaryLeafsIterator(Spacetree *) -> BoundaryLeafsIterator< Spacetree, TIterationOrder >
LeafsIterator(Spacetree *) -> LeafsIterator< Spacetree, TIterationOrder >
#define LEVEL
Definition setup_big.h:7
Direction direction
Spacetree * cell
Grid * getFirst(Grid *parent)=delete
Grid * getNext(Grid *sibling)=delete
Grid * getFirst(Grid *parent)
Grid * getNext(Grid *node)
NaturalOrder(Grid *top)