• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright John Maddock 2007.
2 //  Copyright Paul A. Bristow 2010
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 // Note that this file contains quickbook mark-up as well as code
9 // and comments, don't change any of the special comment mark-ups!
10 
11 #include <iostream>
12 using std::cout;  using std::endl;
13 #include <cerrno> // for ::errno
14 
15 //[policy_eg_4
16 
17 /*`
18 Suppose we want `C::foo()` to behave in a C-compatible way and set
19 `::errno` on error rather than throwing any exceptions.
20 
21 We'll begin by including the needed header for our function:
22 */
23 
24 #include <boost/math/special_functions.hpp>
25 //using boost::math::tgamma; // Not needed because using C::tgamma.
26 
27 /*`
28 Open up the "C" namespace that we'll use for our functions, and
29 define the policy type we want: in this case a C-style one that sets
30 ::errno and returns a standard value, rather than throwing exceptions.
31 
32 Any policies we don't specify here will inherit the defaults.
33 */
34 
35 namespace C
36 { // To hold our C-style policy.
37   //using namespace boost::math::policies; or explicitly:
38   using boost::math::policies::policy;
39 
40   using boost::math::policies::domain_error;
41   using boost::math::policies::pole_error;
42   using boost::math::policies::overflow_error;
43   using boost::math::policies::evaluation_error;
44   using boost::math::policies::errno_on_error;
45 
46   typedef policy<
47      domain_error<errno_on_error>,
48      pole_error<errno_on_error>,
49      overflow_error<errno_on_error>,
50      evaluation_error<errno_on_error>
51   > c_policy;
52 
53 /*`
54 All we need do now is invoke the BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS
55 macro passing our policy type c_policy as the single argument:
56 */
57 
58 BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(c_policy)
59 
60 } // close namespace C
61 
62 /*`
63 We now have a set of forwarding functions defined in namespace C
64 that all look something like this:
65 
66 ``
67 template <class RealType>
68 inline typename boost::math::tools::promote_args<RT>::type
69    tgamma(RT z)
70 {
71    return boost::math::tgamma(z, c_policy());
72 }
73 ``
74 
75 So that when we call `C::tgamma(z)`, we really end up calling
76 `boost::math::tgamma(z, C::c_policy())`:
77 */
78 
main()79 int main()
80 {
81    errno = 0;
82    cout << "Result of tgamma(30000) is: "
83       << C::tgamma(30000) << endl; // Note using C::tgamma
84    cout << "errno = " << errno << endl; // errno = 34
85    cout << "Result of tgamma(-10) is: "
86       << C::tgamma(-10) << endl;
87    cout << "errno = " << errno << endl; // errno = 33, overwriting previous value of 34.
88 }
89 
90 /*`
91 
92 Which outputs:
93 
94 [pre
95 Result of C::tgamma(30000) is: 1.#INF
96 errno = 34
97 Result of C::tgamma(-10) is: 1.#QNAN
98 errno = 33
99 ]
100 
101 This mechanism is particularly useful when we want to define a project-wide policy,
102 and don't want to modify the Boost source,
103 or to set project wide build macros (possibly fragile and easy to forget).
104 
105 */
106 //] //[/policy_eg_4]
107 
108