@ -39,25 +39,64 @@ bool isEqualF(const Type x, const Type y, const Type eps = 1e-4f)
@@ -39,25 +39,64 @@ bool isEqualF(const Type x, const Type y, const Type eps = 1e-4f)
| | ( isinf ( x ) & & isinf ( y ) & & isnan ( x - y ) ) ;
}
namespace detail
{
template < typename Floating >
Floating wrap_floating ( Floating x , Floating low , Floating high ) {
// already in range
if ( low < = x & & x < high ) {
return x ;
}
const auto range = high - low ;
const auto inv_range = Floating ( 1 ) / range ; // should evaluate at compile time, multiplies below at runtime
const auto num_wraps = floor ( ( x - low ) * inv_range ) ;
return x - range * num_wraps ;
}
} // namespace detail
/**
* Wrap value to stay in range [ low , high )
* Wrap single precision floating point value to stay in range [ low , high )
*
* @ param x input possibly outside of the range
* @ param low lower limit of the allowed range
* @ param high upper limit of the allowed range
* @ return wrapped value inside the range
*/
template < typename Type >
Type wrap ( Type x , Type low , Type high ) {
// already in range
if ( low < = x & & x < high ) {
return x ;
}
float wrap ( float x , float low , float high ) {
return matrix : : detail : : wrap_floating ( x , low , high ) ;
}
const Type range = high - low ;
const Type inv_range = Type ( 1 ) / range ; // should evaluate at compile time, multiplies below at runtime
const Type num_wraps = floor ( ( x - low ) * inv_range ) ;
return x - range * num_wraps ;
/**
* Wrap double precision floating point value to stay in range [ low , high )
*
* @ param x input possibly outside of the range
* @ param low lower limit of the allowed range
* @ param high upper limit of the allowed range
* @ return wrapped value inside the range
*/
double wrap ( double x , double low , double high ) {
return matrix : : detail : : wrap_floating ( x , low , high ) ;
}
/**
* Wrap integer value to stay in range [ low , high )
*
* @ param x input possibly outside of the range
* @ param low lower limit of the allowed range
* @ param high upper limit of the allowed range
* @ return wrapped value inside the range
*/
template < typename Integer >
Integer wrap ( Integer x , Integer low , Integer high ) {
const auto range = high - low ;
if ( x < low )
x + = range * ( ( low - x ) / range + 1 ) ;
return low + ( x - low ) % range ;
}
/**