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