github.com/goki/ki@v1.1.11/kit/convert.go (about)

     1  // Copyright (c) 2018, The GoKi Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package kit
     6  
     7  import (
     8  	"fmt"
     9  	"log"
    10  	"math"
    11  	"reflect"
    12  	"strconv"
    13  	"unicode"
    14  
    15  	"github.com/goki/ki/floats"
    16  	"github.com/goki/ki/ints"
    17  )
    18  
    19  // Sel implements the "mute" function from here
    20  // http://blog.vladimirvivien.com/2014/03/hacking-go-filter-values-from-multi.html
    21  // provides a way to select a particular return value in a single expression,
    22  // without having a separate assignment in between -- I just call it "Sel" as
    23  // I'm unlikely to remember how to type a mu
    24  func Sel(a ...interface{}) []interface{} {
    25  	return a
    26  }
    27  
    28  // IfaceIsNil checks if an interface value is nil -- the interface itself could be
    29  // nil, or the value pointed to by the interface could be nil -- this checks
    30  // both, safely
    31  // gopy:interface=handle
    32  func IfaceIsNil(it interface{}) bool {
    33  	if it == nil {
    34  		return true
    35  	}
    36  	v := reflect.ValueOf(it)
    37  	vk := v.Kind()
    38  	if vk == reflect.Ptr || vk == reflect.Interface || vk == reflect.Map || vk == reflect.Slice || vk == reflect.Func || vk == reflect.Chan {
    39  		return v.IsNil()
    40  	}
    41  	return false
    42  }
    43  
    44  // KindIsBasic returns true if the reflect.Kind is a basic type such as Int, Float, etc
    45  func KindIsBasic(vk reflect.Kind) bool {
    46  	if vk >= reflect.Bool && vk <= reflect.Complex128 {
    47  		return true
    48  	}
    49  	return false
    50  }
    51  
    52  // ValueIsZero returns true if the reflect.Value is Zero or nil or invalid or
    53  // otherwise doesn't have a useful value -- from
    54  // https://github.com/golang/go/issues/7501
    55  func ValueIsZero(v reflect.Value) bool {
    56  	if !v.IsValid() {
    57  		return true
    58  	}
    59  	switch v.Kind() {
    60  	case reflect.Array, reflect.String:
    61  		return v.Len() == 0
    62  	case reflect.Bool:
    63  		return !v.Bool()
    64  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    65  		return v.Int() == 0
    66  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
    67  		return v.Uint() == 0
    68  	case reflect.Float32, reflect.Float64:
    69  		return v.Float() == 0
    70  	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
    71  		return v.IsNil()
    72  	case reflect.Func:
    73  		return v == reflect.Zero(v.Type())
    74  	}
    75  	return false
    76  }
    77  
    78  // Convenience functions for converting interface{} (e.g. properties) to given
    79  // types uses the "ok" bool mechanism to report failure -- are as robust and
    80  // general as possible.
    81  //
    82  // WARNING: these violate many of the type-safety features of Go but OTOH give
    83  // maximum robustness, appropriate for the world of end-user settable
    84  // properties, and deal with most common-sense cases, e.g., string <-> number,
    85  // etc.  nil values return !ok
    86  
    87  // ToBool robustly converts anything to a bool
    88  // gopy:interface=handle
    89  func ToBool(it interface{}) (bool, bool) {
    90  	// first check for most likely cases for greatest efficiency
    91  	switch bt := it.(type) {
    92  	case bool:
    93  		return bt, true
    94  	case *bool:
    95  		return *bt, true
    96  	case int:
    97  		return bt != 0, true
    98  	case *int:
    99  		return *bt != 0, true
   100  	case int32:
   101  		return bt != 0, true
   102  	case int64:
   103  		return bt != 0, true
   104  	case byte:
   105  		return bt != 0, true
   106  	case float64:
   107  		return bt != 0, true
   108  	case *float64:
   109  		return *bt != 0, true
   110  	case float32:
   111  		return bt != 0, true
   112  	case *float32:
   113  		return *bt != 0, true
   114  	case string:
   115  		r, err := strconv.ParseBool(bt)
   116  		if err != nil {
   117  			return false, false
   118  		}
   119  		return r, true
   120  	case *string:
   121  		r, err := strconv.ParseBool(*bt)
   122  		if err != nil {
   123  			return false, false
   124  		}
   125  		return r, true
   126  	}
   127  
   128  	// then fall back on reflection
   129  	if IfaceIsNil(it) {
   130  		return false, false
   131  	}
   132  	v := NonPtrValue(reflect.ValueOf(it))
   133  	vk := v.Kind()
   134  	switch {
   135  	case vk >= reflect.Int && vk <= reflect.Int64:
   136  		return (v.Int() != 0), true
   137  	case vk >= reflect.Uint && vk <= reflect.Uint64:
   138  		return (v.Uint() != 0), true
   139  	case vk == reflect.Bool:
   140  		return v.Bool(), true
   141  	case vk >= reflect.Float32 && vk <= reflect.Float64:
   142  		return (v.Float() != 0.0), true
   143  	case vk >= reflect.Complex64 && vk <= reflect.Complex128:
   144  		return (real(v.Complex()) != 0.0), true
   145  	case vk == reflect.String:
   146  		r, err := strconv.ParseBool(v.String())
   147  		if err != nil {
   148  			return false, false
   149  		}
   150  		return r, true
   151  	default:
   152  		return false, false
   153  	}
   154  }
   155  
   156  // ToInt robustly converts anything to an int64 -- uses the ints.Inter ToInt
   157  // interface first if available
   158  // gopy:interface=handle
   159  func ToInt(it interface{}) (int64, bool) {
   160  	// first check for most likely cases for greatest efficiency
   161  	switch it := it.(type) {
   162  	case bool:
   163  		if it {
   164  			return 1, true
   165  		}
   166  		return 0, true
   167  	case *bool:
   168  		if *it {
   169  			return 1, true
   170  		}
   171  		return 0, true
   172  	case int:
   173  		return int64(it), true
   174  	case *int:
   175  		return int64(*it), true
   176  	case int32:
   177  		return int64(it), true
   178  	case *int32:
   179  		return int64(*it), true
   180  	case int64:
   181  		return it, true
   182  	case *int64:
   183  		return *it, true
   184  	case byte:
   185  		return int64(it), true
   186  	case *byte:
   187  		return int64(*it), true
   188  	case float64:
   189  		return int64(it), true
   190  	case *float64:
   191  		return int64(*it), true
   192  	case float32:
   193  		return int64(it), true
   194  	case *float32:
   195  		return int64(*it), true
   196  	case string:
   197  		r, err := strconv.ParseInt(it, 0, 64)
   198  		if err != nil {
   199  			return 0, false
   200  		}
   201  		return r, true
   202  	case *string:
   203  		r, err := strconv.ParseInt(*it, 0, 64)
   204  		if err != nil {
   205  			return 0, false
   206  		}
   207  		return r, true
   208  	}
   209  
   210  	// then fall back on reflection
   211  	if IfaceIsNil(it) {
   212  		return 0, false
   213  	}
   214  	if inter, ok := it.(ints.Inter); ok {
   215  		return inter.Int(), true
   216  	}
   217  	v := NonPtrValue(reflect.ValueOf(it))
   218  	vk := v.Kind()
   219  	switch {
   220  	case vk >= reflect.Int && vk <= reflect.Int64:
   221  		return v.Int(), true
   222  	case vk >= reflect.Uint && vk <= reflect.Uint64:
   223  		return int64(v.Uint()), true
   224  	case vk == reflect.Bool:
   225  		if v.Bool() {
   226  			return 1, true
   227  		}
   228  		return 0, true
   229  	case vk >= reflect.Float32 && vk <= reflect.Float64:
   230  		return int64(v.Float()), true
   231  	case vk >= reflect.Complex64 && vk <= reflect.Complex128:
   232  		return int64(real(v.Complex())), true
   233  	case vk == reflect.String:
   234  		r, err := strconv.ParseInt(v.String(), 0, 64)
   235  		if err != nil {
   236  			return 0, false
   237  		}
   238  		return r, true
   239  	default:
   240  		return 0, false
   241  	}
   242  }
   243  
   244  // ToFloat robustly converts anything to a Float64 -- uses the floats.Floater Float()
   245  // interface first if available
   246  // gopy:interface=handle
   247  func ToFloat(it interface{}) (float64, bool) {
   248  	// first check for most likely cases for greatest efficiency
   249  	switch it := it.(type) {
   250  	case bool:
   251  		if it {
   252  			return 1, true
   253  		}
   254  		return 0, true
   255  	case *bool:
   256  		if *it {
   257  			return 1, true
   258  		}
   259  		return 0, true
   260  	case int:
   261  		return float64(it), true
   262  	case *int:
   263  		return float64(*it), true
   264  	case int32:
   265  		return float64(it), true
   266  	case *int32:
   267  		return float64(*it), true
   268  	case int64:
   269  		return float64(it), true
   270  	case *int64:
   271  		return float64(*it), true
   272  	case byte:
   273  		return float64(it), true
   274  	case *byte:
   275  		return float64(*it), true
   276  	case float64:
   277  		return it, true
   278  	case *float64:
   279  		return *it, true
   280  	case float32:
   281  		return float64(it), true
   282  	case *float32:
   283  		return float64(*it), true
   284  	case string:
   285  		r, err := strconv.ParseFloat(it, 64)
   286  		if err != nil {
   287  			return 0.0, false
   288  		}
   289  		return r, true
   290  	case *string:
   291  		r, err := strconv.ParseFloat(*it, 64)
   292  		if err != nil {
   293  			return 0.0, false
   294  		}
   295  		return r, true
   296  	}
   297  
   298  	if floater, ok := it.(floats.Floater); ok {
   299  		return floater.Float(), true
   300  	}
   301  	// then fall back on reflection
   302  	if IfaceIsNil(it) {
   303  		return 0.0, false
   304  	}
   305  	v := NonPtrValue(reflect.ValueOf(it))
   306  	vk := v.Kind()
   307  	switch {
   308  	case vk >= reflect.Int && vk <= reflect.Int64:
   309  		return float64(v.Int()), true
   310  	case vk >= reflect.Uint && vk <= reflect.Uint64:
   311  		return float64(v.Uint()), true
   312  	case vk == reflect.Bool:
   313  		if v.Bool() {
   314  			return 1.0, true
   315  		}
   316  		return 0.0, true
   317  	case vk >= reflect.Float32 && vk <= reflect.Float64:
   318  		return v.Float(), true
   319  	case vk >= reflect.Complex64 && vk <= reflect.Complex128:
   320  		return real(v.Complex()), true
   321  	case vk == reflect.String:
   322  		r, err := strconv.ParseFloat(v.String(), 64)
   323  		if err != nil {
   324  			return 0.0, false
   325  		}
   326  		return r, true
   327  	default:
   328  		return 0.0, false
   329  	}
   330  }
   331  
   332  // ToFloat32 robustly converts anything to a Float32 -- uses the floats.Floater Float()
   333  // interface first if available
   334  // gopy:interface=handle
   335  func ToFloat32(it interface{}) (float32, bool) {
   336  	// first check for most likely cases for greatest efficiency
   337  	switch it := it.(type) {
   338  	case bool:
   339  		if it {
   340  			return 1, true
   341  		}
   342  		return 0, true
   343  	case *bool:
   344  		if *it {
   345  			return 1, true
   346  		}
   347  		return 0, true
   348  	case int:
   349  		return float32(it), true
   350  	case *int:
   351  		return float32(*it), true
   352  	case int32:
   353  		return float32(it), true
   354  	case *int32:
   355  		return float32(*it), true
   356  	case int64:
   357  		return float32(it), true
   358  	case *int64:
   359  		return float32(*it), true
   360  	case byte:
   361  		return float32(it), true
   362  	case *byte:
   363  		return float32(*it), true
   364  	case float64:
   365  		return float32(it), true
   366  	case *float64:
   367  		return float32(*it), true
   368  	case float32:
   369  		return it, true
   370  	case *float32:
   371  		return *it, true
   372  	case string:
   373  		r, err := strconv.ParseFloat(it, 32)
   374  		if err != nil {
   375  			return 0.0, false
   376  		}
   377  		return float32(r), true
   378  	case *string:
   379  		r, err := strconv.ParseFloat(*it, 32)
   380  		if err != nil {
   381  			return 0.0, false
   382  		}
   383  		return float32(r), true
   384  	}
   385  
   386  	if floater, ok := it.(floats.Floater); ok {
   387  		return float32(floater.Float()), true
   388  	}
   389  	// then fall back on reflection
   390  	if IfaceIsNil(it) {
   391  		return float32(0.0), false
   392  	}
   393  	v := NonPtrValue(reflect.ValueOf(it))
   394  	vk := v.Kind()
   395  	switch {
   396  	case vk >= reflect.Int && vk <= reflect.Int64:
   397  		return float32(v.Int()), true
   398  	case vk >= reflect.Uint && vk <= reflect.Uint64:
   399  		return float32(v.Uint()), true
   400  	case vk == reflect.Bool:
   401  		if v.Bool() {
   402  			return 1.0, true
   403  		}
   404  		return 0.0, true
   405  	case vk >= reflect.Float32 && vk <= reflect.Float64:
   406  		return float32(v.Float()), true
   407  	case vk >= reflect.Complex64 && vk <= reflect.Complex128:
   408  		return float32(real(v.Complex())), true
   409  	case vk == reflect.String:
   410  		r, err := strconv.ParseFloat(v.String(), 32)
   411  		if err != nil {
   412  			return float32(0.0), false
   413  		}
   414  		return float32(r), true
   415  	default:
   416  		return float32(0.0), false
   417  	}
   418  }
   419  
   420  // ToString robustly converts anything to a String -- because Stringer is so
   421  // ubiquitous, and we fall back to fmt.Sprintf(%v) in worst case, this should
   422  // definitely work in all cases, so there is no bool return value
   423  // gopy:interface=handle
   424  func ToString(it interface{}) string {
   425  	// first check for most likely cases for greatest efficiency
   426  	switch it := it.(type) {
   427  	case string:
   428  		return it
   429  	case *string:
   430  		return *it
   431  	case bool:
   432  		if it {
   433  			return "true"
   434  		}
   435  		return "false"
   436  	case *bool:
   437  		if *it {
   438  			return "true"
   439  		}
   440  		return "false"
   441  	case int:
   442  		return strconv.FormatInt(int64(it), 10)
   443  	case *int:
   444  		return strconv.FormatInt(int64(*it), 10)
   445  	case int32:
   446  		return strconv.FormatInt(int64(it), 10)
   447  	case *int32:
   448  		return strconv.FormatInt(int64(*it), 10)
   449  	case int64:
   450  		return strconv.FormatInt(it, 10)
   451  	case *int64:
   452  		return strconv.FormatInt(*it, 10)
   453  	case byte:
   454  		return strconv.FormatInt(int64(it), 10)
   455  	case *byte:
   456  		return strconv.FormatInt(int64(*it), 10)
   457  	case float64:
   458  		return strconv.FormatFloat(it, 'G', -1, 64)
   459  	case *float64:
   460  		return strconv.FormatFloat(*it, 'G', -1, 64)
   461  	case float32:
   462  		return strconv.FormatFloat(float64(it), 'G', -1, 32)
   463  	case *float32:
   464  		return strconv.FormatFloat(float64(*it), 'G', -1, 32)
   465  	case uintptr:
   466  		return fmt.Sprintf("%#x", uintptr(it))
   467  	case *uintptr:
   468  		return fmt.Sprintf("%#x", uintptr(*it))
   469  	}
   470  
   471  	if stringer, ok := it.(fmt.Stringer); ok {
   472  		return stringer.String()
   473  	}
   474  	if IfaceIsNil(it) {
   475  		return "nil"
   476  	}
   477  	v := NonPtrValue(reflect.ValueOf(it))
   478  	vk := v.Kind()
   479  	switch {
   480  	case vk >= reflect.Int && vk <= reflect.Int64:
   481  		return strconv.FormatInt(v.Int(), 10)
   482  	case vk >= reflect.Uint && vk <= reflect.Uint64:
   483  		return strconv.FormatUint(v.Uint(), 10)
   484  	case vk == reflect.Bool:
   485  		return strconv.FormatBool(v.Bool())
   486  	case vk >= reflect.Float32 && vk <= reflect.Float64:
   487  		return strconv.FormatFloat(v.Float(), 'G', -1, 64)
   488  	case vk >= reflect.Complex64 && vk <= reflect.Complex128:
   489  		cv := v.Complex()
   490  		rv := strconv.FormatFloat(real(cv), 'G', -1, 64) + "," + strconv.FormatFloat(imag(cv), 'G', -1, 64)
   491  		return rv
   492  	case vk == reflect.String:
   493  		return v.String()
   494  	case vk == reflect.Slice:
   495  		eltyp := SliceElType(it)
   496  		if eltyp.Kind() == reflect.Uint8 { // []byte
   497  			return string(it.([]byte))
   498  		}
   499  		fallthrough
   500  	default:
   501  		return fmt.Sprintf("%v", it)
   502  	}
   503  }
   504  
   505  // ToStringPrec robustly converts anything to a String using given precision
   506  // for converting floating values -- using a value like 6 truncates the
   507  // nuisance random imprecision of actual floating point values due to the
   508  // fact that they are represented with binary bits.  See ToString
   509  // for more info.
   510  // gopy:interface=handle
   511  func ToStringPrec(it interface{}, prec int) string {
   512  	if IfaceIsNil(it) {
   513  		return "nil"
   514  	}
   515  	if stringer, ok := it.(fmt.Stringer); ok {
   516  		return stringer.String()
   517  	}
   518  	v := NonPtrValue(reflect.ValueOf(it))
   519  	vk := v.Kind()
   520  	switch {
   521  	case vk >= reflect.Int && vk <= reflect.Int64:
   522  		return strconv.FormatInt(v.Int(), 10)
   523  	case vk >= reflect.Uint && vk <= reflect.Uint64:
   524  		return strconv.FormatUint(v.Uint(), 10)
   525  	case vk == reflect.Bool:
   526  		return strconv.FormatBool(v.Bool())
   527  	case vk >= reflect.Float32 && vk <= reflect.Float64:
   528  		return strconv.FormatFloat(v.Float(), 'G', prec, 64)
   529  	case vk >= reflect.Complex64 && vk <= reflect.Complex128:
   530  		cv := v.Complex()
   531  		rv := strconv.FormatFloat(real(cv), 'G', prec, 64) + "," + strconv.FormatFloat(imag(cv), 'G', prec, 64)
   532  		return rv
   533  	case vk == reflect.String:
   534  		return v.String()
   535  	case vk == reflect.Slice:
   536  		eltyp := SliceElType(it)
   537  		if eltyp.Kind() == reflect.Uint8 { // []byte
   538  			return string(it.([]byte))
   539  		}
   540  		fallthrough
   541  	default:
   542  		return fmt.Sprintf("%v", it)
   543  	}
   544  }
   545  
   546  // SetRobust robustly sets the to value from the from value -- to must be a
   547  // pointer-to -- only for basic field values -- use copier package for more
   548  // complex cases
   549  // gopy:interface=handle
   550  func SetRobust(to, frm interface{}) bool {
   551  	if IfaceIsNil(to) {
   552  		return false
   553  	}
   554  	v := reflect.ValueOf(to)
   555  	vnp := NonPtrValue(v)
   556  	if !vnp.IsValid() {
   557  		return false
   558  	}
   559  	typ := vnp.Type()
   560  	vp := OnePtrValue(vnp)
   561  	vk := vnp.Kind()
   562  	if !vp.Elem().CanSet() {
   563  		log.Printf("ki.SetRobust 'to' cannot be set -- must be a variable or field, not a const or tmp or other value that cannot be set.  Value info: %v\n", vp)
   564  		return false
   565  	}
   566  	switch {
   567  	case vk >= reflect.Int && vk <= reflect.Int64:
   568  		fm, ok := ToInt(frm)
   569  		if ok {
   570  			vp.Elem().Set(reflect.ValueOf(fm).Convert(typ))
   571  			return true
   572  		}
   573  	case vk >= reflect.Uint && vk <= reflect.Uint64:
   574  		fm, ok := ToInt(frm)
   575  		if ok {
   576  			vp.Elem().Set(reflect.ValueOf(fm).Convert(typ))
   577  			return true
   578  		}
   579  	case vk == reflect.Bool:
   580  		fm, ok := ToBool(frm)
   581  		if ok {
   582  			vp.Elem().Set(reflect.ValueOf(fm).Convert(typ))
   583  			return true
   584  		}
   585  	case vk >= reflect.Float32 && vk <= reflect.Float64:
   586  		fm, ok := ToFloat(frm)
   587  		if ok {
   588  			vp.Elem().Set(reflect.ValueOf(fm).Convert(typ))
   589  			return true
   590  		}
   591  	case vk >= reflect.Complex64 && vk <= reflect.Complex128:
   592  		// cv := v.Complex()
   593  		// rv := strconv.FormatFloat(real(cv), 'G', -1, 64) + "," + strconv.FormatFloat(imag(cv), 'G', -1, 64)
   594  		// return rv, true
   595  	case vk == reflect.String: // todo: what about []byte?
   596  		fm := ToString(frm)
   597  		vp.Elem().Set(reflect.ValueOf(fm).Convert(typ))
   598  		return true
   599  	}
   600  
   601  	fv := reflect.ValueOf(frm)
   602  	// Just set it if possible to assign
   603  	if fv.Type().AssignableTo(typ) {
   604  		vp.Elem().Set(fv)
   605  		return true
   606  	}
   607  	return false
   608  }
   609  
   610  // SetMapRobust robustly sets a map value using reflect.Value representations
   611  // of the map, key, and value elements, ensuring that the proper types are
   612  // used for the key and value elements using sensible conversions.
   613  // map value must be a valid map value -- that is not checked.
   614  func SetMapRobust(mp, ky, val reflect.Value) bool {
   615  	mtyp := mp.Type()
   616  	if mtyp.Kind() != reflect.Map {
   617  		log.Printf("ki.SetMapRobust: map arg is not map, is: %v\n", mtyp.String())
   618  		return false
   619  	}
   620  	if !mp.CanSet() {
   621  		log.Printf("ki.SetMapRobust: map arg is not settable: %v\n", mtyp.String())
   622  		return false
   623  	}
   624  	ktyp := mtyp.Key()
   625  	etyp := mtyp.Elem()
   626  	if etyp.Kind() == val.Kind() && ky.Kind() == ktyp.Kind() {
   627  		mp.SetMapIndex(ky, val)
   628  		return true
   629  	}
   630  	if ky.Kind() == ktyp.Kind() {
   631  		mp.SetMapIndex(ky, val.Convert(etyp))
   632  		return true
   633  	}
   634  	if etyp.Kind() == val.Kind() {
   635  		mp.SetMapIndex(ky.Convert(ktyp), val)
   636  		return true
   637  	}
   638  	mp.SetMapIndex(ky.Convert(ktyp), val.Convert(etyp))
   639  	return true
   640  }
   641  
   642  // MakeMap makes a map that is actually addressable, getting around the hidden
   643  // interface{} that reflect.MakeMap makes, by calling UnhideIfaceValue (from ptrs.go)
   644  func MakeMap(typ reflect.Type) reflect.Value {
   645  	return UnhideIfaceValue(reflect.MakeMap(typ))
   646  }
   647  
   648  // MakeSlice makes a map that is actually addressable, getting around the hidden
   649  // interface{} that reflect.MakeSlice makes, by calling UnhideIfaceValue (from ptrs.go)
   650  func MakeSlice(typ reflect.Type, len, cap int) reflect.Value {
   651  	return UnhideIfaceValue(reflect.MakeSlice(typ, len, cap))
   652  }
   653  
   654  // CloneToType creates a new object of given type, and uses SetRobust to copy
   655  // an existing value (of perhaps another type) into it -- only expected to
   656  // work for basic types
   657  func CloneToType(typ reflect.Type, val interface{}) reflect.Value {
   658  	if NonPtrType(typ).Kind() == reflect.Map {
   659  		return MakeMap(typ)
   660  	} else if NonPtrType(typ).Kind() == reflect.Slice {
   661  		return MakeSlice(typ, 0, 0)
   662  	}
   663  	vn := reflect.New(typ)
   664  	evi := vn.Interface()
   665  	SetRobust(evi, val)
   666  	return vn
   667  }
   668  
   669  // MakeOfType creates a new object of given type with appropriate magic foo to
   670  // make it usable
   671  func MakeOfType(typ reflect.Type) reflect.Value {
   672  	if NonPtrType(typ).Kind() == reflect.Map {
   673  		return MakeMap(typ)
   674  	} else if NonPtrType(typ).Kind() == reflect.Slice {
   675  		return MakeSlice(typ, 0, 0)
   676  	}
   677  	vn := reflect.New(typ)
   678  	return vn
   679  }
   680  
   681  ////////////////////////////////////////////////////////////////////////////////////////
   682  //  Min / Max for other types..
   683  
   684  // math provides Max/Min for 64bit -- these are for specific subtypes
   685  
   686  func Max32(a, b float32) float32 {
   687  	if a > b {
   688  		return a
   689  	}
   690  	return b
   691  }
   692  
   693  func Min32(a, b float32) float32 {
   694  	if a < b {
   695  		return a
   696  	}
   697  	return b
   698  }
   699  
   700  // minimum excluding 0
   701  func MinPos(a, b float64) float64 {
   702  	if a > 0.0 && b > 0.0 {
   703  		return math.Min(a, b)
   704  	} else if a > 0.0 {
   705  		return a
   706  	} else if b > 0.0 {
   707  		return b
   708  	}
   709  	return a
   710  }
   711  
   712  // minimum excluding 0
   713  func MinPos32(a, b float32) float32 {
   714  	if a > 0.0 && b > 0.0 {
   715  		return Min32(a, b)
   716  	} else if a > 0.0 {
   717  		return a
   718  	} else if b > 0.0 {
   719  		return b
   720  	}
   721  	return a
   722  }
   723  
   724  // HasUpperCase returns true if string has an upper-case letter
   725  func HasUpperCase(str string) bool {
   726  	for _, r := range str {
   727  		if unicode.IsUpper(r) {
   728  			return true
   729  		}
   730  	}
   731  	return false
   732  }