Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / math / doc / html / math_toolkit / tutorial / user_def.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Use With User-Defined Types</title>
5 <link rel="stylesheet" href="../../math.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7 <link rel="home" href="../../index.html" title="Math Toolkit 2.11.0">
8 <link rel="up" href="../tutorial.html" title="Tutorial">
9 <link rel="prev" href="templ.html" title="Use in template code">
10 <link rel="next" href="../constants.html" title="The Mathematical Constants">
11 </head>
12 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13 <table cellpadding="2" width="100%"><tr>
14 <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
15 <td align="center"><a href="../../../../../../index.html">Home</a></td>
16 <td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
17 <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18 <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19 <td align="center"><a href="../../../../../../more/index.htm">More</a></td>
20 </tr></table>
21 <hr>
22 <div class="spirit-nav">
23 <a accesskey="p" href="templ.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../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="../constants.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
24 </div>
25 <div class="section">
26 <div class="titlepage"><div><div><h3 class="title">
27 <a name="math_toolkit.tutorial.user_def"></a><a class="link" href="user_def.html" title="Use With User-Defined Types">Use With User-Defined
28       Types</a>
29 </h3></div></div></div>
30 <p>
31         The most common example of a high-precision user-defined type will probably
32         be <a href="../../../../../../libs/multiprecision/doc/html/index.html" target="_top">Boost.Multiprecision</a>.
33       </p>
34 <p>
35         The syntax for using the function-call constants with user-defined types
36         is the same as it is in the template class, which is to say we use:
37       </p>
38 <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">constants</span><span class="special">/</span><span class="identifier">constants</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
39
40 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">constants</span><span class="special">::</span><span class="identifier">pi</span><span class="special">&lt;</span><span class="identifier">UserDefinedType</span><span class="special">&gt;();</span>
41 </pre>
42 <p>
43         For example:
44       </p>
45 <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">constants</span><span class="special">::</span><span class="identifier">pi</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_dec_float_50</span><span class="special">&gt;();</span>
46 </pre>
47 <p>
48         giving &#960; with a precision of 50 decimal digits.
49       </p>
50 <p>
51         However, since the precision of the user-defined type may be much greater
52         than that of the built-in floating point types, how the value returned is
53         created is as follows:
54       </p>
55 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
56 <li class="listitem">
57             If the precision of the type is known at compile time:
58             <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
59 <li class="listitem">
60                   If the precision is less than or equal to that of a <code class="computeroutput"><span class="keyword">float</span></code> and the type is constructable
61                   from a <code class="computeroutput"><span class="keyword">float</span></code> then
62                   our code returns a <code class="computeroutput"><span class="keyword">float</span></code>
63                   literal. If the user-defined type is a literal type then the function
64                   call that returns the constant will be a <code class="computeroutput"><span class="identifier">constexp</span></code>.
65                 </li>
66 <li class="listitem">
67                   If the precision is less than or equal to that of a <code class="computeroutput"><span class="keyword">double</span></code> and the type is constructable
68                   from a <code class="computeroutput"><span class="keyword">double</span></code> then
69                   our code returns a <code class="computeroutput"><span class="keyword">double</span></code>
70                   literal. If the user-defined type is a literal type then the function
71                   call that returns the constant will be a <code class="computeroutput"><span class="identifier">constexp</span></code>.
72                 </li>
73 <li class="listitem">
74                   If the precision is less than or equal to that of a <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">double</span></code>
75                   and the type is constructable from a <code class="computeroutput"><span class="keyword">long</span>
76                   <span class="keyword">double</span></code> then our code returns
77                   a <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">double</span></code>
78                   literal. If the user-defined type is a literal type then the function
79                   call that returns the constant will be a <code class="computeroutput"><span class="identifier">constexp</span></code>.
80                 </li>
81 <li class="listitem">
82                   If the precision is less than or equal to that of a <code class="computeroutput"><span class="identifier">__float128</span></code> (and the compiler
83                   supports such a type) and the type is constructable from a <code class="computeroutput"><span class="identifier">__float128</span></code> then our code returns
84                   a <code class="computeroutput"><span class="identifier">__float128</span></code> literal.
85                   If the user-defined type is a literal type then the function call
86                   that returns the constant will be a <code class="computeroutput"><span class="identifier">constexp</span></code>.
87                 </li>
88 <li class="listitem">
89                   If the precision is less than 100 decimal digits, then the constant
90                   will be constructed (just the once, then cached in a thread-safe
91                   manner) from a string representation of the constant. In this case
92                   the value is returned as a const reference to the cached value.
93                 </li>
94 <li class="listitem">
95                   Otherwise the value is computed (just once, then cached in a thread-safe
96                   manner). In this case the value is returned as a const reference
97                   to the cached value.
98                 </li>
99 </ul></div>
100           </li>
101 <li class="listitem">
102             If the precision is unknown at compile time then:
103             <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
104 <li class="listitem">
105                   If the runtime precision (obtained from a call to <code class="computeroutput"><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">digits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;()</span></code>)
106                   is less than 100 decimal digits, then the constant is constructed
107                   "on the fly" from the string representation of the constant.
108                 </li>
109 <li class="listitem">
110                   Otherwise the value is constructed "on the fly" by calculating
111                   then value of the constant using the current default precision
112                   of the type. Note that this can make use of the constants rather
113                   expensive.
114                 </li>
115 </ul></div>
116           </li>
117 </ul></div>
118 <p>
119         In addition, it is possible to pass a <code class="computeroutput"><span class="identifier">Policy</span></code>
120         type as a second template argument, and use this to control the precision:
121       </p>
122 <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">constants</span><span class="special">/</span><span class="identifier">constants</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
123
124 <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">policies</span><span class="special">::</span><span class="identifier">policy</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">policies</span><span class="special">::</span><span class="identifier">digits2</span><span class="special">&lt;</span><span class="number">80</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">my_policy_type</span><span class="special">;</span>
125 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">constants</span><span class="special">::</span><span class="identifier">pi</span><span class="special">&lt;</span><span class="identifier">MyType</span><span class="special">,</span> <span class="identifier">my_policy_type</span><span class="special">&gt;();</span>
126 </pre>
127 <div class="note"><table border="0" summary="Note">
128 <tr>
129 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
130 <th align="left">Note</th>
131 </tr>
132 <tr><td align="left" valign="top"><p>
133           Boost.Math doesn't know how to control the internal precision of <code class="computeroutput"><span class="identifier">MyType</span></code>, the policy just controls how
134           the selection process above is carried out, and the calculation precision
135           if the result is computed.
136         </p></td></tr>
137 </table></div>
138 <p>
139         It is also possible to control which method is used to construct the constant
140         by specialising the traits class <code class="computeroutput"><span class="identifier">construction_traits</span></code>:
141       </p>
142 <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">constant</span><span class="special">{</span>
143
144 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Policy</span><span class="special">&gt;</span>
145 <span class="keyword">struct</span> <span class="identifier">construction_traits</span>
146 <span class="special">{</span>
147    <span class="keyword">typedef</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">int_</span><span class="special">&lt;</span><span class="identifier">N</span><span class="special">&gt;</span> <span class="identifier">type</span><span class="special">;</span>
148 <span class="special">};</span>
149
150 <span class="special">}}}</span> <span class="comment">// namespaces</span>
151 </pre>
152 <p>
153         Where <span class="emphasis"><em>N</em></span> takes one of the following values:
154       </p>
155 <div class="informaltable"><table class="table">
156 <colgroup>
157 <col>
158 <col>
159 </colgroup>
160 <thead><tr>
161 <th>
162                 <p>
163                   <span class="emphasis"><em>N</em></span>
164                 </p>
165               </th>
166 <th>
167                 <p>
168                   Meaning
169                 </p>
170               </th>
171 </tr></thead>
172 <tbody>
173 <tr>
174 <td>
175                 <p>
176                   0
177                 </p>
178               </td>
179 <td>
180                 <p>
181                   The precision is unavailable at compile time; either construct
182                   from a decimal digit string or calculate on the fly depending upon
183                   the runtime precision.
184                 </p>
185               </td>
186 </tr>
187 <tr>
188 <td>
189                 <p>
190                   1
191                 </p>
192               </td>
193 <td>
194                 <p>
195                   Return a float precision constant.
196                 </p>
197               </td>
198 </tr>
199 <tr>
200 <td>
201                 <p>
202                   2
203                 </p>
204               </td>
205 <td>
206                 <p>
207                   Return a double precision constant.
208                 </p>
209               </td>
210 </tr>
211 <tr>
212 <td>
213                 <p>
214                   3
215                 </p>
216               </td>
217 <td>
218                 <p>
219                   Return a long double precision constant.
220                 </p>
221               </td>
222 </tr>
223 <tr>
224 <td>
225                 <p>
226                   4
227                 </p>
228               </td>
229 <td>
230                 <p>
231                   Construct the result from the string representation, and cache
232                   the result.
233                 </p>
234               </td>
235 </tr>
236 <tr>
237 <td>
238                 <p>
239                   Any other value <span class="emphasis"><em>N</em></span>
240                 </p>
241               </td>
242 <td>
243                 <p>
244                   Sets the compile time precision to <span class="emphasis"><em>N</em></span> bits.
245                 </p>
246               </td>
247 </tr>
248 </tbody>
249 </table></div>
250 <h6>
251 <a name="math_toolkit.tutorial.user_def.h0"></a>
252         <span class="phrase"><a name="math_toolkit.tutorial.user_def.custom_specializing_a_constant"></a></span><a class="link" href="user_def.html#math_toolkit.tutorial.user_def.custom_specializing_a_constant">Custom
253         Specializing a constant</a>
254       </h6>
255 <p>
256         In addition, for user-defined types that need special handling, it's possible
257         to partially-specialize the internal structure used by each constant. For
258         example, suppose we're using the C++ wrapper around MPFR <code class="computeroutput"><span class="identifier">mpfr_class</span></code>:
259         this has its own representation of Pi which we may well wish to use in place
260         of the above mechanism. We can achieve this by specialising the class template
261         <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">constants</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">constant_pi</span></code>:
262       </p>
263 <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">constants</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">detail</span><span class="special">{</span>
264
265 <span class="keyword">template</span><span class="special">&lt;&gt;</span>
266 <span class="keyword">struct</span> <span class="identifier">constant_pi</span><span class="special">&lt;</span><span class="identifier">mpfr_class</span><span class="special">&gt;</span>
267 <span class="special">{</span>
268    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">&gt;</span>
269    <span class="keyword">static</span> <span class="identifier">mpfr_class</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">int_</span><span class="special">&lt;</span><span class="identifier">N</span><span class="special">&gt;&amp;)</span>
270    <span class="special">{</span>
271       <span class="comment">// The template param N is one of the values in the table above,</span>
272       <span class="comment">// we can either handle all cases in one as is the case here,</span>
273       <span class="comment">// or overload "get" for the different options.</span>
274       <span class="identifier">mpfr_class</span> <span class="identifier">result</span><span class="special">;</span>
275       <span class="identifier">mpfr_const_pi</span><span class="special">(</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">get_mpfr_t</span><span class="special">(),</span> <span class="identifier">GMP_RNDN</span><span class="special">);</span>
276       <span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
277    <span class="special">}</span>
278 <span class="special">};</span>
279
280 <span class="special">}}}}</span> <span class="comment">// namespaces</span>
281 </pre>
282 <h6>
283 <a name="math_toolkit.tutorial.user_def.h1"></a>
284         <span class="phrase"><a name="math_toolkit.tutorial.user_def.diagnosing_what_meta_programmed_"></a></span><a class="link" href="user_def.html#math_toolkit.tutorial.user_def.diagnosing_what_meta_programmed_">Diagnosing
285         what meta-programmed code is doing</a>
286       </h6>
287 <p>
288         Finally, since it can be tricky to diagnose what meta-programmed code is
289         doing, there is a diagnostic routine that prints information about how this
290         library will handle a specific type, it can be used like this:
291       </p>
292 <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">constants</span><span class="special">/</span><span class="identifier">info</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
293
294 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
295 <span class="special">{</span>
296    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">constants</span><span class="special">::</span><span class="identifier">print_info_on_type</span><span class="special">&lt;</span><span class="identifier">MyType</span><span class="special">&gt;();</span>
297 <span class="special">}</span>
298 </pre>
299 <p>
300         If you wish, you can also pass an optional std::ostream argument to the
301         <code class="computeroutput"><span class="identifier">print_info_on_type</span></code> function.
302         Typical output for a user-defined type looks like this:
303       </p>
304 <pre class="programlisting">Information on the Implementation and Handling of
305 Mathematical Constants for Type class boost::math::concepts::real_concept
306
307 Checking for std::numeric_limits&lt;class boost::math::concepts::real_concept&gt; specialisation: no
308 boost::math::policies::precision&lt;class boost::math::concepts::real_concept, Policy&gt;
309 reports that there is no compile type precision available.
310 boost::math::tools::digits&lt;class boost::math::concepts::real_concept&gt;()
311 reports that the current runtime precision is
312 53 binary digits.
313 No compile time precision is available, the construction method
314 will be decided at runtime and results will not be cached
315 - this may lead to poor runtime performance.
316 Current runtime precision indicates that
317 the constant will be constructed from a string on each call.
318 </pre>
319 </div>
320 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
321 <td align="left"></td>
322 <td align="right"><div class="copyright-footer">Copyright &#169; 2006-2019 Nikhar
323       Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
324       Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Matthew Pulver, Johan
325       R&#229;de, Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg,
326       Daryle Walker and Xiaogang Zhang<p>
327         Distributed under the Boost Software License, Version 1.0. (See accompanying
328         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>)
329       </p>
330 </div></td>
331 </tr></table>
332 <hr>
333 <div class="spirit-nav">
334 <a accesskey="p" href="templ.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../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="../constants.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
335 </div>
336 </body>
337 </html>