<?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">
  <title>safe&lt;T, PP, EP&gt;</title>

  <?dbhtml stop-chunking?>

  <section>
    <title>Description</title>

    <para>A <code>safe&lt;T, PP , EP&gt;</code> can be used anywhere a type T
    can be used. Any expression which uses this type is guaranteed to return
    an arithmetically correct value or to trap in some way.</para>
  </section>

  <section>
    <title>Notation</title>

    <informaltable>
      <tgroup cols="2">
        <colspec align="left" colwidth="1*"/>

        <colspec align="left" colwidth="10*"/>

        <thead>
          <row>
            <entry align="left">Symbol</entry>

            <entry align="left">Description</entry>
          </row>
        </thead>

        <tbody>
          <row>
            <entry><code>T</code></entry>

            <entry>Underlying type from which a safe type is being
            derived</entry>
          </row>
        </tbody>
      </tgroup>
    </informaltable>
  </section>

  <section>
    <title>Associated Types</title>

    <informaltable>
      <tgroup cols="2">
        <colspec align="left" colwidth="1*"/>

        <colspec align="left" colwidth="8*"/>

        <tbody>
          <row>
            <entry><code>PP</code></entry>

            <entry>Promotion Policy. A type which specifies the result type of
            an expression using safe types.</entry>
          </row>

          <row>
            <entry><code>EP</code></entry>

            <entry>Exception Policy. A type containing members which are
            called when a correct result cannot be returned</entry>
          </row>
        </tbody>
      </tgroup>
    </informaltable>
  </section>

  <section>
    <title>Template Parameters</title>

    <informaltable>
      <tgroup cols="3">
        <colspec colwidth="1*"/>

        <colspec align="left" colwidth="3*"/>

        <colspec align="left" colwidth="7*"/>

        <thead>
          <row>
            <entry align="left">Parameter</entry>

            <entry align="left">Type Requirements</entry>

            <entry>Description</entry>
          </row>
        </thead>

        <tbody>
          <row>
            <entry><code>T</code></entry>

            <entry><link
            linkend="safe_numerics.integer_concept">std::is_integer&lt;T&gt;</link></entry>

            <entry><para>The underlying type. Currently only built-in integer
            types are supported</para></entry>
          </row>

          <row>
            <entry><code>PP</code></entry>

            <entry><link
            linkend="safe_numerics.promotion_policy">PromotionPolicy&lt;PP&gt;</link></entry>

            <entry><para>Optional promotion policy. Default value is <link
            linkend="safe_numerics.promotion_policies.native"><code>boost::numeric::native</code></link></para></entry>
          </row>

          <row>
            <entry><code>EP</code></entry>

            <entry><link linkend="safe_numerics.exception_policy">Exception
            Policy&lt;EP&gt;</link></entry>

            <entry><para>Optional exception policy. Default value is <link
            linkend="safe_numerics.exception_policies.default_exception_policy"><code>boost::numeric::default_exception_policy</code></link></para></entry>
          </row>
        </tbody>
      </tgroup>
    </informaltable>

    <para>See examples below.</para>
  </section>

  <section>
    <title>Model of</title>

    <para><link linkend="safe_numerics.numeric_concept">Numeric</link></para>

    <para><link linkend="safe_numerics.numeric_concept">Integer</link></para>
  </section>

  <section>
    <title>Valid Expressions</title>

    <para>Implements all expressions and only those expressions supported by
    the base type T. Note that all these expressions are
    <code>constexpr</code>. The result type of such an expression will be
    another safe type. The actual type of the result of such an expression
    will depend upon the specific promotion policy template parameter.</para>

    <para>When a binary operand is applied to two instances of safe&lt;T, PP,
    EP&gt;one of the following must be true:<itemizedlist>
        <listitem>
          <para>The promotion policies of the two operands must be the same or
          one of them must be void</para>
        </listitem>

        <listitem>
          <para>The exception policies of the two operands must be the same or
          one of them must be void</para>
        </listitem>
      </itemizedlist>If either of the above is not true, a compile error will
    result.</para>
  </section>

  <section>
    <title>Examples of use</title>

    <para>The most common usage would be safe&lt;T&gt; which uses the default
    promotion and exception policies. This type is meant to be a "drop-in"
    replacement of the intrinsic integer types. That is, expressions involving
    these types will be evaluated into result types which reflect the standard
    rules for evaluation of C++ expressions. Should it occur that such
    evaluation cannot return a correct result, an exception will be
    thrown.</para>

    <para>There are two aspects of the operation of this type which can be
    customized with a policy. The first is the result type of an arithmetic
    operation. C++ defines the rules which define this result type in terms of
    the constituent types of the operation. Here we refer to these rules as
    "type promotion" rules. These rules will sometimes result in a type which
    cannot hold the actual arithmetic result of the operation. This is the
    main motivation for making this library in the first place. One way to
    deal with this problem is to substitute our own type promotion rules for
    the C++ ones.</para>

    <section id="safe_numerics.drop_in_replacement">
      <title>As a Drop-in replacement for standard integer types.</title>

      <para>The following program will throw an exception and emit an error
      message at runtime if any of several events result in an incorrect
      arithmetic result. Behavior of this program could vary according to the
      machine architecture in question.</para>

      <para><programlisting>#include &lt;exception&gt;
