]> 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:
 
 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.
 
         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.
 
         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,
         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.
 
     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,
     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 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
 //
 // 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{
 
 //
 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);
 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
 }
 
 #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&)
 {
 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{
 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:
    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)
    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)
 {
 #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
 #endif
-   // 
+   //
    // An unknown type with no numeric_limits support,
    // so what are we supposed to do we do here?
    //
    // 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;
 }
 
    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;
 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;
 }
 
    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;
 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;
    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) {
    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;
 }
 
    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>());
 }
 {
    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 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
 #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
 #else
-   return detail::fpclassify_imp(t, method());
+   return detail::fpclassify_imp(static_cast<value_type>(t), method());
 #endif
 }
 
 #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
 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
 
     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)();
     }
 
     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)
     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;
     }
 
 #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;
     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)
     }
 
 #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>());
 }
 {
    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;
 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
 //------------------------------------------------------------------------------
 
 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
 
     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;
     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)();
     }
 
             && 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)
     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);
     }
 
 #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;
     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)
     }
 
 #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>());
 }
 {
    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;
 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
 //------------------------------------------------------------------------------
 
 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
 
     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
     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());
     }
 
             && ( 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)
     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;
     }
 
 #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;
     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;
     }
 
         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;
     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)
     }
 
 #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>());
 }
 {
    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
 
 
 }   // 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;
 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
 //------------------------------------------------------------------------------
 
 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
 
     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
     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;
     }
 
             : 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)
     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;
     }
 
 #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;
     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;
     }
 
         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;
     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
 
 
 }   // 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;
 { //!< \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());
 }
 
    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()); }
 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
 #endif
 
 } // namespace math