annotate DEPENDENCIES/generic/include/boost/math/policies/error_handling.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // Copyright John Maddock 2007.
Chris@16 2 // Copyright Paul A. Bristow 2007.
Chris@16 3
Chris@16 4 // Use, modification and distribution are subject to the
Chris@16 5 // Boost Software License, Version 1.0. (See accompanying file
Chris@16 6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7
Chris@16 8 #ifndef BOOST_MATH_POLICY_ERROR_HANDLING_HPP
Chris@16 9 #define BOOST_MATH_POLICY_ERROR_HANDLING_HPP
Chris@16 10
Chris@16 11 #include <stdexcept>
Chris@16 12 #include <iomanip>
Chris@16 13 #include <string>
Chris@16 14 #include <cerrno>
Chris@16 15 #include <boost/config/no_tr1/complex.hpp>
Chris@16 16 #include <boost/config/no_tr1/cmath.hpp>
Chris@16 17 #include <stdexcept>
Chris@16 18 #include <boost/math/tools/config.hpp>
Chris@16 19 #include <boost/math/policies/policy.hpp>
Chris@16 20 #include <boost/math/tools/precision.hpp>
Chris@16 21 #include <boost/cstdint.hpp>
Chris@16 22 #ifdef BOOST_MSVC
Chris@16 23 # pragma warning(push) // Quiet warnings in boost/format.hpp
Chris@16 24 # pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE
Chris@16 25 # pragma warning(disable: 4512) // assignment operator could not be generated.
Chris@16 26 // And warnings in error handling:
Chris@16 27 # pragma warning(disable: 4702) // unreachable code.
Chris@16 28 // Note that this only occurs when the compiler can deduce code is unreachable,
Chris@16 29 // for example when policy macros are used to ignore errors rather than throw.
Chris@16 30 #endif
Chris@16 31 #include <boost/format.hpp>
Chris@16 32
Chris@16 33 namespace boost{ namespace math{
Chris@16 34
Chris@16 35 class evaluation_error : public std::runtime_error
Chris@16 36 {
Chris@16 37 public:
Chris@16 38 evaluation_error(const std::string& s) : std::runtime_error(s){}
Chris@16 39 };
Chris@16 40
Chris@16 41 class rounding_error : public std::runtime_error
Chris@16 42 {
Chris@16 43 public:
Chris@16 44 rounding_error(const std::string& s) : std::runtime_error(s){}
Chris@16 45 };
Chris@16 46
Chris@16 47 namespace policies{
Chris@16 48 //
Chris@16 49 // Forward declarations of user error handlers,
Chris@16 50 // it's up to the user to provide the definition of these:
Chris@16 51 //
Chris@16 52 template <class T>
Chris@16 53 T user_domain_error(const char* function, const char* message, const T& val);
Chris@16 54 template <class T>
Chris@16 55 T user_pole_error(const char* function, const char* message, const T& val);
Chris@16 56 template <class T>
Chris@16 57 T user_overflow_error(const char* function, const char* message, const T& val);
Chris@16 58 template <class T>
Chris@16 59 T user_underflow_error(const char* function, const char* message, const T& val);
Chris@16 60 template <class T>
Chris@16 61 T user_denorm_error(const char* function, const char* message, const T& val);
Chris@16 62 template <class T>
Chris@16 63 T user_evaluation_error(const char* function, const char* message, const T& val);
Chris@16 64 template <class T, class TargetType>
Chris@16 65 T user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t);
Chris@16 66 template <class T>
Chris@16 67 T user_indeterminate_result_error(const char* function, const char* message, const T& val);
Chris@16 68
Chris@16 69 namespace detail
Chris@16 70 {
Chris@16 71 //
Chris@16 72 // Helper function to avoid binding rvalue to non-const-reference,
Chris@16 73 // in other words a warning suppression mechanism:
Chris@16 74 //
Chris@16 75 template <class Formatter, class Group>
Chris@16 76 inline std::string do_format(Formatter f, const Group& g)
Chris@16 77 {
Chris@16 78 return (f % g).str();
Chris@16 79 }
Chris@16 80
Chris@101 81 template <class T>
Chris@101 82 inline const char* name_of()
Chris@101 83 {
Chris@101 84 #ifndef BOOST_NO_RTTI
Chris@101 85 return typeid(T).name();
Chris@101 86 #else
Chris@101 87 return "unknown";
Chris@101 88 #endif
Chris@101 89 }
Chris@101 90 template <> inline const char* name_of<float>(){ return "float"; }
Chris@101 91 template <> inline const char* name_of<double>(){ return "double"; }
Chris@101 92 template <> inline const char* name_of<long double>(){ return "long double"; }
Chris@101 93
Chris@101 94 #ifdef BOOST_MATH_USE_FLOAT128
Chris@101 95 template <>
Chris@101 96 inline const char* name_of<BOOST_MATH_FLOAT128_TYPE>()
Chris@101 97 {
Chris@101 98 return "__float128";
Chris@101 99 }
Chris@101 100 #endif
Chris@101 101
Chris@16 102 template <class E, class T>
Chris@16 103 void raise_error(const char* function, const char* message)
Chris@16 104 {
Chris@16 105 if(function == 0)
Chris@16 106 function = "Unknown function operating on type %1%";
Chris@16 107 if(message == 0)
Chris@16 108 message = "Cause unknown";
Chris@16 109
Chris@16 110 std::string msg("Error in function ");
Chris@101 111 #ifndef BOOST_NO_RTTI
Chris@101 112 msg += (boost::format(function) % boost::math::policies::detail::name_of<T>()).str();
Chris@101 113 #else
Chris@101 114 msg += function;
Chris@101 115 #endif
Chris@16 116 msg += ": ";
Chris@16 117 msg += message;
Chris@16 118
Chris@16 119 E e(msg);
Chris@16 120 boost::throw_exception(e);
Chris@16 121 }
Chris@16 122
Chris@16 123 template <class E, class T>
Chris@16 124 void raise_error(const char* function, const char* message, const T& val)
Chris@16 125 {
Chris@16 126 if(function == 0)
Chris@16 127 function = "Unknown function operating on type %1%";
Chris@16 128 if(message == 0)
Chris@16 129 message = "Cause unknown: error caused by bad argument with value %1%";
Chris@16 130
Chris@16 131 std::string msg("Error in function ");
Chris@101 132 #ifndef BOOST_NO_RTTI
Chris@101 133 msg += (boost::format(function) % boost::math::policies::detail::name_of<T>()).str();
Chris@101 134 #else
Chris@101 135 msg += function;
Chris@101 136 #endif
Chris@16 137 msg += ": ";
Chris@16 138 msg += message;
Chris@16 139
Chris@16 140 int prec = 2 + (boost::math::policies::digits<T, boost::math::policies::policy<> >() * 30103UL) / 100000UL;
Chris@16 141 msg = do_format(boost::format(msg), boost::io::group(std::setprecision(prec), val));
Chris@16 142
Chris@16 143 E e(msg);
Chris@16 144 boost::throw_exception(e);
Chris@16 145 }
Chris@16 146
Chris@16 147 template <class T>
Chris@16 148 inline T raise_domain_error(
Chris@16 149 const char* function,
Chris@16 150 const char* message,
Chris@16 151 const T& val,
Chris@16 152 const ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>&)
Chris@16 153 {
Chris@16 154 raise_error<std::domain_error, T>(function, message, val);
Chris@16 155 // we never get here:
Chris@16 156 return std::numeric_limits<T>::quiet_NaN();
Chris@16 157 }
Chris@16 158
Chris@16 159 template <class T>
Chris@16 160 inline T raise_domain_error(
Chris@16 161 const char* ,
Chris@16 162 const char* ,
Chris@16 163 const T& ,
Chris@16 164 const ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>&)
Chris@16 165 {
Chris@16 166 // This may or may not do the right thing, but the user asked for the error
Chris@16 167 // to be ignored so here we go anyway:
Chris@16 168 return std::numeric_limits<T>::quiet_NaN();
Chris@16 169 }
Chris@16 170
Chris@16 171 template <class T>
Chris@16 172 inline T raise_domain_error(
Chris@16 173 const char* ,
Chris@16 174 const char* ,
Chris@16 175 const T& ,
Chris@16 176 const ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>&)
Chris@16 177 {
Chris@16 178 errno = EDOM;
Chris@16 179 // This may or may not do the right thing, but the user asked for the error
Chris@16 180 // to be silent so here we go anyway:
Chris@16 181 return std::numeric_limits<T>::quiet_NaN();
Chris@16 182 }
Chris@16 183
Chris@16 184 template <class T>
Chris@16 185 inline T raise_domain_error(
Chris@16 186 const char* function,
Chris@16 187 const char* message,
Chris@16 188 const T& val,
Chris@16 189 const ::boost::math::policies::domain_error< ::boost::math::policies::user_error>&)
Chris@16 190 {
Chris@16 191 return user_domain_error(function, message, val);
Chris@16 192 }
Chris@16 193
Chris@16 194 template <class T>
Chris@16 195 inline T raise_pole_error(
Chris@16 196 const char* function,
Chris@16 197 const char* message,
Chris@16 198 const T& val,
Chris@16 199 const ::boost::math::policies::pole_error< ::boost::math::policies::throw_on_error>&)
Chris@16 200 {
Chris@16 201 return boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>());
Chris@16 202 }
Chris@16 203
Chris@16 204 template <class T>
Chris@16 205 inline T raise_pole_error(
Chris@16 206 const char* function,
Chris@16 207 const char* message,
Chris@16 208 const T& val,
Chris@16 209 const ::boost::math::policies::pole_error< ::boost::math::policies::ignore_error>&)
Chris@16 210 {
Chris@16 211 return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>());
Chris@16 212 }
Chris@16 213
Chris@16 214 template <class T>
Chris@16 215 inline T raise_pole_error(
Chris@16 216 const char* function,
Chris@16 217 const char* message,
Chris@16 218 const T& val,
Chris@16 219 const ::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>&)
Chris@16 220 {
Chris@16 221 return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>());
Chris@16 222 }
Chris@16 223
Chris@16 224 template <class T>
Chris@16 225 inline T raise_pole_error(
Chris@16 226 const char* function,
Chris@16 227 const char* message,
Chris@16 228 const T& val,
Chris@16 229 const ::boost::math::policies::pole_error< ::boost::math::policies::user_error>&)
Chris@16 230 {
Chris@16 231 return user_pole_error(function, message, val);
Chris@16 232 }
Chris@16 233
Chris@16 234
Chris@16 235 template <class T>
Chris@16 236 inline T raise_overflow_error(
Chris@16 237 const char* function,
Chris@16 238 const char* message,
Chris@16 239 const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&)
Chris@16 240 {
Chris@16 241 raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow");
Chris@16 242 // We should never get here:
Chris@16 243 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
Chris@16 244 }
Chris@16 245
Chris@16 246 template <class T>
Chris@16 247 inline T raise_overflow_error(
Chris@16 248 const char* function,
Chris@16 249 const char* message,
Chris@16 250 const T& val,
Chris@16 251 const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&)
Chris@16 252 {
Chris@16 253 raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow", val);
Chris@16 254 // We should never get here:
Chris@16 255 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
Chris@16 256 }
Chris@16 257
Chris@16 258 template <class T>
Chris@16 259 inline T raise_overflow_error(
Chris@16 260 const char* ,
Chris@16 261 const char* ,
Chris@16 262 const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&)
Chris@16 263 {
Chris@16 264 // This may or may not do the right thing, but the user asked for the error
Chris@16 265 // to be ignored so here we go anyway:
Chris@16 266 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
Chris@16 267 }
Chris@16 268
Chris@16 269 template <class T>
Chris@16 270 inline T raise_overflow_error(
Chris@16 271 const char* ,
Chris@16 272 const char* ,
Chris@101 273 const T&,
Chris@101 274 const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&)
Chris@101 275 {
Chris@101 276 // This may or may not do the right thing, but the user asked for the error
Chris@101 277 // to be ignored so here we go anyway:
Chris@101 278 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
Chris@101 279 }
Chris@101 280
Chris@101 281 template <class T>
Chris@101 282 inline T raise_overflow_error(
Chris@101 283 const char* ,
Chris@101 284 const char* ,
Chris@101 285 const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&)
Chris@101 286 {
Chris@101 287 errno = ERANGE;
Chris@101 288 // This may or may not do the right thing, but the user asked for the error
Chris@101 289 // to be silent so here we go anyway:
Chris@101 290 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
Chris@101 291 }
Chris@101 292
Chris@101 293 template <class T>
Chris@101 294 inline T raise_overflow_error(
Chris@101 295 const char* ,
Chris@101 296 const char* ,
Chris@101 297 const T&,
Chris@16 298 const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&)
Chris@16 299 {
Chris@16 300 errno = ERANGE;
Chris@16 301 // This may or may not do the right thing, but the user asked for the error
Chris@16 302 // to be silent so here we go anyway:
Chris@16 303 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
Chris@16 304 }
Chris@16 305
Chris@16 306 template <class T>
Chris@16 307 inline T raise_overflow_error(
Chris@16 308 const char* function,
Chris@16 309 const char* message,
Chris@16 310 const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)
Chris@16 311 {
Chris@16 312 return user_overflow_error(function, message, std::numeric_limits<T>::infinity());
Chris@16 313 }
Chris@16 314
Chris@101 315 template <class T>
Chris@101 316 inline T raise_overflow_error(
Chris@101 317 const char* function,
Chris@101 318 const char* message,
Chris@101 319 const T& val,
Chris@101 320 const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)
Chris@101 321 {
Chris@101 322 std::string fmsg("Error in function ");
Chris@101 323 #ifndef BOOST_NO_RTTI
Chris@101 324 fmsg += (boost::format(function) % boost::math::policies::detail::name_of<T>()).str();
Chris@101 325 #else
Chris@101 326 fmsg += function;
Chris@101 327 #endif
Chris@101 328 int prec = 2 + (boost::math::policies::digits<T, boost::math::policies::policy<> >() * 30103UL) / 100000UL;
Chris@101 329 std::string msg = do_format(boost::format(message), boost::io::group(std::setprecision(prec), val));
Chris@101 330 return user_overflow_error(fmsg.c_str(), msg.c_str(), std::numeric_limits<T>::infinity());
Chris@101 331 }
Chris@16 332
Chris@16 333 template <class T>
Chris@16 334 inline T raise_underflow_error(
Chris@16 335 const char* function,
Chris@16 336 const char* message,
Chris@16 337 const ::boost::math::policies::underflow_error< ::boost::math::policies::throw_on_error>&)
Chris@16 338 {
Chris@16 339 raise_error<std::underflow_error, T>(function, message ? message : "numeric underflow");
Chris@16 340 // We should never get here:
Chris@16 341 return 0;
Chris@16 342 }
Chris@16 343
Chris@16 344 template <class T>
Chris@16 345 inline T raise_underflow_error(
Chris@16 346 const char* ,
Chris@16 347 const char* ,
Chris@16 348 const ::boost::math::policies::underflow_error< ::boost::math::policies::ignore_error>&)
Chris@16 349 {
Chris@16 350 // This may or may not do the right thing, but the user asked for the error
Chris@16 351 // to be ignored so here we go anyway:
Chris@16 352 return T(0);
Chris@16 353 }
Chris@16 354
Chris@16 355 template <class T>
Chris@16 356 inline T raise_underflow_error(
Chris@16 357 const char* /* function */,
Chris@16 358 const char* /* message */,
Chris@16 359 const ::boost::math::policies::underflow_error< ::boost::math::policies::errno_on_error>&)
Chris@16 360 {
Chris@16 361 errno = ERANGE;
Chris@16 362 // This may or may not do the right thing, but the user asked for the error
Chris@16 363 // to be silent so here we go anyway:
Chris@16 364 return T(0);
Chris@16 365 }
Chris@16 366
Chris@16 367 template <class T>
Chris@16 368 inline T raise_underflow_error(
Chris@16 369 const char* function,
Chris@16 370 const char* message,
Chris@16 371 const ::boost::math::policies::underflow_error< ::boost::math::policies::user_error>&)
Chris@16 372 {
Chris@16 373 return user_underflow_error(function, message, T(0));
Chris@16 374 }
Chris@16 375
Chris@16 376 template <class T>
Chris@16 377 inline T raise_denorm_error(
Chris@16 378 const char* function,
Chris@16 379 const char* message,
Chris@16 380 const T& /* val */,
Chris@16 381 const ::boost::math::policies::denorm_error< ::boost::math::policies::throw_on_error>&)
Chris@16 382 {
Chris@16 383 raise_error<std::underflow_error, T>(function, message ? message : "denormalised result");
Chris@16 384 // we never get here:
Chris@16 385 return T(0);
Chris@16 386 }
Chris@16 387
Chris@16 388 template <class T>
Chris@16 389 inline T raise_denorm_error(
Chris@16 390 const char* ,
Chris@16 391 const char* ,
Chris@16 392 const T& val,
Chris@16 393 const ::boost::math::policies::denorm_error< ::boost::math::policies::ignore_error>&)
Chris@16 394 {
Chris@16 395 // This may or may not do the right thing, but the user asked for the error
Chris@16 396 // to be ignored so here we go anyway:
Chris@16 397 return val;
Chris@16 398 }
Chris@16 399
Chris@16 400 template <class T>
Chris@16 401 inline T raise_denorm_error(
Chris@16 402 const char* ,
Chris@16 403 const char* ,
Chris@16 404 const T& val,
Chris@16 405 const ::boost::math::policies::denorm_error< ::boost::math::policies::errno_on_error>&)
Chris@16 406 {
Chris@16 407 errno = ERANGE;
Chris@16 408 // This may or may not do the right thing, but the user asked for the error
Chris@16 409 // to be silent so here we go anyway:
Chris@16 410 return val;
Chris@16 411 }
Chris@16 412
Chris@16 413 template <class T>
Chris@16 414 inline T raise_denorm_error(
Chris@16 415 const char* function,
Chris@16 416 const char* message,
Chris@16 417 const T& val,
Chris@16 418 const ::boost::math::policies::denorm_error< ::boost::math::policies::user_error>&)
Chris@16 419 {
Chris@16 420 return user_denorm_error(function, message, val);
Chris@16 421 }
Chris@16 422
Chris@16 423 template <class T>
Chris@16 424 inline T raise_evaluation_error(
Chris@16 425 const char* function,
Chris@16 426 const char* message,
Chris@16 427 const T& val,
Chris@16 428 const ::boost::math::policies::evaluation_error< ::boost::math::policies::throw_on_error>&)
Chris@16 429 {
Chris@16 430 raise_error<boost::math::evaluation_error, T>(function, message, val);
Chris@16 431 // we never get here:
Chris@16 432 return T(0);
Chris@16 433 }
Chris@16 434
Chris@16 435 template <class T>
Chris@16 436 inline T raise_evaluation_error(
Chris@16 437 const char* ,
Chris@16 438 const char* ,
Chris@16 439 const T& val,
Chris@16 440 const ::boost::math::policies::evaluation_error< ::boost::math::policies::ignore_error>&)
Chris@16 441 {
Chris@16 442 // This may or may not do the right thing, but the user asked for the error
Chris@16 443 // to be ignored so here we go anyway:
Chris@16 444 return val;
Chris@16 445 }
Chris@16 446
Chris@16 447 template <class T>
Chris@16 448 inline T raise_evaluation_error(
Chris@16 449 const char* ,
Chris@16 450 const char* ,
Chris@16 451 const T& val,
Chris@16 452 const ::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>&)
Chris@16 453 {
Chris@16 454 errno = EDOM;
Chris@16 455 // This may or may not do the right thing, but the user asked for the error
Chris@16 456 // to be silent so here we go anyway:
Chris@16 457 return val;
Chris@16 458 }
Chris@16 459
Chris@16 460 template <class T>
Chris@16 461 inline T raise_evaluation_error(
Chris@16 462 const char* function,
Chris@16 463 const char* message,
Chris@16 464 const T& val,
Chris@16 465 const ::boost::math::policies::evaluation_error< ::boost::math::policies::user_error>&)
Chris@16 466 {
Chris@16 467 return user_evaluation_error(function, message, val);
Chris@16 468 }
Chris@16 469
Chris@16 470 template <class T, class TargetType>
Chris@16 471 inline TargetType raise_rounding_error(
Chris@16 472 const char* function,
Chris@16 473 const char* message,
Chris@16 474 const T& val,
Chris@16 475 const TargetType&,
Chris@16 476 const ::boost::math::policies::rounding_error< ::boost::math::policies::throw_on_error>&)
Chris@16 477 {
Chris@16 478 raise_error<boost::math::rounding_error, T>(function, message, val);
Chris@16 479 // we never get here:
Chris@16 480 return TargetType(0);
Chris@16 481 }
Chris@16 482
Chris@16 483 template <class T, class TargetType>
Chris@16 484 inline TargetType raise_rounding_error(
Chris@16 485 const char* ,
Chris@16 486 const char* ,
Chris@16 487 const T& val,
Chris@16 488 const TargetType&,
Chris@16 489 const ::boost::math::policies::rounding_error< ::boost::math::policies::ignore_error>&)
Chris@16 490 {
Chris@16 491 // This may or may not do the right thing, but the user asked for the error
Chris@16 492 // to be ignored so here we go anyway:
Chris@16 493 BOOST_STATIC_ASSERT(std::numeric_limits<TargetType>::is_specialized);
Chris@16 494 return val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)());
Chris@16 495 }
Chris@16 496
Chris@16 497 template <class T, class TargetType>
Chris@16 498 inline TargetType raise_rounding_error(
Chris@16 499 const char* ,
Chris@16 500 const char* ,
Chris@16 501 const T& val,
Chris@16 502 const TargetType&,
Chris@16 503 const ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&)
Chris@16 504 {
Chris@16 505 errno = ERANGE;
Chris@16 506 // This may or may not do the right thing, but the user asked for the error
Chris@16 507 // to be silent so here we go anyway:
Chris@16 508 BOOST_STATIC_ASSERT(std::numeric_limits<TargetType>::is_specialized);
Chris@16 509 return val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)());
Chris@16 510 }
Chris@16 511
Chris@16 512 template <class T, class TargetType>
Chris@16 513 inline TargetType raise_rounding_error(
Chris@16 514 const char* function,
Chris@16 515 const char* message,
Chris@16 516 const T& val,
Chris@16 517 const TargetType& t,
Chris@16 518 const ::boost::math::policies::rounding_error< ::boost::math::policies::user_error>&)
Chris@16 519 {
Chris@16 520 return user_rounding_error(function, message, val, t);
Chris@16 521 }
Chris@16 522
Chris@16 523 template <class T, class R>
Chris@16 524 inline T raise_indeterminate_result_error(
Chris@16 525 const char* function,
Chris@16 526 const char* message,
Chris@16 527 const T& val,
Chris@16 528 const R& ,
Chris@16 529 const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::throw_on_error>&)
Chris@16 530 {
Chris@16 531 raise_error<std::domain_error, T>(function, message, val);
Chris@16 532 // we never get here:
Chris@16 533 return std::numeric_limits<T>::quiet_NaN();
Chris@16 534 }
Chris@16 535
Chris@16 536 template <class T, class R>
Chris@16 537 inline T raise_indeterminate_result_error(
Chris@16 538 const char* ,
Chris@16 539 const char* ,
Chris@16 540 const T& ,
Chris@16 541 const R& result,
Chris@16 542 const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::ignore_error>&)
Chris@16 543 {
Chris@16 544 // This may or may not do the right thing, but the user asked for the error
Chris@16 545 // to be ignored so here we go anyway:
Chris@16 546 return result;
Chris@16 547 }
Chris@16 548
Chris@16 549 template <class T, class R>
Chris@16 550 inline T raise_indeterminate_result_error(
Chris@16 551 const char* ,
Chris@16 552 const char* ,
Chris@16 553 const T& ,
Chris@16 554 const R& result,
Chris@16 555 const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::errno_on_error>&)
Chris@16 556 {
Chris@16 557 errno = EDOM;
Chris@16 558 // This may or may not do the right thing, but the user asked for the error
Chris@16 559 // to be silent so here we go anyway:
Chris@16 560 return result;
Chris@16 561 }
Chris@16 562
Chris@16 563 template <class T, class R>
Chris@16 564 inline T raise_indeterminate_result_error(
Chris@16 565 const char* function,
Chris@16 566 const char* message,
Chris@16 567 const T& val,
Chris@16 568 const R& ,
Chris@16 569 const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::user_error>&)
Chris@16 570 {
Chris@16 571 return user_indeterminate_result_error(function, message, val);
Chris@16 572 }
Chris@16 573
Chris@16 574 } // namespace detail
Chris@16 575
Chris@16 576 template <class T, class Policy>
Chris@16 577 inline T raise_domain_error(const char* function, const char* message, const T& val, const Policy&)
Chris@16 578 {
Chris@16 579 typedef typename Policy::domain_error_type policy_type;
Chris@16 580 return detail::raise_domain_error(
Chris@16 581 function, message ? message : "Domain Error evaluating function at %1%",
Chris@16 582 val, policy_type());
Chris@16 583 }
Chris@16 584
Chris@16 585 template <class T, class Policy>
Chris@16 586 inline T raise_pole_error(const char* function, const char* message, const T& val, const Policy&)
Chris@16 587 {
Chris@16 588 typedef typename Policy::pole_error_type policy_type;
Chris@16 589 return detail::raise_pole_error(
Chris@16 590 function, message ? message : "Evaluation of function at pole %1%",
Chris@16 591 val, policy_type());
Chris@16 592 }
Chris@16 593
Chris@16 594 template <class T, class Policy>
Chris@16 595 inline T raise_overflow_error(const char* function, const char* message, const Policy&)
Chris@16 596 {
Chris@16 597 typedef typename Policy::overflow_error_type policy_type;
Chris@16 598 return detail::raise_overflow_error<T>(
Chris@16 599 function, message ? message : "Overflow Error",
Chris@16 600 policy_type());
Chris@16 601 }
Chris@16 602
Chris@16 603 template <class T, class Policy>
Chris@16 604 inline T raise_overflow_error(const char* function, const char* message, const T& val, const Policy&)
Chris@16 605 {
Chris@16 606 typedef typename Policy::overflow_error_type policy_type;
Chris@16 607 return detail::raise_overflow_error(
Chris@16 608 function, message ? message : "Overflow evaluating function at %1%",
Chris@16 609 val, policy_type());
Chris@16 610 }
Chris@16 611
Chris@16 612 template <class T, class Policy>
Chris@16 613 inline T raise_underflow_error(const char* function, const char* message, const Policy&)
Chris@16 614 {
Chris@16 615 typedef typename Policy::underflow_error_type policy_type;
Chris@16 616 return detail::raise_underflow_error<T>(
Chris@16 617 function, message ? message : "Underflow Error",
Chris@16 618 policy_type());
Chris@16 619 }
Chris@16 620
Chris@16 621 template <class T, class Policy>
Chris@16 622 inline T raise_denorm_error(const char* function, const char* message, const T& val, const Policy&)
Chris@16 623 {
Chris@16 624 typedef typename Policy::denorm_error_type policy_type;
Chris@16 625 return detail::raise_denorm_error<T>(
Chris@16 626 function, message ? message : "Denorm Error",
Chris@16 627 val,
Chris@16 628 policy_type());
Chris@16 629 }
Chris@16 630
Chris@16 631 template <class T, class Policy>
Chris@16 632 inline T raise_evaluation_error(const char* function, const char* message, const T& val, const Policy&)
Chris@16 633 {
Chris@16 634 typedef typename Policy::evaluation_error_type policy_type;
Chris@16 635 return detail::raise_evaluation_error(
Chris@16 636 function, message ? message : "Internal Evaluation Error, best value so far was %1%",
Chris@16 637 val, policy_type());
Chris@16 638 }
Chris@16 639
Chris@16 640 template <class T, class TargetType, class Policy>
Chris@16 641 inline TargetType raise_rounding_error(const char* function, const char* message, const T& val, const TargetType& t, const Policy&)
Chris@16 642 {
Chris@16 643 typedef typename Policy::rounding_error_type policy_type;
Chris@16 644 return detail::raise_rounding_error(
Chris@16 645 function, message ? message : "Value %1% can not be represented in the target integer type.",
Chris@16 646 val, t, policy_type());
Chris@16 647 }
Chris@16 648
Chris@16 649 template <class T, class R, class Policy>
Chris@16 650 inline T raise_indeterminate_result_error(const char* function, const char* message, const T& val, const R& result, const Policy&)
Chris@16 651 {
Chris@16 652 typedef typename Policy::indeterminate_result_error_type policy_type;
Chris@16 653 return detail::raise_indeterminate_result_error(
Chris@16 654 function, message ? message : "Indeterminate result with value %1%",
Chris@16 655 val, result, policy_type());
Chris@16 656 }
Chris@16 657
Chris@16 658 //
Chris@16 659 // checked_narrowing_cast:
Chris@16 660 //
Chris@16 661 namespace detail
Chris@16 662 {
Chris@16 663
Chris@16 664 template <class R, class T, class Policy>
Chris@16 665 inline bool check_overflow(T val, R* result, const char* function, const Policy& pol)
Chris@16 666 {
Chris@16 667 BOOST_MATH_STD_USING
Chris@16 668 if(fabs(val) > tools::max_value<R>())
Chris@16 669 {
Chris@101 670 boost::math::policies::detail::raise_overflow_error<R>(function, 0, pol);
Chris@101 671 *result = static_cast<R>(val);
Chris@16 672 return true;
Chris@16 673 }
Chris@16 674 return false;
Chris@16 675 }
Chris@16 676 template <class R, class T, class Policy>
Chris@16 677 inline bool check_overflow(std::complex<T> val, R* result, const char* function, const Policy& pol)
Chris@16 678 {
Chris@16 679 typedef typename R::value_type r_type;
Chris@16 680 r_type re, im;
Chris@16 681 bool r = check_overflow<r_type>(val.real(), &re, function, pol);
Chris@16 682 r = check_overflow<r_type>(val.imag(), &im, function, pol) || r;
Chris@16 683 *result = R(re, im);
Chris@16 684 return r;
Chris@16 685 }
Chris@16 686 template <class R, class T, class Policy>
Chris@16 687 inline bool check_underflow(T val, R* result, const char* function, const Policy& pol)
Chris@16 688 {
Chris@16 689 if((val != 0) && (static_cast<R>(val) == 0))
Chris@16 690 {
Chris@16 691 *result = static_cast<R>(boost::math::policies::detail::raise_underflow_error<R>(function, 0, pol));
Chris@16 692 return true;
Chris@16 693 }
Chris@16 694 return false;
Chris@16 695 }
Chris@16 696 template <class R, class T, class Policy>
Chris@16 697 inline bool check_underflow(std::complex<T> val, R* result, const char* function, const Policy& pol)
Chris@16 698 {
Chris@16 699 typedef typename R::value_type r_type;
Chris@16 700 r_type re, im;
Chris@16 701 bool r = check_underflow<r_type>(val.real(), &re, function, pol);
Chris@16 702 r = check_underflow<r_type>(val.imag(), &im, function, pol) || r;
Chris@16 703 *result = R(re, im);
Chris@16 704 return r;
Chris@16 705 }
Chris@16 706 template <class R, class T, class Policy>
Chris@16 707 inline bool check_denorm(T val, R* result, const char* function, const Policy& pol)
Chris@16 708 {
Chris@16 709 BOOST_MATH_STD_USING
Chris@16 710 if((fabs(val) < static_cast<T>(tools::min_value<R>())) && (static_cast<R>(val) != 0))
Chris@16 711 {
Chris@16 712 *result = static_cast<R>(boost::math::policies::detail::raise_denorm_error<R>(function, 0, static_cast<R>(val), pol));
Chris@16 713 return true;
Chris@16 714 }
Chris@16 715 return false;
Chris@16 716 }
Chris@16 717 template <class R, class T, class Policy>
Chris@16 718 inline bool check_denorm(std::complex<T> val, R* result, const char* function, const Policy& pol)
Chris@16 719 {
Chris@16 720 typedef typename R::value_type r_type;
Chris@16 721 r_type re, im;
Chris@16 722 bool r = check_denorm<r_type>(val.real(), &re, function, pol);
Chris@16 723 r = check_denorm<r_type>(val.imag(), &im, function, pol) || r;
Chris@16 724 *result = R(re, im);
Chris@16 725 return r;
Chris@16 726 }
Chris@16 727
Chris@16 728 // Default instantiations with ignore_error policy.
Chris@16 729 template <class R, class T>
Chris@16 730 inline bool check_overflow(T /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&){ return false; }
Chris@16 731 template <class R, class T>
Chris@16 732 inline bool check_overflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&){ return false; }
Chris@16 733 template <class R, class T>
Chris@16 734 inline bool check_underflow(T /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&){ return false; }
Chris@16 735 template <class R, class T>
Chris@16 736 inline bool check_underflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&){ return false; }
Chris@16 737 template <class R, class T>
Chris@16 738 inline bool check_denorm(T /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&){ return false; }
Chris@16 739 template <class R, class T>
Chris@16 740 inline bool check_denorm(std::complex<T> /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&){ return false; }
Chris@16 741
Chris@16 742 } // namespace detail
Chris@16 743
Chris@16 744 template <class R, class Policy, class T>
Chris@16 745 inline R checked_narrowing_cast(T val, const char* function)
Chris@16 746 {
Chris@16 747 typedef typename Policy::overflow_error_type overflow_type;
Chris@16 748 typedef typename Policy::underflow_error_type underflow_type;
Chris@16 749 typedef typename Policy::denorm_error_type denorm_type;
Chris@16 750 //
Chris@16 751 // Most of what follows will evaluate to a no-op:
Chris@16 752 //
Chris@16 753 R result = 0;
Chris@16 754 if(detail::check_overflow<R>(val, &result, function, overflow_type()))
Chris@16 755 return result;
Chris@16 756 if(detail::check_underflow<R>(val, &result, function, underflow_type()))
Chris@16 757 return result;
Chris@16 758 if(detail::check_denorm<R>(val, &result, function, denorm_type()))
Chris@16 759 return result;
Chris@16 760
Chris@16 761 return static_cast<R>(val);
Chris@16 762 }
Chris@16 763
Chris@16 764 template <class T, class Policy>
Chris@16 765 inline void check_series_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol)
Chris@16 766 {
Chris@16 767 if(max_iter >= policies::get_max_series_iterations<Policy>())
Chris@16 768 raise_evaluation_error<T>(
Chris@16 769 function,
Chris@16 770 "Series evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
Chris@16 771 }
Chris@16 772
Chris@16 773 template <class T, class Policy>
Chris@16 774 inline void check_root_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol)
Chris@16 775 {
Chris@16 776 if(max_iter >= policies::get_max_root_iterations<Policy>())
Chris@16 777 raise_evaluation_error<T>(
Chris@16 778 function,
Chris@16 779 "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
Chris@16 780 }
Chris@16 781
Chris@16 782 } //namespace policies
Chris@16 783
Chris@101 784 namespace detail{
Chris@101 785
Chris@101 786 //
Chris@101 787 // Simple helper function to assist in returning a pair from a single value,
Chris@101 788 // that value usually comes from one of the error handlers above:
Chris@101 789 //
Chris@101 790 template <class T>
Chris@101 791 std::pair<T, T> pair_from_single(const T& val)
Chris@101 792 {
Chris@101 793 return std::make_pair(val, val);
Chris@101 794 }
Chris@101 795
Chris@101 796 }
Chris@101 797
Chris@16 798 #ifdef BOOST_MSVC
Chris@16 799 # pragma warning(pop)
Chris@16 800 #endif
Chris@16 801
Chris@16 802 }} // namespaces boost/math
Chris@16 803
Chris@16 804 #endif // BOOST_MATH_POLICY_ERROR_HANDLING_HPP
Chris@16 805