-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
array-iterator.spice
104 lines (92 loc) · 2.41 KB
/
array-iterator.spice
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import "std/iterator/iterator";
import "std/data/pair";
// Generic type definitions
type I dyn;
type Numeric int|long|short;
/**
* A ArrayIterator in Spice can be used to iterate over an arbitrary array
*/
public type ArrayIterator<I> struct : IIterator<I> {
I* array
unsigned long size
unsigned long cursor
}
public p ArrayIterator.ctor(I[] array, unsigned long size) {
this.array = array;
this.size = size;
this.cursor = 0l;
}
/**
* Returns the current item of the array
*
* @return Reference to the current item
*/
public inline f<I&> ArrayIterator.get() {
unsafe {
return this.array[this.cursor];
}
}
public inline f<Pair<unsigned long, I&>> ArrayIterator.getIdx() {
unsafe {
return Pair<unsigned long, I&>(this.cursor, this.array[this.cursor]);
}
}
/**
* Check if the iterator is valid
*
* @return true or false
*/
public inline const f<bool> ArrayIterator.isValid() {
return this.cursor < this.size;
}
/**
* Returns the current item of the array and moves the cursor to the next one
*/
public inline p ArrayIterator.next() {
if !this.isValid() { panic(Error("Calling next() on invalid iterator")); }
this.cursor++;
}
/**
* Advances the cursor by one
*
* @param it ArrayIterator
*/
public inline p operator++<I>(ArrayIterator<I>& it) {
if it.cursor >= it.size - 1 { panic(Error("Iterator out of bounds")); }
it.cursor++;
}
/**
* Move the cursor back by one
*
* @param it ArrayIterator
*/
public inline p operator--<I>(ArrayIterator<I>& it) {
if it.cursor <= 0 { panic(Error("Iterator out of bounds")); }
it.cursor--;
}
/**
* Advances the cursor by the given offset
*
* @param it ArrayIterator
* @param offset Offset
*/
public inline p operator+=<I, Numeric>(ArrayIterator<I>& it, Numeric offset) {
if it.cursor + offset >= it.size || it.cursor + offset < 0 { panic(Error("Iterator out of bounds")); }
it.cursor += offset;
}
/**
* Move the cursor back by the given offset
*
* @param it ArrayIterator
* @param offset Offset
*/
public inline p operator-=<I, Numeric>(ArrayIterator<I>& it, Numeric offset) {
if it.cursor - offset >= it.size || it.cursor - offset < 0 { panic(Error("Iterator out of bounds")); }
it.cursor -= offset;
}
/**
* Convenience wrapper for creating a simple array iterator
*/
public inline f<ArrayIterator<I>> iterate<I>(I[] array, unsigned long size) {
return ArrayIterator<I>(array, size);
}