github.com/andeya/ameda@v1.5.3/utils.go (about)

     1  package ameda
     2  
     3  import (
     4  	"errors"
     5  	"math"
     6  	"reflect"
     7  	"strconv"
     8  )
     9  
    10  const (
    11  	Host64bit      = strconv.IntSize == 64
    12  	Host32bit      = ^uint(0)>>32 == 0
    13  	MaxUnsignedInt = ^uint(0)
    14  	MinUnsignedInt = 0
    15  	MaxInteger     = int(MaxUnsignedInt >> 1)
    16  	MinInteger     = -MaxInteger - 1
    17  )
    18  
    19  var (
    20  	errNegativeValue = errors.New("contains negative value")
    21  	errOverflowValue = errors.New("contains overflow value")
    22  )
    23  
    24  var (
    25  	maxUint32 = uint32(math.MaxUint32)
    26  	maxInt64  = int64(math.MaxInt64)
    27  )
    28  
    29  func isEmptyAsZero(emptyAsZero []bool) bool {
    30  	return len(emptyAsZero) > 0 && emptyAsZero[0]
    31  }
    32  
    33  func getFromIndex(length int, fromIndex ...int) int {
    34  	if len(fromIndex) > 0 {
    35  		return fixIndex(length, fromIndex[0], true)
    36  	}
    37  	return 0
    38  }
    39  
    40  func fixRange(length, start int, end ...int) (fixedStart, fixedEnd int, ok bool) {
    41  	fixedStart = fixIndex(length, start, true)
    42  	if fixedStart == length {
    43  		return
    44  	}
    45  	fixedEnd = length
    46  	if len(end) > 0 {
    47  		fixedEnd = fixIndex(length, end[0], true)
    48  	}
    49  	if fixedEnd-fixedStart <= 0 {
    50  		return
    51  	}
    52  	ok = true
    53  	return
    54  }
    55  
    56  func fixIndex(length int, idx int, canLen bool) int {
    57  	if idx < 0 {
    58  		idx = length + idx
    59  		if idx < 0 {
    60  			return 0
    61  		}
    62  		return idx
    63  	}
    64  	if idx >= length {
    65  		if canLen {
    66  			return length
    67  		}
    68  		return length - 1
    69  	}
    70  	return idx
    71  }
    72  
    73  // isZero reports whether v is the zero value for its type.
    74  // It panics if the argument is invalid.
    75  func isZero(v reflect.Value) bool {
    76  	switch v.Kind() {
    77  	case reflect.Bool:
    78  		return !v.Bool()
    79  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    80  		return v.Int() == 0
    81  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
    82  		return v.Uint() == 0
    83  	case reflect.Float32, reflect.Float64:
    84  		return math.Float64bits(v.Float()) == 0
    85  	case reflect.Complex64, reflect.Complex128:
    86  		c := v.Complex()
    87  		return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
    88  	case reflect.Array:
    89  		for i := 0; i < v.Len(); i++ {
    90  			if !isZero(v.Index(i)) {
    91  				return false
    92  			}
    93  		}
    94  		return true
    95  	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
    96  		return v.IsNil()
    97  	case reflect.String:
    98  		return v.Len() == 0
    99  	case reflect.Struct:
   100  		for i := 0; i < v.NumField(); i++ {
   101  			if !isZero(v.Field(i)) {
   102  				return false
   103  			}
   104  		}
   105  		return true
   106  	default:
   107  		// This should never happens, but will act as a safeguard for
   108  		// later, as a default value doesn't makes sense here.
   109  		panic(&reflect.ValueError{"reflect.Value.IsZero", v.Kind()})
   110  	}
   111  }