policy_eg_4.cpp 2.8 KB

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