这是基于 RadioKat 答案的实现,但它会抑制编译器警告,例如:
warning: pointless comparison of unsigned integer with zero
warning: integer conversion resulted in a change of sign
通过使用模板元编程:
#include <limits>
template< typename T_Range, typename T_Value, bool T_RangeSigned, bool T_ValueSigned >
struct InIntegerRange;
template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, false, false >
{
bool operator()( T_Value const & x )
{
return x >= std::numeric_limits< T_Range >::min() &&
x <= std::numeric_limits< T_Range >::max();
}
};
template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, false, true >
{
bool operator()( T_Value const & x )
{
return x >= 0 && x <= std::numeric_limits< T_Range >::max();
}
};
template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, true, false >
{
bool operator()( T_Value const & x )
{
return x <= std::numeric_limits< T_Range >::max(); /* x >= 0 is given */
}
};
template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, true, true >
{
bool operator()( T_Value const & x )
{
return x >= std::numeric_limits< T_Range >::min() &&
x <= std::numeric_limits< T_Range >::max();
}
};
template< typename T_Range, typename T_Value >
inline bool inRange( T_Value const & x )
{
if( std::numeric_limits< T_Range >::is_integer )
{
return InIntegerRange< T_Range, T_Value,
std::numeric_limits< T_Range >::is_signed,
std::numeric_limits< T_Value >::is_signed >()( x );
}
else
{
return ( x > 0 ? x : -x ) <= std::numeric_limits< T_Range >::max() ||
( std::isnan(x) && std::numeric_limits< T_Range >::has_quiet_NaN ) ||
( std::isinf(x) && std::numeric_limits< T_Range >::has_infinity );
}
}