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  }