improved_numeric_cast__.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Improved numeric_cast&lt;&gt;</title>
  5. <link rel="stylesheet" href="../boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.NumericConversion">
  8. <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.NumericConversion">
  9. <link rel="prev" href="numeric_converter_policy_classes.html" title="Numeric Converter Policy Classes">
  10. <link rel="next" href="../numeric_conversion/history_and_acknowledgments.html" title="History and Acknowledgments">
  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="numeric_converter_policy_classes.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="../numeric_conversion/history_and_acknowledgments.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
  24. </div>
  25. <div class="section">
  26. <div class="titlepage"><div><div><h2 class="title" style="clear: both">
  27. <a name="boost_numericconversion.improved_numeric_cast__"></a><a class="link" href="improved_numeric_cast__.html" title="Improved numeric_cast&lt;&gt;">Improved
  28. numeric_cast&lt;&gt;</a>
  29. </h2></div></div></div>
  30. <div class="toc"><dl class="toc">
  31. <dt><span class="section"><a href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.introduction">Introduction</a></span></dt>
  32. <dt><span class="section"><a href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast">numeric_cast</a></span></dt>
  33. <dt><span class="section"><a href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast_traits">numeric_cast_traits</a></span></dt>
  34. <dt><span class="section"><a href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.examples">Examples</a></span></dt>
  35. </dl></div>
  36. <div class="section">
  37. <div class="titlepage"><div><div><h3 class="title">
  38. <a name="boost_numericconversion.improved_numeric_cast__.introduction"></a><a class="link" href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.introduction" title="Introduction">Introduction</a>
  39. </h3></div></div></div>
  40. <p>
  41. The lack of preservation of range makes conversions between numeric types
  42. error prone. This is true for both implicit conversions and explicit conversions
  43. (through <code class="computeroutput"><span class="keyword">static_cast</span></code>). <a class="link" href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast" title="numeric_cast"><code class="computeroutput"><span class="identifier">numeric_cast</span></code></a> detects loss of range
  44. when a numeric type is converted, and throws an exception if the range cannot
  45. be preserved.
  46. </p>
  47. <p>
  48. There are several situations where conversions are unsafe:
  49. </p>
  50. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  51. <li class="listitem">
  52. Conversions from an integral type with a wider range than the target
  53. integral type.
  54. </li>
  55. <li class="listitem">
  56. Conversions from unsigned to signed (and vice versa) integral types.
  57. </li>
  58. <li class="listitem">
  59. Conversions from floating point types to integral types.
  60. </li>
  61. </ul></div>
  62. <p>
  63. The C++ Standard does not specify the behavior when a numeric type is assigned
  64. a value that cannot be represented by the type, except for unsigned integral
  65. types [3.9.1.4], which must obey the laws of arithmetic modulo 2n (this implies
  66. that the result will be reduced modulo the number that is one greater than
  67. the largest value that can be represented). The fact that the behavior for
  68. overflow is undefined for all conversions (except the aforementioned unsigned
  69. to unsigned) makes any code that may produce positive or negative overflows
  70. exposed to portability issues.
  71. </p>
  72. <p>
  73. By default <code class="computeroutput"><span class="identifier">numeric_cast</span></code> adheres
  74. to the rules for implicit conversions mandated by the C++ Standard, such
  75. as truncating floating point types when converting to integral types. The
  76. implementation must guarantee that for a conversion to a type that can hold
  77. all possible values of the source type, there will be no runtime overhead.
  78. </p>
  79. </div>
  80. <div class="section">
  81. <div class="titlepage"><div><div><h3 class="title">
  82. <a name="boost_numericconversion.improved_numeric_cast__.numeric_cast"></a><a class="link" href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast" title="numeric_cast">numeric_cast</a>
  83. </h3></div></div></div>
  84. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Target</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Source</span><span class="special">&gt;</span> <span class="keyword">inline</span>
  85. <span class="identifier">Target</span> <span class="identifier">numeric_cast</span><span class="special">(</span> <span class="identifier">Source</span> <span class="identifier">arg</span> <span class="special">)</span>
  86. <span class="special">{</span>
  87. <span class="keyword">typedef</span> <span class="identifier">conversion_traits</span><span class="special">&lt;</span><span class="identifier">Target</span><span class="special">,</span> <span class="identifier">Source</span><span class="special">&gt;</span> <span class="identifier">conv_traits</span><span class="special">;</span>
  88. <span class="keyword">typedef</span> <span class="identifier">numeric_cast_traits</span><span class="special">&lt;</span><span class="identifier">Target</span><span class="special">,</span> <span class="identifier">Source</span><span class="special">&gt;</span> <span class="identifier">cast_traits</span><span class="special">;</span>
  89. <span class="keyword">typedef</span> <span class="identifier">converter</span>
  90. <span class="special">&lt;</span>
  91. <span class="identifier">Target</span><span class="special">,</span>
  92. <span class="identifier">Source</span><span class="special">,</span>
  93. <span class="identifier">conv_traits</span><span class="special">,</span>
  94. <span class="keyword">typename</span> <span class="identifier">cast_traits</span><span class="special">::</span><span class="identifier">overflow_policy</span><span class="special">,</span>
  95. <span class="keyword">typename</span> <span class="identifier">cast_traits</span><span class="special">::</span><span class="identifier">rounding_policy</span><span class="special">,</span>
  96. <span class="identifier">raw_converter</span><span class="special">&lt;</span><span class="identifier">conv_traits</span><span class="special">&gt;,</span>
  97. <span class="keyword">typename</span> <span class="identifier">cast_traits</span><span class="special">::</span><span class="identifier">range_checking_policy</span>
  98. <span class="special">&gt;</span> <span class="identifier">converter</span><span class="special">;</span>
  99. <span class="keyword">return</span> <span class="identifier">converter</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="identifier">arg</span><span class="special">);</span>
  100. <span class="special">}</span>
  101. </pre>
  102. <p>
  103. <code class="computeroutput"><span class="identifier">numeric_cast</span></code> returns the
  104. result of converting a value of type Source to a value of type Target. If
  105. out-of-range is detected, an overflow policy is executed whose default behavior
  106. is to throw an an exception (see <a class="link" href="numeric_converter_policy_classes.html#numeric_conversion_bad_numeric_cast">bad_numeric_cast</a>,
  107. <a class="link" href="numeric_converter_policy_classes.html#numeric_conversion_negative_overflow">negative_overflow</a>
  108. and <a class="link" href="numeric_converter_policy_classes.html#numeric_conversion_possitive_overflow">positive_overflow</a>
  109. ).
  110. </p>
  111. </div>
  112. <div class="section">
  113. <div class="titlepage"><div><div><h3 class="title">
  114. <a name="boost_numericconversion.improved_numeric_cast__.numeric_cast_traits"></a><a class="link" href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.numeric_cast_traits" title="numeric_cast_traits">numeric_cast_traits</a>
  115. </h3></div></div></div>
  116. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Target</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Source</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">EnableIf</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">&gt;</span>
  117. <span class="keyword">struct</span> <span class="identifier">numeric_cast_traits</span>
  118. <span class="special">{</span>
  119. <span class="keyword">typedef</span> <span class="identifier">def_overflow_handler</span> <span class="identifier">overflow_policy</span><span class="special">;</span>
  120. <span class="keyword">typedef</span> <span class="identifier">UseInternalRangeChecker</span> <span class="identifier">range_checking_policy</span><span class="special">;</span>
  121. <span class="keyword">typedef</span> <span class="identifier">Trunc</span><span class="special">&lt;</span><span class="identifier">Source</span><span class="special">&gt;</span> <span class="identifier">rounding_policy</span><span class="special">;</span>
  122. <span class="special">};</span>
  123. </pre>
  124. <p>
  125. The behavior of <code class="computeroutput"><span class="identifier">numeric_cast</span></code>
  126. may be tailored for custom numeric types through the specialization of <code class="computeroutput"><span class="identifier">numeric_cast_traits</span></code>. (see <a class="link" href="type_requirements_and_user_defined_types_support.html" title="Type Requirements and User-defined-types support">User
  127. Defined Types</a> for details. )
  128. </p>
  129. </div>
  130. <div class="section">
  131. <div class="titlepage"><div><div><h3 class="title">
  132. <a name="boost_numericconversion.improved_numeric_cast__.examples"></a><a class="link" href="improved_numeric_cast__.html#boost_numericconversion.improved_numeric_cast__.examples" title="Examples">Examples</a>
  133. </h3></div></div></div>
  134. <p>
  135. The following example performs some typical conversions between numeric types:
  136. </p>
  137. <div class="orderedlist"><ol class="orderedlist" type="1">
  138. <li class="listitem">
  139. include &lt;boost/numeric/conversion/cast.hpp&gt;
  140. </li>
  141. <li class="listitem">
  142. include &lt;iostream&gt;
  143. </li>
  144. </ol></div>
  145. <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
  146. <span class="special">{</span>
  147. <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric_cast</span><span class="special">;</span>
  148. <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">bad_numeric_cast</span><span class="special">;</span>
  149. <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">positive_overflow</span><span class="special">;</span>
  150. <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">::</span><span class="identifier">negative_overflow</span><span class="special">;</span>
  151. <span class="keyword">try</span>
  152. <span class="special">{</span>
  153. <span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">42</span><span class="special">;</span>
  154. <span class="keyword">short</span> <span class="identifier">s</span><span class="special">=</span><span class="identifier">numeric_cast</span><span class="special">&lt;</span><span class="keyword">short</span><span class="special">&gt;(</span><span class="identifier">i</span><span class="special">);</span> <span class="comment">// This conversion succeeds (is in range)</span>
  155. <span class="special">}</span>
  156. <span class="keyword">catch</span><span class="special">(</span><span class="identifier">negative_overflow</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
  157. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">();</span>
  158. <span class="special">}</span>
  159. <span class="keyword">catch</span><span class="special">(</span><span class="identifier">positive_overflow</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
  160. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">();</span>
  161. <span class="special">}</span>
  162. <span class="keyword">try</span>
  163. <span class="special">{</span>
  164. <span class="keyword">float</span> <span class="identifier">f</span><span class="special">=-</span><span class="number">42.1234</span><span class="special">;</span>
  165. <span class="comment">// This will cause a boost::numeric::negative_overflow exception to be thrown</span>
  166. <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="identifier">numeric_cast</span><span class="special">&lt;</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">);</span>
  167. <span class="special">}</span>
  168. <span class="keyword">catch</span><span class="special">(</span><span class="identifier">bad_numeric_cast</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
  169. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">();</span>
  170. <span class="special">}</span>
  171. <span class="keyword">double</span> <span class="identifier">d</span><span class="special">=</span> <span class="identifier">f</span> <span class="special">+</span> <span class="identifier">numeric_cast</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</span><span class="number">123</span><span class="special">);</span> <span class="comment">// int -&gt; double</span>
  172. <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="identifier">l</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="keyword">unsigned</span> <span class="keyword">long</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">();</span>
  173. <span class="keyword">try</span>
  174. <span class="special">{</span>
  175. <span class="comment">// This will cause a boost::numeric::positive_overflow exception to be thrown</span>
  176. <span class="comment">// NOTE: *operations* on unsigned integral types cannot cause overflow</span>
  177. <span class="comment">// but *conversions* to a signed type ARE range checked by numeric_cast.</span>
  178. <span class="keyword">unsigned</span> <span class="keyword">char</span> <span class="identifier">c</span><span class="special">=</span><span class="identifier">numeric_cast</span><span class="special">&lt;</span><span class="keyword">unsigned</span> <span class="keyword">char</span><span class="special">&gt;(</span><span class="identifier">l</span><span class="special">);</span>
  179. <span class="special">}</span>
  180. <span class="keyword">catch</span><span class="special">(</span><span class="identifier">positive_overflow</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
  181. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">();</span>
  182. <span class="special">}</span>
  183. <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
  184. <span class="special">}</span>
  185. </pre>
  186. </div>
  187. </div>
  188. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  189. <td align="left"></td>
  190. <td align="right"><div class="copyright-footer">Copyright &#169; 2004-2007 Fernando
  191. Luis Cacciola Carballal<p>
  192. Distributed under the Boost Software License, Version 1.0. (See accompanying
  193. 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>)
  194. </p>
  195. </div></td>
  196. </tr></table>
  197. <hr>
  198. <div class="spirit-nav">
  199. <a accesskey="p" href="numeric_converter_policy_classes.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="../numeric_conversion/history_and_acknowledgments.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
  200. </div>
  201. </body>
  202. </html>