-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathiota.go
61 lines (49 loc) · 2.06 KB
/
iota.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
package ranges
import "math"
const nearlyZero = 1e-12
type iotaResult[T RealNumber] struct {
current T
end T
}
func (ir *iotaResult[T]) Empty() bool { return ir.current >= ir.end }
func (ir *iotaResult[T]) Front() T { return ir.current }
func (ir *iotaResult[T]) PopFront() { ir.current++ }
func (ir *iotaResult[T]) Back() T { return ir.end - 1 }
func (ir *iotaResult[T]) PopBack() { ir.end-- }
func (ir *iotaResult[T]) Save() ForwardRange[T] { return ir.SaveB() }
func (ir *iotaResult[T]) SaveB() BidirectionalRange[T] { return IotaStart(ir.current, ir.end) }
// Iota returns a range of values from 0 to `end`, excluding `end`, incrementing by `1`
func Iota[T RealNumber](end T) BidirectionalRange[T] {
return &iotaResult[T]{0, end}
}
// IotaStart returns a range of values from `begin` to `end`, excluding `end`, incrementing by `1`
func IotaStart[T RealNumber](begin, end T) BidirectionalRange[T] {
return &iotaResult[T]{begin, end}
}
type iotaStepResult[T RealNumber] struct {
current T
end T
step T
}
func (ir *iotaStepResult[T]) lenOfRange() T {
return 1 + (ir.end-1-ir.current)/ir.step
}
func (ir *iotaStepResult[T]) Empty() bool { return ir.current >= ir.end }
func (ir *iotaStepResult[T]) Front() T { return ir.current }
func (ir *iotaStepResult[T]) PopFront() { ir.current += ir.step }
func (ir *iotaStepResult[T]) Back() T {
remainder := math.Mod(float64(ir.end-ir.current), float64(ir.step))
if remainder > nearlyZero {
return ir.end - T(remainder)
}
return ir.end - ir.step
}
func (ir *iotaStepResult[T]) PopBack() { ir.end -= ir.step }
func (ir *iotaStepResult[T]) Save() ForwardRange[T] { return ir.SaveB() }
func (ir *iotaStepResult[T]) SaveB() BidirectionalRange[T] {
return IotaStep(ir.current, ir.end, ir.step)
}
// IotaStep returns a range of values from `begin` to `end`, excluding `end`, incrementing by `step`
func IotaStep[T RealNumber](begin, end, step T) BidirectionalRange[T] {
return &iotaStepResult[T]{begin, end, step}
}