Files
safe_numerics/doc/boostbook/safe_numerics.xml
Robert Ramey b62ef86e28 Added case study for embedded system
corrections in cpp promotion
added make_safe_literal
separated integers from other types
dropped example91
updated CMakeLists.txt and Jamfile.v2 accordingly
2018-07-21 09:57:35 -07:00

347 lines
13 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.1//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<library dirname="safe_numerics" id="safe_numerics" last-revision="$Date"
name="Safe Numerics">
<title>Safe Numerics</title>
<libraryinfo last-revision="January 29, 2015">
<author>
<firstname>Robert</firstname>
<surname>Ramey</surname>
</author>
<copyright>
<year>2012-2018</year>
<holder>Robert Ramey</holder>
</copyright>
<legalnotice>
<para><ulink url="http://www.boost.org/LICENSE_1_0.txt">Subject to Boost
Software License</ulink></para>
</legalnotice>
<librarypurpose>Safe integer operations</librarypurpose>
<librarycategory name="Numerics">Numerics</librarycategory>
</libraryinfo>
<xi:include href="safe_introduction.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="tutorial.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="eliminate_runtime_penalty.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<section>
<title id="safe_numerics.case_studies">Case Studies</title>
<xi:include href="rational.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="motor.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
</section>
<xi:include href="notes.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<section id="safe_numerics.concepts">
<title>Type Requirements</title>
<xi:include href="numeric_concept.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="integer_concept.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="safe_numeric_concept.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="promotion_policy_concept.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="exception_policy_concept.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
</section>
<section id="safe_numerics.types">
<title>Types</title>
<xi:include href="safe.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="safe_range.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="safe_literal.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="exception.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="exception_policy.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<section id="safe_numerics.promotion_policies">
<title>Promotion Policies</title>
<xi:include href="native.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="automatic.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="cpp.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
</section>
</section>
<section id="safe_numerics.exception_safety">
<title>Exception Safety</title>
<para>All operations in this library are exception safe and meet the
strong guarantee.</para>
</section>
<section id="safe_numerics.library_implementation">
<title>Library Implementation</title>
<para>This library should compile and run correctly on any conforming
C++14 compiler.</para>
<para>The Safe Numerics library is implemented in terms of some more
fundamental software components described here. It is not necessary to
know about these components to use the library. This information has been
included to help those who want to understand how the library works so
they can extend it, correct bugs in it, or understand its limitations.
These components are also interesting in their own right. For all these
reasons, they are documented here.</para>
<para>In general terms, the library works in the following manner:</para>
<itemizedlist>
<listitem>
<para>The library defines "safe" versions of C++ primitive arithmetic
types such as int, unsigned int, etc.</para>
</listitem>
<listitem>
<para>Arithmetic operators are defined for these "safe" types. These
operators are enhanced versions of the standard C/C++ implementations.
These operators are declared and implemented in the files
"safe_base.hpp" and "safe_base_operations.hpp".</para>
</listitem>
<listitem>
<para>For binary operators, verify that both operands have the same
promotion and and exception handling policies. If they don't, invoke
compilation error.</para>
</listitem>
<listitem>
<para>Retrieve range of values for each operand of type T from
<code>std::numeric_limits&lt;T&gt;::min()</code> and
<code>std::numeric_limits&lt;T&gt;::max()</code>. A range is a pair of
values representing a closed interval with a minimum and maximum
value.</para>
</listitem>
<listitem>
<para>These ranges are cast to equivalent values of the result type,
R. It's possible that values cannot be cast to the result type so the
result of the cast is returned as a variant type, <link
linkend="safenumerics.checked_result"><code>checked_result&lt;R&gt;</code></link>.
<link
linkend="safenumerics.checked_result"><code>checked_result&lt;R&gt;</code></link>
may hold either a value of type R or a <link
linkend="safe_numerics.safe_numerics_error"><code>safe_numerics_error</code></link>
value indicating why the cast could not be accomplished. Ranges are
represented as a pair of values of the type <link
linkend="safenumerics.checked_result"><code>checked_result&lt;R&gt;</code></link>.</para>
</listitem>
<listitem>
<para><link
linkend="safenumerics.checked_result"><code>checked_result&lt;R&gt;</code></link>
can be considered enhanced versions of the underlying type R.
Operations which are legal on values of type R such as +, -, ... are
also legal on values of <link
linkend="safenumerics.checked_result"><code>checked_result&lt;R&gt;</code></link>.
The difference is that the latter can record operation failures and
propagate such failures to subsequent operations.<link
linkend="safenumerics.checked_result"><code>checked_result&lt;R&gt;</code></link>
is implemented in the header file "checked_result.hpp". Operations on
such types are implemented in "checked_result_operations.hpp".</para>
</listitem>
<listitem>
<para>Given the ranges of the operands, determine the range of the
result of the operation using compile-time interval arithmetic. The
<code>constexpr</code> facility of C++14 permits the range of the
result to be calculated at compile time. Interval arithmetic is
implemented in the header file "interval.hpp". The range of the result
is also represented as a pair of values of the type <link
linkend="safenumerics.checked_result"><code>checked_result&lt;R&gt;</code></link>.</para>
</listitem>
<listitem>
<para>If the range of the result type includes only arithmetically
valid values, the operation is guaranteed to produce an arithmetically
correct result and no runtime checking is necessary. The operation
invokes the original built-in C/C++ operation and returns the result
value.</para>
</listitem>
<listitem>
<para>Otherwise, operands are cast to the result type, R, according to
the selected promotion policy. These "checked" cast operations return
values of type <link
linkend="safenumerics.checked_result"><code>checked_result&lt;R&gt;</code></link>.</para>
</listitem>
<listitem>
<para>If either of the casting operations fails, an exception is
handled in accordance with the exception policy.</para>
</listitem>
<listitem>
<para>Otherwise, the operation is performed as another "checked
operation". These free functions mirror the normal operators +, -, *,
... except that rather than returning values of type R, they return
values of the type <link
linkend="safenumerics.checked_result"><code>checked_result&lt;R&gt;</code></link>.
They are defined in files "checked_default.hpp", "checked_integer.hpp"
,"checked_float.hpp".</para>
</listitem>
<listitem>
<para>If the operation is not successful, the designated exception
policy function is invoked.</para>
</listitem>
<listitem>
<para>Otherwise, the result value is returned.</para>
</listitem>
<listitem>
<para>In all cases, result values are returned as a
<code>safe&lt;R&gt;</code> type with the above calculated result
range.</para>
</listitem>
</itemizedlist>
<para>The following components realize the design described here.</para>
<xi:include href="checked_result.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="checked.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="interval.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="safe_compare.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
</section>
<section id="safe_numerics.performance_tests">
<title>Performance Tests</title>
<para>Our goal is to create facilities which make it possible to write
programs known to be correct. But we also want programmers to actually use
the facilities we provide here. This won't happen if using these
facilities impacts performance to a significant degree. Although we've
taken precautions to avoid doing this, the only real way to know is to
create and run some tests.</para>
<para>So far we've only run one explicit performance test -
<filename><ulink
url="../../test/test_performance.cpp">test_performance.cpp</ulink></filename>.
This runs a test from the Boost Multiprecision library to count prime
numbers and uses on integer arithmetic. We've run the tests with
<code>unsigned</code> integers and with <code>safe&lt;unsigned&gt;</code>
on two different compilers.. No other change was made to the program. We
list the results without further comment.</para>
<screen>g++ (GCC) 6.2.0
Testing type unsigned:
time = 17.6215
count = 1857858
Testing type safe&lt;unsigned&gt;:
time = 22.4226
count = 1857858
clang-802.0.41
Testing type unsigned:
time = 16.9174
count = 1857858
Testing type safe&lt;unsigned&gt;:
time = 36.5166
count = 1857858
</screen>
</section>
<xi:include href="faq.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<section id="safe_numerics.pending_issues">
<title>Pending Issues</title>
<para>The library is under development. There are a number of issues still
pending.</para>
<itemizedlist>
<listitem>
<para>The library is currently limited to integers.</para>
</listitem>
<listitem>
<para>Conversions to safe integer types from floating point types is
not explicitly addressed.</para>
</listitem>
<listitem>
<para>Note that standard library stream conversion functions such as
<code>strtoi</code> etc. DO check for valid input and throw the
exception <code>std::out_of_range</code> if the string cannot be
converted to the specified integer type. In other words,
<code>strtoi</code> already contains some of the functionality that
<code>safe&lt;int&gt;</code> provides.</para>
</listitem>
<listitem>
<para>Although care has been taken to make the library portable, it's
likely that at least some parts of the implementation - particularly
<code>checked</code> arithmetic - depend upon two's complement
representation of integers. Hence the library is probably not
currently portable to all other possible C++ architectures.</para>
</listitem>
<listitem>
<para>Currently the library permits a <code>safe&lt;int&gt;</code>
value to be uninitialized. This supports the goal of "drop-in"
replacement of C++/C built-in types with safe counter parts. On the
other hand, this breaks the "always valid" guarantee.</para>
</listitem>
</itemizedlist>
</section>
<xi:include href="acknowledgements.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<section id="safe_numerics.change_log">
<title>Change Log</title>
<para>This is the third version.</para>
</section>
<xi:include href="bibliography.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
</library>