]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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> | |
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> | |
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 | ||
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] |