1 // Copyright (c) 2006-7 John Maddock 2 // Use, modification and distribution are subject to the 3 // Boost Software License, Version 1.0. (See accompanying file 4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #ifndef BOOST_MATH_TOOLS_CONFIG_HPP 7 #define BOOST_MATH_TOOLS_CONFIG_HPP 8 9 #ifdef _MSC_VER 10 #pragma once 11 #endif 12 13 #include <boost/config.hpp> 14 #include <boost/cstdint.hpp> // for boost::uintmax_t 15 #include <boost/detail/workaround.hpp> 16 #include <algorithm> // for min and max 17 #include <boost/config/no_tr1/cmath.hpp> 18 #include <climits> 19 #include <cfloat> 20 #if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) 21 # include <math.h> 22 #endif 23 24 #include <boost/math/tools/user.hpp> 25 #include <boost/math/special_functions/detail/round_fwd.hpp> 26 27 #if (defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__NetBSD__) \ 28 || (defined(__hppa) && !defined(__OpenBSD__)) || (defined(__NO_LONG_DOUBLE_MATH) && (DBL_MANT_DIG != LDBL_MANT_DIG))) \ 29 && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) 30 # define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS 31 #endif 32 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) 33 // 34 // Borland post 5.8.2 uses Dinkumware's std C lib which 35 // doesn't have true long double precision. Earlier 36 // versions are problematic too: 37 // 38 # define BOOST_MATH_NO_REAL_CONCEPT_TESTS 39 # define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS 40 # define BOOST_MATH_CONTROL_FP _control87(MCW_EM,MCW_EM) 41 # include <float.h> 42 #endif 43 #ifdef __IBMCPP__ 44 // 45 // For reasons I don't unserstand, the tests with IMB's compiler all 46 // pass at long double precision, but fail with real_concept, those tests 47 // are disabled for now. (JM 2012). 48 # define BOOST_MATH_NO_REAL_CONCEPT_TESTS 49 #endif 50 #if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) 51 // 52 // Darwin's rather strange "double double" is rather hard to 53 // support, it should be possible given enough effort though... 54 // 55 # define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS 56 #endif 57 #if defined(unix) && defined(__INTEL_COMPILER) && (__INTEL_COMPILER <= 1000) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) 58 // 59 // Intel compiler prior to version 10 has sporadic problems 60 // calling the long double overloads of the std lib math functions: 61 // calling ::powl is OK, but std::pow(long double, long double) 62 // may segfault depending upon the value of the arguments passed 63 // and the specific Linux distribution. 64 // 65 // We'll be conservative and disable long double support for this compiler. 66 // 67 // Comment out this #define and try building the tests to determine whether 68 // your Intel compiler version has this issue or not. 69 // 70 # define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS 71 #endif 72 #if defined(unix) && defined(__INTEL_COMPILER) 73 // 74 // Intel compiler has sporadic issues compiling std::fpclassify depending on 75 // the exact OS version used. Use our own code for this as we know it works 76 // well on Intel processors: 77 // 78 #define BOOST_MATH_DISABLE_STD_FPCLASSIFY 79 #endif 80 81 #if defined(BOOST_MSVC) && !defined(_WIN32_WCE) 82 // Better safe than sorry, our tests don't support hardware exceptions: 83 # define BOOST_MATH_CONTROL_FP _control87(MCW_EM,MCW_EM) 84 #endif 85 86 #ifdef __IBMCPP__ 87 # define BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS 88 #endif 89 90 #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)) 91 # define BOOST_MATH_USE_C99 92 #endif 93 94 #if (defined(__hpux) && !defined(__hppa)) 95 # define BOOST_MATH_USE_C99 96 #endif 97 98 #if defined(__GNUC__) && defined(_GLIBCXX_USE_C99) 99 # define BOOST_MATH_USE_C99 100 #endif 101 102 #if defined(__CYGWIN__) || defined(__HP_aCC) || defined(BOOST_INTEL) \ 103 || defined(BOOST_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) \ 104 || (defined(__GNUC__) && !defined(BOOST_MATH_USE_C99)) 105 # define BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY 106 #endif 107 108 #if defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) 109 110 # include "boost/type.hpp" 111 # include "boost/non_type.hpp" 112 113 # define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) boost::type<t>* = 0 114 # define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) boost::type<t>* 115 # define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) boost::non_type<t, v>* = 0 116 # define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) boost::non_type<t, v>* 117 118 # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t) \ 119 , BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) 120 # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) \ 121 , BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) 122 # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) \ 123 , BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) 124 # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) \ 125 , BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) 126 127 #else 128 129 // no workaround needed: expand to nothing 130 131 # define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) 132 # define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) 133 # define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) 134 # define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) 135 136 # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t) 137 # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) 138 # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) 139 # define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) 140 141 142 #endif // defined BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS 143 144 #if (defined(__SUNPRO_CC) || defined(__hppa) || defined(__GNUC__)) && !defined(BOOST_MATH_SMALL_CONSTANT) 145 // Sun's compiler emits a hard error if a constant underflows, 146 // as does aCC on PA-RISC, while gcc issues a large number of warnings: 147 # define BOOST_MATH_SMALL_CONSTANT(x) 0 148 #else 149 # define BOOST_MATH_SMALL_CONSTANT(x) x 150 #endif 151 152 153 #if BOOST_WORKAROUND(BOOST_MSVC, < 1400) 154 // 155 // Define if constants too large for a float cause "bad" 156 // values to be stored in the data, rather than infinity 157 // or a suitably large value. 158 // 159 # define BOOST_MATH_BUGGY_LARGE_FLOAT_CONSTANTS 160 #endif 161 // 162 // Tune performance options for specific compilers: 163 // 164 #ifdef BOOST_MSVC 165 # define BOOST_MATH_POLY_METHOD 2 166 #elif defined(BOOST_INTEL) 167 # define BOOST_MATH_POLY_METHOD 2 168 # define BOOST_MATH_RATIONAL_METHOD 2 169 #elif defined(__GNUC__) 170 # define BOOST_MATH_POLY_METHOD 3 171 # define BOOST_MATH_RATIONAL_METHOD 3 172 # define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT 173 # define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L 174 #endif 175 176 #if defined(BOOST_NO_LONG_LONG) && !defined(BOOST_MATH_INT_TABLE_TYPE) 177 # define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT 178 # define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L 179 #endif 180 181 // 182 // The maximum order of polynomial that will be evaluated 183 // via an unrolled specialisation: 184 // 185 #ifndef BOOST_MATH_MAX_POLY_ORDER 186 # define BOOST_MATH_MAX_POLY_ORDER 17 187 #endif 188 // 189 // Set the method used to evaluate polynomials and rationals: 190 // 191 #ifndef BOOST_MATH_POLY_METHOD 192 # define BOOST_MATH_POLY_METHOD 1 193 #endif 194 #ifndef BOOST_MATH_RATIONAL_METHOD 195 # define BOOST_MATH_RATIONAL_METHOD 0 196 #endif 197 // 198 // decide whether to store constants as integers or reals: 199 // 200 #ifndef BOOST_MATH_INT_TABLE_TYPE 201 # define BOOST_MATH_INT_TABLE_TYPE(RT, IT) IT 202 #endif 203 #ifndef BOOST_MATH_INT_VALUE_SUFFIX 204 # define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##SUF 205 #endif 206 207 // 208 // Helper macro for controlling the FP behaviour: 209 // 210 #ifndef BOOST_MATH_CONTROL_FP 211 # define BOOST_MATH_CONTROL_FP 212 #endif 213 // 214 // Helper macro for using statements: 215 // 216 #define BOOST_MATH_STD_USING \ 217 using std::abs;\ 218 using std::acos;\ 219 using std::cos;\ 220 using std::fmod;\ 221 using std::modf;\ 222 using std::tan;\ 223 using std::asin;\ 224 using std::cosh;\ 225 using std::frexp;\ 226 using std::pow;\ 227 using std::tanh;\ 228 using std::atan;\ 229 using std::exp;\ 230 using std::ldexp;\ 231 using std::sin;\ 232 using std::atan2;\ 233 using std::fabs;\ 234 using std::log;\ 235 using std::sinh;\ 236 using std::ceil;\ 237 using std::floor;\ 238 using std::log10;\ 239 using std::sqrt;\ 240 using boost::math::round;\ 241 using boost::math::iround;\ 242 using boost::math::lround;\ 243 using boost::math::trunc;\ 244 using boost::math::itrunc;\ 245 using boost::math::ltrunc;\ 246 using boost::math::modf; 247 248 249 namespace boost{ namespace math{ 250 namespace tools 251 { 252 253 template <class T> 254 inline T max BOOST_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c) 255 { 256 return (std::max)((std::max)(a, b), c); 257 } 258 259 template <class T> 260 inline T max BOOST_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c, T d) 261 { 262 return (std::max)((std::max)(a, b), (std::max)(c, d)); 263 } 264 265 } // namespace tools 266 267 template <class T> 268 void suppress_unused_variable_warning(const T&) 269 { 270 } 271 272 }} // namespace boost namespace math 273 274 #if ((defined(__linux__) && !defined(__UCLIBC__)) || defined(__QNX__) || defined(__IBMCPP__)) && !defined(BOOST_NO_FENV_H) 275 276 #include <boost/detail/fenv.hpp> 277 278 # ifdef FE_ALL_EXCEPT 279 280 namespace boost{ namespace math{ 281 namespace detail 282 { 283 struct fpu_guard 284 { 285 fpu_guard() 286 { 287 fegetexceptflag(&m_flags, FE_ALL_EXCEPT); 288 feclearexcept(FE_ALL_EXCEPT); 289 } 290 ~fpu_guard() 291 { 292 fesetexceptflag(&m_flags, FE_ALL_EXCEPT); 293 } 294 private: 295 fexcept_t m_flags; 296 }; 297 298 } // namespace detail 299 }} // namespaces 300 301 # define BOOST_FPU_EXCEPTION_GUARD boost::math::detail::fpu_guard local_guard_object; 302 # define BOOST_MATH_INSTRUMENT_FPU do{ fexcept_t cpu_flags; fegetexceptflag(&cpu_flags, FE_ALL_EXCEPT); BOOST_MATH_INSTRUMENT_VARIABLE(cpu_flags); } while(0); 303 304 # else 305 306 # define BOOST_FPU_EXCEPTION_GUARD 307 # define BOOST_MATH_INSTRUMENT_FPU 308 309 # endif 310 311 #else // All other platforms. 312 # define BOOST_FPU_EXCEPTION_GUARD 313 # define BOOST_MATH_INSTRUMENT_FPU 314 #endif 315 316 #ifdef BOOST_MATH_INSTRUMENT 317 #define BOOST_MATH_INSTRUMENT_CODE(x) \ 318 std::cout << std::setprecision(35) << __FILE__ << ":" << __LINE__ << " " << x << std::endl; 319 #define BOOST_MATH_INSTRUMENT_VARIABLE(name) BOOST_MATH_INSTRUMENT_CODE(BOOST_STRINGIZE(name) << " = " << name) 320 #else 321 #define BOOST_MATH_INSTRUMENT_CODE(x) 322 #define BOOST_MATH_INSTRUMENT_VARIABLE(name) 323 #endif 324 325 #endif // BOOST_MATH_TOOLS_CONFIG_HPP 326 327 328 329 330 331