package mathutil

import (
	
	
	
	
	
	

	
	
)

/*************************************************************
 * region convert to int
 *************************************************************/

// Int convert value to int
func ( any) (int, error) { return ToInt() }

// SafeInt convert value to int, will ignore error
func ( any) int {
	,  := ToInt()
	return 
}

// QuietInt convert value to int, will ignore error
func ( any) int { return SafeInt() }

// IntOrPanic convert value to int, will panic on error
func ( any) int {
	,  := ToInt()
	if  != nil {
		panic()
	}
	return 
}

// MustInt convert value to int, will panic on error
func ( any) int { return IntOrPanic() }

// IntOrDefault convert value to int, return defaultVal on failed
func ( any,  int) int { return IntOr(, ) }

// IntOr convert value to int, return defaultVal on failed
func ( any,  int) int {
	,  := ToIntWith()
	if  != nil {
		return 
	}
	return 
}

// IntOrErr convert value to int, return error on failed
func ( any) (int, error) { return ToIntWith() }

// ToInt convert value to int, return error on failed
func ( any) (int, error) { return ToIntWith() }

// ToIntWith convert value to int, can with some option func.
//
// Example:
//
//	ToIntWithFunc(val, mathutil.WithNilAsFail, mathutil.WithUserConvFn(func(in any) (int, error) {
//	})
func ( any,  ...ConvOptionFn[int]) ( int,  error) {
	if len() == 0 &&  == nil {
		return 0, nil
	}

	var  *ConvOption[int]
	if len() > 0 {
		 = NewConvOption(...)
		if  == nil && .NilAsFail {
			 = comdef.ErrConvType
			return
		}
	}

	if ,  := .(string);  {
		// in strict mode, cannot convert string to int
		if  != nil && .StrictMode {
			 = comdef.ErrConvType
			return
		}

		// try convert to int
		,  = TryStrInt()
		return
	}

	switch tVal := .(type) {
	case int:
		 = 
	case *int: // default support int ptr type
		 = *
	case int8:
		 = int()
	case int16:
		 = int()
	case int32:
		 = int()
	case int64:
		if  > math.MaxInt32 {
			 = fmt.Errorf("value overflow int32. input: %v", )
		} else {
			 = int()
		}
	case uint:
		if  > math.MaxInt32 {
			 = fmt.Errorf("value overflow int32. input: %v", )
		} else {
			 = int()
		}
	case uint8:
		 = int()
	case uint16:
		 = int()
	case uint32:
		if  > math.MaxInt32 {
			 = fmt.Errorf("value overflow int32. input: %v", )
		} else {
			 = int()
		}
	case uint64:
		if  > math.MaxInt32 {
			 = fmt.Errorf("value overflow int32. input: %v", )
		} else {
			 = int()
		}
	case float32:
		 = int()
	case float64:
		 = int()
	case time.Duration:
		if  > math.MaxInt32 {
			 = fmt.Errorf("value overflow int32. input: %v", )
		} else {
			 = int()
		}
	case comdef.Int64able: // eg: json.Number
		var  int64
		if ,  = .Int64();  == nil {
			if  > math.MaxInt32 {
				 = fmt.Errorf("value overflow int32. input: %v", )
			} else {
				 = int()
			}
		}
	default:
		if  == nil {
			 = comdef.ErrConvType
			return
		}

		if .UserConvFn != nil {
			,  = .UserConvFn()
		} else if .HandlePtr {
			if  := reflect.ValueOf(); .Kind() == reflect.Pointer {
				 = .Elem()
				if checkfn.IsSimpleKind(.Kind()) {
					return (.Interface(), ...)
				}
			}
		} else {
			 = comdef.ErrConvType
		}
	}
	return
}

/*************************************************************
 * region convert to int64
 *************************************************************/

// Int64 convert value to int64, return error on failed
func ( any) (int64, error) { return ToInt64() }

// SafeInt64 convert value to int64, will ignore error
func ( any) int64 {
	,  := ToInt64With()
	return 
}

// QuietInt64 convert value to int64, will ignore error
func ( any) int64 { return SafeInt64() }

// MustInt64 convert value to int64, will panic on error
func ( any) int64 {
	,  := ToInt64With()
	if  != nil {
		panic()
	}
	return 
}

// Int64OrDefault convert value to int64, return default val on failed
func ( any,  int64) int64 { return Int64Or(, ) }

// Int64Or convert value to int64, return default val on failed
func ( any,  int64) int64 {
	,  := ToInt64With()
	if  != nil {
		return 
	}
	return 
}

// ToInt64 convert value to int64, return error on failed
func ( any) (int64, error) { return ToInt64With() }

// Int64OrErr convert value to int64, return error on failed
func ( any) (int64, error) { return ToInt64With() }

