github.com/bobyang007/helper@v1.1.3/reflecth/op-binary.go (about)

     1  package reflecth
     2  
     3  import (
     4  	"github.com/bobyang007/helper/strconvh"
     5  	"go/token"
     6  	"reflect"
     7  )
     8  
     9  //replacer:ignore
    10  //go:generate go run $GOPATH/src/github.com/apaxa-go/generator/replacer/main.go -- $GOFILE
    11  
    12  //replacer:ignore
    13  //go:generate go run $GOPATH/src/github.com/apaxa-go/generator/replacer/main.go -- $GOFILE
    14  
    15  // BinaryOp performs binary operation <x><op><y> as Go language specification describes.
    16  // Supported operations: && || + - * / % & | ^ &^ .
    17  // If operation cannot be performed then error will be returned.
    18  func BinaryOp(x reflect.Value, op token.Token, y reflect.Value) (r reflect.Value, err error) {
    19  	// Basic check
    20  	if xT, yT := x.Type(), y.Type(); !xT.AssignableTo(yT) && !yT.AssignableTo(xT) {
    21  		return reflect.Value{}, binaryOpMismatchTypesError(x, op, y)
    22  	}
    23  
    24  	r = reflect.New(x.Type()).Elem()
    25  	switch x.Kind() {
    26  	case reflect.Bool:
    27  		v, err := binaryOpBool(x.Bool(), op, y.Bool())
    28  		if err != nil {
    29  			return reflect.Value{}, err
    30  		}
    31  		r.SetBool(v)
    32  	case reflect.Int:
    33  		v, err := binaryOpInt(int(x.Int()), op, int(y.Int()))
    34  		if err != nil {
    35  			return reflect.Value{}, err
    36  		}
    37  		r.SetInt(int64(v))
    38  	case reflect.Int8:
    39  		v, err := binaryOpInt8(int8(x.Int()), op, int8(y.Int()))
    40  		if err != nil {
    41  			return reflect.Value{}, err
    42  		}
    43  		r.SetInt(int64(v))
    44  	case reflect.Int16:
    45  		v, err := binaryOpInt16(int16(x.Int()), op, int16(y.Int()))
    46  		if err != nil {
    47  			return reflect.Value{}, err
    48  		}
    49  		r.SetInt(int64(v))
    50  	case reflect.Int32:
    51  		v, err := binaryOpInt32(int32(x.Int()), op, int32(y.Int()))
    52  		if err != nil {
    53  			return reflect.Value{}, err
    54  		}
    55  		r.SetInt(int64(v))
    56  	case reflect.Int64:
    57  		v, err := binaryOpInt64(x.Int(), op, y.Int())
    58  		if err != nil {
    59  			return reflect.Value{}, err
    60  		}
    61  		r.SetInt(v)
    62  	case reflect.Uint:
    63  		v, err := binaryOpUint(uint(x.Uint()), op, uint(y.Uint()))
    64  		if err != nil {
    65  			return reflect.Value{}, err
    66  		}
    67  		r.SetUint(uint64(v))
    68  	case reflect.Uint8:
    69  		v, err := binaryOpUint8(uint8(x.Uint()), op, uint8(y.Uint()))
    70  		if err != nil {
    71  			return reflect.Value{}, err
    72  		}
    73  		r.SetUint(uint64(v))
    74  	case reflect.Uint16:
    75  		v, err := binaryOpUint16(uint16(x.Uint()), op, uint16(y.Uint()))
    76  		if err != nil {
    77  			return reflect.Value{}, err
    78  		}
    79  		r.SetUint(uint64(v))
    80  	case reflect.Uint32:
    81  		v, err := binaryOpUint32(uint32(x.Uint()), op, uint32(y.Uint()))
    82  		if err != nil {
    83  			return reflect.Value{}, err
    84  		}
    85  		r.SetUint(uint64(v))
    86  	case reflect.Uint64:
    87  		v, err := binaryOpUint64(x.Uint(), op, y.Uint())
    88  		if err != nil {
    89  			return reflect.Value{}, err
    90  		}
    91  		r.SetUint(v)
    92  	case reflect.Float32:
    93  		v, err := binaryOpFloat32(float32(x.Float()), op, float32(y.Float()))
    94  		if err != nil {
    95  			return reflect.Value{}, err
    96  		}
    97  		r.SetFloat(float64(v))
    98  	case reflect.Float64:
    99  		v, err := binaryOpFloat64(x.Float(), op, y.Float())
   100  		if err != nil {
   101  			return reflect.Value{}, err
   102  		}
   103  		r.SetFloat(v)
   104  	case reflect.Complex64:
   105  		v, err := binaryOpComplex64(complex64(x.Complex()), op, complex64(y.Complex()))
   106  		if err != nil {
   107  			return reflect.Value{}, err
   108  		}
   109  		r.SetComplex(complex128(v))
   110  	case reflect.Complex128:
   111  		v, err := binaryOpComplex128(x.Complex(), op, y.Complex())
   112  		if err != nil {
   113  			return reflect.Value{}, err
   114  		}
   115  		r.SetComplex(v)
   116  	case reflect.String:
   117  		v, err := binaryOpString(x.String(), op, y.String())
   118  		if err != nil {
   119  			return reflect.Value{}, err
   120  		}
   121  		r.SetString(v)
   122  	default:
   123  		return reflect.Value{}, invBinOpTypesInvalError(x, op, y)
   124  	}
   125  	return
   126  }
   127  
   128  func binaryOpBool(x bool, op token.Token, y bool) (r bool, err error) {
   129  	switch op {
   130  	case token.LAND:
   131  		return x && y, nil
   132  	case token.LOR:
   133  		return x || y, nil
   134  	default:
   135  		return false, binaryOpInvalidOperatorSError(strconvh.FormatBool(x), op.String(), strconvh.FormatBool(y))
   136  	}
   137  }
   138  
   139  func binaryOpString(x string, op token.Token, y string) (r string, err error) {
   140  	switch op {
   141  	case token.ADD:
   142  		return x + y, nil
   143  	default:
   144  		return "", binaryOpInvalidOperatorSError(x, op.String(), y)
   145  	}
   146  }
   147  
   148  //replacer:replace
   149  //replacer:old int64	Int64
   150  //replacer:new int	Int
   151  //replacer:new int8	Int8
   152  //replacer:new int16	Int16
   153  //replacer:new int32	Int32
   154  //replacer:new uint	Uint
   155  //replacer:new uint8	Uint8
   156  //replacer:new uint16	Uint16
   157  //replacer:new uint32	Uint32
   158  //replacer:new uint64	Uint64
   159  
   160  func binaryOpInt64(x int64, op token.Token, y int64) (r int64, err error) {
   161  	switch op {
   162  	case token.ADD:
   163  		return x + y, nil
   164  	case token.SUB:
   165  		return x - y, nil
   166  	case token.MUL:
   167  		return x * y, nil
   168  	case token.QUO:
   169  		return x / y, nil
   170  	case token.REM:
   171  		return x % y, nil
   172  	case token.AND:
   173  		return x & y, nil
   174  	case token.OR:
   175  		return x | y, nil
   176  	case token.XOR:
   177  		return x ^ y, nil
   178  	case token.AND_NOT:
   179  		return x &^ y, nil
   180  	default:
   181  		return 0, binaryOpInvalidOperatorSError(strconvh.FormatInt64(x), op.String(), strconvh.FormatInt64(y))
   182  	}
   183  }
   184  
   185  //replacer:replace
   186  //replacer:old float32		Float32
   187  //replacer:new float64		Float64
   188  //replacer:new complex64	Complex64
   189  //replacer:new complex128	Complex128
   190  
   191  func binaryOpFloat32(x float32, op token.Token, y float32) (r float32, err error) {
   192  	switch op {
   193  	case token.ADD:
   194  		return x + y, nil
   195  	case token.SUB:
   196  		return x - y, nil
   197  	case token.MUL:
   198  		return x * y, nil
   199  	case token.QUO:
   200  		return x / y, nil
   201  	default:
   202  		return 0, binaryOpInvalidOperatorSError(strconvh.FormatFloat32(x), op.String(), strconvh.FormatFloat32(y))
   203  	}
   204  }