]> git.donarmstrong.com Git - rsem.git/blobdiff - boost/math/special_functions/fpclassify.hpp
Updated boost to v1.55.0
[rsem.git] / boost / math / special_functions / fpclassify.hpp
index d3dc42b0caf6ba98fe4d6e51d6f09288b5745ecb..75f57b03b862a780351c66b1109d0085434af513 100644 (file)
@@ -37,13 +37,13 @@ the template is never instantiated.
 a floating point type (float, double or long double) can be determined
 at compile time, then the following algorithm is used:
 
-        If all exponent bits, the flag bit (if there is one), 
+        If all exponent bits, the flag bit (if there is one),
         and all significand bits are 0, then the number is zero.
 
-        If all exponent bits and the flag bit (if there is one) are 0, 
+        If all exponent bits and the flag bit (if there is one) are 0,
         and at least one significand bit is 1, then the number is subnormal.
 
-        If all exponent bits are 1 and all significand bits are 0, 
+        If all exponent bits are 1 and all significand bits are 0,
         then the number is infinity.
 
         If all exponent bits are 1 and at least one significand bit is 1,
@@ -56,7 +56,7 @@ at compile time, then the following algorithm is used:
 
     Most formats have the structure
         sign bit + exponent bits + significand bits.
-    
+
     A few have the structure
         sign bit + exponent bits + flag bit + significand bits.
     The flag bit is 0 for zero and subnormal numbers,
@@ -85,9 +85,8 @@ is used.
   namespace std{ using ::abs; using ::fabs; }
 #endif
 
-namespace boost{ 
+namespace boost{
 
-#if defined(BOOST_HAS_FPCLASSIFY) || defined(isnan)
 //
 // This must not be located in any namespace under boost::math
 // otherwise we can get into an infinite loop if isnan is
@@ -95,16 +94,28 @@ namespace boost{
 //
 namespace math_detail{
 
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4800)
+#endif
+
 template <class T>
 inline bool is_nan_helper(T t, const boost::true_type&)
 {
 #ifdef isnan
    return isnan(t);
+#elif defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) || !defined(BOOST_HAS_FPCLASSIFY)
+   (void)t;
+   return false;
 #else // BOOST_HAS_FPCLASSIFY
    return (BOOST_FPCLASSIFY_PREFIX fpclassify(t) == (int)FP_NAN);
 #endif
 }
 
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
 template <class T>
 inline bool is_nan_helper(T, const boost::false_type&)
 {
@@ -113,8 +124,6 @@ inline bool is_nan_helper(T, const boost::false_type&)
 
 }
 
-#endif // defined(BOOST_HAS_FPCLASSIFY) || defined(isnan)
-
 namespace math{
 
 namespace detail{
@@ -133,7 +142,7 @@ inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<true>&)
    BOOST_MATH_INSTRUMENT_VARIABLE(t);
 
    // whenever possible check for Nan's first:
-#ifdef BOOST_HAS_FPCLASSIFY
+#if defined(BOOST_HAS_FPCLASSIFY)  && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
    if(::boost::math_detail::is_nan_helper(t, ::boost::is_floating_point<T>()))
       return FP_NAN;
 #elif defined(isnan)
@@ -168,9 +177,9 @@ inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<false>&)
 {
 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
    if(std::numeric_limits<T>::is_specialized)
-      return fp_classify_imp(t, mpl::true_());
+      return fpclassify_imp(t, generic_tag<true>());
 #endif
-   // 
+   //
    // An unknown type with no numeric_limits support,
    // so what are we supposed to do we do here?
    //
@@ -179,7 +188,7 @@ inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<false>&)
    return t == 0 ? FP_ZERO : FP_NORMAL;
 }
 
-template<class T> 
+template<class T>
 int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_all_bits_tag)
 {
    typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
@@ -208,7 +217,7 @@ int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_all_bits_tag)
    return FP_NAN;
 }
 
