1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 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.12.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"><</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">boost</span><span class="special">::</span><span class="identifier">integral_constant</span><span class="special"><</span><span class="keyword">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">boost</span><span class="special">::</span><span class="identifier">integral_constant</span><span class="special"><</span><span class="keyword">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 305Mathematical Constants for Type class boost::math::concepts::real_concept 306 307Checking for std::numeric_limits<class boost::math::concepts::real_concept> specialisation: no 308boost::math::policies::precision<class boost::math::concepts::real_concept, Policy> 309reports that there is no compile type precision available. 310boost::math::tools::digits<class boost::math::concepts::real_concept>() 311reports that the current runtime precision is 31253 binary digits. 313No compile time precision is available, the construction method 314will be decided at runtime and results will not be cached 315- this may lead to poor runtime performance. 316Current runtime precision indicates that 317the 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-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å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> 338