65template <
typename T>
inline constexpr T
Clamp(
const T& lower,
const T& value,
const T& upper )
67 assert( upper >= lower );
71 else if( upper < value )
77#ifdef HAVE_WIMPLICIT_FLOAT_CONVERSION
78 _Pragma(
"GCC diagnostic push" ) \
79 _Pragma(
"GCC diagnostic ignored \"-Wimplicit-int-float-conversion\"" )
88template <
typename in_type =
long long int,
typename ret_type =
int>
91 if constexpr( std::is_same_v<in_type, long long int> && std::is_same_v<ret_type, int> )
93 if( v > std::numeric_limits<int>::max() )
97 return std::numeric_limits<int>::max();
99 else if( v < std::numeric_limits<int>::lowest() )
103 return std::numeric_limits<int>::lowest();
120template <
typename fp_type,
typename ret_type =
int>
123 using max_ret =
long long int;
124 fp_type ret = v < 0 ? v - 0.5 : v + 0.5;
126 if( ret > std::numeric_limits<ret_type>::max() )
130 return std::numeric_limits<ret_type>::max() - 1;
132 else if( ret < std::numeric_limits<ret_type>::lowest() )
136 if( std::numeric_limits<ret_type>::is_signed )
137 return std::numeric_limits<ret_type>::lowest() + 1;
141#if __cplusplus >= 202302L
142 else if constexpr( std::is_floating_point_v<fp_type> )
144 if( std::isnan( v ) )
153 return ret_type( max_ret( ret ) );
156#ifdef HAVE_WIMPLICIT_FLOAT_CONVERSION
157 _Pragma(
"GCC diagnostic pop" )
165T
rescale( T aNumerator, T aValue, T aDenominator )
167 return aNumerator * aValue / aDenominator;
173 return ( T( 0 ) < val) - ( val < T( 0 ) );
178int rescale(
int aNumerator,
int aValue,
int aDenominator );
181int64_t
rescale( int64_t aNumerator, int64_t aValue, int64_t aDenominator );
193typename std::enable_if<std::is_floating_point<T>::value,
bool>::type
194equals( T aFirst, T aSecond, T aEpsilon = std::numeric_limits<T>::epsilon() )
196 T diff =
std::abs( aFirst - aSecond );
198 if( diff < aEpsilon )
205 T largest = aFirst > aSecond ? aFirst : aSecond;
207 if( diff <= largest * aEpsilon )
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
std::enable_if< std::is_floating_point< T >::value, bool >::type equals(T aFirst, T aSecond, T aEpsilon=std::numeric_limits< T >::epsilon())
Template to compare two floating point values for equality within a required epsilon.
void kimathLogOverflow(double v, const char *aTypeName)
Workaround to avoid the empty-string conversion issue in wxWidgets.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
T rescale(T aNumerator, T aValue, T aDenominator)
Scale a number (value) by rational (numerator/denominator).
void kimathLogDebug(const char *aFormatString,...)
Helper to avoid directly including wx/log.h for the templated functions in kimath.
constexpr T Clamp(const T &lower, const T &value, const T &upper)
Limit value within the range lower <= value <= upper.
constexpr ret_type KiCheckedCast(in_type v)
Perform a cast between numerical types.