...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
All of the special functions in this library come in two overloaded forms, one with a final "policy" parameter, and one without. For example:
namespace boost{ namespace math{ template <class RealType, class Policy> RealType tgamma(RealType, const Policy&); template <class RealType> RealType tgamma(RealType); }} // namespaces
Normally, the second version is just a forwarding wrapper to the first like this:
template <class RealType> inline RealType tgamma(RealType x) { return tgamma(x, policies::policy<>()); }
So calling a special function with a specific policy is just a matter of
defining the policy type to use and passing it as the final parameter. For
example, suppose we want tgamma
to behave in a C-compatible fashion and set ::errno
when an error occurs, and never throw
an exception:
#include <boost/math/special_functions/gamma.hpp> using boost::math::tgamma; // Define the policy to use: using namespace boost::math::policies; // may be convenient, or using boost::math::policies::policy; // Types of error whose action can be altered by policies:. using boost::math::policies::evaluation_error; using boost::math::policies::domain_error; using boost::math::policies::overflow_error; using boost::math::policies::domain_error; using boost::math::policies::pole_error; // Actions on error (in enum error_policy_type): using boost::math::policies::errno_on_error; using boost::math::policies::ignore_error; using boost::math::policies::throw_on_error; using boost::math::policies::user_error; typedef policy< domain_error<errno_on_error>, pole_error<errno_on_error>, overflow_error<errno_on_error>, evaluation_error<errno_on_error> > c_policy; // // Now use the policy when calling tgamma: // http://msdn.microsoft.com/en-us/library/t3ayayh1.aspx // Microsoft errno declared in STDLIB.H as "extern int errno;" int main() { errno = 0; // Reset. cout << "Result of tgamma(30000) is: " << tgamma(30000, c_policy()) << endl; // Too big parameter cout << "errno = " << errno << endl; // errno 34 Numerical result out of range. cout << "Result of tgamma(-10) is: " << boost::math::tgamma(-10, c_policy()) << endl; // Negative parameter. cout << "errno = " << errno << endl; // error 33 Numerical argument out of domain. } // int main()
which outputs:
Result of tgamma(30000) is: 1.#INF errno = 34 Result of tgamma(-10) is: 1.#QNAN errno = 33
Alternatively, for ad hoc use, we can use the make_policy
helper function to create a policy for us: this usage is more verbose, so
is probably only preferred when a policy is going to be used once only:
#include <boost/math/special_functions/gamma.hpp> using boost::math::tgamma; int main() { // using namespace boost::math::policies; // or using boost::math::policies::errno_on_error; using boost::math::policies::make_policy; using boost::math::policies::pole_error; using boost::math::policies::domain_error; using boost::math::policies::overflow_error; using boost::math::policies::evaluation_error; errno = 0; std::cout << "Result of tgamma(30000) is: " << boost::math::tgamma( 30000, make_policy( domain_error<errno_on_error>(), pole_error<errno_on_error>(), overflow_error<errno_on_error>(), evaluation_error<errno_on_error>() ) ) << std::endl; // Check errno was set: std::cout << "errno = " << errno << std::endl; // and again with evaluation at a pole: std::cout << "Result of tgamma(-10) is: " << boost::math::tgamma( -10, make_policy( domain_error<errno_on_error>(), pole_error<errno_on_error>(), overflow_error<errno_on_error>(), evaluation_error<errno_on_error>() ) ) << std::endl; // Check errno was set: std::cout << "errno = " << errno << std::endl; }