Files
safe_numerics/doc/boostbook/safe_numeric_concept.xml
2017-04-11 10:33:01 -07:00

300 lines
8.5 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.1//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<section id="safe_numerics.safe_numeric_concept">
<title>SafeNumeric&lt;T&gt;</title>
<?dbhtml stop-chunking?>
<section>
<title>Description</title>
<para>This holds an arithmetic value which can be used as a replacement
for built-in C++ arithmetic values. These types differ from their built-in
counter parts in that the are guaranteed not to produce invalid arithmetic
results. These operations return safe types rather than built-in
types.</para>
</section>
<section>
<title>Refinement of</title>
<para><link linkend="safe_numerics.numeric">Numeric</link></para>
</section>
<section>
<title>Notation</title>
<informaltable>
<tgroup cols="2">
<colspec align="left" colwidth="2*"/>
<colspec align="left" colwidth="10*"/>
<thead>
<row>
<entry align="left">Symbol</entry>
<entry align="left">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>T, U</code></entry>
<entry>Types fulfilling <link
linkend="safe_numerics.numeric">Numeric</link> type
requirements</entry>
</row>
<row>
<entry>t, u</entry>
<entry>objects of types T, U</entry>
</row>
<row>
<entry>S, S1, S2</entry>
<entry>A type fulfilling SafeNumeric type requirements</entry>
</row>
<row>
<entry>s, s1, s2</entry>
<entry>objects of types S</entry>
</row>
<row>
<entry>op</entry>
<entry>C++ infix operator</entry>
</row>
<row>
<entry>prefix_op</entry>
<entry>C++ prefix operator: -, +, ~</entry>
</row>
<row>
<entry>postfix_op</entry>
<entry>C++ postfix operator</entry>
</row>
<row>
<entry>assign_op</entry>
<entry>C++ assignment operator</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Valid Expressions</title>
<para><informaltable>
<tgroup cols="3">
<colspec align="left" colwidth="2*"/>
<colspec align="left" colwidth="2*"/>
<colspec align="left" colwidth="8*"/>
<thead>
<row>
<entry align="left">Expression</entry>
<entry align="left">Result Type</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>s op t</code></entry>
<entry>unspecified S</entry>
<entry><para>invoke safe C++ operator op and return another
SafeNumeric type.</para></entry>
</row>
<row>
<entry><code>t op s</code></entry>
<entry>unspecified S</entry>
<entry><para>invoke safe C++ operator op and return another
SafeNumeric type.</para></entry>
</row>
<row>
<entry><code>s1 op s2</code></entry>
<entry>unspecified S</entry>
<entry><para>invoke safe C++ operator op and return another
SafeNumeric type.</para></entry>
</row>
<row>
<entry><code>prefix_op S</code></entry>
<entry>unspecified S</entry>
<entry><para>invoke safe C++ operator <code>prefix_op</code> and
return another SafeNumeric type.</para></entry>
</row>
<row>
<entry><code>S postfix_op</code></entry>
<entry>unspecified S</entry>
<entry><para>invoke safe C++ operator <code>postfix_op</code>
and return another SafeNumeric type.</para></entry>
</row>
<row>
<entry><code>s assign_op t</code></entry>
<entry>S1</entry>
<entry><para>convert t to type S1 and assign it to s1. If the
value t cannot be represented as an instance of type S1, it is
an error.</para></entry>
</row>
<row>
<entry><code>S(t)</code></entry>
<entry>unspecified S</entry>
<entry><para>construct an instance of S from a value of type T.
If the value t cannot be represented as an instance of type S1,
it is an error.</para></entry>
</row>
<row>
<entry><code>S</code></entry>
<entry>S</entry>
<entry><para>construct an uninitialized instance of
S.</para></entry>
</row>
<row>
<entry><code>is_safe&lt;S&gt;</code></entry>
<entry><code>std::true_type</code> or
<code>std::false_type</code></entry>
<entry><para>type trait to query whether any type T fulfills the
requirements for a SafeNumeric type.</para></entry>
</row>
<row>
<entry><code>static_cast&lt;T&gt;(s)</code></entry>
<entry>T</entry>
<entry><para>convert the value of s to type T. If the value of s
cannot be correctly represented as a type T, it is an error.
Note that implicit casting from a safe type to a built-in
integer type is expressly prohibited and should invoke a compile
time error.</para></entry>
</row>
</tbody>
</tgroup>
</informaltable></para>
<itemizedlist>
<listitem>
<para>The result of any binary operation where one or both of the
operands is a SafeNumeric type is also a SafeNumeric type.</para>
</listitem>
<listitem>
<para>All the expressions in the above table are
<code>constexpr</code> expressions</para>
</listitem>
<listitem>
<para>Binary expressions which are not assignments require that
promotion and exception policies of the operands be identical.</para>
</listitem>
<listitem>
<para><code>|</code>, <code>&amp;</code>, <code>^</code> and
<code>~</code> operations defined for safe signed integer types. It's
not clear that this is the correct decision. On one hand, usage of
these operators on signed types is almost certainly an error in
program logic. But trapping this as an error conflicts with the goal
of making safe types "drop-in" replacements for the corresponding
built-in types. In light of this, these operators are currently
supported as they are for normal built-in types.</para>
</listitem>
<listitem>
<para>Safe Numeric operators will NOT perform standard numeric
conversions in order to convert to built-in types.<programlisting>void f(int);
int main(){
long x;
f(x); // OK - builtin implicit version
safe&lt;long&gt; y;
f(y); // compile time error
return 0;
}</programlisting>This behavior prevents a <code>safe&lt;T&gt;</code> from
being a "drop-in" replacement for a <code>T</code>.</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Complexity Guarantees</title>
<para>There are no complexity guarantees explicitly enforced here.
However, it would be very surprising if any implementation were to be more
complex that O(0);</para>
</section>
<section>
<title>Invariants</title>
<para>The fundamental requirement of a SafeNumeric type is that it
implements all C++ operations permitted on its base type in a way the
prevents the return of an incorrect arithmetic result. Various
implementations of this concept may handle circumstances which produce
such results differently (throw exception, compile time trap, etc..) no
implementation should return an arithmetically incorrect result.</para>
</section>
<section>
<title>Header</title>
<para><ulink
url="../../include/concept/exception_policy.hpp"><code>#include
&lt;safe_numerics/include/concepts/safe_numeric.hpp&gt;</code></ulink></para>
</section>
<section>
<title>Models</title>
<para>safe&lt;T&gt;</para>
<para>safe_signed_range&lt;-11, 11&gt;</para>
<para>safe_unsigned_range&lt;0, 11&gt;</para>
<para>safe_literal&lt;4&gt;</para>
</section>
</section>