123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- <?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<T></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> or <link
- linkend="safe_numerics.integer">Integer</link></para>
- </section>
- <section>
- <title>Notation</title>
- <informaltable>
- <tgroup cols="2">
- <colspec align="left" colwidth="3*"/>
- <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> or <link
- linkend="safe_numerics.integer">Integer</link> type
- requirements.</entry>
- </row>
- <row>
- <entry>t, u</entry>
- <entry>objects of types T, U</entry>
- </row>
- <row>
- <entry>S</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 supported by underlying type T</entry>
- </row>
- <row>
- <entry>prefix_op</entry>
- <entry>C++ prefix operator: -, +, ~, ++, -- supported by
- underlying type T</entry>
- </row>
- <row>
- <entry>postfix_op</entry>
- <entry>C++ postfix operator:++, -- supported by underlying type
- T</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="3*"/>
- <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 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 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 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 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 C++ operator <code>postfix_op</code> and
- return another SafeNumeric type.</para></entry>
- </row>
- <row>
- <entry><code>s assign_op t</code></entry>
- <entry>S &</entry>
- <entry><para>convert t to type S and assign it to s.
- </para></entry>
- </row>
- <row>
- <entry><code>t assign_op s</code></entry>
- <entry>T &</entry>
- <entry><para>convert s to type T and assign it to s. If the
- value t cannot be represented as an instance of type S, it is an
- error.</para></entry>
- </row>
- <row>
- <entry><code>S(t)</code></entry>
- <entry>S</entry>
- <entry><para>construct an instance of S from a value of type T.
- In this case, T is referred to as the base type of S. If the
- value t cannot be represented as an instance of type S, it is an
- exception condition is invoked. </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>T(s)</code></entry>
- <entry>T</entry>
- <entry><para>implicit conversion of the value of s to type T. If
- the value of s cannot be correctly represented as a type T, an
- exception condition is invoked.</para></entry>
- </row>
- <row>
- <entry><code>static_cast<T>(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, an exception
- condition is invoked. </para></entry>
- </row>
- <row>
- <entry><code>is_safe<S></code></entry>
- <entry><code>std::true_type</code></entry>
- <entry><para>type trait to query whether any type S fulfills the
- requirements for a SafeNumeric type.</para></entry>
- </row>
- <row>
- <entry><code>base_type<S>::type</code></entry>
- <entry>T</entry>
- <entry><para>Retrieve the base type of a given safe
- type.</para></entry>
- </row>
- <row>
- <entry><code>base_value(s)</code></entry>
- <entry>T</entry>
- <entry><para>Retrieve the value of an instance of a safe type.
- This is equivalent to
- <code>static_cast<base_type<S>>(s)</code>.</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 and whose operands
- are both safe types require that promotion and exception policies of
- the operands be identical.</para>
- </listitem>
- <listitem>
- <para><code>Operations on safe types are supported if and only if the
- same operation is supported on the underlying types. For example, the
- binary operations |</code>, <code>&</code>, <code>^</code> and
- <code>~</code> operations defined for safe unsigned integer types. But
- they are not defined for floating point types. Currently the are also
- defined for 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 types will be implicitly converted to built-in
- types when appropriate. Here's an example:<programlisting>void f(int);
- int main(){
- long x;
- f(x); // OK - builtin implicit version
- safe<long> y;
- f(y);
- return 0;
- }</programlisting>This behavior supports the concept of
- <code>safe<T></code> as being a "drop-in" replacement for a
- <code>T</code>.</para>
- </listitem>
- </itemizedlist>
- </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..). But
- no implementation should return an arithmetically incorrect result.</para>
- </section>
- <section>
- <title>Models</title>
- <para><code>safe<T></code></para>
- <para><code>safe_signed_range<-11, 11></code></para>
- <para><code>safe_unsigned_range<0, 11></code></para>
- <para><code>safe_signed_literal<4></code></para>
- </section>
- <section>
- <title>Header</title>
- <para><ulink
- url="../../include/boost/safe_numerics/concept/safe_numeric.hpp"><code>#include
- <boost/numeric/safe_numerics/concepts/safe_numeric.hpp></code></ulink></para>
- </section>
- </section>
|