github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/niterator/unrollinverse/iterator.go (about) 1 package unrollinverse 2 3 import ( 4 "io" 5 6 "github.com/egonelbre/exp/niterator/shape" 7 ) 8 9 type Index struct { 10 Track uint32 11 Shape uint32 12 Stride 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 track := [4]Index{} 25 for i := range ap.Shape { 26 track[i].Track = uint32(ap.Shape[i]) 27 track[i].Shape = uint32(ap.Shape[i]) 28 track[i].Stride = uint32(ap.Stride[i]) 29 } 30 31 return &Iterator{ 32 AP: ap, 33 Track: track, 34 } 35 } 36 37 func (it *Iterator) IsDone() bool { 38 return it.Done 39 } 40 41 func (it *Iterator) Next() (int, error) { 42 if it.Done { 43 return 0, io.EOF 44 } 45 46 next := it.NextIndex 47 result := int(next) 48 49 x := &it.Track[3] 50 x.Track-- 51 if x.Track > 0 { 52 next += x.Stride 53 it.NextIndex = next 54 return result, nil 55 } 56 x.Track = x.Shape 57 next -= (x.Shape - 1) * x.Stride 58 59 x = &it.Track[2] 60 x.Track-- 61 if x.Track > 0 { 62 next += x.Stride 63 it.NextIndex = next 64 return result, nil 65 } 66 x.Track = x.Shape 67 next -= (x.Shape - 1) * x.Stride 68 69 x = &it.Track[1] 70 x.Track-- 71 if x.Track > 0 { 72 next += x.Stride 73 it.NextIndex = next 74 return result, nil 75 } 76 x.Track = x.Shape 77 next -= (x.Shape - 1) * x.Stride 78 79 x = &it.Track[0] 80 x.Track-- 81 if x.Track > 0 { 82 next += x.Stride 83 it.NextIndex = next 84 return result, nil 85 } 86 it.Done = true 87 it.NextIndex = next 88 89 return result, nil 90 }