go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/fu/convert.go (about)

     1  package fu
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"reflect"
     7  	"strconv"
     8  )
     9  
    10  func Isna(v reflect.Value) bool {
    11  	if !v.IsValid() {
    12  		return true
    13  	}
    14  	switch v.Kind() {
    15  	case reflect.Float32, reflect.Float64:
    16  		return math.IsNaN(v.Float())
    17  	}
    18  	return false
    19  }
    20  
    21  func Nan(tp reflect.Type) reflect.Value {
    22  	switch tp.Kind() {
    23  	case reflect.Float32:
    24  		return reflect.ValueOf(float32(math.NaN()))
    25  	case reflect.Float64:
    26  		return reflect.ValueOf(math.NaN())
    27  	}
    28  	return reflect.Zero(tp)
    29  }
    30  
    31  func ConvertSlice(v reflect.Value, na Bits, tp reflect.Type, nocopy ...bool) reflect.Value {
    32  	L := v.Len()
    33  	vt := v.Type().Elem()
    34  	if vt == tp && Fnzb(nocopy...) {
    35  		return v.Slice(0, L)
    36  	}
    37  	r := reflect.MakeSlice(reflect.SliceOf(tp), L, L)
    38  	if vt == tp {
    39  		reflect.Copy(r, v)
    40  	} else {
    41  		for i := 0; i < L; i++ {
    42  			r.Index(i).Set(Convert(v.Index(i), na.Bit(i), tp))
    43  		}
    44  	}
    45  	return r
    46  }
    47  
    48  func Convert(v reflect.Value, na bool, tp reflect.Type) reflect.Value {
    49  	if na {
    50  		return Nan(tp)
    51  	}
    52  	if v.Type() == tp {
    53  		return v
    54  	} else if tp.Kind() == reflect.String {
    55  		return reflect.ValueOf(fmt.Sprint(v.Interface()))
    56  	} else if v.Kind() == reflect.String {
    57  		switch tp.Kind() {
    58  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    59  			x, err := strconv.ParseInt(v.String(), 10, 64)
    60  			if err != nil {
    61  				panic(err)
    62  			}
    63  			return reflect.ValueOf(x).Convert(tp)
    64  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
    65  			x, err := strconv.ParseUint(v.String(), 10, 64)
    66  			if err != nil {
    67  				panic(err)
    68  			}
    69  			return reflect.ValueOf(x).Convert(tp)
    70  		case reflect.Float32, reflect.Float64:
    71  			x, err := strconv.ParseFloat(v.String(), 64)
    72  			if err != nil {
    73  				panic(err)
    74  			}
    75  			return reflect.ValueOf(x).Convert(tp)
    76  		}
    77  	} else if tp.Kind() == reflect.Float32 {
    78  		switch v.Kind() {
    79  		case reflect.Float32:
    80  			return v
    81  		case reflect.Struct:
    82  			if q, ok := v.Interface().(Fixed8); ok {
    83  				return reflect.ValueOf(q.Float32())
    84  			}
    85  		case reflect.Float64:
    86  			return reflect.ValueOf(float32(v.Float()))
    87  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
    88  			return reflect.ValueOf(float32(v.Uint()))
    89  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    90  			return reflect.ValueOf(float32(v.Int()))
    91  		}
    92  	} else if tp.Kind() == reflect.Float64 {
    93  		switch v.Kind() {
    94  		case reflect.Float64:
    95  			return v
    96  		case reflect.Struct:
    97  			if q, ok := v.Interface().(Fixed8); ok {
    98  				return reflect.ValueOf(float64(q.Float32()))
    99  			}
   100  		case reflect.Float32:
   101  			return reflect.ValueOf(v.Float())
   102  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   103  			return reflect.ValueOf(float64(v.Uint()))
   104  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   105  			return reflect.ValueOf(float64(v.Int()))
   106  		}
   107  	}
   108  	return v.Convert(tp)
   109  }