1 // Copyright John Maddock 2007.
2 // Copyright Paul a. Bristow 2010
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 // Note that this file contains quickbook mark-up as well as code
8 // and comments, don't change any of the special comment mark-ups!
9
10 #ifdef _MSC_VER
11 # pragma warning (disable : 4100) // unreferenced formal parameters
12 #endif
13
14 #include <iostream>
15 using std::cout; using std::endl; using std::cerr;
16
17 //[policy_eg_8
18
19 /*`
20 Suppose we want our own user-defined error handlers rather than the
21 any of the default ones supplied by the library to be used.
22 If we set the policy for a specific type of error to `user_error`
23 then the library will call a user-supplied error handler.
24 These are forward declared, but not defined in
25 boost/math/policies/error_handling.hpp like this:
26
27 namespace boost{ namespace math{ namespace policies{
28
29 template <class T>
30 T user_domain_error(const char* function, const char* message, const T& val);
31 template <class T>
32 T user_pole_error(const char* function, const char* message, const T& val);
33 template <class T>
34 T user_overflow_error(const char* function, const char* message, const T& val);
35 template <class T>
36 T user_underflow_error(const char* function, const char* message, const T& val);
37 template <class T>
38 T user_denorm_error(const char* function, const char* message, const T& val);
39 template <class T>
40 T user_evaluation_error(const char* function, const char* message, const T& val);
41 template <class T, class TargetType>
42 T user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t);
43 template <class T>
44 T user_indeterminate_result_error(const char* function, const char* message, const T& val);
45
46 }}} // namespaces
47
48 So out first job is to include the header we want to use, and then
49 provide definitions for our user-defined error handlers that we want to use.
50 We only provide our special domain and pole error handlers;
51 other errors like overflow and underflow use the default.
52 */
53
54 #include <boost/math/special_functions.hpp>
55
56 namespace boost{ namespace math
57 {
58 namespace policies
59 {
60 template <class T>
user_domain_error(const char * function,const char * message,const T & val)61 T user_domain_error(const char* function, const char* message, const T& val)
62 { // Ignoring function, message and val for this example, perhaps unhelpfully.
63 cerr << "Domain Error!" << endl;
64 return std::numeric_limits<T>::quiet_NaN();
65 }
66
67 template <class T>
user_pole_error(const char * function,const char * message,const T & val)68 T user_pole_error(const char* function, const char* message, const T& val)
69 { // Ignoring function, message and val for this example, perhaps unhelpfully.
70 cerr << "Pole Error!" << endl;
71 return std::numeric_limits<T>::quiet_NaN();
72 }
73 } // namespace policies
74 }} // namespace boost{ namespace math
75
76
77 /*`
78 Now we'll need to define a suitable policy that will call these handlers,
79 and define some forwarding functions that make use of the policy:
80 */
81
82 namespace mymath{
83
84 using namespace boost::math::policies;
85
86 typedef policy<
87 domain_error<user_error>,
88 pole_error<user_error>
89 > user_error_policy;
90
91 BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(user_error_policy)
92
93 } // close unnamed namespace
94
95 /*`
96 We now have a set of forwarding functions defined in namespace mymath
97 that all look something like this:
98
99 ``
100 template <class RealType>
101 inline typename boost::math::tools::promote_args<RT>::type
102 tgamma(RT z)
103 {
104 return boost::math::tgamma(z, user_error_policy());
105 }
106 ``
107
108 So that when we call `mymath::tgamma(z)` we really end up calling
109 `boost::math::tgamma(z, user_error_policy())`, and any
110 errors will get directed to our own error handlers.
111 */
112
main()113 int main()
114 {
115 cout << "Result of erf_inv(-10) is: "
116 << mymath::erf_inv(-10) << endl;
117 cout << "Result of tgamma(-10) is: "
118 << mymath::tgamma(-10) << endl;
119 }
120
121 /*`
122
123 Which outputs:
124
125 [pre
126 Domain Error!
127 Pole Error!
128 Result of erf_inv(-10) is: 1.#QNAN
129 Result of tgamma(-10) is: 1.#QNAN
130 ]
131 */
132
133 //] // //[/policy_eg_8]
134