-
Notifications
You must be signed in to change notification settings - Fork 1
/
stride.go
86 lines (68 loc) · 1.66 KB
/
stride.go
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
package ranges
type strideResult[T any] struct {
r InputRange[T]
size int
}
func (sr *strideResult[T]) Empty() bool {
return sr.r.Empty()
}
func (sr *strideResult[T]) Front() T {
return sr.r.Front()
}
func (sr *strideResult[T]) PopFront() {
sr.r.PopFront()
for i := 1; i < sr.size && !sr.r.Empty(); i++ {
sr.r.PopFront()
}
}
type strideForwardResult[T any] struct {
strideResult[T]
}
func (sfr *strideForwardResult[T]) Save() ForwardRange[T] {
return &strideForwardResult[T]{
strideResult[T]{sfr.r.(ForwardRange[T]).Save(), sfr.size},
}
}
type strideSliceResult[T any] struct {
slice []T
size int
}
func (ssr *strideSliceResult[T]) Empty() bool {
return len(ssr.slice) == 0
}
func (ssr *strideSliceResult[T]) Front() T {
return ssr.slice[0]
}
func (ssr *strideSliceResult[T]) PopFront() {
if ssr.size > len(ssr.slice) {
ssr.slice = nil
} else {
ssr.slice = ssr.slice[ssr.size:]
}
}
func (ssr *strideSliceResult[T]) Save() ForwardRange[T] {
return &strideSliceResult[T]{ssr.slice, ssr.size}
}
// Stride produces every `step` elements in a range.
func Stride[T any](r InputRange[T], step int) InputRange[T] {
if step < 1 {
panic("step < 1 for Stride")
}
return &strideResult[T]{r, step}
}
// StrideF is `Stride` producing a `ForwardRange`
func StrideF[T any](r ForwardRange[T], step int) ForwardRange[T] {
if step < 1 {
panic("step < 1 for Stride")
}
return &strideForwardResult[T]{strideResult[T]{r, step}}
}
// StrideS is `StrideF` accepting a slice.
//
// This result is optimized for slices.
func StrideS[T any](r []T, step int) ForwardRange[T] {
if step < 1 {
panic("step < 1 for Stride")
}
return &strideSliceResult[T]{r, step}
}