github.com/haraldrudell/parl@v0.4.176/ints/unsigned.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package ints 7 8 import ( 9 "errors" 10 11 "github.com/haraldrudell/parl/perrors" 12 "golang.org/x/exp/constraints" 13 ) 14 15 // can be tested: errors.Is(err, ints.ErrToLarge) 16 var ErrTooLarge = errors.New("value too large") 17 18 // can be tested: errors.Is(err, ints.ErrNegative) 19 var ErrNegative = errors.New("negative value") 20 21 // Unsigned converts integer of type T to an unsigned value that fits the size of unsigned integer U 22 // - U is the unsigned integer returned 23 // - T is the input integer 24 // - integer T is of any integer size and may be signed 25 // - unsigned U is any size unsigned integer 26 // - error: if integer is negative or too large to be held in type U 27 func Unsigned[U constraints.Unsigned, T constraints.Integer](integer T, label string) (unsigned U, err error) { 28 29 // check for negative value 30 // - those come in signed integers 31 if isSigned, _, _, _ := IntProperties[T](); isSigned { 32 // whatever it is, it will fit into int64 33 if i64 := int64(integer); i64 < 0 { 34 if label == "" { 35 label = perrors.PackFunc() 36 } 37 err = perrors.Errorf("%s %w: %d -0x%x", label, ErrNegative, i64, -i64) 38 return 39 } 40 } 41 // integer is a positive number of a signed or unsigned integer 42 43 // check that positive value fits 44 var u64 = uint64(integer) 45 _, max, _, _ := IntProperties[U]() 46 if u64 > max { 47 if label == "" { 48 label = perrors.PackFunc() 49 } 50 err = perrors.Errorf("%s %w: %d 0x%[1]x max: %d 0x%[2]x", label, ErrTooLarge, u64, max) 51 return 52 } 53 54 unsigned = U(u64) 55 56 return 57 }