github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/niterator/unrollinreverseswitch/iterator.go (about) 1 package unrollinreverseswitch 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[3-i].Track = uint32(ap.Shape[i]) 27 track[3-i].Shape = uint32(ap.Shape[i]) 28 track[3-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 switch len(it.Shape) { 47 case 4: 48 next := it.NextIndex 49 result := int(next) 50 51 x := &it.Track[0] 52 x.Track-- 53 if x.Track > 0 { 54 next += x.Stride 55 it.NextIndex = next 56 return result, nil 57 } 58 x.Track = x.Shape 59 next -= (x.Shape - 1) * x.Stride 60 61 x = &it.Track[1] 62 x.Track-- 63 if x.Track > 0 { 64 next += x.Stride 65 it.NextIndex = next 66 return result, nil 67 } 68 x.Track = x.Shape 69 next -= (x.Shape - 1) * x.Stride 70 71 x = &it.Track[2] 72 x.Track-- 73 if x.Track > 0 { 74 next += x.Stride 75 it.NextIndex = next 76 return result, nil 77 } 78 x.Track = x.Shape 79 next -= (x.Shape - 1) * x.Stride 80 81 x = &it.Track[3] 82 x.Track-- 83 if x.Track > 0 { 84 next += x.Stride 85 it.NextIndex = next 86 return result, nil 87 } 88 it.Done = true 89 it.NextIndex = next 90 91 return result, nil 92 case 3: 93 next := it.NextIndex 94 result := int(next) 95 96 x := &it.Track[0] 97 x.Track-- 98 if x.Track > 0 { 99 next += x.Stride 100 it.NextIndex = next 101 return result, nil 102 } 103 x.Track = x.Shape 104 next -= (x.Shape - 1) * x.Stride 105 106 x = &it.Track[1] 107 x.Track-- 108 if x.Track > 0 { 109 next += x.Stride 110 it.NextIndex = next 111 return result, nil 112 } 113 x.Track = x.Shape 114 next -= (x.Shape - 1) * x.Stride 115 116 x = &it.Track[2] 117 x.Track-- 118 if x.Track > 0 { 119 next += x.Stride 120 it.NextIndex = next 121 return result, nil 122 } 123 it.Done = true 124 it.NextIndex = next 125 126 return result, nil 127 case 2: 128 next := it.NextIndex 129 result := int(next) 130 131 x := &it.Track[0] 132 x.Track-- 133 if x.Track > 0 { 134 next += x.Stride 135 it.NextIndex = next 136 return result, nil 137 } 138 x.Track = x.Shape 139 next -= (x.Shape - 1) * x.Stride 140 141 x = &it.Track[1] 142 x.Track-- 143 if x.Track > 0 { 144 next += x.Stride 145 it.NextIndex = next 146 return result, nil 147 } 148 it.Done = true 149 it.NextIndex = next 150 151 return result, nil 152 case 1: 153 next := it.NextIndex 154 result := int(next) 155 156 x := &it.Track[0] 157 x.Track-- 158 if x.Track > 0 { 159 next += x.Stride 160 it.NextIndex = next 161 return result, nil 162 } 163 it.Done = true 164 it.NextIndex = next 165 166 return result, nil 167 } 168 169 return -1, nil 170 }