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