• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
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&lt;T&gt;</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&lt;T&gt;::value == false</code>. For example see
23    <code>safe_signed_integer&lt;int&gt;</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&lt;T&gt;</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&lt;T&gt;::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&lt;T&gt;::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&lt;T&gt;::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&lt;T&gt;::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 &lt; 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 &lt;= 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 &gt; 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 &gt;= 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&lt;int&gt;,
375    safe_signed_range&lt;int&gt;, checked_result&lt;int&gt;,
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    &lt;boost/numeric/safe_numerics/concepts/numeric.hpp&gt;
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&lt;T&gt;</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&lt;T&gt;</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&lt;T&gt;</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&lt;U&gt;</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&lt;T&gt;</code>, <code>is_integral&lt;T&gt;</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&lt;int&gt;</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&lt;T&gt;" 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