Chris@16: // Copyright (c) 2006-7 John Maddock Chris@16: // Use, modification and distribution are subject to the Chris@16: // Boost Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_MATH_TOOLS_CONFIG_HPP Chris@16: #define BOOST_MATH_TOOLS_CONFIG_HPP Chris@16: Chris@16: #ifdef _MSC_VER Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include // for boost::uintmax_t Chris@16: #include Chris@101: #include Chris@16: #include // for min and max Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) Chris@16: # include Chris@16: #endif Chris@101: #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS Chris@101: # include Chris@101: #endif Chris@16: Chris@16: #include Chris@16: Chris@16: #if (defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__NetBSD__) \ Chris@16: || (defined(__hppa) && !defined(__OpenBSD__)) || (defined(__NO_LONG_DOUBLE_MATH) && (DBL_MANT_DIG != LDBL_MANT_DIG))) \ Chris@16: && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) Chris@16: # define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS Chris@16: #endif Chris@16: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) Chris@16: // Chris@16: // Borland post 5.8.2 uses Dinkumware's std C lib which Chris@16: // doesn't have true long double precision. Earlier Chris@16: // versions are problematic too: Chris@16: // Chris@16: # define BOOST_MATH_NO_REAL_CONCEPT_TESTS Chris@16: # define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS Chris@16: # define BOOST_MATH_CONTROL_FP _control87(MCW_EM,MCW_EM) Chris@16: # include Chris@16: #endif Chris@16: #ifdef __IBMCPP__ Chris@16: // Chris@16: // For reasons I don't unserstand, the tests with IMB's compiler all Chris@16: // pass at long double precision, but fail with real_concept, those tests Chris@16: // are disabled for now. (JM 2012). Chris@16: # define BOOST_MATH_NO_REAL_CONCEPT_TESTS Chris@16: #endif Chris@101: #ifdef sun Chris@101: // Any use of __float128 in program startup code causes a segfault (tested JM 2015, Solaris 11). Chris@101: # define BOOST_MATH_DISABLE_FLOAT128 Chris@101: #endif Chris@16: #if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) Chris@16: // Chris@16: // Darwin's rather strange "double double" is rather hard to Chris@16: // support, it should be possible given enough effort though... Chris@16: // Chris@16: # define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS Chris@16: #endif Chris@16: #if defined(unix) && defined(__INTEL_COMPILER) && (__INTEL_COMPILER <= 1000) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) Chris@16: // Chris@16: // Intel compiler prior to version 10 has sporadic problems Chris@16: // calling the long double overloads of the std lib math functions: Chris@16: // calling ::powl is OK, but std::pow(long double, long double) Chris@16: // may segfault depending upon the value of the arguments passed Chris@16: // and the specific Linux distribution. Chris@16: // Chris@16: // We'll be conservative and disable long double support for this compiler. Chris@16: // Chris@16: // Comment out this #define and try building the tests to determine whether Chris@16: // your Intel compiler version has this issue or not. Chris@16: // Chris@16: # define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS Chris@16: #endif Chris@16: #if defined(unix) && defined(__INTEL_COMPILER) Chris@16: // Chris@16: // Intel compiler has sporadic issues compiling std::fpclassify depending on Chris@16: // the exact OS version used. Use our own code for this as we know it works Chris@16: // well on Intel processors: Chris@16: // Chris@16: #define BOOST_MATH_DISABLE_STD_FPCLASSIFY Chris@16: #endif Chris@16: Chris@16: #if defined(BOOST_MSVC) && !defined(_WIN32_WCE) Chris@16: // Better safe than sorry, our tests don't support hardware exceptions: Chris@16: # define BOOST_MATH_CONTROL_FP _control87(MCW_EM,MCW_EM) Chris@16: #endif Chris@16: Chris@16: #ifdef __IBMCPP__ Chris@16: # define BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS Chris@16: #endif Chris@16: Chris@16: #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)) Chris@16: # define BOOST_MATH_USE_C99 Chris@16: #endif Chris@16: Chris@16: #if (defined(__hpux) && !defined(__hppa)) Chris@16: # define BOOST_MATH_USE_C99 Chris@16: #endif Chris@16: Chris@16: #if defined(__GNUC__) && defined(_GLIBCXX_USE_C99) Chris@16: # define BOOST_MATH_USE_C99 Chris@16: #endif Chris@16: Chris@16: #if defined(_LIBCPP_VERSION) && !defined(_MSC_VER) Chris@16: # define BOOST_MATH_USE_C99 Chris@16: #endif Chris@16: Chris@16: #if defined(__CYGWIN__) || defined(__HP_aCC) || defined(BOOST_INTEL) \ Chris@16: || defined(BOOST_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) \ Chris@16: || (defined(__GNUC__) && !defined(BOOST_MATH_USE_C99))\ Chris@16: || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) Chris@16: # define BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY Chris@16: #endif Chris@16: Chris@101: #if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) Chris@16: Chris@16: # include "boost/type.hpp" Chris@16: # include "boost/non_type.hpp" Chris@16: Chris@16: # define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) boost::type* = 0 Chris@16: # define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) boost::type* Chris@16: # define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) boost::non_type* = 0 Chris@16: # define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) boost::non_type* Chris@16: Chris@16: # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t) \ Chris@16: , BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) Chris@16: # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) \ Chris@16: , BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) Chris@16: # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) \ Chris@16: , BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) Chris@16: # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) \ Chris@16: , BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) Chris@16: Chris@16: #else Chris@16: Chris@16: // no workaround needed: expand to nothing Chris@16: Chris@16: # define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) Chris@16: # define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) Chris@16: # define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) Chris@16: # define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) Chris@16: Chris@16: # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t) Chris@16: # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) Chris@16: # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) Chris@16: # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) Chris@16: Chris@16: Chris@101: #endif // __SUNPRO_CC Chris@16: Chris@16: #if (defined(__SUNPRO_CC) || defined(__hppa) || defined(__GNUC__)) && !defined(BOOST_MATH_SMALL_CONSTANT) Chris@16: // Sun's compiler emits a hard error if a constant underflows, Chris@16: // as does aCC on PA-RISC, while gcc issues a large number of warnings: Chris@101: # define BOOST_MATH_SMALL_CONSTANT(x) 0.0 Chris@16: #else Chris@16: # define BOOST_MATH_SMALL_CONSTANT(x) x Chris@16: #endif Chris@16: Chris@16: Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC, < 1400) Chris@16: // Chris@16: // Define if constants too large for a float cause "bad" Chris@16: // values to be stored in the data, rather than infinity Chris@16: // or a suitably large value. Chris@16: // Chris@16: # define BOOST_MATH_BUGGY_LARGE_FLOAT_CONSTANTS Chris@16: #endif Chris@16: // Chris@16: // Tune performance options for specific compilers: Chris@16: // Chris@16: #ifdef BOOST_MSVC Chris@16: # define BOOST_MATH_POLY_METHOD 2 Chris@16: #elif defined(BOOST_INTEL) Chris@16: # define BOOST_MATH_POLY_METHOD 2 Chris@16: # define BOOST_MATH_RATIONAL_METHOD 2 Chris@16: #elif defined(__GNUC__) Chris@16: # define BOOST_MATH_POLY_METHOD 3 Chris@16: # define BOOST_MATH_RATIONAL_METHOD 3 Chris@16: # define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT Chris@16: # define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L Chris@16: #endif Chris@16: Chris@16: #if defined(BOOST_NO_LONG_LONG) && !defined(BOOST_MATH_INT_TABLE_TYPE) Chris@16: # define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT Chris@16: # define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L Chris@16: #endif Chris@16: Chris@16: // Chris@16: // The maximum order of polynomial that will be evaluated Chris@16: // via an unrolled specialisation: Chris@16: // Chris@16: #ifndef BOOST_MATH_MAX_POLY_ORDER Chris@16: # define BOOST_MATH_MAX_POLY_ORDER 17 Chris@16: #endif Chris@16: // Chris@16: // Set the method used to evaluate polynomials and rationals: Chris@16: // Chris@16: #ifndef BOOST_MATH_POLY_METHOD Chris@16: # define BOOST_MATH_POLY_METHOD 1 Chris@16: #endif Chris@16: #ifndef BOOST_MATH_RATIONAL_METHOD Chris@16: # define BOOST_MATH_RATIONAL_METHOD 0 Chris@16: #endif Chris@16: // Chris@16: // decide whether to store constants as integers or reals: Chris@16: // Chris@16: #ifndef BOOST_MATH_INT_TABLE_TYPE Chris@16: # define BOOST_MATH_INT_TABLE_TYPE(RT, IT) IT Chris@16: #endif Chris@16: #ifndef BOOST_MATH_INT_VALUE_SUFFIX Chris@16: # define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##SUF Chris@16: #endif Chris@16: // Chris@16: // Test whether to support __float128: Chris@16: // Chris@101: #if defined(_GLIBCXX_USE_FLOAT128) && defined(BOOST_GCC) && !defined(__STRICT_ANSI__) \ Chris@101: && !defined(BOOST_MATH_DISABLE_FLOAT128) || defined(BOOST_MATH_USE_FLOAT128) Chris@16: // Chris@16: // Only enable this when the compiler really is GCC as clang and probably Chris@16: // intel too don't support __float128 yet :-( Chris@16: // Chris@101: #ifndef BOOST_MATH_USE_FLOAT128 Chris@16: # define BOOST_MATH_USE_FLOAT128 Chris@16: #endif Chris@101: Chris@101: # if defined(BOOST_INTEL) && defined(BOOST_INTEL_CXX_VERSION) && (BOOST_INTEL_CXX_VERSION >= 1310) && defined(__GNUC__) Chris@101: # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) Chris@101: # define BOOST_MATH_FLOAT128_TYPE __float128 Chris@101: # endif Chris@101: # elif defined(__GNUC__) Chris@101: # define BOOST_MATH_FLOAT128_TYPE __float128 Chris@101: # endif Chris@101: Chris@101: # ifndef BOOST_MATH_FLOAT128_TYPE Chris@101: # define BOOST_MATH_FLOAT128_TYPE _Quad Chris@101: # endif Chris@101: #endif Chris@16: // Chris@16: // Check for WinCE with no iostream support: Chris@16: // Chris@16: #if defined(_WIN32_WCE) && !defined(__SGI_STL_PORT) Chris@16: # define BOOST_MATH_NO_LEXICAL_CAST Chris@16: #endif Chris@16: Chris@16: // Chris@16: // Helper macro for controlling the FP behaviour: Chris@16: // Chris@16: #ifndef BOOST_MATH_CONTROL_FP Chris@16: # define BOOST_MATH_CONTROL_FP Chris@16: #endif Chris@16: // Chris@16: // Helper macro for using statements: Chris@16: // Chris@16: #define BOOST_MATH_STD_USING_CORE \ Chris@16: using std::abs;\ Chris@16: using std::acos;\ Chris@16: using std::cos;\ Chris@16: using std::fmod;\ Chris@16: using std::modf;\ Chris@16: using std::tan;\ Chris@16: using std::asin;\ Chris@16: using std::cosh;\ Chris@16: using std::frexp;\ Chris@16: using std::pow;\ Chris@16: using std::tanh;\ Chris@16: using std::atan;\ Chris@16: using std::exp;\ Chris@16: using std::ldexp;\ Chris@16: using std::sin;\ Chris@16: using std::atan2;\ Chris@16: using std::fabs;\ Chris@16: using std::log;\ Chris@16: using std::sinh;\ Chris@16: using std::ceil;\ Chris@16: using std::floor;\ Chris@16: using std::log10;\ Chris@16: using std::sqrt; Chris@16: Chris@16: #define BOOST_MATH_STD_USING BOOST_MATH_STD_USING_CORE Chris@16: Chris@16: namespace boost{ namespace math{ Chris@16: namespace tools Chris@16: { Chris@16: Chris@16: template Chris@16: inline T max BOOST_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c) Chris@16: { Chris@16: return (std::max)((std::max)(a, b), c); Chris@16: } Chris@16: Chris@16: template Chris@16: inline T max BOOST_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c, T d) Chris@16: { Chris@16: return (std::max)((std::max)(a, b), (std::max)(c, d)); Chris@16: } Chris@16: Chris@16: } // namespace tools Chris@16: Chris@16: template Chris@16: void suppress_unused_variable_warning(const T&) Chris@16: { Chris@16: } Chris@16: Chris@101: namespace detail{ Chris@101: Chris@101: template Chris@101: struct is_integer_for_rounding Chris@101: { Chris@101: static const bool value = boost::is_integral::value Chris@101: #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS Chris@101: || (std::numeric_limits::is_specialized && std::numeric_limits::is_integer) Chris@101: #endif Chris@101: ; Chris@101: }; Chris@101: Chris@101: } Chris@101: Chris@16: }} // namespace boost namespace math Chris@16: Chris@101: #ifdef __GLIBC_PREREQ Chris@101: # if __GLIBC_PREREQ(2,14) Chris@101: # define BOOST_MATH_HAVE_FIXED_GLIBC Chris@101: # endif Chris@101: #endif Chris@101: Chris@101: #if ((defined(__linux__) && !defined(__UCLIBC__) && !defined(BOOST_MATH_HAVE_FIXED_GLIBC)) || defined(__QNX__) || defined(__IBMCPP__)) && !defined(BOOST_NO_FENV_H) Chris@101: // Chris@101: // This code was introduced in response to this glibc bug: http://sourceware.org/bugzilla/show_bug.cgi?id=2445 Chris@101: // Basically powl and expl can return garbage when the result is small and certain exception flags are set Chris@101: // on entrance to these functions. This appears to have been fixed in Glibc 2.14 (May 2011). Chris@101: // Much more information in this message thread: https://groups.google.com/forum/#!topic/boost-list/ZT99wtIFlb4 Chris@101: // Chris@16: Chris@16: #include Chris@16: Chris@16: # ifdef FE_ALL_EXCEPT Chris@16: Chris@16: namespace boost{ namespace math{ Chris@16: namespace detail Chris@16: { Chris@16: struct fpu_guard Chris@16: { Chris@16: fpu_guard() Chris@16: { Chris@16: fegetexceptflag(&m_flags, FE_ALL_EXCEPT); Chris@16: feclearexcept(FE_ALL_EXCEPT); Chris@16: } Chris@16: ~fpu_guard() Chris@16: { Chris@16: fesetexceptflag(&m_flags, FE_ALL_EXCEPT); Chris@16: } Chris@16: private: Chris@16: fexcept_t m_flags; Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: }} // namespaces Chris@16: Chris@16: # define BOOST_FPU_EXCEPTION_GUARD boost::math::detail::fpu_guard local_guard_object; Chris@16: # define BOOST_MATH_INSTRUMENT_FPU do{ fexcept_t cpu_flags; fegetexceptflag(&cpu_flags, FE_ALL_EXCEPT); BOOST_MATH_INSTRUMENT_VARIABLE(cpu_flags); } while(0); Chris@16: Chris@16: # else Chris@16: Chris@16: # define BOOST_FPU_EXCEPTION_GUARD Chris@16: # define BOOST_MATH_INSTRUMENT_FPU Chris@16: Chris@16: # endif Chris@16: Chris@16: #else // All other platforms. Chris@16: # define BOOST_FPU_EXCEPTION_GUARD Chris@16: # define BOOST_MATH_INSTRUMENT_FPU Chris@16: #endif Chris@16: Chris@16: #ifdef BOOST_MATH_INSTRUMENT Chris@16: Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: # define BOOST_MATH_INSTRUMENT_CODE(x) \ Chris@16: std::cout << std::setprecision(35) << __FILE__ << ":" << __LINE__ << " " << x << std::endl; Chris@16: # define BOOST_MATH_INSTRUMENT_VARIABLE(name) BOOST_MATH_INSTRUMENT_CODE(BOOST_STRINGIZE(name) << " = " << name) Chris@16: Chris@16: #else Chris@16: Chris@16: # define BOOST_MATH_INSTRUMENT_CODE(x) Chris@16: # define BOOST_MATH_INSTRUMENT_VARIABLE(name) Chris@16: Chris@16: #endif Chris@16: Chris@16: #endif // BOOST_MATH_TOOLS_CONFIG_HPP Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: