123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- <?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.promotion_policy">
- <title>PromotionPolicy<PP></title>
- <?dbhtml stop-chunking?>
- <section>
- <title>Description</title>
- <para>In C++, arithmetic operations result in types which may or may not
- be the same as the constituent types. A promotion policy determines the
- type of the result of an arithmetic operation. For example, in the
- following code<programlisting>int x;
- char y;
- auto z = x + y</programlisting>the type of <code>z</code> will be an
- <code>int</code>. This is a consequence for the standard rules for type
- promotion for C/C++ arithmetic. A key feature of library permits one to
- specify his own type promotion rules via a PromotionPolicy class.</para>
- </section>
- <section>
- <title>Notation</title>
- <informaltable>
- <tgroup cols="2" colsep="1" rowsep="1">
- <colspec align="left" colwidth="1*"/>
- <colspec align="left" colwidth="4*"/>
- <tbody>
- <row>
- <entry><code>PP</code></entry>
- <entry>A type that full fills the requirements of a
- PromotionPollicy</entry>
- </row>
- <row>
- <entry><code>T, U</code></entry>
- <entry>A type that is a model of the Numeric concept</entry>
- </row>
- <row>
- <entry><code>R</code></entry>
- <entry>An object of type modeling Numeric which can be used to
- construct a SafeNumeric type.</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- </section>
- <section>
- <title>Valid Expressions</title>
- <para>Any operations which result in integers which cannot be represented
- as some Numeric type will throw an exception.These expressions return a
- type which can be used as the basis create a SafeNumeric type.</para>
- <para><informaltable>
- <tgroup cols="2">
- <colspec align="left"/>
- <colspec align="left"/>
- <thead>
- <row>
- <entry align="left">Expression</entry>
- <entry>Return Value</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry><code>PP::addition_result<T,
- U>::type</code></entry>
- <entry>unspecified Numeric type</entry>
- </row>
- <row>
- <entry><code>PP::subtraction_result<T,
- U>::type</code></entry>
- <entry>unspecified Numeric type</entry>
- </row>
- <row>
- <entry><code>PP::multiplication_result<T,
- U>::type</code></entry>
- <entry>unspecified Numeric type</entry>
- </row>
- <row>
- <entry><code>PP::division_result<T,
- U>::type</code></entry>
- <entry>unspecified Numeric type</entry>
- </row>
- <row>
- <entry><code>PP::modulus_result<T, U>::type</code></entry>
- <entry>unspecified Numeric type</entry>
- </row>
- <row>
- <entry><code>PP::comparison_result<T,
- U>::type</code></entry>
- <entry>bool</entry>
- </row>
- <row>
- <entry><code>PP::left_shift_result<T,
- U>::type</code></entry>
- <entry>unspecified Numeric type</entry>
- </row>
- <row>
- <entry><code>PP::right_shift_result<T,
- u>::type</code></entry>
- <entry>unspecified Numeric type</entry>
- </row>
- <row>
- <entry><code>PP::bitwise_or_result<T,
- U>::type</code></entry>
- <entry>unspecified Numeric type</entry>
- </row>
- <row>
- <entry><code>PP::bitwise_and_result<T,
- U>::type</code></entry>
- <entry>unspecified Numeric type</entry>
- </row>
- <row>
- <entry><code>PP::bitwise_xor_result<T,
- U>::type</code></entry>
- <entry>unspecified Numeric type</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable></para>
- </section>
- <section>
- <title>Models</title>
- <para>The library contains a number of pre-made promotion policies:</para>
- <itemizedlist>
- <listitem id="safe_numerics.promotion_policy.models.native">
- <para><code>boost::numeric::native</code></para>
- <para>Use the normal C/C++ expression type promotion rules.
- <programlisting name="cpp">int x;
- char y;
- auto z = x + y; // could result in overflow
- safe<int, native> sx;
- auto sz = sx + y; // standard C++ code which detects errors</programlisting></para>
- <para>Type sz will be a <link
- linkend="safe_numerics.safe_numeric_concept">SafeNumeric</link> type
- based on <code>int</code>. If the result exceeds the maximum value
- that can be stored in an <code>int</code>, an error is
- detected.</para>
- <para>The <code>native</code> policy is documented in <link
- linkend="safe_numerics.promotion_policies.native">Promotion Policies -
- native</link>.</para>
- </listitem>
- <listitem id="safe_numerics.promotion_policy.models.automatic">
- <para><code>boost::numeric::automatic</code></para>
- <para>Use optimizing expression type promotion rules. These rules
- replace the normal C/C++ type promotion rules with other rules which
- are designed to result in more efficient computations. Expression
- types are promoted to the smallest type which can be guaranteed to
- hold the result without overflow. If there is no such type, the result
- will be checked for overflow. Consider the following
- example:<programlisting>int x;
- char y;
- auto z = x + y; // could result in overflow
- safe<int, automatic> sx;
- auto sz = sx + y;
- // sz is a safe type based on long
- // hence sz is guaranteed not to overflow.
- safe_unsigned_range<1, 4> a;
- safe_unsigned_range<2, 4> b;
- auto c = a + b; // c will be a safe type with a range [3,8] and cannot overflow
- </programlisting></para>
- <para>Type sz will be a <link
- linkend="safe_numerics.safe_numeric_concept">SafeNumeric</link> type
- which is guaranteed to hold he result of x + y. In this case that will
- be a long int (or perhaps a long long) depending upon the compiler and
- machine architecture. In this case, there will be no need for any
- special checking on the result and there can be no overflow.</para>
- <para>Type of c will be a signed character as that type can be
- guaranteed to hold the sum so no overflow checking is done.</para>
- <para>This policy is documented in <link
- linkend="safe_numerics.promotion_policies.automatic">Promotion
- Policies - automatic</link></para>
- </listitem>
- <listitem>
- <para>boost::numeric::cpp</para>
- <para>Use expression type promotion rules to emulate another
- processor. When this policy is used, C++ type for safe integers
- follows the rules that a compiler on the target processor would use.
- This permits one to test code destined for a one processor on the
- another one. One situation there this can be very, very useful is when
- testing code destined for a micro controller which doesn't have the
- logging, debugging, input/output facilities of a
- desktop.<programlisting>// specify a promotion policy to support proper emulation of
- // PIC 18f2520 types on the desktop
- using pic16_promotion = boost::numeric::cpp<
- 8, // char 8 bits
- 16, // short 16 bits
- 16, // int 16 bits
- 16, // long 16 bits
- 32 // long long 32 bits
- >;
- ...
- safe<std::uint16_t, pic16_promotion> x, y;
- ...
- x + y; // detect possible overflow on the pic.</programlisting></para>
- <para>For a complete example see <link
- linkend="safe_numerics.safety_critical_embedded_controller">Safety
- Critical Embedded Controller</link>.</para>
- </listitem>
- </itemizedlist>
- </section>
- <section>
- <title>Header</title>
- <para><ulink
- url="../../include/boost/safe_numerics/concept/promotion_policy.hpp"><code>#include
- <boost/numeric/safe_numerics/concepts/promotion_policy.hpp>
- </code></ulink></para>
- </section>
- </section>
|