numeric_concept.xml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.1//EN"
  3. "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
  4. <section id="safe_numerics.numeric">
  5. <title>Numeric&lt;T&gt;</title>
  6. <?dbhtml stop-chunking?>
  7. <section id="safe_numerics.numeric.description">
  8. <title>Description</title>
  9. <para>A type is Numeric if it has the properties of a number.</para>
  10. <para>More specifically, a type T is Numeric if there exists a
  11. specialization of <code>std::numeric_limits&lt;T&gt;</code>. See the
  12. documentation for the standard library class <code>numeric_limits</code>.
  13. The standard library includes such specializations for all the built-in
  14. numeric types. Note that this concept is distinct from the C++ standard
  15. library type traits <code>is_integral</code> and
  16. <code>is_arithmetic</code>. These latter fulfill the requirement of the
  17. concept Numeric. But there are types T which fulfill this concept for
  18. which <code>is_arithmetic&lt;T&gt;::value == false</code>. For example see
  19. <code>safe_signed_integer&lt;int&gt;</code>.</para>
  20. </section>
  21. <section>
  22. <title>Notation</title>
  23. <informaltable>
  24. <tgroup cols="2" colsep="1" rowsep="1">
  25. <colspec align="left"/>
  26. <colspec align="left" colwidth="3*"/>
  27. <tbody>
  28. <row>
  29. <entry><code>T, U, V</code></entry>
  30. <entry>A type that is a model of Numeric</entry>
  31. </row>
  32. <row>
  33. <entry><code>t, u</code></entry>
  34. <entry>An object of a type modeling Numeric</entry>
  35. </row>
  36. </tbody>
  37. </tgroup>
  38. </informaltable>
  39. </section>
  40. <section>
  41. <title>Associated Types</title>
  42. <informaltable>
  43. <tgroup cols="2">
  44. <colspec align="left"/>
  45. <colspec align="left" colwidth="3*"/>
  46. <tbody>
  47. <row>
  48. <entry><code>std::numeric_limits&lt;T&gt;</code></entry>
  49. <entry>The numeric_limits class template provides a C++ program
  50. with information about various properties of the implementation's
  51. representation of the arithmetic types. See C++ standard
  52. 18.3.2.2.</entry>
  53. </row>
  54. </tbody>
  55. </tgroup>
  56. </informaltable>
  57. </section>
  58. <section>
  59. <title>Valid Expressions</title>
  60. <para>In addition to the expressions defined in <ulink
  61. url="http://www.sgi.com/tech/stl/Assignable.html">Assignable</ulink> the
  62. following expressions must be valid. Any operations which result in
  63. integers which cannot be represented as some Numeric type will throw an
  64. exception.<table>
  65. <title>General</title>
  66. <tgroup cols="3">
  67. <colspec align="left" colwidth="2*"/>
  68. <colspec align="left" colwidth="1*"/>
  69. <colspec align="left" colwidth="2*"/>
  70. <thead>
  71. <row>
  72. <entry align="left">Expression</entry>
  73. <entry>Return Type</entry>
  74. <entry>Return Value</entry>
  75. </row>
  76. </thead>
  77. <tbody>
  78. <row>
  79. <entry><code>std::numeric_limits&lt;T&gt;::is_bounded
  80. </code></entry>
  81. <entry><code>bool</code></entry>
  82. <entry><code>true</code> or <code>false</code></entry>
  83. </row>
  84. <row>
  85. <entry><code>std::numeric_limits&lt;T&gt;::is_integer</code></entry>
  86. <entry><code>bool</code></entry>
  87. <entry><code>true</code> or <code>false</code></entry>
  88. </row>
  89. <row>
  90. <entry><code>std::numeric_limits&lt;T&gt;::is_signed</code></entry>
  91. <entry><code>bool</code></entry>
  92. <entry><code>true</code> or <code>false</code></entry>
  93. </row>
  94. <row>
  95. <entry><code>std::numeric_limits&lt;T&gt;::is_specialized
  96. </code></entry>
  97. <entry><code>bool</code></entry>
  98. <entry><code>true</code></entry>
  99. </row>
  100. </tbody>
  101. </tgroup>
  102. </table></para>
  103. <table>
  104. <title>Unary Operators</title>
  105. <tgroup cols="3">
  106. <colspec align="left"/>
  107. <colspec align="left"/>
  108. <colspec align="left" colwidth="3*"/>
  109. <thead>
  110. <row>
  111. <entry align="left">Expression</entry>
  112. <entry>Return Type</entry>
  113. <entry>Semantics</entry>
  114. </row>
  115. </thead>
  116. <tbody>
  117. <row>
  118. <entry><code>-t</code></entry>
  119. <entry><code>T</code></entry>
  120. <entry>Invert sign</entry>
  121. </row>
  122. <row>
  123. <entry><code>+t</code></entry>
  124. <entry><code>T</code></entry>
  125. <entry>unary plus - a no op</entry>
  126. </row>
  127. <row>
  128. <entry><code>t--</code></entry>
  129. <entry><code>T</code></entry>
  130. <entry>post decrement</entry>
  131. </row>
  132. <row>
  133. <entry><code>t++</code></entry>
  134. <entry><code>T</code></entry>
  135. <entry>post increment</entry>
  136. </row>
  137. <row>
  138. <entry><code>--t</code></entry>
  139. <entry><code>T</code></entry>
  140. <entry>pre decrement</entry>
  141. </row>
  142. <row>
  143. <entry><code>++t</code></entry>
  144. <entry><code>T</code></entry>
  145. <entry>pre increment</entry>
  146. </row>
  147. </tbody>
  148. </tgroup>
  149. </table>
  150. <table>
  151. <title>Binary Operators</title>
  152. <tgroup cols="3">
  153. <colspec align="left"/>
  154. <colspec align="left"/>
  155. <colspec align="left" colwidth="3*"/>
  156. <thead>
  157. <row>
  158. <entry align="left">Expression</entry>
  159. <entry>Return Type</entry>
  160. <entry>Semantics</entry>
  161. </row>
  162. </thead>
  163. <tbody>
  164. <row>
  165. <entry><code>t - u</code></entry>
  166. <entry><code>V</code></entry>
  167. <entry>subtract u from t</entry>
  168. </row>
  169. <row>
  170. <entry><code>t + u</code></entry>
  171. <entry><code>V</code></entry>
  172. <entry>add u to t</entry>
  173. </row>
  174. <row>
  175. <entry><code>t * u</code></entry>
  176. <entry><code>V</code></entry>
  177. <entry>multiply t by u</entry>
  178. </row>
  179. <row>
  180. <entry><code>t / u</code></entry>
  181. <entry><code>T</code></entry>
  182. <entry>divide t by u</entry>
  183. </row>
  184. <row>
  185. <entry><code>t % u</code></entry>
  186. <entry><code>T</code></entry>
  187. <entry>t modulus u</entry>
  188. </row>
  189. <row>
  190. <entry><code>t &lt; u</code></entry>
  191. <entry><code>bool</code></entry>
  192. <entry><code>true</code> if t less than u, <code>false</code>
  193. otherwise</entry>
  194. </row>
  195. <row>
  196. <entry><code>t &lt;= u</code></entry>
  197. <entry><code>bool</code></entry>
  198. <entry><code>true</code> if t less than or equal to u,
  199. <code>false</code> otherwise</entry>
  200. </row>
  201. <row>
  202. <entry><code>t &gt; u</code></entry>
  203. <entry><code>bool</code></entry>
  204. <entry><code>true</code> if t greater than u, <code>false</code>
  205. otherwise</entry>
  206. </row>
  207. <row>
  208. <entry><code>t &gt;= u</code></entry>
  209. <entry><code>bool</code></entry>
  210. <entry><code>true</code> if t greater than or equal to u,
  211. <code>false</code> otherwise</entry>
  212. </row>
  213. <row>
  214. <entry><code>t == u</code></entry>
  215. <entry><code>bool</code></entry>
  216. <entry><code>true</code> if t equal to u, <code>false</code>
  217. otherwise</entry>
  218. </row>
  219. <row>
  220. <entry><code>t != u</code></entry>
  221. <entry><code>bool</code></entry>
  222. <entry><code>true</code> if t not equal to u, <code>false</code>
  223. otherwise</entry>
  224. </row>
  225. <row>
  226. <entry><code>t = u</code></entry>
  227. <entry><code><code>T</code></code></entry>
  228. <entry>assign value of u to t</entry>
  229. </row>
  230. <row>
  231. <entry><code>t += u</code></entry>
  232. <entry><code><code>T</code></code></entry>
  233. <entry>add u to t and assign to t</entry>
  234. </row>
  235. <row>
  236. <entry><code>t -= u</code></entry>
  237. <entry><code><code>T</code></code></entry>
  238. <entry>subtract u from t and assign to t</entry>
  239. </row>
  240. <row>
  241. <entry><code>t *= u</code></entry>
  242. <entry><code><code>T</code></code></entry>
  243. <entry>multiply t by u and assign to t</entry>
  244. </row>
  245. <row>
  246. <entry><code>t /= u</code></entry>
  247. <entry><code><code>T</code></code></entry>
  248. <entry>divide t by u and assign to t</entry>
  249. </row>
  250. </tbody>
  251. </tgroup>
  252. </table>
  253. </section>
  254. <section>
  255. <title>Models</title>
  256. <para><code>int, float, safe_signed_integer&lt;int&gt;,
  257. safe_signed_range&lt;int&gt;, checked_result&lt;int&gt;,
  258. etc.</code></para>
  259. </section>
  260. <section>
  261. <title>Header</title>
  262. <para><ulink
  263. url="../../include/boost/safe_numerics/concept/numeric.hpp"><code>#include
  264. &lt;boost/numeric/safe_numerics/concepts/numeric.hpp&gt;
  265. </code></ulink></para>
  266. </section>
  267. <section>
  268. <title>Note on Usage of <code>std::numeric_limits</code></title>
  269. <para>We define the word "Numeric" in terms of the operations which are
  270. supported by "Numeric" types. This is in line with the current and
  271. historical usage of the word "concept" in the context of C++. It is also
  272. common to define compile time predicates such as
  273. "<code>is_numeric&lt;T&gt;</code>" to permit one to include expressions in
  274. his code which will generated a compile time error if the specified type
  275. (T) does not support the operations required. But this is not always true.
  276. In the C++ standard library there is a predicate
  277. <code>is_arithmetic&lt;T&gt;</code> whose name might suggest that it
  278. should return <code>true</code> for any type which supports the operations
  279. above. But this is not the case. The standard defines
  280. <code>is_arithmetic&lt;T&gt;</code> as <code>true</code> for any of the
  281. builtin types <code>int</code>, <code>long</code>, <code>float</code>,
  282. <code>double</code>, etc and <code>false</code> for any other types. So
  283. even if a user defined type U were to support the operations above,
  284. <code>is_arithmetic&lt;U&gt;</code> would still return <code>false</code>.
  285. This is quite unintuitive and not a good match for our purposes. Hence we
  286. define our own term "Numeric" to designate any type T which:</para>
  287. <para><itemizedlist>
  288. <listitem>
  289. <para>Supports the operations above</para>
  290. </listitem>
  291. <listitem>
  292. <para>Specializes the standard type numeric_limits</para>
  293. </listitem>
  294. </itemizedlist>while following the C++ standard in using
  295. <code>is_arithmetic&lt;T&gt;</code>, <code>is_integral&lt;T&gt;</code> to
  296. detect specific types only. The standard types are useful in various
  297. aspects of the implementation - which of course is done in terms of the
  298. standard types.</para>
  299. <para>This in turn raises another question: Is it "legal" to specialize
  300. <code>std::numeric_limits</code> for one's own types such as
  301. <code>safe&lt;int&gt;</code>. In my view the standard is ambiguous on
  302. this. See various interpretations: <itemizedlist>
  303. <listitem>
  304. <para><ulink
  305. url="https://stackoverflow.com/questions/16122912/is-it-ok-to-specialize-stdnumeric-limitst-for-user-defined-number-like-class">is-it-ok-to-specialize-stdnumeric-limitst-for-user-defined-number-like-class</ulink></para>
  306. </listitem>
  307. <listitem>
  308. <para><ulink
  309. url="https://en.cppreference.com/w/cpp/types/numeric_limits">cppreference.com/w/cpp/types/numeric_limits</ulink></para>
  310. </listitem>
  311. </itemizedlist></para>
  312. <para>In any case, it seems pretty clear that no harm will come of it. In
  313. spite of the consideration given to this issue, it turns out that the
  314. found no real need to implement these predicates. For example, there is no
  315. "is_numeric&lt;T&gt;" implemented as part of the safe numerics library.
  316. This may change in the future though. Even if not used, defining and
  317. maintaining these type requirements in this document has been very
  318. valuable in keeping the concepts and code more unified and
  319. understandable.</para>
  320. <para>Remember that above considerations apply to other numeric types used
  321. in this library even though we don't explicitly repeat this information
  322. for every case.</para>
  323. </section>
  324. </section>