github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/niterator/onearrrevspecialize/iterator.go (about) 1 package onearrrevspecialize 2 3 import ( 4 "io" 5 6 "github.com/egonelbre/exp/niterator/shape" 7 ) 8 9 type Index struct { 10 Track uint32 11 Stride uint32 12 Shape uint32 13 } 14 15 type Iterator struct { 16 *shape.AP 17 18 Track [4]Index 19 NextIndex uint32 20 Done bool 21 } 22 23 func NewIterator(ap *shape.AP) *Iterator { 24 it := &Iterator{} 25 it.AP = ap 26 27 last := len(ap.Shape) - 1 28 track := &it.Track 29 for i := range ap.Shape { 30 (*track)[last-i].Track = uint32(ap.Shape[i]) 31 (*track)[last-i].Shape = uint32(ap.Shape[i]) 32 (*track)[last-i].Stride = uint32(ap.Stride[i]) 33 } 34 35 return it 36 } 37 38 func (it *Iterator) IsDone() bool { 39 return it.Done 40 } 41 42 func (it *Iterator) Next() (int, error) { 43 if it.Done { 44 return 0, io.EOF 45 } 46 47 next := it.NextIndex 48 result := next 49 for i := range it.Track { 50 x := &it.Track[i] 51 x.Track-- 52 if x.Track > 0 { 53 next += x.Stride 54 it.NextIndex = next 55 return int(result), nil 56 } 57 x.Track = x.Shape 58 next -= (x.Shape - 1) * x.Stride 59 } 60 61 it.Done = true 62 it.NextIndex = next 63 return int(result), nil 64 }