go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/tables/ifxx.go (about) 1 package tables 2 3 import ( 4 "fmt" 5 "go-ml.dev/pkg/base/fu" 6 "go-ml.dev/pkg/base/fu/lazy" 7 "math" 8 "reflect" 9 ) 10 11 const epsilon = 1e-9 12 13 func equalf(vc reflect.Value) func(v reflect.Value) bool { 14 switch vc.Kind() { 15 case reflect.Slice: 16 vv := []func(reflect.Value) bool{} 17 for i := 0; i < vc.Len(); i++ { 18 vv = append(vv, equalf(vc.Index(i))) 19 } 20 return func(v reflect.Value) bool { 21 for _, f := range vv { 22 if f(v) { 23 return true 24 } 25 } 26 return false 27 } 28 case reflect.Interface: 29 return equalf(vc.Elem()) 30 case reflect.Float32, reflect.Float64: 31 vv := vc.Float() 32 return func(v reflect.Value) bool { 33 switch v.Kind() { 34 case reflect.Float64, reflect.Float32: 35 return math.Abs(v.Float()-vv) < epsilon 36 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 37 return math.Abs(float64(v.Uint())-vv) < epsilon 38 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 39 return math.Abs(float64(v.Int())-vv) < epsilon 40 default: 41 if v.Type() == fu.Fixed8Type { 42 return math.Abs(float64(v.Interface().(fu.Fixed8).Float32())-vv) < epsilon 43 } 44 } 45 return false 46 } 47 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 48 vv := vc.Int() 49 return func(v reflect.Value) bool { 50 switch v.Kind() { 51 case reflect.Float64, reflect.Float32: 52 return int64(v.Float()) == vv 53 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 54 return int64(v.Uint()) == vv 55 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 56 return v.Int() == vv 57 default: 58 if v.Type() == fu.Fixed8Type { 59 return int64(v.Interface().(fu.Fixed8).Float32()) == vv 60 } 61 } 62 return false 63 } 64 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 65 vv := vc.Uint() 66 return func(v reflect.Value) bool { 67 switch v.Kind() { 68 case reflect.Float64, reflect.Float32: 69 return uint64(v.Float()) == vv 70 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 71 return uint64(v.Uint()) == vv 72 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 73 return v.Uint() == vv 74 default: 75 if v.Type() == fu.Fixed8Type { 76 return uint64(v.Interface().(fu.Fixed8).Float32()) == vv 77 } 78 } 79 return false 80 } 81 case reflect.String: 82 vv := vc.String() 83 return func(v reflect.Value) bool { 84 switch v.Kind() { 85 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 86 return fmt.Sprintf("%d", v.Uint()) == vv 87 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 88 return fmt.Sprintf("%d", v.Int()) == vv 89 case reflect.String: 90 return vv == v.String() 91 } 92 return false 93 } 94 default: 95 return func(v reflect.Value) bool { 96 return reflect.DeepEqual(v, vc) 97 } 98 } 99 } 100 101 func lessf(c interface{}) func(v reflect.Value) bool { 102 vc := reflect.ValueOf(c) 103 switch vc.Kind() { 104 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 105 vv := vc.Int() 106 return func(v reflect.Value) bool { 107 switch v.Kind() { 108 case reflect.Float64, reflect.Float32: 109 return int64(v.Float()) < vv 110 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 111 return int64(v.Uint()) < vv 112 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 113 return v.Int() < vv 114 } 115 return false 116 } 117 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 118 vv := vc.Uint() 119 return func(v reflect.Value) bool { 120 switch v.Kind() { 121 case reflect.Float64, reflect.Float32: 122 return uint64(v.Float()) < vv 123 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 124 return uint64(v.Uint()) < vv 125 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 126 return v.Uint() < vv 127 } 128 return false 129 } 130 case reflect.String: 131 vv := vc.String() 132 return func(v reflect.Value) bool { 133 if v.Kind() == reflect.String { 134 return vv < v.String() 135 } 136 return false 137 } 138 default: 139 return func(v reflect.Value) bool { 140 return fu.Less(v, vc) 141 } 142 } 143 } 144 145 func greatf(c interface{}) func(v reflect.Value) bool { 146 vc := reflect.ValueOf(c) 147 switch vc.Kind() { 148 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 149 vv := vc.Int() 150 return func(v reflect.Value) bool { 151 switch v.Kind() { 152 case reflect.Float64, reflect.Float32: 153 return int64(v.Float()) > vv 154 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 155 return int64(v.Uint()) > vv 156 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 157 return v.Int() > vv 158 } 159 return false 160 } 161 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 162 vv := vc.Uint() 163 return func(v reflect.Value) bool { 164 switch v.Kind() { 165 case reflect.Float64, reflect.Float32: 166 return uint64(v.Float()) > vv 167 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 168 return uint64(v.Uint()) > vv 169 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 170 return v.Uint() > vv 171 } 172 return false 173 } 174 case reflect.String: 175 vv := vc.String() 176 return func(v reflect.Value) bool { 177 if v.Kind() > reflect.String { 178 return vv < v.String() 179 } 180 return false 181 } 182 default: 183 return func(v reflect.Value) bool { 184 return fu.Less(vc, v) 185 } 186 } 187 } 188 189 func (zf Lazy) IfEq(c string, v ...interface{}) Lazy { 190 var eq func(reflect.Value) bool 191 if len(v) == 0 { 192 return zf 193 } 194 if len(v) > 2 { 195 eq = equalf(reflect.ValueOf(v)) 196 } else { 197 eq = equalf(reflect.ValueOf(v[0])) 198 } 199 return func() lazy.Stream { 200 z := zf() 201 nx := fu.AtomicSingleIndex{} 202 return func(index uint64) (v reflect.Value, err error) { 203 if v, err = z(index); err != nil || v.Kind() == reflect.Bool { 204 return 205 } 206 lr := v.Interface().(fu.Struct) 207 j, ok := nx.Get() 208 if !ok { 209 j, _ = nx.Set(lr.Pos(c)) 210 } 211 if eq(lr.ValueAt(j)) { 212 return 213 } 214 return fu.True, nil 215 } 216 } 217 } 218 219 func (zf Lazy) TrueIfEq(c string, v interface{}, flag string) Lazy { 220 eq := equalf(reflect.ValueOf(v)) 221 return func() lazy.Stream { 222 z := zf() 223 nx := fu.AtomicSingleIndex{} 224 return func(index uint64) (v reflect.Value, err error) { 225 if v, err = z(index); err != nil || v.Kind() == reflect.Bool { 226 return 227 } 228 lr := v.Interface().(fu.Struct) 229 j, ok := nx.Get() 230 if !ok { 231 j, _ = nx.Set(lr.Pos(c)) 232 } 233 if eq(lr.ValueAt(j)) { 234 lr.Set(flag, fu.True) 235 } else { 236 lr.Set(flag, fu.False) 237 } 238 return 239 } 240 } 241 } 242 243 func (zf Lazy) IfNe(c string, v interface{}) Lazy { 244 eq := equalf(reflect.ValueOf(v)) 245 return func() lazy.Stream { 246 z := zf() 247 nx := fu.AtomicSingleIndex{} 248 return func(index uint64) (v reflect.Value, err error) { 249 if v, err = z(index); err != nil || v.Kind() == reflect.Bool { 250 return 251 } 252 lr := v.Interface().(fu.Struct) 253 j, ok := nx.Get() 254 if !ok { 255 j, _ = nx.Set(lr.Pos(c)) 256 } 257 if !eq(lr.ValueAt(j)) { 258 return 259 } 260 return fu.True, nil 261 } 262 } 263 } 264 265 func (zf Lazy) TrueIfNe(c string, v interface{}, flag string) Lazy { 266 eq := equalf(reflect.ValueOf(v)) 267 return func() lazy.Stream { 268 z := zf() 269 nx := fu.AtomicSingleIndex{} 270 return func(index uint64) (v reflect.Value, err error) { 271 if v, err = z(index); err != nil || v.Kind() == reflect.Bool { 272 return 273 } 274 lr := v.Interface().(fu.Struct) 275 j, ok := nx.Get() 276 if !ok { 277 j, _ = nx.Set(lr.Pos(c)) 278 } 279 if !eq(lr.ValueAt(j)) { 280 lr.Set(flag, fu.True) 281 } else { 282 lr.Set(flag, fu.False) 283 } 284 return 285 } 286 } 287 } 288 289 func (zf Lazy) IfLt(c string, v interface{}) Lazy { 290 lt := lessf(v) 291 return func() lazy.Stream { 292 z := zf() 293 nx := fu.AtomicSingleIndex{} 294 return func(index uint64) (v reflect.Value, err error) { 295 if v, err = z(index); err != nil || v.Kind() == reflect.Bool { 296 return 297 } 298 lr := v.Interface().(fu.Struct) 299 j, ok := nx.Get() 300 if !ok { 301 j, _ = nx.Set(lr.Pos(c)) 302 } 303 if lt(lr.ValueAt(j)) { 304 return 305 } 306 return fu.True, nil 307 } 308 } 309 } 310 311 func (zf Lazy) IfGt(c string, v interface{}) Lazy { 312 gt := greatf(v) 313 return func() lazy.Stream { 314 z := zf() 315 nx := fu.AtomicSingleIndex{} 316 return func(index uint64) (v reflect.Value, err error) { 317 if v, err = z(index); err != nil || v.Kind() == reflect.Bool { 318 return 319 } 320 lr := v.Interface().(fu.Struct) 321 j, ok := nx.Get() 322 if !ok { 323 j, _ = nx.Set(lr.Pos(c)) 324 } 325 if gt(lr.ValueAt(j)) { 326 return 327 } 328 return fu.True, nil 329 } 330 } 331 }