-template<class T> 
+template<class T>
 int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag)
 {
    typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
@@ -216,7 +225,7 @@ int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag)
    BOOST_MATH_INSTRUMENT_VARIABLE(x);
 
    BOOST_DEDUCED_TYPENAME traits::bits a;
-   traits::get_bits(x,a); 
+   traits::get_bits(x,a);
    a &= traits::exponent | traits::flag | traits::significand;
 
    if(a <= traits::significand) {
@@ -235,9 +244,8 @@ int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag)
    return FP_NAN;
 }
 
-#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
-template <>
-inline int fpclassify_imp<long double> BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
+#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && (defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS))
+inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
 {
    return boost::math::detail::fpclassify_imp(t, generic_tag<true>());
 }
@@ -250,44 +258,62 @@ inline int fpclassify BOOST_NO_MACRO_EXPAND(T t)
 {
    typedef typename detail::fp_traits<T>::type traits;
    typedef typename traits::method method;
+   typedef typename tools::promote_args_permissive<T>::type value_type;
 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
-   if(std::numeric_limits<T>::is_specialized && detail::is_generic_tag_false(method()))
-      return detail::fpclassify_imp(t, detail::generic_tag<true>());
-   return detail::fpclassify_imp(t, method());
+   if(std::numeric_limits<T>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(0)))
+      return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
+   return detail::fpclassify_imp(static_cast<value_type>(t), method());
 #else
-   return detail::fpclassify_imp(t, method());
+   return detail::fpclassify_imp(static_cast<value_type>(t), method());
 #endif
 }
 
