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