Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-16 09:19:38

0001 //  Copyright (c) 2006-7 John Maddock
0002 //  Copyright (c) 2021 Matt Borland
0003 //  Use, modification and distribution are subject to the
0004 //  Boost Software License, Version 1.0. (See accompanying file
0005 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_MATH_TOOLS_CONFIG_HPP
0008 #define BOOST_MATH_TOOLS_CONFIG_HPP
0009 
0010 #ifdef _MSC_VER
0011 #pragma once
0012 #endif
0013 
0014 #include <boost/math/tools/is_standalone.hpp>
0015 
0016 // Minimum language standard transition
0017 #ifdef _MSVC_LANG
0018 #  if _MSVC_LANG < 201402L
0019 #    pragma warning("The minimum language standard to use Boost.Math will be C++14 starting in July 2023 (Boost 1.82 release)");
0020 #  endif
0021 #else
0022 #  if __cplusplus < 201402L
0023 #    warning "The minimum language standard to use Boost.Math will be C++14 starting in July 2023 (Boost 1.82 release)"
0024 #  endif
0025 #endif
0026 
0027 #ifndef BOOST_MATH_STANDALONE
0028 #include <boost/config.hpp>
0029 
0030 #else // Things from boost/config that are required, and easy to replicate
0031 
0032 #define BOOST_PREVENT_MACRO_SUBSTITUTION
0033 #define BOOST_MATH_NO_REAL_CONCEPT_TESTS
0034 #define BOOST_MATH_NO_DISTRIBUTION_CONCEPT_TESTS
0035 #define BOOST_MATH_NO_LEXICAL_CAST
0036 
0037 // Since Boost.Multiprecision is in active development some tests do not fully cooperate yet.
0038 #define BOOST_MATH_NO_MP_TESTS
0039 
0040 #if (__cplusplus > 201400L || _MSVC_LANG > 201400L)
0041 #define BOOST_CXX14_CONSTEXPR constexpr
0042 #else
0043 #define BOOST_CXX14_CONSTEXPR
0044 #define BOOST_NO_CXX14_CONSTEXPR
0045 #endif // BOOST_CXX14_CONSTEXPR
0046 
0047 #if (__cplusplus > 201700L || _MSVC_LANG > 201700L)
0048 #define BOOST_IF_CONSTEXPR if constexpr
0049 
0050 // Clang on mac provides the execution header with none of the functionality. TODO: Check back on this
0051 // https://en.cppreference.com/w/cpp/compiler_support "Standardization of Parallelism TS"
0052 #if !__has_include(<execution>) || (defined(__APPLE__) && defined(__clang__))
0053 #define BOOST_NO_CXX17_HDR_EXECUTION
0054 #endif
0055 #else
0056 #define BOOST_IF_CONSTEXPR if
0057 #define BOOST_NO_CXX17_IF_CONSTEXPR
0058 #define BOOST_NO_CXX17_HDR_EXECUTION
0059 #endif
0060 
0061 #if __cpp_lib_gcd_lcm >= 201606L
0062 #define BOOST_MATH_HAS_CXX17_NUMERIC
0063 #endif
0064 
0065 #define BOOST_JOIN(X, Y) BOOST_DO_JOIN(X, Y)
0066 #define BOOST_DO_JOIN(X, Y) BOOST_DO_JOIN2(X,Y)
0067 #define BOOST_DO_JOIN2(X, Y) X##Y
0068 
0069 #define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X)
0070 #define BOOST_DO_STRINGIZE(X) #X
0071 
0072 #ifdef BOOST_DISABLE_THREADS // No threads, do nothing
0073 // Detect thread support via STL implementation
0074 #elif defined(__has_include)
0075 #  if !__has_include(<thread>) || !__has_include(<mutex>) || !__has_include(<future>) || !__has_include(<atomic>)
0076 #     define BOOST_DISABLE_THREADS
0077 #  else
0078 #     define BOOST_HAS_THREADS
0079 #  endif 
0080 #else
0081 #  define BOOST_HAS_THREADS // The default assumption is that the machine has threads
0082 #endif // Thread Support
0083 
0084 #ifdef BOOST_DISABLE_THREADS
0085 #  define BOOST_NO_CXX11_HDR_ATOMIC
0086 #  define BOOST_NO_CXX11_HDR_FUTURE
0087 #  define BOOST_NO_CXX11_HDR_THREAD
0088 #  define BOOST_NO_CXX11_THREAD_LOCAL
0089 #endif // BOOST_DISABLE_THREADS
0090 
0091 #ifdef __GNUC__
0092 #  if !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS)
0093 #     define BOOST_NO_EXCEPTIONS
0094 #  endif
0095    //
0096    // Make sure we have some std lib headers included so we can detect __GXX_RTTI:
0097    //
0098 #  include <algorithm>  // for min and max
0099 #  include <limits>
0100 #  ifndef __GXX_RTTI
0101 #     ifndef BOOST_NO_TYPEID
0102 #        define BOOST_NO_TYPEID
0103 #     endif
0104 #     ifndef BOOST_NO_RTTI
0105 #        define BOOST_NO_RTTI
0106 #     endif
0107 #  endif
0108 #endif
0109 
0110 #if !defined(BOOST_NOINLINE)
0111 #  if defined(_MSC_VER)
0112 #    define BOOST_NOINLINE __declspec(noinline)
0113 #  elif defined(__GNUC__) && __GNUC__ > 3
0114      // Clang also defines __GNUC__ (as 4)
0115 #    if defined(__CUDACC__)
0116        // nvcc doesn't always parse __noinline__,
0117        // see: https://svn.boost.org/trac/boost/ticket/9392
0118 #      define BOOST_NOINLINE __attribute__ ((noinline))
0119 #    elif defined(__HIP__)
0120        // See https://github.com/boostorg/config/issues/392
0121 #      define BOOST_NOINLINE __attribute__ ((noinline))
0122 #    else
0123 #      define BOOST_NOINLINE __attribute__ ((__noinline__))
0124 #    endif
0125 #  else
0126 #    define BOOST_NOINLINE
0127 #  endif
0128 #endif
0129 
0130 #if !defined(BOOST_FORCEINLINE)
0131 #  if defined(_MSC_VER)
0132 #    define BOOST_FORCEINLINE __forceinline
0133 #  elif defined(__GNUC__) && __GNUC__ > 3
0134      // Clang also defines __GNUC__ (as 4)
0135 #    define BOOST_FORCEINLINE inline __attribute__ ((__always_inline__))
0136 #  else
0137 #    define BOOST_FORCEINLINE inline
0138 #  endif
0139 #endif
0140 
0141 #endif // BOOST_MATH_STANDALONE
0142 
0143 // Support compilers with P0024R2 implemented without linking TBB
0144 // https://en.cppreference.com/w/cpp/compiler_support
0145 #if !defined(BOOST_NO_CXX17_HDR_EXECUTION) && defined(BOOST_HAS_THREADS)
0146 #  define BOOST_MATH_EXEC_COMPATIBLE
0147 #endif
0148 
0149 // C++23
0150 #if __cplusplus > 202002L || _MSVC_LANG > 202002L
0151 #  if __GNUC__ >= 13
0152      // libstdc++3 only defines to/from_chars for std::float128_t when one of these defines are set
0153      // otherwise we're right out of luck...
0154 #    if defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) || defined(_GLIBCXX_HAVE_FLOAT128_MATH)
0155 #      include <cstring> // std::strlen is used with from_chars
0156 #      include <charconv>
0157 #      include <stdfloat>
0158 #      define BOOST_MATH_USE_CHARCONV_FOR_CONVERSION
0159 #    endif
0160 #  endif
0161 #endif
0162 
0163 #include <algorithm>  // for min and max
0164 #include <limits>
0165 #include <cmath>
0166 #include <climits>
0167 #include <cfloat>
0168 
0169 #include <boost/math/tools/user.hpp>
0170 
0171 #if (defined(__NetBSD__) || defined(__EMSCRIPTEN__)\
0172    || (defined(__hppa) && !defined(__OpenBSD__)) || (defined(__NO_LONG_DOUBLE_MATH) && (DBL_MANT_DIG != LDBL_MANT_DIG))) \
0173    && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
0174 //#  define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0175 #endif
0176 
0177 #ifdef __IBMCPP__
0178 //
0179 // For reasons I don't understand, the tests with IMB's compiler all
0180 // pass at long double precision, but fail with real_concept, those tests
0181 // are disabled for now.  (JM 2012).
0182 #ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS
0183 #  define BOOST_MATH_NO_REAL_CONCEPT_TESTS
0184 #endif // BOOST_MATH_NO_REAL_CONCEPT_TESTS
0185 #endif
0186 #ifdef sun
0187 // Any use of __float128 in program startup code causes a segfault  (tested JM 2015, Solaris 11).
0188 #  define BOOST_MATH_DISABLE_FLOAT128
0189 #endif
0190 #ifdef __HAIKU__
0191 //
0192 // Not sure what's up with the math detection on Haiku, but linking fails with
0193 // float128 code enabled, and we don't have an implementation of __expl, so
0194 // disabling long double functions for now as well.
0195 #  define BOOST_MATH_DISABLE_FLOAT128
0196 #  define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0197 #endif
0198 #if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
0199 //
0200 // Darwin's rather strange "double double" is rather hard to
0201 // support, it should be possible given enough effort though...
0202 //
0203 #  define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0204 #endif
0205 #if !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) && (LDBL_MANT_DIG == 106) && (LDBL_MIN_EXP > DBL_MIN_EXP)
0206 //
0207 // Generic catch all case for gcc's "double-double" long double type.
0208 // We do not support this as it's not even remotely IEEE conforming:
0209 //
0210 #  define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0211 #endif
0212 #if defined(unix) && defined(__INTEL_COMPILER) && (__INTEL_COMPILER <= 1000) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
0213 //
0214 // Intel compiler prior to version 10 has sporadic problems
0215 // calling the long double overloads of the std lib math functions:
0216 // calling ::powl is OK, but std::pow(long double, long double) 
0217 // may segfault depending upon the value of the arguments passed 
0218 // and the specific Linux distribution.
0219 //
0220 // We'll be conservative and disable long double support for this compiler.
0221 //
0222 // Comment out this #define and try building the tests to determine whether
0223 // your Intel compiler version has this issue or not.
0224 //
0225 #  define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0226 #endif
0227 #if defined(unix) && defined(__INTEL_COMPILER)
0228 //
0229 // Intel compiler has sporadic issues compiling std::fpclassify depending on
0230 // the exact OS version used.  Use our own code for this as we know it works
0231 // well on Intel processors:
0232 //
0233 #define BOOST_MATH_DISABLE_STD_FPCLASSIFY
0234 #endif
0235 
0236 #if defined(_MSC_VER) && !defined(_WIN32_WCE)
0237    // Better safe than sorry, our tests don't support hardware exceptions:
0238 #  define BOOST_MATH_CONTROL_FP _control87(MCW_EM,MCW_EM)
0239 #endif
0240 
0241 #ifdef __IBMCPP__
0242 #  define BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS
0243 #endif
0244 
0245 #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901))
0246 #  define BOOST_MATH_USE_C99
0247 #endif
0248 
0249 #if (defined(__hpux) && !defined(__hppa))
0250 #  define BOOST_MATH_USE_C99
0251 #endif
0252 
0253 #if defined(__GNUC__) && defined(_GLIBCXX_USE_C99)
0254 #  define BOOST_MATH_USE_C99
0255 #endif
0256 
0257 #if defined(_LIBCPP_VERSION) && !defined(_MSC_VER)
0258 #  define BOOST_MATH_USE_C99
0259 #endif
0260 
0261 #if defined(__CYGWIN__) || defined(__HP_aCC) || defined(__INTEL_COMPILER) \
0262   || defined(BOOST_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) \
0263   || (defined(__GNUC__) && !defined(BOOST_MATH_USE_C99))\
0264   || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
0265 #  define BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY
0266 #endif
0267 
0268 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x590)
0269 
0270 namespace boost { namespace math { namespace tools { namespace detail {
0271 template <typename T>
0272 struct type {};
0273 
0274 template <typename T, T n>
0275 struct non_type {};
0276 }}}} // Namespace boost, math tools, detail
0277 
0278 #  define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t)              boost::math::tools::detail::type<t>* = 0
0279 #  define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t)         boost::math::tools::detail::type<t>*
0280 #  define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v)       boost::math::tools::detail::non_type<t, v>* = 0
0281 #  define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)  boost::math::tools::detail::non_type<t, v>*
0282 
0283 #  define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t)         \
0284              , BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t)
0285 #  define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t)    \
0286              , BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t)
0287 #  define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v)  \
0288              , BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v)
0289 #  define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)  \
0290              , BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)
0291 
0292 #else
0293 
0294 // no workaround needed: expand to nothing
0295 
0296 #  define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t)
0297 #  define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t)
0298 #  define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v)
0299 #  define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)
0300 
0301 #  define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t)
0302 #  define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t)
0303 #  define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v)
0304 #  define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)
0305 
0306 
0307 #endif // __SUNPRO_CC
0308 
0309 #if (defined(__SUNPRO_CC) || defined(__hppa) || defined(__GNUC__)) && !defined(BOOST_MATH_SMALL_CONSTANT)
0310 // Sun's compiler emits a hard error if a constant underflows,
0311 // as does aCC on PA-RISC, while gcc issues a large number of warnings:
0312 #  define BOOST_MATH_SMALL_CONSTANT(x) 0.0
0313 #else
0314 #  define BOOST_MATH_SMALL_CONSTANT(x) x
0315 #endif
0316 
0317 //
0318 // Tune performance options for specific compilers:
0319 //
0320 #ifdef _MSC_VER
0321 #  define BOOST_MATH_POLY_METHOD 2
0322 #if _MSC_VER <= 1900
0323 #  define BOOST_MATH_RATIONAL_METHOD 1
0324 #else
0325 #  define BOOST_MATH_RATIONAL_METHOD 2
0326 #endif
0327 #if _MSC_VER > 1900
0328 #  define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT
0329 #  define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L
0330 #endif
0331 
0332 #elif defined(__INTEL_COMPILER)
0333 #  define BOOST_MATH_POLY_METHOD 2
0334 #  define BOOST_MATH_RATIONAL_METHOD 1
0335 
0336 #elif defined(__GNUC__)
0337 #if __GNUC__ < 4
0338 #  define BOOST_MATH_POLY_METHOD 3
0339 #  define BOOST_MATH_RATIONAL_METHOD 3
0340 #  define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT
0341 #  define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L
0342 #else
0343 #  define BOOST_MATH_POLY_METHOD 3
0344 #  define BOOST_MATH_RATIONAL_METHOD 3
0345 #endif
0346 
0347 #elif defined(__clang__)
0348 
0349 #if __clang__ > 6
0350 #  define BOOST_MATH_POLY_METHOD 3
0351 #  define BOOST_MATH_RATIONAL_METHOD 3
0352 #  define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT
0353 #  define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L
0354 #endif
0355 
0356 #endif
0357 
0358 //
0359 // noexcept support:
0360 //
0361 #include <type_traits>
0362 #define BOOST_MATH_NOEXCEPT(T) noexcept(std::is_floating_point<T>::value)
0363 #define BOOST_MATH_IS_FLOAT(T) (std::is_floating_point<T>::value)
0364 
0365 //
0366 // The maximum order of polynomial that will be evaluated 
0367 // via an unrolled specialisation:
0368 //
0369 #ifndef BOOST_MATH_MAX_POLY_ORDER
0370 #  define BOOST_MATH_MAX_POLY_ORDER 20
0371 #endif 
0372 //
0373 // Set the method used to evaluate polynomials and rationals:
0374 //
0375 #ifndef BOOST_MATH_POLY_METHOD
0376 #  define BOOST_MATH_POLY_METHOD 2
0377 #endif 
0378 #ifndef BOOST_MATH_RATIONAL_METHOD
0379 #  define BOOST_MATH_RATIONAL_METHOD 1
0380 #endif 
0381 //
0382 // decide whether to store constants as integers or reals:
0383 //
0384 #ifndef BOOST_MATH_INT_TABLE_TYPE
0385 #  define BOOST_MATH_INT_TABLE_TYPE(RT, IT) IT
0386 #endif
0387 #ifndef BOOST_MATH_INT_VALUE_SUFFIX
0388 #  define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##SUF
0389 #endif
0390 //
0391 // And then the actual configuration:
0392 //
0393 #if defined(BOOST_MATH_STANDALONE) && defined(_GLIBCXX_USE_FLOAT128) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && !defined(__STRICT_ANSI__) \
0394    && !defined(BOOST_MATH_DISABLE_FLOAT128) && !defined(BOOST_MATH_USE_FLOAT128)
0395 #  define BOOST_MATH_USE_FLOAT128
0396 #elif defined(BOOST_HAS_FLOAT128) && !defined(BOOST_MATH_USE_FLOAT128)
0397 #  define BOOST_MATH_USE_FLOAT128
0398 #endif
0399 #ifdef BOOST_MATH_USE_FLOAT128
0400 //
0401 // Only enable this when the compiler really is GCC as clang and probably 
0402 // intel too don't support __float128 yet :-(
0403 //
0404 #  if defined(__INTEL_COMPILER) && defined(__GNUC__)
0405 #    if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))
0406 #      define BOOST_MATH_FLOAT128_TYPE __float128
0407 #    endif
0408 #  elif defined(__GNUC__)
0409 #      define BOOST_MATH_FLOAT128_TYPE __float128
0410 #  endif
0411 
0412 #  ifndef BOOST_MATH_FLOAT128_TYPE
0413 #      define BOOST_MATH_FLOAT128_TYPE _Quad
0414 #  endif
0415 #endif
0416 //
0417 // Check for WinCE with no iostream support:
0418 //
0419 #if defined(_WIN32_WCE) && !defined(__SGI_STL_PORT)
0420 #  define BOOST_MATH_NO_LEXICAL_CAST
0421 #endif
0422 
0423 //
0424 // Helper macro for controlling the FP behaviour:
0425 //
0426 #ifndef BOOST_MATH_CONTROL_FP
0427 #  define BOOST_MATH_CONTROL_FP
0428 #endif
0429 //
0430 // Helper macro for using statements:
0431 //
0432 #define BOOST_MATH_STD_USING_CORE \
0433    using std::abs;\
0434    using std::acos;\
0435    using std::cos;\
0436    using std::fmod;\
0437    using std::modf;\
0438    using std::tan;\
0439    using std::asin;\
0440    using std::cosh;\
0441    using std::frexp;\
0442    using std::pow;\
0443    using std::tanh;\
0444    using std::atan;\
0445    using std::exp;\
0446    using std::ldexp;\
0447    using std::sin;\
0448    using std::atan2;\
0449    using std::fabs;\
0450    using std::log;\
0451    using std::sinh;\
0452    using std::ceil;\
0453    using std::floor;\
0454    using std::log10;\
0455    using std::sqrt;
0456 
0457 #define BOOST_MATH_STD_USING BOOST_MATH_STD_USING_CORE
0458 
0459 namespace boost{ namespace math{
0460 namespace tools
0461 {
0462 
0463 template <class T>
0464 inline T max BOOST_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c) BOOST_MATH_NOEXCEPT(T)
0465 {
0466    return (std::max)((std::max)(a, b), c);
0467 }
0468 
0469 template <class T>
0470 inline T max BOOST_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c, T d) BOOST_MATH_NOEXCEPT(T)
0471 {
0472    return (std::max)((std::max)(a, b), (std::max)(c, d));
0473 }
0474 
0475 } // namespace tools
0476 
0477 template <class T>
0478 void suppress_unused_variable_warning(const T&) BOOST_MATH_NOEXCEPT(T)
0479 {
0480 }
0481 
0482 namespace detail{
0483 
0484 template <class T>
0485 struct is_integer_for_rounding
0486 {
0487    static constexpr bool value = std::is_integral<T>::value || (std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::is_integer);
0488 };
0489 
0490 }
0491 
0492 }} // namespace boost namespace math
0493 
0494 #ifdef __GLIBC_PREREQ
0495 #  if __GLIBC_PREREQ(2,14)
0496 #     define BOOST_MATH_HAVE_FIXED_GLIBC
0497 #  endif
0498 #endif
0499 
0500 #if ((defined(__linux__) && !defined(__UCLIBC__) && !defined(BOOST_MATH_HAVE_FIXED_GLIBC)) || defined(__QNX__) || defined(__IBMCPP__))
0501 //
0502 // This code was introduced in response to this glibc bug: http://sourceware.org/bugzilla/show_bug.cgi?id=2445
0503 // Basically powl and expl can return garbage when the result is small and certain exception flags are set
0504 // on entrance to these functions.  This appears to have been fixed in Glibc 2.14 (May 2011).
0505 // Much more information in this message thread: https://groups.google.com/forum/#!topic/boost-list/ZT99wtIFlb4
0506 //
0507 
0508 #include <cfenv>
0509 
0510 #  ifdef FE_ALL_EXCEPT
0511 
0512 namespace boost{ namespace math{
0513    namespace detail
0514    {
0515    struct fpu_guard
0516    {
0517       fpu_guard()
0518       {
0519          fegetexceptflag(&m_flags, FE_ALL_EXCEPT);
0520          feclearexcept(FE_ALL_EXCEPT);
0521       }
0522       ~fpu_guard()
0523       {
0524          fesetexceptflag(&m_flags, FE_ALL_EXCEPT);
0525       }
0526    private:
0527       fexcept_t m_flags;
0528    };
0529 
0530    } // namespace detail
0531    }} // namespaces
0532 
0533 #    define BOOST_FPU_EXCEPTION_GUARD boost::math::detail::fpu_guard local_guard_object;
0534 #    define BOOST_MATH_INSTRUMENT_FPU do{ fexcept_t cpu_flags; fegetexceptflag(&cpu_flags, FE_ALL_EXCEPT); BOOST_MATH_INSTRUMENT_VARIABLE(cpu_flags); } while(0); 
0535 
0536 #  else
0537 
0538 #    define BOOST_FPU_EXCEPTION_GUARD
0539 #    define BOOST_MATH_INSTRUMENT_FPU
0540 
0541 #  endif
0542 
0543 #else // All other platforms.
0544 #  define BOOST_FPU_EXCEPTION_GUARD
0545 #  define BOOST_MATH_INSTRUMENT_FPU
0546 #endif
0547 
0548 #ifdef BOOST_MATH_INSTRUMENT
0549 
0550 #  include <iostream>
0551 #  include <iomanip>
0552 #  include <typeinfo>
0553 
0554 #  define BOOST_MATH_INSTRUMENT_CODE(x) \
0555       std::cout << std::setprecision(35) << __FILE__ << ":" << __LINE__ << " " << x << std::endl;
0556 #  define BOOST_MATH_INSTRUMENT_VARIABLE(name) BOOST_MATH_INSTRUMENT_CODE(#name << " = " << name)
0557 
0558 #else
0559 
0560 #  define BOOST_MATH_INSTRUMENT_CODE(x)
0561 #  define BOOST_MATH_INSTRUMENT_VARIABLE(name)
0562 
0563 #endif
0564 
0565 //
0566 // Thread local storage:
0567 //
0568 #ifndef BOOST_DISABLE_THREADS
0569 #  define BOOST_MATH_THREAD_LOCAL thread_local
0570 #else
0571 #  define BOOST_MATH_THREAD_LOCAL 
0572 #endif
0573 
0574 //
0575 // Some mingw flavours have issues with thread_local and types with non-trivial destructors
0576 // See https://sourceforge.net/p/mingw-w64/bugs/527/
0577 //
0578 #if (defined(__MINGW32__) && (__GNUC__ < 9) && !defined(__clang__))
0579 #  define BOOST_MATH_NO_THREAD_LOCAL_WITH_NON_TRIVIAL_TYPES
0580 #endif
0581 
0582 
0583 //
0584 // Can we have constexpr tables?
0585 //
0586 #if (!defined(BOOST_NO_CXX14_CONSTEXPR)) || (defined(_MSC_VER) && _MSC_VER >= 1910)
0587 #define BOOST_MATH_HAVE_CONSTEXPR_TABLES
0588 #define BOOST_MATH_CONSTEXPR_TABLE_FUNCTION constexpr
0589 #else
0590 #define BOOST_MATH_CONSTEXPR_TABLE_FUNCTION
0591 #endif
0592 
0593 
0594 #endif // BOOST_MATH_TOOLS_CONFIG_HPP
0595 
0596 
0597 
0598