// ToInt64With try to convert value to int64. can with some option func, more see ConvOption.
func ( any,  ...ConvOptionFn[int64]) ( int64,  error) {
	if len() == 0 &&  == nil {
		return 0, nil
	}

	var  *ConvOption[int64]
	if len() > 0 {
		 = NewConvOption(...)
		if  == nil && .NilAsFail {
			 = comdef.ErrConvType
			return
		}
	}

	if ,  := .(string);  {
		// in strict mode, cannot convert string to int
		if  != nil && .StrictMode {
			 = comdef.ErrConvType
			return
		}
		// try convert to int64
		,  = TryStrInt64()
		return
	}

	switch tVal := .(type) {
	case int:
		 = int64()
	case int8:
		 = int64()
	case int16:
		 = int64()
	case int32:
		 = int64()
	case int64:
		 = 
	case *int64: // default support int64 ptr type
		 = *
	case uint:
		 = int64()
	case uint8:
		 = int64()
	case uint16:
		 = int64()
	case uint32:
		 = int64()
	case uint64:
		 = int64()
	case float32:
		// in strict mode, cannot convert float to int
		if  != nil && .StrictMode {
			 = comdef.ErrConvType
			return
		}
		 = int64()
	case float64:
		// in strict mode, cannot convert float to int
		if  != nil && .StrictMode {
			 = comdef.ErrConvType
			return
		}
		if  > math.MaxInt64 {
			 = comdef.ErrConvType
			return
		}
		 = int64()
	case time.Duration:
		 = int64()
	case comdef.Int64able: // eg: json.Number
		,  = .Int64()
	default:
		if  == nil {
			 = comdef.ErrConvType
			return
		}

		if .UserConvFn != nil {
			,  = .UserConvFn()
		} else if .HandlePtr {
			if  := reflect.ValueOf(); .Kind() == reflect.Pointer {
				 = .Elem()
				if checkfn.IsSimpleKind(.Kind()) {
					return (.Interface(), ...)
				}
			}
		} else {
			 = comdef.ErrConvType
		}
	}
	return
}

/*************************************************************
 * region convert to uint
 *************************************************************/

// Uint convert any to uint, return error on failed
func ( any) (uint, error) { return ToUint() }

// SafeUint convert any to uint, will ignore error
func ( any) uint {
	,  := ToUint()
	return 
}

// QuietUint convert any to uint, will ignore error
func ( any) uint { return SafeUint() }

// MustUint convert any to uint, will panic on error
func ( any) uint {
	,  := ToUintWith()
	if  != nil {
		panic()
	}
	return 
}

// UintOrDefault convert any to uint, return default val on failed
func ( any,  uint) uint { return UintOr(, ) }

// UintOr convert any to uint, return default val on failed
func ( any,  uint) uint {
	,  := ToUintWith()
	if  != nil {
		return 
	}
	return 
}

// UintOrErr convert value to uint, return error on failed
func ( any) (uint, error) { return ToUintWith() }

// ToUint convert value to uint, return error on failed
func ( any) ( uint,  error) { return ToUintWith() }

// ToUintWith try to convert value to uint. can with some option func, more see ConvOption.
func ( any,  ...ConvOptionFn[uint]) ( uint,  error) {
	if len() == 0 &&  == nil {
		return 0, nil
	}

	var  *ConvOption[uint]
	if len() > 0 {
		 = NewConvOption(...)
		if  == nil && .NilAsFail {
			 = comdef.ErrConvType
			return
		}
	}

	if ,  := .(string);  {
		// in strict mode, cannot convert string to int
		if  != nil && .StrictMode {
			 = comdef.ErrConvType
			return
		}

		// try convert to uint64
		var  uint64
		if ,  = TryStrUint64();  == nil {
			 = uint()
		}
		return
	}

	switch tVal := .(type) {
	case int:
		 = uint()
	case int8:
		 = uint()
	case int16:
		 = uint()
	case int32:
		 = uint()
	case int64:
		 = uint()
	case uint:
		 = 
	case *uint: // default support uint ptr type
		 = *
	case uint8:
		 = uint()
	case uint16:
		 = uint()
	case uint32:
		 = uint()
	case uint64:
		 = uint()
	case float32:
		 = uint()
	case float64:
		 = uint()
	case time.Duration:
		 = uint()
	case comdef.Int64able: // eg: json.Number
		var  int64
		,  = .Int64()
		 = uint()
	default:
		if  == nil {
			 = comdef.ErrConvType
			return
		}

		if .UserConvFn != nil {
			,  = .UserConvFn()
		} else if .HandlePtr {
			if  := reflect.ValueOf(); .Kind() == reflect.Pointer {
				 = .Elem()
				if checkfn.IsSimpleKind(.Kind()) {
					return (.Interface(), ...)
				}
			}
		} else {
			 = comdef.ErrConvType
		}
	}
	return
}

/*************************************************************
 * region convert to uint64
 *************************************************************/

