-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patharray.go
More file actions
106 lines (87 loc) · 2.19 KB
/
array.go
File metadata and controls
106 lines (87 loc) · 2.19 KB
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
105
106
package grid
import (
"iter"
geom "github.com/gravitton/geometry"
"github.com/gravitton/geometry/types/ints"
)
// Array is a 2D array.
type Array[T any] struct {
size ints.Size
data []T
}
// Arr makes a new Array from Size.
func Arr[T any](size ints.Size) Array[T] {
return Array[T]{size, make([]T, size.Area())}
}
// Size returns Array size.
func (a Array[T]) Size() ints.Size {
return a.size
}
// Width returns Array width.
func (a Array[T]) Width() int {
return a.size.Width
}
// Height returns Array height.
func (a Array[T]) Height() int {
return a.size.Height
}
// Len returns Array length.
func (a Array[T]) Len() int {
return len(a.data)
}
// Has reports whether the index is within bounds.
func (a Array[T]) Has(index ints.Point) bool {
return a.valid(index)
}
// Get returns a pointer to the value at index. Panics if index is out of bounds.
func (a Array[T]) Get(index ints.Point) *T {
return &a.data[a.index(index)]
}
// Set stores value at index. Panics if index is out of bounds.
func (a Array[T]) Set(index ints.Point, value T) {
a.data[a.index(index)] = value
}
// Fill sets every element to value.
func (a Array[T]) Fill(value T) {
for i := 0; i < len(a.data); i++ {
a.data[i] = value
}
}
// Clear resets every element to the zero value.
func (a Array[T]) Clear() {
clear(a.data)
}
// Clone returns a deep copy of the array.
func (a Array[T]) Clone() Array[T] {
data := make([]T, len(a.data))
copy(data, a.data)
return Array[T]{a.size, data}
}
// Iter returns iterator over all points.
func (a Array[T]) Iter() iter.Seq[ints.Point] {
return func(yield func(ints.Point) bool) {
for y := range a.Height() {
for x := range a.Width() {
if !yield(geom.Pt(x, y)) {
return
}
}
}
}
}
// Iter2 returns an iterator over all (point, value) pairs.
func (a Array[T]) Iter2() iter.Seq2[ints.Point, *T] {
return func(yield func(ints.Point, *T) bool) {
for pt := range a.Iter() {
if !yield(pt, &a.data[a.index(pt)]) {
return
}
}
}
}
func (a Array[T]) index(index ints.Point) int {
return index.X + index.Y*a.size.Width
}
func (a Array[T]) valid(index ints.Point) bool {
return index.X >= 0 && index.X < a.Width() && index.Y >= 0 && index.Y < a.Height()
}