blob: ed9a095b0805a9af041aec2e152c90ec4caf5edb [file] [log] [blame]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Setting Policies at Namespace or Translation Unit Scope</title>
<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.74.0">
<link rel="home" href="../../../index.html" title="Math Toolkit">
<link rel="up" href="../pol_tutorial.html" title="Policy Tutorial">
<link rel="prev" href="ad_hoc_sf_policies.html" title="Changing the Policy on an Ad Hoc Basis for the Special Functions">
<link rel="next" href="user_def_err_pol.html" title="Calling User Defined Error Handlers">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="ad_hoc_sf_policies.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../pol_tutorial.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="user_def_err_pol.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="math_toolkit.policy.pol_tutorial.namespace_policies"></a><a class="link" href="namespace_policies.html" title="Setting Policies at Namespace or Translation Unit Scope">
Setting Policies at Namespace or Translation Unit Scope</a>
</h4></div></div></div>
<p>
Sometimes what you want to do is just change a set of policies within the
current scope: <span class="bold"><strong>the one thing you should not do in
this situation is use the configuration macros</strong></span>, as this can
lead to "One Definition Rule" violations. Instead this library
provides a pair of macros especially for this purpose.
</p>
<p>
Let's consider the special functions first: we can declare a set of forwarding
functions that all use a specific policy using the macro BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(<span class="emphasis"><em>Policy</em></span>).
This macro should be used either inside a unique namespace set aside for
the purpose (for example, a C namespace for a C-style policy), or an unnamed
namespace if you just want the functions visible in global scope for the
current file only.
</p>
<p>
</p>
<p>
Suppose we want <code class="computeroutput"><span class="identifier">C</span><span class="special">::</span><span class="identifier">foo</span><span class="special">()</span></code>
to behave in a C-compatible way and set <code class="computeroutput"><span class="special">::</span><span class="identifier">errno</span></code> on error rather than throwing
any exceptions.
</p>
<p>
</p>
<p>
We'll begin by including the needed header for our function:
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="comment">//using boost::math::tgamma; // Not needed because using C::tgamma.</span></pre>
<p>
</p>
<p>
</p>
<p>
Open up the "C" namespace that we'll use for our functions,
and define the policy type we want: in this case a C-style one that sets
::errno and returns a standard value, rather than throwing exceptions.
</p>
<p>
</p>
<p>
Any policies we don't specify here will inherit the defaults.
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">C</span>
<span class="special">{</span> <span class="comment">// To hold our C-style policy.
</span> <span class="comment">//using namespace boost::math::policies; or explicitly:
</span> <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">::</span><span class="identifier">policy</span><span class="special">;</span>
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">::</span><span class="identifier">domain_error</span><span class="special">;</span>
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">::</span><span class="identifier">pole_error</span><span class="special">;</span>
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">::</span><span class="identifier">overflow_error</span><span class="special">;</span>
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">::</span><span class="identifier">evaluation_error</span><span class="special">;</span>
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">::</span><span class="identifier">errno_on_error</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">policy</span><span class="special">&lt;</span>
<span class="identifier">domain_error</span><span class="special">&lt;</span><span class="identifier">errno_on_error</span><span class="special">&gt;,</span>
<span class="identifier">pole_error</span><span class="special">&lt;</span><span class="identifier">errno_on_error</span><span class="special">&gt;,</span>
<span class="identifier">overflow_error</span><span class="special">&lt;</span><span class="identifier">errno_on_error</span><span class="special">&gt;,</span>
<span class="identifier">evaluation_error</span><span class="special">&lt;</span><span class="identifier">errno_on_error</span><span class="special">&gt;</span>
<span class="special">&gt;</span> <span class="identifier">c_policy</span><span class="special">;</span></pre>
<p>
</p>
<p>
</p>
<p>
All we need do now is invoke the BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS
macro passing our policy type c_policy as the single argument:
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS</span><span class="special">(</span><span class="identifier">c_policy</span><span class="special">)</span>
<span class="special">}</span> <span class="comment">// close namespace C</span></pre>
<p>
</p>
<p>
</p>
<p>
We now have a set of forwarding functions defined in namespace C that
all look something like this:
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">RealType</span><span class="special">&gt;</span>
<span class="keyword">inline</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tools</span><span class="special">::</span><span class="identifier">promote_args</span><span class="special">&lt;</span><span class="identifier">RT</span><span class="special">&gt;::</span><span class="identifier">type</span>
<span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">RT</span> <span class="identifier">z</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">z</span><span class="special">,</span> <span class="identifier">c_policy</span><span class="special">());</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
</p>
<p>
So that when we call <code class="computeroutput"><span class="identifier">C</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">z</span><span class="special">)</span></code>, we really end up calling <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">z</span><span class="special">,</span> <span class="identifier">C</span><span class="special">::</span><span class="identifier">c_policy</span><span class="special">())</span></code>:
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">errno</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of tgamma(30000) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">C</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="number">30000</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span> <span class="comment">// Note using C::tgamma
</span> <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"errno = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">errno</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span> <span class="comment">// errno = 34
</span> <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of tgamma(-10) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">C</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(-</span><span class="number">10</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"errno = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">errno</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span> <span class="comment">// errno = 33, overwriting previous value of 34.
</span><span class="special">}</span></pre>
<p>
</p>
<p>
</p>
<p>
Which outputs:
</p>
<p>
</p>
<pre class="programlisting">Result of C::tgamma(30000) is: 1.#INF
errno = 34
Result of C::tgamma(-10) is: 1.#QNAN
errno = 33
</pre>
<p>
</p>
<p>
This mechanism is particularly useful when we want to define a project-wide
policy, and don't want to modify the Boost source, or to set project
wide build macros (possibly fragile and easy to forget).
</p>
<p>
</p>
<p>
The same mechanism works well at file scope as well, by using an unnamed
namespace, we can ensure that these declarations don't conflict with any
alternate policies present in other translation units:
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="comment">// using boost::math::tgamma; // Would create an ambiguity between
</span><span class="comment">// 'double boost::math::tgamma&lt;int&gt;(T)' and
</span><span class="comment">// 'double 'anonymous-namespace'::tgamma&lt;int&gt;(RT)'.
</span>
<span class="keyword">namespace</span>
<span class="special">{</span> <span class="comment">// unnamed
</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">policy</span><span class="special">&lt;</span>
<span class="identifier">domain_error</span><span class="special">&lt;</span><span class="identifier">errno_on_error</span><span class="special">&gt;,</span>
<span class="identifier">pole_error</span><span class="special">&lt;</span><span class="identifier">errno_on_error</span><span class="special">&gt;,</span>
<span class="identifier">overflow_error</span><span class="special">&lt;</span><span class="identifier">errno_on_error</span><span class="special">&gt;,</span>
<span class="identifier">evaluation_error</span><span class="special">&lt;</span><span class="identifier">errno_on_error</span><span class="special">&gt;</span>
<span class="special">&gt;</span> <span class="identifier">c_policy</span><span class="special">;</span>
<span class="identifier">BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS</span><span class="special">(</span><span class="identifier">c_policy</span><span class="special">)</span></pre>
<p>
</p>
<p>
</p>
<p>
So that when we call <code class="computeroutput"><span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">z</span><span class="special">)</span></code>, we really end up calling <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">tgamma</span><span class="special">(</span><span class="identifier">z</span><span class="special">,</span> <span class="identifier">anonymous</span><span class="special">-</span><span class="keyword">namespace</span><span class="special">::</span><span class="identifier">c_policy</span><span class="special">())</span></code>.
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="special">}</span> <span class="comment">// close unnamed namespace
</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">errno</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of tgamma(30000) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">tgamma</span><span class="special">(</span><span class="number">30000</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// tgamma in unnamed namespace in this translation unit (file) only.
</span> <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"errno = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">errno</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of tgamma(-10) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">tgamma</span><span class="special">(-</span><span class="number">10</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"errno = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">errno</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// Default tgamma policy would throw an exception, and abort.
</span><span class="special">}</span>
</pre>
<p>
</p>
<p>
</p>
<p>
Handling policies for the statistical distributions is very similar except
that now the macro BOOST_MATH_DECLARE_DISTRIBUTIONS accepts two parameters:
the floating point type to use, and the policy type to apply. For example:
</p>
<pre class="programlisting"><span class="identifier">BOOST_MATH_DECLARE_DISTRIBUTIONS</span><span class="special">(</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">mypolicy</span><span class="special">)</span>
</pre>
<p>
Results a set of typedefs being defined like this:
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">normal_distribution</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">mypolicy</span><span class="special">&gt;</span> <span class="identifier">normal</span><span class="special">;</span>
</pre>
<p>
The name of each typedef is the same as the name of the distribution class
template, but without the "_distribution" suffix.
</p>
<p>
</p>
<p>
Suppose we want a set of distributions to behave as follows:
</p>
<p>
</p>
<div class="itemizedlist"><ul type="disc">
<li>
Return infinity on overflow, rather than throwing an exception.
</li>
<li>
Don't perform any promotion from double to long double internally.
</li>
<li>
Return the closest integer result from the quantiles of discrete
distributions.
</li>
</ul></div>
<p>
</p>
<p>
We'll begin by including the needed header for all the distributions:
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">distributions</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></pre>
<p>
</p>
<p>
</p>
<p>
Open up an appropriate namespace, calling it <code class="computeroutput"><span class="identifier">my_distributions</span></code>,
for our distributions, and define the policy type we want. Any policies
we don't specify here will inherit the defaults:
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">my_distributions</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">;</span>
<span class="comment">// using boost::math::policies::errno_on_error; // etc.
</span>
<span class="keyword">typedef</span> <span class="identifier">policy</span><span class="special">&lt;</span>
<span class="comment">// return infinity and set errno rather than throw:
</span> <span class="identifier">overflow_error</span><span class="special">&lt;</span><span class="identifier">errno_on_error</span><span class="special">&gt;,</span>
<span class="comment">// Don't promote double -&gt; long double internally:
</span> <span class="identifier">promote_double</span><span class="special">&lt;</span><span class="keyword">false</span><span class="special">&gt;,</span>
<span class="comment">// Return the closest integer result for discrete quantiles:
</span> <span class="identifier">discrete_quantile</span><span class="special">&lt;</span><span class="identifier">integer_round_nearest</span><span class="special">&gt;</span>
<span class="special">&gt;</span> <span class="identifier">my_policy</span><span class="special">;</span></pre>
<p>
</p>
<p>
</p>
<p>
All we need do now is invoke the BOOST_MATH_DECLARE_DISTRIBUTIONS macro
passing the floating point type <code class="computeroutput"><span class="keyword">double</span></code>
and policy types <code class="computeroutput"><span class="identifier">my_policy</span></code>
as arguments:
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">BOOST_MATH_DECLARE_DISTRIBUTIONS</span><span class="special">(</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">my_policy</span><span class="special">)</span>
<span class="special">}</span> <span class="comment">// close namespace my_namespace</span></pre>
<p>
</p>
<p>
</p>
<p>
We now have a set of typedefs defined in namespace my_distributions that
all look something like this:
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">normal_distribution</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">my_policy</span><span class="special">&gt;</span> <span class="identifier">normal</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">cauchy_distribution</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">my_policy</span><span class="special">&gt;</span> <span class="identifier">cauchy</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gamma_distribution</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">my_policy</span><span class="special">&gt;</span> <span class="identifier">gamma</span><span class="special">;</span>
<span class="comment">// etc
</span></pre>
<p>
</p>
<p>
</p>
<p>
So that when we use my_distributions::normal we really end up using
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">normal_distribution</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">my_policy</span><span class="special">&gt;</span></code>:
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="comment">// Construct distribution with something we know will overflow
</span> <span class="comment">// (using double rather than if promoted to long double):
</span> <span class="identifier">my_distributions</span><span class="special">::</span><span class="identifier">normal</span> <span class="identifier">norm</span><span class="special">(</span><span class="number">10</span><span class="special">,</span> <span class="number">2</span><span class="special">);</span>
<span class="identifier">errno</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of quantile(norm, 0) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">quantile</span><span class="special">(</span><span class="identifier">norm</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span> <span class="comment">// -infinity.
</span> <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"errno = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">errno</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">errno</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of quantile(norm, 1) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">quantile</span><span class="special">(</span><span class="identifier">norm</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span> <span class="comment">// +infinity.
</span> <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"errno = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">errno</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// Now try a discrete distribution.
</span> <span class="identifier">my_distributions</span><span class="special">::</span><span class="identifier">binomial</span> <span class="identifier">binom</span><span class="special">(</span><span class="number">20</span><span class="special">,</span> <span class="number">0.25</span><span class="special">);</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of quantile(binom, 0.05) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">quantile</span><span class="special">(</span><span class="identifier">binom</span><span class="special">,</span> <span class="number">0.05</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span> <span class="comment">// To check we get integer results.
</span> <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of quantile(complement(binom, 0.05)) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">quantile</span><span class="special">(</span><span class="identifier">complement</span><span class="special">(</span><span class="identifier">binom</span><span class="special">,</span> <span class="number">0.05</span><span class="special">))</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span></pre>
<p>
</p>
<p>
</p>
<p>
Which outputs:
</p>
<p>
</p>
<pre class="programlisting">Result of quantile(norm, 0) is: -1.#INF
errno = 34
Result of quantile(norm, 1) is: 1.#INF
errno = 34
Result of quantile(binom, 0.05) is: 1
Result of quantile(complement(binom, 0.05)) is: 8
</pre>
<p>
</p>
<p>
This mechanism is particularly useful when we want to define a project-wide
policy, and don't want to modify the Boost source or set project wide
build macros (possibly fragile and easy to forget).
</p>
<p>
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
There is an important limitation to note: you can *not use the macros
BOOST_MATH_DECLARE_DISTRIBUTIONS and BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS
<span class="emphasis"><em>in the same namespace</em></span>*, as doing so creates ambiguities
between functions and distributions of the same name.
</p></td></tr>
</table></div>
<p>
As before, the same mechanism works well at file scope as well: by using
an unnamed namespace, we can ensure that these declarations don't conflict
with any alternate policies present in other translation units:
</p>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">distributions</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// All distributions.
</span><span class="comment">// using boost::math::normal; // Would create an ambguity between
</span><span class="comment">// boost::math::normal_distribution&lt;RealType&gt; boost::math::normal and
</span><span class="comment">// 'anonymous-namespace'::normal'.
</span>
<span class="keyword">namespace</span>
<span class="special">{</span> <span class="comment">// anonymous or unnnamed (rather than named as in policy_eg_6.cpp).
</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">;</span>
<span class="comment">// using boost::math::policies::errno_on_error; // etc.
</span> <span class="keyword">typedef</span> <span class="identifier">policy</span><span class="special">&lt;</span>
<span class="comment">// return infinity and set errno rather than throw:
</span> <span class="identifier">overflow_error</span><span class="special">&lt;</span><span class="identifier">errno_on_error</span><span class="special">&gt;,</span>
<span class="comment">// Don't promote double -&gt; long double internally:
</span> <span class="identifier">promote_double</span><span class="special">&lt;</span><span class="keyword">false</span><span class="special">&gt;,</span>
<span class="comment">// Return the closest integer result for discrete quantiles:
</span> <span class="identifier">discrete_quantile</span><span class="special">&lt;</span><span class="identifier">integer_round_nearest</span><span class="special">&gt;</span>
<span class="special">&gt;</span> <span class="identifier">my_policy</span><span class="special">;</span>
<span class="identifier">BOOST_MATH_DECLARE_DISTRIBUTIONS</span><span class="special">(</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">my_policy</span><span class="special">)</span>
<span class="special">}</span> <span class="comment">// close namespace my_namespace
</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="comment">// Construct distribution with something we know will overflow.
</span> <span class="identifier">normal</span> <span class="identifier">norm</span><span class="special">(</span><span class="number">10</span><span class="special">,</span> <span class="number">2</span><span class="special">);</span> <span class="comment">// using 'anonymous-namespace'::normal
</span> <span class="identifier">errno</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of quantile(norm, 0) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">quantile</span><span class="special">(</span><span class="identifier">norm</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"errno = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">errno</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">errno</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of quantile(norm, 1) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">quantile</span><span class="special">(</span><span class="identifier">norm</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"errno = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">errno</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="comment">//
</span> <span class="comment">// Now try a discrete distribution:
</span> <span class="identifier">binomial</span> <span class="identifier">binom</span><span class="special">(</span><span class="number">20</span><span class="special">,</span> <span class="number">0.25</span><span class="special">);</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of quantile(binom, 0.05) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">quantile</span><span class="special">(</span><span class="identifier">binom</span><span class="special">,</span> <span class="number">0.05</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Result of quantile(complement(binom, 0.05)) is: "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">quantile</span><span class="special">(</span><span class="identifier">complement</span><span class="special">(</span><span class="identifier">binom</span><span class="special">,</span> <span class="number">0.05</span><span class="special">))</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006 , 2007, 2008, 2009, 2010 John Maddock, Paul A. Bristow,
Hubert Holin, Xiaogang Zhang, Bruno Lalande, Johan R&#229;de, Gautam Sewani and
Thijs van den Berg<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="ad_hoc_sf_policies.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../pol_tutorial.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="user_def_err_pol.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>