+#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+template <>
+inline int fpclassify<long double> BOOST_NO_MACRO_EXPAND(long double t)
+{
+   typedef detail::fp_traits<long double>::type traits;
+   typedef traits::method method;
+   typedef long double value_type;
+#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+   if(std::numeric_limits<long double>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(0)))
+      return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
+   return detail::fpclassify_imp(static_cast<value_type>(t), method());
+#else
+   return detail::fpclassify_imp(static_cast<value_type>(t), method());
+#endif
+}
+#endif
+
 namespace detail {
 
 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
-    template<class T> 
+    template<class T>
     inline bool isfinite_impl(T x, native_tag const&)
     {
         return (std::isfinite)(x);
     }
 #endif
 
-    template<class T> 
+    template<class T>
     inline bool isfinite_impl(T x, generic_tag<true> const&)
     {
         return x >= -(std::numeric_limits<T>::max)()
             && x <= (std::numeric_limits<T>::max)();
     }
 
-    template<class T> 
+    template<class T>
     inline bool isfinite_impl(T x, generic_tag<false> const&)
     {
 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
       if(std::numeric_limits<T>::is_specialized)
-         return isfinite_impl(x, mpl::true_());
+         return isfinite_impl(x, generic_tag<true>());
 #endif
        (void)x; // warning supression.
        return true;
     }
 
-    template<class T> 
+    template<class T>
     inline bool isfinite_impl(T x, ieee_tag const&)
     {
         typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
@@ -298,8 +324,7 @@ namespace detail {
     }
 
 #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
-template <>
-inline bool isfinite_impl<long double> BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
+inline bool isfinite_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
 {
    return boost::math::detail::isfinite_impl(t, generic_tag<true>());
 }
@@ -307,28 +332,41 @@ inline bool isfinite_impl<long double> BOOST_NO_MACRO_EXPAND(long double t, cons
 
 }
 
-template<class T> 
+template<class T>
 inline bool (isfinite)(T x)
 { //!< \brief return true if floating-point type t is finite.
    typedef typename detail::fp_traits<T>::type traits;
    typedef typename traits::method method;
-   typedef typename boost::is_floating_point<T>::type fp_tag;
-   return detail::isfinite_impl(x, method());
+   // typedef typename boost::is_floating_point<T>::type fp_tag;
+   typedef typename tools::promote_args_permissive<T>::type value_type;
+   return detail::isfinite_impl(static_cast<value_type>(x), method());
 }
 
+#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+template<>
+inline bool (isfinite)(long double x)
+{ //!< \brief return true if floating-point type t is finite.
+   typedef detail::fp_traits<long double>::type traits;
+   typedef traits::method method;
+   typedef boost::is_floating_point<long double>::type fp_tag;
+   typedef long double value_type;
+   return detail::isfinite_impl(static_cast<value_type>(x), method());
+}
+#endif
+
 //------------------------------------------------------------------------------
 
 namespace detail {
 
 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
-    template<class T> 
+    template<class T>
     inline bool isnormal_impl(T x, native_tag const&)
     {
         return (std::isnormal)(x);
     }
 #endif
 
-    template<class T> 
+    template<class T>
     inline bool isnormal_impl(T x, generic_tag<true> const&)
     {
         if(x < 0) x = -x;
@@ -336,17 +374,17 @@ namespace detail {
             && x <= (std::numeric_limits<T>::max)();
     }
 
-    template<class T> 
+    template<class T>
     inline bool isnormal_impl(T x, generic_tag<false> const&)
     {
 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
       if(std::numeric_limits<T>::is_specialized)
-         return isnormal_impl(x, mpl::true_());
+         return isnormal_impl(x, generic_tag<true>());
 #endif
        return !(x == 0);
     }
 
-    template<class T> 
+    template<class T>
     inline bool isnormal_impl(T x, ieee_tag const&)
     {
         typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
@@ -357,8 +395,7 @@ namespace detail {
     }
 
 #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
-template <>
-inline bool isnormal_impl<long double> BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
+inline bool isnormal_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
 {
    return boost::math::detail::isnormal_impl(t, generic_tag<true>());
 }
@@ -366,48 +403,61 @@ inline bool isnormal_impl<long double> BOOST_NO_MACRO_EXPAND(long double t, cons
 
 }
 
-template<class T> 
+template<class T>
 inline bool (isnormal)(T x)
 {
    typedef typename detail::fp_traits<T>::type traits;
    typedef typename traits::method method;
-   typedef typename boost::is_floating_point<T>::type fp_tag;
-   return detail::isnormal_impl(x, method());
+   //typedef typename boost::is_floating_point<T>::type fp_tag;
+   typedef typename tools::promote_args_permissive<T>::type value_type;
+   return detail::isnormal_impl(static_cast<value_type>(x), method());
 }
 
+#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+template<>
+inline bool (isnormal)(long double x)
+{
+   typedef detail::fp_traits<long double>::type traits;
+   typedef traits::method method;
+   typedef boost::is_floating_point<long double>::type fp_tag;
+   typedef long double value_type;
+   return detail::isnormal_impl(static_cast<value_type>(x), method());
+}
+#endif
+
 //------------------------------------------------------------------------------
 
 namespace detail {
 
 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
-    template<class T> 
+    template<class T>
     inline bool isinf_impl(T x, native_tag const&)
     {
         return (std::isinf)(x);
     }
 #endif
 
-    template<class T> 
+    template<class T>
     inline bool isinf_impl(T x, generic_tag<true> const&)
     {
         (void)x; // in case the compiler thinks that x is unused because std::numeric_limits<T>::has_infinity is false
-        return std::numeric_limits<T>::has_infinity 
+        return std::numeric_limits<T>::has_infinity
             && ( x == std::numeric_limits<T>::infinity()
                  || x == -std::numeric_limits<T>::infinity());
     }
 
-    template<class T> 
+    template<class T>
     inline bool isinf_impl(T x, generic_tag<false> const&)
     {
 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
       if(std::numeric_limits<T>::is_specialized)
-         return isinf_impl(x, mpl::true_());
+         return isinf_impl(x, generic_tag<true>());
 #endif
         (void)x; // warning supression.
         return false;
     }
 
-    template<class T> 
+    template<class T>
     inline bool isinf_impl(T x, ieee_copy_all_bits_tag const&)
     {
         typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
@@ -418,7 +468,7 @@ namespace detail {
         return a == traits::exponent;
     }
 
-    template<class T> 
+    template<class T>
     inline bool isinf_impl(T x, ieee_copy_leading_bits_tag const&)
     {
         typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
@@ -434,8 +484,7 @@ namespace detail {
     }
 
 #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
-template <>
-inline bool isinf_impl<long double> BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
+inline bool isinf_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
 {
    return boost::math::detail::isinf_impl(t, generic_tag<true>());
 }
@@ -443,28 +492,41 @@ inline bool isinf_impl<long double> BOOST_NO_MACRO_EXPAND(long double t, const n
 
 }   // namespace detail
 
-template<class T> 
+template<class T>
 inline bool (isinf)(T x)
 {
    typedef typename detail::fp_traits<T>::type traits;
    typedef typename traits::method method;
-   typedef typename boost::is_floating_point<T>::type fp_tag;
-   return detail::isinf_impl(x, method());
+   // typedef typename boost::is_floating_point<T>::type fp_tag;
+   typedef typename tools::promote_args_permissive<T>::type value_type;
+   return detail::isinf_impl(static_cast<value_type>(x), method());
 }
 
+#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+template<>
+inline bool (isinf)(long double x)
+{
+   typedef detail::fp_traits<long double>::type traits;
+   typedef traits::method method;
+   typedef boost::is_floating_point<long double>::type fp_tag;
+   typedef long double value_type;
+   return detail::isinf_impl(static_cast<value_type>(x), method());
+}
+#endif
+
 //------------------------------------------------------------------------------
 
 namespace detail {
 
 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
-    template<class T> 
+    template<class T>
     inline bool isnan_impl(T x, native_tag const&)
     {
         return (std::isnan)(x);
     }
 #endif
 
-    template<class T> 
+    template<class T>
     inline bool isnan_impl(T x, generic_tag<true> const&)
     {
         return std::numeric_limits<T>::has_infinity
@@ -472,18 +534,18 @@ namespace detail {
             : x != x;
     }
 
-    template<class T> 
+    template<class T>
     inline bool isnan_impl(T x, generic_tag<false> const&)
     {
 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
       if(std::numeric_limits<T>::is_specialized)
-         return isnan_impl(x, mpl::true_());
+         return isnan_impl(x, generic_tag<true>());
 #endif
         (void)x; // warning supression
         return false;
     }
 
-    template<class T> 
+    template<class T>
     inline bool isnan_impl(T x, ieee_copy_all_bits_tag const&)
     {
         typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
@@ -494,7 +556,7 @@ namespace detail {
         return a > traits::exponent;
     }
 
-    template<class T> 
+    template<class T>
     inline bool isnan_impl(T x, ieee_copy_leading_bits_tag const&)
     {
         typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
@@ -513,11 +575,12 @@ namespace detail {
 
 }   // namespace detail
 
-template<class T> bool (isnan)(T x)
+template<class T>
+inline bool (isnan)(T x)
 { //!< \brief return true if floating-point type t is NaN (Not A Number).
    typedef typename detail::fp_traits<T>::type traits;
    typedef typename traits::method method;
-   typedef typename boost::is_floating_point<T>::type fp_tag;
+   // typedef typename boost::is_floating_point<T>::type fp_tag;
    return detail::isnan_impl(x, method());
 }
 
@@ -525,6 +588,15 @@ template<class T> bool (isnan)(T x)
 template <> inline bool isnan BOOST_NO_MACRO_EXPAND<float>(float t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
 template <> inline bool isnan BOOST_NO_MACRO_EXPAND<double>(double t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
 template <> inline bool isnan BOOST_NO_MACRO_EXPAND<long double>(long double t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
+#elif defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
+template<>
+inline bool (isnan)(long double x)
+{ //!< \brief return true if floating-point type t is NaN (Not A Number).
+   typedef detail::fp_traits<long double>::type traits;
+   typedef traits::method method;
+   typedef boost::is_floating_point<long double>::type fp_tag;
+   return detail::isnan_impl(x, method());
+}
 #endif
 
 } // namespace math