#include &lt;iostream&gt;
#include &lt;safe_integer.hpp&gt;

void f(){
    using namespace boost::safe_numerics;
    safe&lt;int&gt; j;
    try {
        safe&lt;int&gt; i;
        std::cin &gt;&gt; i;  // could overflow !
        j = i * i;      // could overflow
    }
    catch(std::exception &amp; e){
       std::cout &lt;&lt; e.what() &lt;&lt; std::endl;
    }
    std::cout &lt;&lt; j;
}</programlisting>The term "drop-in replacement" reveals the aspiration of
      this library. In most cases, this aspiration is realized. In the
      following example, the normal implicit conversions function the same for
      safe integers as they do for built-in integers. <programlisting><xi:include
            href="../../example/example16.cpp" parse="text"
            xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>When
      the <code>safe&lt;long&gt;</code> is implicitly converted to an
      <code>int</code> when calling <code>f</code>, the value is checked to be
      sure that it is within the legal range of an int and will invoke an
      exception if it cannot. We can easily verify this by altering the
      exception handling policy in the above example to
      <code>loose_trap_policy</code>. This will invoke a compile time error on
      any conversion might invoke a runtime exception.</para>

      <para><programlisting><xi:include href="../../example/example17.cpp"
            parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting></para>

      <para>But this raises it's own questions. We can see that in this
      example, the program can never fail:</para>

      <itemizedlist>
        <listitem>
          <para>The value 97 is assigned to y</para>
        </listitem>

        <listitem>
          <para>y is converted to an int</para>
        </listitem>

        <listitem>
          <para>and used as an argument to f</para>
        </listitem>
      </itemizedlist>

      <para>The conversion can never fail because the value of 97 can always
      fit into an int. But the library code can't detect this and emits the
      checking code even though it's not necessary.</para>

      <para>This can be addressed by using a <link
      linkend="safe_numerics.safe_literal"><code>safe_literal</code></link>. A
      safe literal can contain one and only one value. All the functions in
      this library are marked <code>constexpr</code>. So it can be determined
      at compile time that conversion to an <code>int</code> can never fail
      and no runtime checking code need be emitted. Making this small change
      will permit the above example to run with zero runtime overhead while
      guaranteeing that no error can ever occur.</para>

      <programlisting><xi:include href="../../example/example18.cpp"
          parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

      <para>With this trivial example, such efforts would hardly be deemed
      necessary. But in a more complex case, perhaps including compile time
      arithmetic expressions, it could be much more difficult to verify that
      the constant is valid and/or no checking code is needed. And there is
      also possibility that over the life time of the application, the compile
      time constants might change, thus rendering any ad hoc analyse obsolete.
      Using <link
      linkend="safe_numerics.safe_literal"><code>safe_literal</code></link>
      will future-proof your code against well-meaning, but code-breaking
      updates.</para>
    </section>

    <section>
      <title>Adjust type promotion rules.</title>

      <para>Another way to avoid arithmetic errors like overflow is to promote
      types to larger sizes before doing the arithmetic.</para>

      <para>Stepping back, we can see that many of the cases of invalid
      arithmetic wouldn't exist if the result types were larger. So we can
      avoid these problems by replacing the C++ type promotion rules for
      expressions with our own rules. This can be done by specifying a
      promotion policy <code><code>automatic</code></code>. The policy stores
      the result of an expression in the smallest size type that can
      accommodate the largest value that an expression can yield. No checking
      for exceptions is necessary. The following example illustrates
      this.</para>

      <para><programlisting>#include &lt;boost/safe_numerics/safe_integer.hpp&gt;
#include &lt;iostream&gt;

int main(int, char[]){
    using safe_int = safe&lt;
        int, boost::numeric::automatic, 
        boost::numeric::default_exception_policy
    &gt;; 
    safe_int i;
    std::cin &gt;&gt; i; // might throw exception
    auto j = i * i; // won't ever trap - result type can hold the maximum value of i * i
    static_assert(boost::numeric::is_safe&lt;decltype(j)&gt;::value); // result is another safe type
    static_assert(
        std::numeric_limits&lt;decltype(i * i)&gt;::max() &gt;=
        std::numeric_limits&lt;safe_int&gt;::max() * std::numeric_limits&lt;safe_int&gt;::max()
    ); // always true

    return 0;
}</programlisting></para>
    </section>
  </section>

  <section>
    <title>Header</title>

    <para><filename><ulink
    url="../../include/boost/safe_numerics/safe_integer.hpp">#include
    &lt;boost/safe_numerics/safe_integer.hpp&gt;</ulink></filename></para>
  </section>
</section>
