]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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.77.1"> | |
7 | <link rel="home" href="../../index.html" title="Math Toolkit 2.5.1"> | |
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"><</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">></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"><</span><span class="identifier">UserDefinedType</span><span class="special">>();</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"><</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">>();</span> | |
46 | </pre> | |
47 | <p> | |
48 | giving π 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"><</span><span class="identifier">T</span><span class="special">>()</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"><</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">></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"><</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"><</span><span class="number">80</span><span class="special">></span> <span class="special">></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"><</span><span class="identifier">MyType</span><span class="special">,</span> <span class="identifier">my_policy_type</span><span class="special">>();</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"><</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">></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"><</span><span class="identifier">N</span><span class="special">></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"><></span> | |
266 | <span class="keyword">struct</span> <span class="identifier">constant_pi</span><span class="special"><</span><span class="identifier">mpfr_class</span><span class="special">></span> | |
267 | <span class="special">{</span> | |
268 | <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">></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"><</span><span class="identifier">N</span><span class="special">>&)</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"><</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">></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"><</span><span class="identifier">MyType</span><span class="special">>();</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<class boost::math::concepts::real_concept> specialisation: no | |
308 | boost::math::policies::precision<class boost::math::concepts::real_concept, Policy> | |
309 | reports that there is no compile type precision available. | |
310 | boost::math::tools::digits<class boost::math::concepts::real_concept>() | |
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 © 2006-2010, 2012-2014 Nikhar Agrawal, | |
323 | Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert | |
324 | Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani, | |
325 | Benjamin Sobotta, Thijs van den Berg, Daryle Walker and Xiaogang Zhang<p> | |
326 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
327 | 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>) | |
328 | </p> | |
329 | </div></td> | |
330 | </tr></table> | |
331 | <hr> | |
332 | <div class="spirit-nav"> | |
333 | <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> | |
334 | </div> | |
335 | </body> | |
336 | </html> |