diff --git a/core/vnl/vnl_math.h b/core/vnl/vnl_math.h index 4c9d87b1bd..31e3c6a11a 100644 --- a/core/vnl/vnl_math.h +++ b/core/vnl/vnl_math.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #ifdef _MSC_VER # include @@ -179,29 +180,45 @@ namespace numeric_predicates { // Wrap the classification functions to guarantee a bool return type; // some standard libraries returned a signed integer from these. +// Integral arguments are short-circuited: an integer is always finite, never +// inf/NaN, and normal when non-zero. This also avoids an ambiguous fpclassify +// overload in older Windows SDK integer templates, where +// std::isfinite/isnan of an integer fails to compile (error C2668). template inline bool isinf(TArg arg) { - return bool(std::isinf(arg)); + if constexpr (std::is_integral_v) + return false; + else + return bool(std::isinf(arg)); } template inline bool isnan(TArg arg) { - return bool(std::isnan(arg)); + if constexpr (std::is_integral_v) + return false; + else + return bool(std::isnan(arg)); } template inline bool isfinite(TArg arg) { - return bool(std::isfinite(arg)); + if constexpr (std::is_integral_v) + return true; + else + return bool(std::isfinite(arg)); } template inline bool isnormal(TArg arg) { - return bool(std::isnormal(arg)); + if constexpr (std::is_integral_v) + return arg != TArg(0); + else + return bool(std::isnormal(arg)); } } // namespace numeric_predicates