// Uint64 convert any to uint64, return error on failed
func ( any) (uint64, error) { return ToUint64() }

// QuietUint64 convert any to uint64, will ignore error
func ( any) uint64 { return SafeUint64() }

// SafeUint64 convert any to uint64, will ignore error
func ( any) uint64 {
	,  := ToUint64()
	return 
}

// MustUint64 convert any to uint64, will panic on error
func ( any) uint64 {
	,  := ToUint64With()
	if  != nil {
		panic()
	}
	return 
}

// Uint64OrDefault convert any to uint64, return default val on failed
func ( any,  uint64) uint64 { return Uint64Or(, ) }

// Uint64Or convert any to uint64, return default val on failed
func ( any,  uint64) uint64 {
	,  := ToUint64With()
	if  != nil {
		return 
	}
	return 
}

// Uint64OrErr convert value to uint64, return error on failed
func ( any) (uint64, error) { return ToUint64With() }

// ToUint64 convert value to uint64, return error on failed
func ( any) (uint64, error) { return ToUint64With() }

// ToUint64With try to convert value to uint64. can with some option func, more see ConvOption.
func ( any,  ...ConvOptionFn[uint64]) ( uint64,  error) {
	if len() == 0 &&  == nil {
		return 0, nil
	}

	var  *ConvOption[uint64]
	if len() > 0 {
		 = NewConvOption(...)
		if  == nil && .NilAsFail {
			 = comdef.ErrConvType
			return
		}
	}

	if ,  := .(string);  {
		// in strict mode, cannot convert string to int
		if  != nil && .StrictMode {
			 = comdef.ErrConvType
			return
		}
		// try convert to uint64
		,  = TryStrUint64()
		return
	}

	switch tVal := .(type) {
	case int:
		 = uint64()
	case int8:
		 = uint64()
	case int16:
		 = uint64()
	case int32:
		 = uint64()
	case int64:
		 = uint64()
	case uint:
		 = uint64()
	case uint8:
		 = uint64()
	case uint16:
		 = uint64()
	case uint32:
		 = uint64()
	case uint64:
		 = 
	case *uint64: // default support uint64 ptr type
		 = *
	case float32:
		 = uint64()
	case float64:
		 = uint64()
	case time.Duration:
		 = uint64()
	case comdef.Int64able: // eg: json.Number
		var  int64
		,  = .Int64()
		 = uint64()
	default:
		if  == nil {
			 = comdef.ErrConvType
			return
		}

		if .UserConvFn != nil {
			,  = .UserConvFn()
		} else if .HandlePtr {
			if  := reflect.ValueOf(); .Kind() == reflect.Pointer {
				 = .Elem()
				if checkfn.IsSimpleKind(.Kind()) {
					return (.Interface(), ...)
				}
			}
		} else {
			 = comdef.ErrConvType
		}
	}
	return
}

/*************************************************************
 * region string to intX/uintX
 *************************************************************/

// StrInt convert string to int, ignore error
func ( string) int {
	,  := strconv.Atoi(strings.TrimSpace())
	return 
}

// StrIntOr convert string to int, return default val on failed
func ( string,  int) int {
	,  := strconv.Atoi(strings.TrimSpace())
	if  != nil {
		return 
	}
	return 
}

// TryStrInt convert string to int, return error on failed.
//
//  - empty string will return 0.
//  - allow float string.
func ( string) (int, error) {
	 = strings.TrimSpace()
	if  == "" {
		return 0, nil
	}

	// try convert to int
	,  := strconv.Atoi()

	// handle the case where the string might be a float
	if  != nil && checkfn.IsNumeric() {
		var  float64
		if ,  = strconv.ParseFloat(, 64);  == nil {
			 = int(math.Round())
			 = nil
		}
	}
	return , 
}

// TryStrInt64 convert string to int64, return error on failed.
//
//  - empty string will return 0.
//  - allow float string.
func ( string) (int64, error) {
	 = strings.TrimSpace()
	if  == "" {
		return 0, nil
	}
	,  := strconv.ParseInt(, 10, 0)

	// handle the case where the string might be a float
	if  != nil && checkfn.IsNumeric() {
		var  float64
		if ,  = strconv.ParseFloat(, 64);  == nil {
			 = int64(math.Round())
			 = nil
		}
	}
	return , 
}

// TryStrUint64 try to convert string to uint64, return error on failed
//
//  - empty string will return 0.
//  - allow float string.
func ( string) (uint64, error) {
	 = strings.TrimSpace()
	if  == "" {
		return 0, nil
	}

	// try convert to int64
	,  := strconv.ParseUint(, 10, 0)

	// handle the case where the string might be a float
	if  != nil && checkfn.IsPositiveNum() {
		var  float64
		if ,  = strconv.ParseFloat(, 64);  == nil {
			 = uint64(math.Round())
			 = nil
		}
	}
	return , 
}