Showing preview only (1,849K chars total). The displayed content is truncated. Use the JSON API for full output.
Repository: boostorg/safe_numerics
Branch: develop
Commit: c46d7a33fa6e
Files: 333
Total size: 1.7 MB
Directory structure:
gitextract_uxocpujy/
├── .drone/
│ └── drone.sh
├── .drone.star
├── .github/
│ └── workflows/
│ ├── posix.yml
│ └── windows.yml
├── .travis.yml
├── CMakeLists.txt
├── LICENSE_1_0.txt
├── README.md
├── appveyor.yml
├── b2.log
├── build.jam
├── doc/
│ ├── boostbook/
│ │ ├── HTML.manifest
│ │ ├── accu/
│ │ │ ├── accu.xml
│ │ │ ├── bb2db.xsl
│ │ │ ├── db2epub.xsl
│ │ │ ├── db2fo.xsl
│ │ │ ├── db2html.xsl
│ │ │ ├── makehtml.sh
│ │ │ └── makepdf.sh
│ │ ├── acknowledgements.xml
│ │ ├── automatic.xml
│ │ ├── bb2db.xsl
│ │ ├── bibliography.xml
│ │ ├── checked.xml
│ │ ├── checked_result.xml
│ │ ├── cpp.xml
│ │ ├── db2epub.xsl
│ │ ├── db2fo.xsl
│ │ ├── db2html.xsl
│ │ ├── db2pdf.xsl
│ │ ├── eliminate_runtime_penalty.xml
│ │ ├── exception.xml
│ │ ├── exception_policy.xml
│ │ ├── exception_policy_concept.xml
│ │ ├── faq.xml
│ │ ├── ignore_exception.xml
│ │ ├── integer_concept.xml
│ │ ├── interval.xml
│ │ ├── makeepub.sh
│ │ ├── makehtml.bat
│ │ ├── makehtml.sh
│ │ ├── makepdf.sh
│ │ ├── makeproposal.sh
│ │ ├── motor.xml
│ │ ├── native.xml
│ │ ├── no_exception_support.xml
│ │ ├── notes.xml
│ │ ├── numeric_concept.xml
│ │ ├── overflow.xml
│ │ ├── pending.xml
│ │ ├── promotion_policy_concept.xml
│ │ ├── proposal.xml
│ │ ├── rational.xml
│ │ ├── safe.xml
│ │ ├── safe_cast.xml
│ │ ├── safe_compare.xml
│ │ ├── safe_introduction.xml
│ │ ├── safe_literal.xml
│ │ ├── safe_numerics.xml
│ │ ├── safe_range.xml
│ │ ├── trap_exception.xml
│ │ └── tutorial.xml
│ └── html/
│ ├── acknowledgements.html
│ ├── bibliography.html
│ ├── boostbook.css
│ ├── case_studies.html
│ ├── change_log.html
│ ├── checked_arithmetic.html
│ ├── checked_integer_arithmetic.html
│ ├── checked_result.html
│ ├── composition_with_other_libraries.html
│ ├── concepts.html
│ ├── eliminate_runtime_penalty/
│ │ ├── 1.html
│ │ ├── 2.html
│ │ └── 3.html
│ ├── eliminate_runtime_penalty.html
│ ├── exception.html
│ ├── exception_policies.html
│ ├── exception_policy.html
│ ├── exception_safety.html
│ ├── index.html
│ ├── integer.html
│ ├── integer_concept.html
│ ├── interval.html
│ ├── introduction.html
│ ├── library_implementation.html
│ ├── notes.html
│ ├── numeric.html
│ ├── numeric_concept.html
│ ├── pending_issues.html
│ ├── performance_tests.html
│ ├── promotion_policies/
│ │ ├── automatic.html
│ │ ├── cpp.html
│ │ └── native.html
│ ├── promotion_policies.html
│ ├── promotion_policy.html
│ ├── rationale.html
│ ├── safe.html
│ ├── safe_literal.html
│ ├── safe_numeric_concept.html
│ ├── safe_numerics_error.html
│ ├── safe_range.html
│ ├── safety_critical_embedded_controller.html
│ ├── tutorial/
│ │ ├── 1.html
│ │ ├── 10.html
│ │ ├── 2.html
│ │ ├── 3.html
│ │ ├── 4.html
│ │ ├── 5.html
│ │ ├── 6.html
│ │ ├── 7.html
│ │ ├── 8.html
│ │ └── 9.html
│ ├── tutorial.html
│ └── types.html
├── example/
│ ├── CMakeLists.txt
│ ├── Jamfile.v2
│ ├── Motor.c
│ ├── example1.cpp
│ ├── example10.cpp
│ ├── example11.cpp
│ ├── example13.cpp
│ ├── example14.cpp
│ ├── example15.cpp
│ ├── example16.cpp
│ ├── example17.cpp
│ ├── example18.cpp
│ ├── example19.cpp
│ ├── example2.cpp
│ ├── example20.cpp
│ ├── example3.cpp
│ ├── example4.cpp
│ ├── example5.cpp
│ ├── example6.cpp
│ ├── example7.cpp
│ ├── example8.cpp
│ ├── example81.cpp
│ ├── example82.cpp
│ ├── example83.cpp
│ ├── example84.cpp
│ ├── example91.cpp
│ ├── example92.cpp
│ ├── example93.cpp
│ ├── links.html
│ ├── motor1.c
│ ├── motor2.c
│ ├── motor3.c
│ ├── motor_test1.c
│ ├── motor_test2.c
│ ├── motor_test3.c
│ ├── picsfr.h
│ └── safe_format.hpp
├── html
├── include/
│ └── boost/
│ └── safe_numerics/
│ ├── CMakeLists.txt
│ ├── automatic.hpp
│ ├── checked_default.hpp
│ ├── checked_float.hpp
│ ├── checked_integer.hpp
│ ├── checked_result.hpp
│ ├── checked_result_operations.hpp
│ ├── concept/
│ │ ├── CMakeLists.txt
│ │ ├── exception_policy.hpp
│ │ ├── integer.hpp
│ │ ├── numeric.hpp
│ │ └── promotion_policy.hpp
│ ├── cpp.hpp
│ ├── exception.hpp
│ ├── exception_policies.hpp
│ ├── interval.hpp
│ ├── native.hpp
│ ├── range_value.hpp
│ ├── safe_base.hpp
│ ├── safe_base_operations.hpp
│ ├── safe_common.hpp
│ ├── safe_compare.hpp
│ ├── safe_integer.hpp
│ ├── safe_integer_literal.hpp
│ ├── safe_integer_range.hpp
│ └── utility.hpp
├── index.html
├── meta/
│ └── libraries.json
└── test/
├── CMakeLists.txt
├── Jamfile.v2
├── check_symmetry.hpp
├── test0.cpp
├── test_add.hpp
├── test_add_automatic.cpp
├── test_add_automatic_constexpr.cpp
├── test_add_automatic_results.hpp
├── test_add_constexpr.hpp
├── test_add_native.cpp
├── test_add_native_constexpr.cpp
├── test_add_native_results.hpp
├── test_and.hpp
├── test_and_automatic.cpp
├── test_and_automatic_constexpr.cpp
├── test_and_native.cpp
├── test_and_native_constexpr.cpp
├── test_assignment.cpp
├── test_assignment.hpp
├── test_auto.cpp
├── test_cast.cpp
├── test_cast_constexpr.cpp
├── test_checked_add.cpp
├── test_checked_add.hpp
├── test_checked_add_constexpr.cpp
├── test_checked_and.cpp
├── test_checked_and.hpp
├── test_checked_and_constexpr.cpp
├── test_checked_cast.cpp
├── test_checked_cast.hpp
├── test_checked_cast_constexpr.cpp
├── test_checked_comparison.hpp
├── test_checked_divide.cpp
├── test_checked_divide.hpp
├── test_checked_divide_constexpr.cpp
├── test_checked_equal_to.cpp
├── test_checked_equal_to_constexpr.cpp
├── test_checked_left_shift.cpp
├── test_checked_left_shift.hpp
├── test_checked_left_shift_constexpr.cpp
├── test_checked_less_than.cpp
├── test_checked_less_than_constexpr.cpp
├── test_checked_modulus.cpp
├── test_checked_modulus.hpp
├── test_checked_modulus_constexpr.cpp
├── test_checked_multiply.cpp
├── test_checked_multiply.hpp
├── test_checked_multiply_constexpr.cpp
├── test_checked_or.cpp
├── test_checked_or.hpp
├── test_checked_or_constexpr.cpp
├── test_checked_right_shift.cpp
├── test_checked_right_shift.hpp
├── test_checked_right_shift_constexpr.cpp
├── test_checked_subtract.cpp
├── test_checked_subtract.hpp
├── test_checked_subtract_constexpr.cpp
├── test_checked_values.hpp
├── test_checked_xor.cpp
├── test_checked_xor.hpp
├── test_checked_xor_constexpr.cpp
├── test_compare_automatic.hpp
├── test_compare_native.hpp
├── test_concept_integer.cpp
├── test_concept_numeric.cpp
├── test_constexpr.cpp
├── test_construction.cpp
├── test_cpp.cpp
├── test_custom_exception.cpp
├── test_divide.hpp
├── test_divide_automatic.cpp
├── test_divide_automatic_constexpr.cpp
├── test_divide_automatic_results.hpp
├── test_divide_constexpr.hpp
├── test_divide_native.cpp
├── test_divide_native_constexpr.cpp
├── test_divide_native_results.hpp
├── test_equal.hpp
├── test_equal_automatic.cpp
├── test_equal_automatic_constexpr.cpp
├── test_equal_constexpr.hpp
├── test_equal_native.cpp
├── test_equal_native_constexpr.cpp
├── test_float.cpp
├── test_interval.cpp
├── test_left_shift.hpp
├── test_left_shift_automatic.cpp
├── test_left_shift_automatic_constexpr.cpp
├── test_left_shift_automatic_results.hpp
├── test_left_shift_constexpr.hpp
├── test_left_shift_native.cpp
├── test_left_shift_native_constexpr.cpp
├── test_left_shift_native_results.hpp
├── test_less_than.hpp
├── test_less_than_automatic.cpp
├── test_less_than_automatic_constexpr.cpp
├── test_less_than_constexpr.hpp
├── test_less_than_native.cpp
├── test_less_than_native_constexpr.cpp
├── test_modulus.hpp
├── test_modulus_automatic.cpp
├── test_modulus_automatic_constexpr.cpp
├── test_modulus_automatic_results.hpp
├── test_modulus_constexpr.hpp
├── test_modulus_native.cpp
├── test_modulus_native_constexpr.cpp
├── test_modulus_native_results.hpp
├── test_multiply.hpp
├── test_multiply_automatic.cpp
├── test_multiply_automatic_constexpr.cpp
├── test_multiply_automatic_results.hpp
├── test_multiply_constexpr.hpp
├── test_multiply_native.cpp
├── test_multiply_native_constexpr.cpp
├── test_multiply_native_results.hpp
├── test_notepad.hpp
├── test_or.hpp
├── test_or_automatic.cpp
├── test_or_automatic_constexpr.cpp
├── test_or_constexpr.hpp
├── test_or_native.cpp
├── test_or_native_constexpr.cpp
├── test_performance.cpp
├── test_range.cpp
├── test_rational.cpp
├── test_right_shift.hpp
├── test_right_shift_automatic.cpp
├── test_right_shift_automatic_constexpr.cpp
├── test_right_shift_automatic_results.hpp
├── test_right_shift_constexpr.hpp
├── test_right_shift_native.cpp
├── test_right_shift_native_constexpr.cpp
├── test_right_shift_native_results.hpp
├── test_safe_compare.cpp
├── test_stream_overload.cpp
├── test_subtract.hpp
├── test_subtract_automatic.cpp
├── test_subtract_automatic_constexpr.cpp
├── test_subtract_automatic_results.hpp
├── test_subtract_constexpr.hpp
├── test_subtract_native.cpp
├── test_subtract_native_constexpr.cpp
├── test_subtract_native_results.hpp
├── test_trap.cpp
├── test_values.hpp
├── test_xor.hpp
├── test_xor_automatic.cpp
├── test_xor_automatic_constexpr.cpp
├── test_xor_constexpr.hpp
├── test_xor_native.cpp
├── test_xor_native_constexpr.cpp
└── test_z.cpp
================================================
FILE CONTENTS
================================================
================================================
FILE: .drone/drone.sh
================================================
#!/bin/bash
# Copyright 2020 Rene Rivera, Sam Darwin
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt)
set -e
export TRAVIS_BUILD_DIR=$(pwd)
export DRONE_BUILD_DIR=$(pwd)
export TRAVIS_BRANCH=$DRONE_BRANCH
export VCS_COMMIT_ID=$DRONE_COMMIT
export GIT_COMMIT=$DRONE_COMMIT
export REPO_NAME=$DRONE_REPO
export PATH=~/.local/bin:/usr/local/bin:$PATH
if [ "$DRONE_JOB_BUILDTYPE" == "boost" ]; then
echo '==================================> INSTALL'
BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
cd ..
git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost
cd boost
git submodule update --init tools/build
git submodule update --init libs/config
git submodule update --init tools/boostdep
git submodule update --init tools/boost_install
git submodule update --init libs/headers
mkdir -p libs/safe_numerics
cp -r $TRAVIS_BUILD_DIR/* libs/safe_numerics
python tools/boostdep/depinst/depinst.py safe_numerics
./bootstrap.sh
./b2 headers
echo '==================================> SCRIPT'
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
./b2 -j 3 libs/safe_numerics/test toolset=$TOOLSET cxxstd=$CXXSTD
fi
================================================
FILE: .drone.star
================================================
# Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE.txt)
#
# Copyright Rene Rivera 2020.
# For Drone CI we use the Starlark scripting language to reduce duplication.
# As the yaml syntax for Drone CI is rather limited.
#
#
globalenv={}
linuxglobalimage="cppalliance/droneubuntu1604:1"
windowsglobalimage="cppalliance/dronevs2019"
def main(ctx):
return [
linux_cxx("TOOLSET=gcc COMPILER=g++-6 CXXSTD=14,1z Job 0", "g++-6", packages="g++-6", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '14,1z', 'DRONE_JOB_UUID': 'b6589fc6ab'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-7 CXXSTD=14,17 Job 1", "g++-7", packages="g++-7", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '14,17', 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-8 CXXSTD=14,17 Job 2", "g++-8", packages="g++-8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': '14,17', 'DRONE_JOB_UUID': 'da4b9237ba'}, globalenv=globalenv),
linux_cxx("TOOLSET=gcc COMPILER=g++-9 CXXSTD=14,17,2a Job 3", "g++-9", packages="g++-9", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '14,17,2a', 'DRONE_JOB_UUID': '77de68daec'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=14, Job 4", "clang++-3.9", packages="clang-3.9", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.9', 'CXXSTD': '14,1z', 'DRONE_JOB_UUID': '1b64538924'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=14, Job 5", "clang++-4.0", packages="clang-4.0 libstdc++-6-dev", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '14,1z', 'DRONE_JOB_UUID': 'ac3478d69a'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=14, Job 6", "clang++-5.0", packages="clang-5.0 libstdc++-7-dev", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '14,1z', 'DRONE_JOB_UUID': 'c1dfd96eea'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=14, Job 7", "clang++-6.0", packages="clang-6.0 libstdc++-8-dev", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '14,17', 'DRONE_JOB_UUID': '902ba3cda1'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-7 CXXSTD=14,17 Job 8", "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '14,17,2a', 'DRONE_JOB_UUID': 'fe5dbbcea5'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-8 CXXSTD=14,17 Job 9", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '14,17,2a', 'DRONE_JOB_UUID': '0ade7c2cf9'}, globalenv=globalenv),
linux_cxx("TOOLSET=clang COMPILER=clang++-libc++ CXXSTD= Job 10", "clang++-libc++", packages="libc++-dev", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-libc++', 'CXXSTD': '14,1z', 'DRONE_JOB_UUID': 'b1d5781111'}, globalenv=globalenv),
osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=14,1z Job 11", "clang++", packages="", buildtype="boost", buildscript="drone", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '14,1z', 'DRONE_JOB_UUID': '17ba079149'}, globalenv=globalenv),
]
# from https://github.com/boostorg/boost-ci
load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx")
================================================
FILE: .github/workflows/posix.yml
================================================
name: POSIX
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
LIBRARY: safe_numerics
UBSAN_OPTIONS: print_stacktrace=1
jobs:
CI:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-6
cxxstd: "14,1z"
os: ubuntu-16.04
install: g++-6
- toolset: gcc-7
cxxstd: "14,17"
os: ubuntu-18.04
- toolset: gcc-8
cxxstd: "14,17,2a"
os: ubuntu-18.04
- toolset: gcc-9
cxxstd: "14,17,2a"
os: ubuntu-18.04
- toolset: gcc-10
cxxstd: "14,17,2a"
os: ubuntu-18.04
- toolset: clang
cxxstd: "14,17,2a"
os: ubuntu-18.04
- toolset: clang
cxxstd: "14,17,2a"
os: macos-10.15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release
================================================
FILE: .github/workflows/windows.yml
================================================
name: Windows
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
LIBRARY: safe_numerics
jobs:
CI:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.1
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2016
- toolset: msvc-14.2
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2019
- toolset: gcc
cxxstd: "14,17,2a"
addrmd: 64
os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Setup Boost
shell: cmd
run: |
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
if "%GITHUB_BASE_REF%" == "master" set BOOST_BRANCH=master
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
================================================
FILE: .travis.yml
================================================
# Copyright 2018 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
language: cpp
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
- os: linux
arch: arm64
compiler: g++-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
arch: ppc64le
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
arch: s390x
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=14,17
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=14,17,2a
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=14,1z
addons:
apt:
packages:
- clang-3.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=14,1z
addons:
apt:
packages:
- clang-4.0
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-5.0
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=14,1z
addons:
apt:
packages:
- clang-5.0
- libstdc++-7-dev
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-6.0
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=14,17
addons:
apt:
packages:
- clang-6.0
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-7
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=14,17,2a
addons:
apt:
packages:
- clang-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-7
- os: linux
compiler: clang++-8
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=14,17,2a
addons:
apt:
packages:
- clang-8
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-8
- os: linux
dist: trusty
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=14,1z
addons:
apt:
packages:
- libc++-dev
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=14,1z
install:
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
- cd ..
- git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost
- cd boost
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- git submodule update --init tools/boost_install
- git submodule update --init libs/headers
- mkdir -p libs/safe_numerics
- cp -r $TRAVIS_BUILD_DIR/* libs/safe_numerics
- python tools/boostdep/depinst/depinst.py safe_numerics
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- ./b2 -j 3 libs/safe_numerics/test toolset=$TOOLSET cxxstd=$CXXSTD
notifications:
email:
on_success: alwaysa
================================================
FILE: CMakeLists.txt
================================================
if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
# Generated by `boostdep --cmake safe_numerics`
# Copyright 2020, 2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.8...3.20)
project(boost_safe_numerics VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_safe_numerics INTERFACE)
add_library(Boost::safe_numerics ALIAS boost_safe_numerics)
target_include_directories(boost_safe_numerics INTERFACE include)
target_link_libraries(boost_safe_numerics
INTERFACE
Boost::concept_check
Boost::config
Boost::core
Boost::integer
Boost::logic
Boost::mp11
)
target_compile_features(boost_safe_numerics INTERFACE cxx_std_14)
else()
# CMake build control file for safe numerics Library Examples
cmake_minimum_required(VERSION 3.8.6)
project("SafeIntegers")
enable_language(CXX)
########################################################
# Create interface library
#
add_library(boost_safe_numerics INTERFACE)
add_library(Boost::safe_numerics ALIAS boost_safe_numerics)
target_include_directories(boost_safe_numerics INTERFACE "${Boost_INCLUDE_DIRS}")
target_compile_features(boost_safe_numerics INTERFACE cxx_std_14)
########################################################
# Compiler settings - special settings for known compilers
#
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
message(STATUS "compiler is ${CMAKE_CXX_COMPILER_ID}" )
if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
add_compile_options(-Wnon-virtual-dtor -ansi -Wcast-align -Wchar-subscripts -Wall -Wextra -W -Wshadow -Wsign-compare )
add_compile_options( -ftemplate-depth=255 )
elseif( CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" )
# warning level 4 and all warnings as errors
add_compile_options(/W4 /WX /wd4996 /wd4068)
elseif( CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" )
add_compile_options(-Wnon-virtual-dtor -ansi -Wcast-align -Wchar-subscripts -Wall -Wextra -W -Wshadow -Wsign-compare )
add_compile_options( -ftemplate-depth=255 )
add_compile_options( -fbracket-depth=2048 )
elseif( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
add_compile_options(-Wnon-virtual-dtor -ansi -Wcast-align -Wchar-subscripts -Wall -Wextra -W -Wshadow -Wsign-compare )
add_compile_options( -ftemplate-depth=255 )
add_compile_options( -fbracket-depth=2048 )
endif()
#
# Project settings
#
find_package(Boost )
if(Boost_FOUND)
if( CMAKE_HOST_APPLE )
set(Boost_ADDRESS_MODEL 64 CACHE STRING "32/64 bits")
endif()
message(STATUS "Boost directories found at ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost version found is ${Boost_VERSION}")
include_directories("${Boost_INCLUDE_DIRS}") # note: sets header search path?
elseif()
message("Boost NOT Found!")
endif()
message(STATUS "include directories are:" )
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${dirs})
message(STATUS " ${dir}")
endforeach()
#use folders in organization of the IDE
set(USE_FOLDERS TRUE)
###########################
# testing and submitting test results to the test dashboard
if(0)
## Create a file named CTestConfig.cmake adjacent to the current file.
## This new file should contain the following:
set(CTEST_PROJECT_NAME "Safe Numerics")
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "my.cdash.org")
# set(CTEST_DROP_LOCATION "/cdash/submit.php?project=MyProject")
set(CTEST_DROP_LOCATION "/index.php?project=Safe+Numerics")
set(CTEST_DROP_SITE_CDASH TRUE)
endif()
function(test_run_pass base_name )
message(STATUS ${base_name})
add_executable(${base_name} ${base_name}.cpp)
add_test(NAME ${base_name} COMMAND ${base_name})
endfunction(test_run_pass)
function(test_compile_pass base_name )
message(STATUS ${base_name} - compile only)
add_library(${base_name} OBJECT ${base_name})
endfunction(test_compile_pass)
function(test_compile_fail base_name )
message(STATUS ${base_name})
# Add failing-to-compile targets
add_executable(${base_name} ${base_name}.cpp)
# Avoid building these targets normally
set_target_properties(${base_name} PROPERTIES
EXCLUDE_FROM_ALL TRUE
EXCLUDE_FROM_DEFAULT_BUILD TRUE
)
# Add the tests. These invoke "cmake --build ..." which is a
# cross-platform way of building the given target.
add_test(NAME ${base_name}
COMMAND ${CMAKE_COMMAND} --build . --target ${base_name} --config $<CONFIGURATION>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
# Expect these tests to fail
# (i.e. cmake --build should return a non-zero value)
set_tests_properties(${base_name} PROPERTIES WILL_FAIL TRUE)
endfunction( test_compile_fail base_name )
########################################################
# End Compiler settings
#
enable_testing()
add_subdirectory("include/boost/safe_numerics")
add_subdirectory("example")
add_subdirectory("test")
endif()
================================================
FILE: LICENSE_1_0.txt
================================================
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
safe_numerics
=============
Arithmetic operations in C++ are NOT guaranteed to yield a correct mathematical result. This feature is inherited from the early days of C. The behavior of int, unsigned int and others were designed to map closely to the underlying hardware. Computer hardware implements these types as a fixed number of bits. When the result of arithmetic operations exceeds this number of bits, the result is undefined and usually not what the programmer intended. It is incumbent upon the C++ programmer to guarantee that this behavior does not result in incorrect behavior of the program. This library implements special versions of these data types which behave exactly like the original ones EXCEPT that the results of these operations are checked to be sure that an exception will be thrown anytime an attempt is made to store the result of an undefined operation.
Note: This is the subject of a various presentations at CPPCon.
The first one is a short version which gives the main motivation for the library with a rowsing sales pitch. Fun and suitable for upper management. https://www.youtube.com/watch?v=cw_8QkFXZjI&t=1s
The second is more extensive in that it addresses a real world case study which touches on most of the important aspects of the libary. https://www.youtube.com/watch?v=93Cjg42bGEw .
Finally, for those who still enjoy the written word there is the documentation in which significant effort has been invested. http://htmlpreview.github.io/?https://github.com/robertramey/safe_numerics/master/doc/html/index.html
If you use this libary and find it useful, please add a star. I need motivation!!!
================================================
FILE: appveyor.yml
================================================
# Copyright 2018 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17
install:
- cd ..
- git clone -b %APPVEYOR_REPO_BRANCH% https://github.com/boostorg/boost.git boost
- cd boost
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- git submodule update --init tools/boost_install
- git submodule update --init libs/headers
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\safe_numerics\
- python tools/boostdep/depinst/depinst.py safe_numerics
- cmd /c bootstrap
- b2 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- b2 -j 3 libs/safe_numerics/test toolset=%TOOLSET% %CXXSTD%
================================================
FILE: b2.log
================================================
================================================
FILE: build.jam
================================================
# Copyright René Ferdinand Rivera Morell 2023-2024
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
require-b2 5.2 ;
constant boost_dependencies :
/boost/concept_check//boost_concept_check
/boost/config//boost_config
/boost/core//boost_core
/boost/integer//boost_integer
/boost/logic//boost_logic
/boost/mp11//boost_mp11 ;
project /boost/safe_numerics
: common-requirements
<include>include
;
explicit
[ alias boost_safe_numerics : : : : <library>$(boost_dependencies) ]
[ alias all : boost_safe_numerics example test ]
;
call-if : boost-library safe_numerics
;
================================================
FILE: doc/boostbook/HTML.manifest
================================================
../html/index.html
../html/introduction.html
../html/tutorial.html
../html/tutorial/1.html
../html/tutorial/2.html
../html/tutorial/3.html
../html/tutorial/4.html
../html/tutorial/5.html
../html/tutorial/6.html
../html/tutorial/7.html
../html/tutorial/8.html
../html/tutorial/9.html
../html/tutorial/10.html
../html/eliminate_runtime_penalty.html
../html/eliminate_runtime_penalty/2.html
../html/eliminate_runtime_penalty/1.html
../html/eliminate_runtime_penalty/3.html
../html/case_studies.html
../html/composition_with_other_libraries.html
../html/safety_critical_embedded_controller.html
../html/notes.html
../html/concepts.html
../html/numeric_concept.html
../html/integer_concept.html
../html/promotion_policy.html
../html/exception_policy.html
../html/types.html
../html/safe.html
../html/safe_range.html
../html/safe_literal.html
../html/exception.html
../html/exception_policies.html
../html/promotion_policies.html
../html/promotion_policies/native.html
../html/promotion_policies/automatic.html
../html/promotion_policies/cpp.html
../html/exception_safety.html
../html/library_implementation.html
../html/checked_result.html
../html/checked_arithmetic.html
../html/interval.html
../html/checked_integer_arithmetic.html
../html/performance_tests.html
../html/rationale.html
../html/pending_issues.html
../html/acknowledgements.html
../html/change_log.html
../html/bibliography.html
================================================
FILE: doc/boostbook/accu/accu.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<article>
<articleinfo>
<title>Correct Integer Operations With Minimal Runtime Penalties</title>
<author>
<firstname>Robert</firstname>
<surname>Ramey</surname>
<affiliation>
<orgname>Robert Ramey Software Development</orgname>
</affiliation>
</author>
<pubdate>22 December 2016</pubdate>
</articleinfo>
<xi:include href="../safe_introduction.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"/>
<xi:include href="../notes.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<section id="safe_numerics.library_implementation">
<title>Library Internals</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 it's limitations.
These components are also interesting in their own right. For all these
reasons, they are described here. In general terms, the library works in
the following manner:</para>
<itemizedlist>
<listitem>
<para>All unary/binary expressions where one of the operands is a
"safe" type are Overloaded. These overloads are declared and defined
in the header file "safe_integer.hpp". SFINAE - "Substitution Failure
Is Not An Error and <code>std::enable_if</code> are key features of
C++ used to define these overloads in a correct manner.</para>
</listitem>
<listitem>
<para>Each overloaded operation implements the following at compile
time:<itemizedlist>
<listitem>
<para>Retrieve range of values for each operand of type T from
<code>std::numeric_limits<T>::min()</code> and
<code>std::numeric_limits<T>::max()</code>.</para>
</listitem>
<listitem>
<para>Given the ranges of the operands, determine the range of
the result of the operation using interval arithmetic. This is
implemented in the "interval.hpp" header file using constexpr
facility of C++14.</para>
</listitem>
<listitem>
<para>if the range of the result type includes the range of the
result of the operation, no run time checking of the result is
necessary. So the operation reduces to the original built-in
C/C++ operation.</para>
</listitem>
<listitem>
<para>Otherwise, the operation is implemented as a "checked
integer operation" at run time. This operation returns a variant
which will contain either a correct result or an exception enum
indicating why a correct result could not be obtained. The
variant object is implemented in the header file
"checked_result.hpp" and the checked operations are implemented
in "checked.hpp".</para>
</listitem>
<listitem>
<para>if a valid result has been obtained, it is passed to the
caller.</para>
</listitem>
<listitem>
<para>Otherwise, an exception is invoked.</para>
</listitem>
</itemizedlist></para>
</listitem>
</itemizedlist>
</section>
<xi:include href="../faq.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<section id="safe_numerics.pending_issues">
<title>Current Status</title>
<para>The library is currently in the <ulink
url="http://www.boost.org/community/review_schedule.html">Boost Review
Queue</ulink>. The proposal submission can be found in the <ulink
url="http://blincubator.com/bi_library/safe-numerics/?gform_post_id=426">Boost
Library Incubator</ulink></para>
<itemizedlist>
<listitem>
<para>The library is currently limited to integers.</para>
</listitem>
<listitem>
<para>Although care was taking 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 other architectures.</para>
</listitem>
<listitem>
<para>Currently the library permits a <code>safe<int></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>
<listitem>
<para>The library is not quite a "drop-in" replacement for all
built-in integer types. In particular, C/C++ implements implicit
conversions and promotions between certain integer types which are not
captured by the operation overloads used to implement the library. In
practice these case are few and can be addressed with minor changes to
the user program to avoid these silent implicit conversions.</para>
</listitem>
</itemizedlist>
</section>
<xi:include href="../acknowledgements.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="../bibliography.xml" xpointer="element(/1)"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
</article>
================================================
FILE: doc/boostbook/accu/bb2db.xsl
================================================
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="http://www.boost.org/tools/boostbook/xsl/docbook.xsl"/>
<!-- highlight C++ source code -->
<xsl:template match="programlisting">
<xsl:apply-templates select="." mode="annotation"/>
</xsl:template>
</xsl:stylesheet>
================================================
FILE: doc/boostbook/accu/db2epub.xsl
================================================
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- ************** HTML ************** -->
<xsl:import href="http://www.boost.org/tools/boostbook/xsl/html.xsl"/>
<!--
Make library documentation header using some elements from boostbook stylesheets.
Override boost book implemenation of header.navigation with our own
-->
<xsl:template name = "header.navigation">
<xsl:param name = "prev" select = "/foo"/>
<xsl:param name = "next" select = "/foo"/>
<xsl:param name = "nav.context"/>
<table cellpadding = "2" width = "100%"><tr>
<td valign = "top">
<img href="index.html" height="164px" src="pre-boost.jpg" alt="Library Documentation Index" />
</td>
<td><h2>Safe Numerics</h2></td>
</tr></table>
<xsl:call-template name = "navbar.spirit">
<xsl:with-param name = "prev" select = "$prev"/>
<xsl:with-param name = "next" select = "$next"/>
<xsl:with-param name = "nav.context" select = "$nav.context"/>
</xsl:call-template>
</xsl:template>
<!-- remove "Chapter 1" from first page -->
<xsl:param name="chapter.autolabel" select="0"/>
<!-- leave the html files in the directory ../html -->
<xsl:param name="base.dir" select="'../html/'"/>
<!-- ******* Table of Contents ******** -->
<!-- How far down sections get TOC's -->
<xsl:param name = "toc.section.depth" select="2" />
<!-- Max depth in each TOC: -->
<xsl:param name = "toc.max.depth" select="2" />
<!-- How far down we go with TOC's -->
<xsl:param name="generate.section.toc.level" select="2" />
<!-- ************ Chunking ************ -->
<!--
BoostBook takes a section node id like safe_numeric.safe_cast
and renders it as safe_numeric/safe_cast. Presumably they do this
so they can make a huge "book" with all the libraries in subdirectories.
But we want something different. To my mind, this should have been
done using the library "directory" attribute. But of course that
doesn't matter now. We'll just re-hack the path to eliminate
the "safe_numeric/" from the above example.
-->
<xsl:template match="*" mode="recursive-chunk-filename">
<xsl:variable name="their">
<xsl:apply-imports mode="recursive-chunk-filename" select="."/>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains($their, '/')">
<xsl:value-of select="substring-after($their, '/')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$their"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- don't make first sections special - leave TOC in different file -->
<xsl:param name="chunk.first.sections" select="3" />
<!-- How far down we chunk nested sections -->
<!--
Note: each chunk have to start with a section with an id
Otherwise the chunk (i.e. file) will be lost. There is no
checking of this
-->
<xsl:param name="chunk.section.depth" select="3" />
</xsl:stylesheet>
================================================
FILE: doc/boostbook/accu/db2fo.xsl
================================================
<?xml version='1.0'?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0"
>
<!-- ************** FOP ************** -->
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
<xsl:param name="fop1.extensions">1</xsl:param>
<xsl:param name="sidebar.float.type">none</xsl:param>
<!--
Make all hyperlinks blue colored:
<xsl:attribute-set name="xref.properties">
<xsl:attribute name="color">blue</xsl:attribute>
</xsl:attribute-set>
-->
<!--
Put a box around admonishments and keep them together:
-->
<xsl:attribute-set name="graphical.admonition.properties">
<xsl:attribute name="border-color">#FF8080</xsl:attribute>
<xsl:attribute name="border-width">1px</xsl:attribute>
<xsl:attribute name="border-style">solid</xsl:attribute>
<xsl:attribute name="padding-left">0.2cm</xsl:attribute>
<xsl:attribute name="padding-right">0.2cm</xsl:attribute>
<xsl:attribute name="padding-top">0.2cm</xsl:attribute>
<xsl:attribute name="padding-bottom">0.2cm</xsl:attribute>
<xsl:attribute name="keep-together.within-page">1</xsl:attribute>
<xsl:attribute name="margin-left">0pt</xsl:attribute>
<xsl:attribute name="margin-right">0pt</xsl:attribute>
</xsl:attribute-set>
<!--
Put a box around code blocks, also set the font size
and keep the block together if we can using the widows
and orphans controls. Hyphenation and line wrapping
is also turned on, so that long lines of code don't
bleed off the edge of the page, a carriage return
symbol is used as the hyphenation character:
-->
<xsl:attribute-set name="monospace.verbatim.properties">
<xsl:attribute name="border-color">#DCDCDC</xsl:attribute>
<xsl:attribute name="border-width">1px</xsl:attribute>
<xsl:attribute name="border-style">solid</xsl:attribute>
<xsl:attribute name="padding-left">0.2cm</xsl:attribute>
<xsl:attribute name="padding-right">0.2cm</xsl:attribute>
<xsl:attribute name="padding-top">0.2cm</xsl:attribute>
<xsl:attribute name="padding-bottom">0.2cm</xsl:attribute>
<xsl:attribute name="widows">6</xsl:attribute>
<xsl:attribute name="orphans">40</xsl:attribute>
<xsl:attribute name="font-size">9pt</xsl:attribute>
<xsl:attribute name="margin-left">0pt</xsl:attribute>
<xsl:attribute name="background-color">#EEEEEE</xsl:attribute>
<xsl:attribute name="margin-right">0pt</xsl:attribute>
<!--
<xsl:attribute name="hyphenate">true</xsl:attribute>
<xsl:attribute name="wrap-option">wrap</xsl:attribute>
<xsl:attribute name="hyphenation-character">↵</xsl:attribute>
-->
<xsl:attribute name="hyphenate">false</xsl:attribute>
<xsl:attribute name="wrap-option">no-wrap</xsl:attribute>
</xsl:attribute-set>
<!--Regular monospace text should have the same font size as code blocks etc-->
<xsl:attribute-set name="monospace.properties">
<xsl:attribute name="font-size">9pt</xsl:attribute>
</xsl:attribute-set>
<!--
Put some small amount of padding around table cells, and keep tables
together on one page if possible:
-->
<xsl:attribute-set name="table.cell.padding">
<xsl:attribute name="padding-left">0.2cm</xsl:attribute>
<xsl:attribute name="padding-right">0.2cm</xsl:attribute>
<xsl:attribute name="padding-top">0.2cm</xsl:attribute>
<xsl:attribute name="padding-bottom">0.2cm</xsl:attribute>
</xsl:attribute-set>
<!--Formal and informal tables have the same properties-->
<xsl:param name="table.frame.border.thickness">medium</xsl:param>
<xsl:param name="table.cell.border.thickness">medium</xsl:param>
<xsl:param name="table.frame.border.color">#DCDCDC</xsl:param>
<xsl:param name="table.cell.border.color">#DCDCDC</xsl:param>
<!--Formal and informal tables have the same properties
Using widow-and-orphan control here gives much better
results for very large tables than a simple "keep-together"
instruction
-->
<xsl:attribute-set name="table.properties">
<xsl:attribute name="keep-together.within-page">1</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="informaltable.properties">
<xsl:attribute name="keep-together.within-page">1</xsl:attribute>
</xsl:attribute-set>
<!--
General default options go here:
* Borders are mid-grey.
* Body text is not indented compared to the titles.
* Page margins are a rather small 0.5in, but we need
all the space we can get for code blocks.
* Paper size is A4: an ISO standard, slightly taller and narrower than US Letter.
* Use SVG graphics for admonishments: the bitmaps look awful in PDF's.
* Disable draft mode so we're not constantly trying to download the necessary graphic.
* Set default image paths to pull down direct from SVN: individual Jamfiles can override this
and pass an absolute path to local versions of the images, but we can't get that here, so
we'll use SVN instead so that most things "just work".
* don't spell out url's
-->
<xsl:param name="body.start.indent">0pt</xsl:param>
<xsl:param name="admon.graphics">1</xsl:param>
<xsl:param name="admon.graphics.extension">.svg</xsl:param>
<xsl:param name="draft.mode">no</xsl:param>
<xsl:param name="double.sided">0</xsl:param>
<xsl:param name="show.bookmarks" select="1"></xsl:param>
<xsl:param name="page.margin.inner">0.75in</xsl:param>
<xsl:param name="page.margin.outer">0.75in</xsl:param>
<xsl:param name="body.margin.top">0.50in</xsl:param>
<xsl:param name="section.autolabel" select="1"></xsl:param>
<xsl:param name="section.autolabel.max.depth">2</xsl:param>
<xsl:param name="alignment">left</xsl:param>
<xsl:param name="ulink.show">0</xsl:param>
<xsl:param name="admon.graphics.path">http://svn.boost.org/svn/boost/trunk/doc/src/images/</xsl:param>
<xsl:param name="callout.graphics.path">http://svn.boost.org/svn/boost/trunk/doc/src/images/callouts/</xsl:param>
<!-- ******* Table of Contents ******** -->
<xsl:param name="generate.toc">
/article title
</xsl:param>
<!-- How far down sections get TOC's -->
<xsl:param name = "toc.section.depth" select="3" />
<!-- Max depth in each TOC: -->
<xsl:param name = "toc.max.depth" select="3" />
<!-- How far down we go with TOC's -->
<xsl:param name="generate.section.toc.level" select="0" />
<!-- Which elements should have which tables of contents -->
<!-- ******* Chapter Titles ******* -->
<xsl:param name="force.blank.pages" select="1"></xsl:param>
<!--
<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
<l:l10n language="en">
<l:context name="title-numbered">
<l:template name="chapter" text="%n. %t"/>
</l:context>
</l:l10n>
</l:i18n>
-->
<xsl:attribute-set name="chapter.title.properties">
<xsl:attribute name="font-family">
<xsl:value-of select="$title.font.family"/>
</xsl:attribute>
<xsl:attribute name="font-weight">bold</xsl:attribute>
<!-- font size is added dynamically by section.heading template -->
<xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.optimum">1.0em</xsl:attribute>
<xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
<xsl:attribute name="text-align">left</xsl:attribute>
<xsl:attribute name="start-indent">0pt</xsl:attribute>
</xsl:attribute-set>
<!-- ******* Section Level 5 properties ******* -->
<!-- used by bridgeheads -->
<xsl:attribute-set name="section.title.level5.properties">
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.2"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
</xsl:attribute-set>
</xsl:stylesheet>
================================================
FILE: doc/boostbook/accu/db2html.xsl
================================================
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- ************** HTML ************** -->
<xsl:import href="http://www.boost.org/tools/boostbook/xsl/html.xsl"/>
<!--
Make library documentation header using some elements from boostbook stylesheets.
Override boost book implemenation of header.navigation with our own
-->
<xsl:template name = "header.navigation">
<xsl:param name = "prev" select = "/foo"/>
<xsl:param name = "next" select = "/foo"/>
<xsl:param name = "nav.context"/>
<table cellpadding = "2" width = "100%"><tr>
<td valign = "top">
<img href="index.html" height="164px" src="accu_logo.png" alt="Library Documentation Index" />
</td>
<td><h2>Safe Numerics</h2></td>
</tr></table>
<xsl:call-template name = "navbar.spirit">
<xsl:with-param name = "prev" select = "$prev"/>
<xsl:with-param name = "next" select = "$next"/>
<xsl:with-param name = "nav.context" select = "$nav.context"/>
</xsl:call-template>
</xsl:template>
<!-- remove "Chapter 1" from first page -->
<xsl:param name="chapter.autolabel" select="0"/>
<!-- leave the html files in the directory ../html -->
<xsl:param name="base.dir" select="'../html/'"/>
<!-- ******* Table of Contents ******** -->
<!-- How far down sections get TOC's -->
<xsl:param name = "toc.section.depth" select="2" />
<!-- Max depth in each TOC: -->
<xsl:param name = "toc.max.depth" select="2" />
<!-- How far down we go with TOC's -->
<xsl:param name="generate.section.toc.level" select="2" />
<!-- ************ Chunking ************ -->
<!--
BoostBook takes a section node id like safe_numeric.safe_cast
and renders it as safe_numeric/safe_cast. Presumably they do this
so they can make a huge "book" with all the libraries in subdirectories.
But we want something different. To my mind, this should have been
done using the library "directory" attribute. But of course that
doesn't matter now. We'll just re-hack the path to eliminate
the "safe_numeric/" from the above example.
-->
<xsl:template match="*" mode="recursive-chunk-filename">
<xsl:variable name="their">
<xsl:apply-imports mode="recursive-chunk-filename" select="."/>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains($their, '/')">
<xsl:value-of select="substring-after($their, '/')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$their"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- don't make first sections special - leave TOC in different file -->
<xsl:param name="chunk.first.sections" select="3" />
<!-- How far down we chunk nested sections -->
<!--
Note: each chunk have to start with a section with an id
Otherwise the chunk (i.e. file) will be lost. There is no
checking of this
-->
<xsl:param name="chunk.section.depth" select="3" />
</xsl:stylesheet>
================================================
FILE: doc/boostbook/accu/makehtml.sh
================================================
if test x = x$BOOST_ROOT
then
echo BOOST_ROOT not set
fi
mkdir html
xsltproc --xinclude --nonet bb2db.xsl accu.xml > accudocbook4.xml
xsltproc --nonet db2html.xsl accudocbook4.xml
cp accu_logo.png html
cp $BOOST_ROOT/doc/src/boostbook.css html
cp -R $BOOST_ROOT/doc/html/images html
================================================
FILE: doc/boostbook/accu/makepdf.sh
================================================
#use -r switch on fop for relaxed validation
xsltproc --xinclude --nonet bb2db.xsl accu.xml > accudocbook4.xml
fop -r -dpi 300 -xsl db2fo.xsl -xml accudocbook4.xml -pdf accu.pdf
================================================
FILE: doc/boostbook/acknowledgements.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<section id="safe_numerics.acknowledgements">
<title>Acknowledgements</title>
<para>This library would never have been created without inspiration,
collaboration and constructive criticism from multiple sources.</para>
<para><glosslist>
<glossentry>
<glossterm>David LeBlanc</glossterm>
<glossdef>
<para>This library is inspired by <ulink
url="http://safeint.codeplex.com">David LeBlanc's SafeInt
Library</ulink> . I found this library very well done in every way
and useful in my embedded systems work. This motivated me to take it
to the "next level".</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm><ulink url="https://akrzemi1.wordpress.com">Andrzej
Krzemienski</ulink></glossterm>
<glossdef>
<para>Andrzej Commented and reviewed the library as it was
originally posted on the Boost Library Incubator. The consequent
back and forth motivated me to invest more effort in developing
documentation and examples to justify the utility, indeed the
necessity, for this library. He also noted many errors in code,
documentation, and tests. Without his interest and effort, I do not
believe the library would have progressed beyond its initial
stages.</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm><ulink url="http://www.boost.org">Boost</ulink></glossterm>
<glossdef>
<para>As always, the Boost Developer's mailing list has been the
source of many useful observations from potential users and
constructive criticism from very knowledgeable developers. During
the Boost formal review, reviews and comments were posted by the
following persons:</para>
<itemizedlist>
<listitem>
<para>Paul A. Bristow</para>
</listitem>
<listitem>
<para>Steven Watanabe</para>
</listitem>
<listitem>
<para>John Maddock</para>
</listitem>
<listitem>
<para>Antony Polukhin</para>
</listitem>
<listitem>
<para>Barrett Adair</para>
</listitem>
<listitem>
<para>Vicente J. Botet Escriba</para>
</listitem>
<listitem>
<para>John McFarlane</para>
</listitem>
<listitem>
<para>Peter Dimov</para>
</listitem>
</itemizedlist>
</glossdef>
</glossentry>
</glosslist></para>
</section>
================================================
FILE: doc/boostbook/automatic.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.promotion_policies.automatic">
<title>automatic</title>
<section>
<title>Description</title>
<para>This type contains the meta-functions to return a type with
sufficient capacity to hold the result of a given binary arithmetic
operation.</para>
<para>The standard C/C++ procedure for executing arithmetic operations on
operands of different types is:<itemizedlist>
<listitem>
<para>Convert operands to some common type using a somewhat
elaborate elaborate rules defined in the C++ standard.</para>
</listitem>
<listitem>
<para>Execute the operation.</para>
</listitem>
<listitem>
<para>If the result of the operation cannot fit in the common type
of the operands, discard the high order bits.</para>
</listitem>
</itemizedlist></para>
<para>The automatic promotion policy replaces the standard C/C++ procedure
for the following one:<itemizedlist>
<listitem>
<para>Convert operands to some common type using to the following
rules.<itemizedlist>
<listitem>
<para>For addition. If the operands are both unsigned the
common type will be unsigned. Otherwise it will be
signed.</para>
</listitem>
<listitem>
<para>For subtraction, the common type will be signed.</para>
</listitem>
<listitem>
<para>For left/right shift, the sign of the result will be the
sign of the left operand.</para>
</listitem>
<listitem>
<para>For all other types of operants, if both operands are
unsigned the common type will be unsigned. Otherwise, it will
be signed.</para>
</listitem>
</itemizedlist></para>
</listitem>
<listitem>
<para>Determine the smallest size of the signed or unsigned type
which can be guaranteed hold the result.</para>
</listitem>
<listitem>
<para>If this size exceeds the maximum size supported by the
compiler, use the maximum size supported by the compiler.</para>
</listitem>
<listitem>
<para>Execute the operation.<itemizedlist>
<listitem>
<para>Convert each operand to the common type.</para>
</listitem>
<listitem>
<para>If the result cannot be contained in the result type as
above, invoke an error procedure.</para>
</listitem>
<listitem>
<para>Otherwise, return the result in the common type</para>
</listitem>
</itemizedlist></para>
</listitem>
</itemizedlist></para>
<para>This type promotion policy is applicable only to safe types whose
base type is an <link linkend="safe_numerics.integer">Integer</link>
type.</para>
</section>
<section>
<title>Model of</title>
<para><link
linkend="safe_numerics.promotion_policy">PromotionPolicy</link></para>
</section>
<section>
<title>Example of use</title>
<para>The following example illustrates the <code>automatic</code> type
being passed as a template parameter for the type
<code>safe<int></code>.</para>
<programlisting>#include <boost/safe_numerics/safe_integer.hpp>
#include <boost/safe_numerics/automatic.hpp>
int main(){
using namespace boost::numeric;
// use automatic promotion policy where C++ standard arithmetic
// might lead to incorrect results
using safe_t = safe<std::int8_t, automatic>;
// In such cases, there is no runtime overhead from using safe types.
safe_t x = 127;
safe_t y = 2;
// z is guaranteed correct without any runtime overhead or exception.
auto z = x + y;
return 0;
}</programlisting>
</section>
<section>
<title>Header</title>
<para><code><ulink
url="../../include/boost/safe_numerics/automatic.hpp"><code>#include
<boost/safe_numerics/automatic.hpp> </code></ulink></code></para>
</section>
</section>
================================================
FILE: doc/boostbook/bb2db.xsl
================================================
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="http://www.boost.org/tools/boostbook/xsl/docbook.xsl"/>
<!-- highlight C++ source code -->
<xsl:template match="programlisting">
<xsl:apply-templates select="." mode="annotation"/>
</xsl:template>
</xsl:stylesheet>
================================================
FILE: doc/boostbook/bibliography.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<section id="safe_numerics.bibliography">
<title>Bibliography</title>
<bibliography>
<biblioentry id="coker">
<abbrev>Coker</abbrev>
<author>
<firstname>Zack</firstname>
<surname>Coker</surname>
</author>
<author>
<firstname>Samir</firstname>
<surname>Hasan</surname>
</author>
<author>
<firstname>Jeffrey</firstname>
<surname>Overbey</surname>
</author>
<author>
<firstname>Munawar</firstname>
<surname>Hafiz</surname>
</author>
<author>
<firstname>Christian</firstname>
<surname>Kästner</surname>
</author>
<title>
<ulink url="http://www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?">
<ulink
url="https://www.cs.cmu.edu/~ckaestne/pdf/csse14-01.pdf">Integers In
C: An Open Invitation To Security Attacks?</ulink>
</ulink>
</title>
<publishername>
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/">JTC1/SC22/WG21 -
The C++ Standards Committee - ISOCPP</ulink>
</publishername>
<date>January 15, 2012</date>
</biblioentry>
<biblioentry id="cook">
<abbrev>Cook</abbrev>
<author>
<firstname>John D.</firstname>
<surname>Cook</surname>
</author>
<title>
<ulink
url="https://www.johndcook.com/blog/ieee_exceptions_in_cpp/">IEEE
floating-point exceptions in C++</ulink>
</title>
</biblioentry>
<biblioentry id="crowl">
<abbrev>Crowl</abbrev>
<author>
<firstname>Lawrence</firstname>
<surname>Crowl</surname>
</author>
<title>
<ulink url="http://www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?">
<ulink
url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3352.html">C++
Binary Fixed-Point Arithmetic</ulink>
</ulink>
</title>
<publishername>
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/">JTC1/SC22/WG21 -
The C++ Standards Committee - ISOCPP</ulink>
</publishername>
<date>January 15, 2012</date>
</biblioentry>
<biblioentry id="crowl2">
<abbrev>Crowl & Ottosen</abbrev>
<author>
<firstname>Lawrence</firstname>
<surname>Crowl</surname>
</author>
<author>
<surname>Thorsten Ottosen</surname>
</author>
<title>
<ulink url="http://www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?">
<ulink
url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1962.html">Proposal
to add Contract Programming to C++</ulink>
</ulink>
</title>
<publishername>
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/">WG21/N1962 and
J16/06-0032 - The C++ Standards Committee - ISOCPP</ulink>
</publishername>
<date>February 25, 2006</date>
</biblioentry>
<biblioentry id="dietz">
<abbrev>Dietz</abbrev>
<author>
<firstname>Will</firstname>
<surname>Dietz</surname>
</author>
<author>
<firstname>Peng</firstname>
<surname>Li</surname>
</author>
<author>
<firstname>John</firstname>
<surname>Regehr</surname>
</author>
<author>
<firstname>Vikram</firstname>
<surname>Adve</surname>
</author>
<title>
<ulink
url="http://www.cs.utah.edu/~regehr/papers/overflow12.pdf">Understanding
Integer Overflow in C/C++</ulink>
</title>
<publishername>
<ulink
url="http://dl.acm.org/citation.cfm?id=2337223&picked=prox">Proceedings
of the 34th International Conference on Software Engineering (ICSE),
Zurich, Switzerland</ulink>
</publishername>
<date>June 2012</date>
</biblioentry>
<biblioentry id="garcia">
<abbrev>Garcia</abbrev>
<author>
<firstname>J. Daniel</firstname>
<surname>Garcia</surname>
</author>
<title>
<ulink url="http://www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?">
<ulink
url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4293.pdf">C++
language support for contract programming</ulink>
</ulink>
</title>
<publishername>
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/">WG21/N4293 - The
C++ Standards Committee - ISOCPP</ulink>
</publishername>
<date>December 23, 2014</date>
</biblioentry>
<biblioentry id="goldberg">
<abbrev>Goldberg</abbrev>
<author>
<firstname>David</firstname>
<surname>Goldberg</surname>
</author>
<title>
<ulink
url="https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html">What
Every Computer Scientist Should Know About Floating-Point
Arithmetic</ulink>
</title>
<publishername>
<ulink url="https://csur.acm.org/index.cfm">ACM Computing
Surveys</ulink>
</publishername>
<date>March, 1991</date>
</biblioentry>
<biblioentry id="katz">
<abbrev>Katz</abbrev>
<author>
<firstname>Omer</firstname>
<surname>Katz</surname>
</author>
<title>
<ulink
url="http://www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?">SafeInt
code proposal</ulink>
</title>
<publishername>
<ulink
url="https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/std-proposals">Boost
Developer's List</ulink>
</publishername>
<abstract>
<para>Posts of various authors regarding a proposed SafeInt library
for boost</para>
</abstract>
</biblioentry>
<biblioentry id="keaton">
<author>
<firstname>David</firstname>
<surname>Keaton</surname>
</author>
<author>
<firstname>Thomas</firstname>
<surname>Plum</surname>
</author>
<author>
<firstname>Robert</firstname>
<othername>C.</othername>
<surname>Seacord</surname>
</author>
<author>
<firstname>David</firstname>
<surname>Svoboda</surname>
</author>
<author>
<firstname>Alex</firstname>
<surname>Volkovitsky</surname>
</author>
<author>
<firstname>Timothy</firstname>
<surname>Wilson</surname>
</author>
<title>
<ulink url="http://www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?">
<ulink
url="http://resources.sei.cmu.edu/asset_files/TechnicalNote/2009_004_001_15074.pdf">As-if
Infinitely Ranged Integer Model</ulink>
</ulink>
</title>
<publishername>
<ulink url="http://www.sei.cmu.edu">Software Engineering
Institute</ulink>
</publishername>
<volumenum>CMU/SEI-2009-TN-023</volumenum>
<abstract>
<para>Presents a model for addressing integer overflow errors.</para>
</abstract>
</biblioentry>
<biblioentry id="leblanc1">
<abbrev>LeBlanc</abbrev>
<author>
<firstname>David</firstname>
<surname>LeBlanc</surname>
</author>
<title>
<ulink
url="https://msdn.microsoft.com/en-us/library/ms972705.aspx">Integer
Handling with the C++ SafeInt Class</ulink>
</title>
<publishername>
<ulink url="https://www.cert.org">Microsoft Developer Network</ulink>
</publishername>
<date>January 7, 2004</date>
</biblioentry>
<biblioentry id="leblanc2">
<abbrev>LeBlanc</abbrev>
<author>
<firstname>David</firstname>
<surname>LeBlanc</surname>
</author>
<title>
<ulink url="https://safeint.codeplex.com">SafeInt</ulink>
</title>
<publishername>
<ulink url="https://www.cert.org">CodePlex</ulink>
</publishername>
<date>Dec 3, 2014</date>
</biblioentry>
<biblioentry id="lions">
<abbrev>Lions</abbrev>
<author>
<firstname>Jacques-Louis</firstname>
<surname>Lions</surname>
</author>
<title>
<ulink
url="https://en.wikisource.org/wiki/Ariane_501_Inquiry_Board_report">Ariane
501 Inquiry Board report</ulink>
</title>
<publishername>
<ulink
url="https://en.wikisource.org/wiki/Main_Page">Wikisource</ulink>
</publishername>
<date>July 19, 1996</date>
</biblioentry>
<biblioentry id="matthews">
<abbrev>Matthews</abbrev>
<author>
<firstname>Hubert</firstname>
<surname>Matthews</surname>
</author>
<title>
<ulink url="https://accu.org/index.php/journals/324">CheckedInt: A
Policy-Based Range-Checked Integer</ulink>
</title>
<publishername>
<ulink url="https://accu.org/index.php">Overload Journal #58</ulink>
</publishername>
<date>December 2003</date>
</biblioentry>
<biblioentry id="mouawad">
<abbrev>Mouawad</abbrev>
<author>
<firstname>Jad</firstname>
<surname>Mouawad</surname>
</author>
<title>
<ulink url="http://www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?">
<ulink
url="http://www.nytimes.com/2015/05/01/business/faa-orders-fix-for-possible-power-loss-in-boeing-787.html?_r=0">F.A.A
Orders Fix for Possible Power Loss in Boeing 787</ulink>
</ulink>
</title>
<publishername>New York Times</publishername>
<date>April 30, 2015</date>
<abstract>
<para>Federal regulators will order operators of Boeing 787
Dreamliners to shut down the plane’s electrical power periodically
after Boeing discovered a software error that could result in a total
loss of power.</para>
</abstract>
</biblioentry>
<biblioentry id="plakosh">
<abbrev>Plakosh</abbrev>
<author>
<firstname>Daniel</firstname>
<surname>Plakosh</surname>
</author>
<title>
<ulink
url="https://buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/312-BSI.html">Safe
Integer Operations</ulink>
</title>
<publishername>
<ulink url="https://buildsecurityin.us-cert.gov">U.S. Department of
Homeland Security</ulink>
</publishername>
<date>May 10, 2013</date>
</biblioentry>
<biblioentry id="seacord1">
<abbrev>Seacord</abbrev>
<author>
<firstname>Robert C.</firstname>
<surname>Seacord</surname>
</author>
<title>
<ulink
url="http://www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?">Secure
Coding in C and C++</ulink>
</title>
<edition>2nd Edition</edition>
<publishername>Addison-Wesley Professional</publishername>
<date>April 12, 2013</date>
<isbn>978-0321822130</isbn>
</biblioentry>
<biblioentry id="seacord2">
<abbrev>INT30-C</abbrev>
<author>
<firstname>Robert C.</firstname>
<surname>Seacord</surname>
</author>
<title>
<ulink
url="https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow?showComments=false">INT30-C.
Ensure that operations on unsigned integers do not wrap</ulink>
</title>
<publishername>
<ulink url="https://www.cert.org">Software Engineering Institute,
Carnegie Mellon University</ulink>
</publishername>
<date>August 17, 2014</date>
</biblioentry>
<biblioentry id="seacord3">
<abbrev>INT32-C</abbrev>
<author>
<firstname>Robert C.</firstname>
<surname>Seacord</surname>
</author>
<title>
<ulink
url="https://www.securecoding.cert.org/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap">INT32-C.
Ensure that operations on signed integers do not result in
overflow</ulink>
</title>
<publishername>
<ulink url="https://www.cert.org">Software Engineering Institute,
Carnegie Mellon University</ulink>
</publishername>
<date>August 17, 2014</date>
</biblioentry>
<biblioentry id="stone">
<abbrev>Stone</abbrev>
<author>
<firstname>David</firstname>
<surname>Stone</surname>
</author>
<title>
<ulink url="http://doublewise.net/c++/bounded/">C++ Bounded Integer
Library</ulink>
</title>
</biblioentry>
<biblioentry id="stroustrup">
<abbrev>Stroustrup</abbrev>
<author>
<firstname>Bjarn</firstname>
<surname>Stroustrup</surname>
</author>
<title>The C++ Programming Language</title>
<edition>Fourth Edition</edition>
<publishername>
<ulink
url="http://www.open-std.org/jtc1/sc22/wg21/">Addison-Wesley</ulink>
</publishername>
<copyright>
<year>2014 by Pearson Education, Inc.</year>
</copyright>
<date>January 15, 2012</date>
</biblioentry>
<biblioentry id="forum">
<abbrev>Forum</abbrev>
<author>
<surname>Forum Posts</surname>
</author>
<title>
<ulink url="http://www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?">
<ulink
url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3352.html">C++
Binary Fixed-Point Arithmetic</ulink>
</ulink>
</title>
<publishername>
<ulink
url="https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/std-proposals">ISO
C++ Standard Future Proposals</ulink>
</publishername>
<abstract>
<para>Posts of various authors regarding proposal to add safe integer
to C++ standard libraries</para>
</abstract>
</biblioentry>
</bibliography>
</section>
================================================
FILE: doc/boostbook/checked.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.checked_arithmetic">
<title>Checked Arithmetic</title>
<?dbhtml stop-chunking?>
<section>
<title>Description</title>
<para>Perform binary operations on arithmetic types. Return either a valid
result or an error code. Under no circumstances should an incorrect result
be returned.</para>
</section>
<section>
<title>Type requirements</title>
<para>All template parameters of the functions must model <link
linkend="safe_numerics.integer">Numeric</link> type requirements.</para>
</section>
<section>
<title>Complexity</title>
<para>Each function performs one and only one arithmetic operation.</para>
</section>
<section>
<title>Example of use</title>
<programlisting>#include <boost/numeric/safe_numerics/checked_default.hpp>
checked_result<int> r = checked::multiply<int>(24, 42);
</programlisting>
</section>
<section>
<title>Notes</title>
<para>Some compilers have command line switches (e.g. -ftrapv) which
enable special behavior such that erroneous integer operations are
detected at run time. The library has been implemented in such a way that
these facilities are not used. It's possible they might be helpful in
particular environment. These could be be exploited by re-implementing
some functions in this library.</para>
</section>
<section>
<title>Synopsis</title>
<programlisting>// safe casting on primitive types
template<class R, class T>
checked_result<R> constexpr checked::cast(const T & t);
// safe addition on primitive types
template<class R>
checked_result<R> constexpr checked::add(const R & t, const R & u);
// safe subtraction on primitive types
template<class R>
checked_result<R> constexpr checked::subtract(const R & t, const R & u);
// safe multiplication on primitive types
template<class R>
checked_result<R> constexpr checked::multiply(const R & t, const R & u);
// safe division on primitive types
template<class R>
checked_result<R> constexpr checked::divide(const R & t, const R & u);
// safe modulus on primitive types
template<class R>
checked_result<R> constexpr checked::modulus(const R & t, const R & u);
// safe less than predicate on primitive types
template<class R>
bool constexpr checked::less_than(const R & t, const R & u);
// safe greater_than_equal predicate on primitive types
template<class R>
bool constexpr checked::greater_than_equal(const R & t, const R & u);
// safe greater_than predicate on primitive types
template<class R>
bool constexpr checked::greater_than(const R & t, const R & u);
// safe less_than_equal predicate on primitive types
template<class R>
bool constexpr checked::less_than_equal(const R & t, const R & u);
// safe equal predicate on primitive types
template<class R>
bool constexpr checked::equal(const R & t, const R & u);
// left shift
template<class R>
checked_result<R> constexpr checked::left_shift(const R & t, const R & u);
// right shift
template<class R>
checked_result<R> constexpr checked::right_shift(const R & t, const R & u);
// bitwise operations
template<class R>
checked_result<R> constexpr checked::bitwise_or(const R & t, const R & u);
template<class R>
checked_result<R> constexpr checked::bitwise_and(const R & t, const R & u);
template<class R>
checked_result<R> constexpr checked::bitwise_xor(const R & t, const R & u);
</programlisting>
</section>
<section>
<title>See Also</title>
<para><link
linkend="safenumerics.checked_result">checked_result<R></link></para>
</section>
<section>
<title>Header</title>
<para><ulink
url="../../include/boost/safe_numerics/checked_default.hpp"><code>#include
<boost/numeric/safe_numerics/checked_default.hpp>
</code></ulink></para>
<para><ulink
url="../../include/boost/safe_numerics/checked_integer.hpp"><code>#include
<boost/numeric/safe_numerics/checked_integer.hpp>
</code></ulink></para>
<para><ulink url="../../include/checked.hpp"><code/></ulink><ulink
url="../../include/boost/safe_numerics/checked_float.hpp"><code>#include
<boost/numeric/safe_numerics/checked_float.hpp>
</code></ulink></para>
</section>
</section>
================================================
FILE: doc/boostbook/checked_result.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="safenumerics.checked_result">
<title>checked_result<R></title>
<?dbhtml stop-chunking?>
<section>
<title>Description</title>
<para>checked_result is a special kind of variant class designed to hold
the result of some operation. It can hold either the result of the
operation or information on why the operation failed to produce a valid
result. It is similar to other types proposed for and/or included to the
C++ standard library or Boost such as<code> expected</code>,
<code>variant</code>, <code>optional</code> and <code>outcome</code>. In
some circumstances it may be referred to as a "monad".</para>
<para><itemizedlist>
<listitem>
<para>All instances of <code>checked_result<R></code> are
immutable. That is, once constructed, they cannot be altered.</para>
</listitem>
<listitem>
<para>There is no default constructor.</para>
</listitem>
<listitem>
<para><code>checked_result<R></code> is never empty.</para>
</listitem>
<listitem>
<para>Binary operations supported by type R are guaranteed to be
supported by checked_result<R>.</para>
</listitem>
<listitem>
<para>Binary operations can be invoked on a pair of
<code>checked_result<R></code> instances if and only if the
underlying type (R) is identical for both instances. They will
return a value of type <code>checked_result<R></code>.</para>
</listitem>
<listitem>
<para>Unary operations can be invoked on
<code>checked_result<R></code> instances. They will return a
value of type <code>checked_result<R></code>.</para>
</listitem>
<listitem>
<para>Comparison operations will return a
<code>boost::logic::tribool</code>. Other binary operations will a
value of the same type as the arguments.</para>
</listitem>
</itemizedlist></para>
<para>Think of <code>checked<R></code> as an "extended" version of R
which can hold all the values that R can hold in addition other "special
values". For example, consider checked<int>.</para>
</section>
<section>
<title>Notation</title>
<informaltable>
<tgroup cols="2">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="4*"/>
<thead>
<row>
<entry align="left">Symbol</entry>
<entry align="left">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>R</code></entry>
<entry>Underlying type</entry>
</row>
<row>
<entry><code>r</code></entry>
<entry>An instance of type R</entry>
</row>
<row>
<entry><code>c, c1, c2</code></entry>
<entry>an instance of checked_result<R></entry>
</row>
<row>
<entry><code>t</code></entry>
<entry>an instance of checked_result<T> for some type T not
necessarily the same as R</entry>
</row>
<row>
<entry><code>e</code></entry>
<entry>An instance of type <link
linkend="safe_numerics.safe_numerics_error"><code>safe_numerics_error</code></link></entry>
</row>
<row>
<entry><code>msg</code></entry>
<entry>An instance of type const char *</entry>
</row>
<row>
<entry><code>OS</code></entry>
<entry>A type convertible to <link
linkend="safe_numerics.safe_numerics_error"><code>std::basic_ostream</code></link></entry>
</row>
<row>
<entry><code>os</code></entry>
<entry>An instance of type convertible to <link
linkend="safe_numerics.safe_numerics_error"><code>std::basic_ostream</code></link></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Template Parameters</title>
<para>R must model the type requirements of <link
linkend="safe_numerics.numeric">Numeric</link></para>
<informaltable>
<tgroup cols="2">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="4*"/>
<thead>
<row>
<entry align="left">Parameter</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>R</code></entry>
<entry>Underlying type</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Model of</title>
<para><link linkend="safe_numerics.numeric">Numeric</link></para>
</section>
<section>
<title>Valid Expressions</title>
<para>All expressions are <code>constexpr</code>.</para>
<para><informaltable>
<tgroup cols="3">
<colspec align="left" colwidth="2*"/>
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="3*"/>
<thead>
<row>
<entry align="left">Expression</entry>
<entry>Return Type</entry>
<entry>Semantics</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>checked_result(r)</code></entry>
<entry><code>checked_result<R></code></entry>
<entry>constructor with valid instance of R</entry>
</row>
<row>
<entry><code>checked_result<R>(t)</code></entry>
<entry><code>checked_result<R></code></entry>
<entry>constructor with <code>checked_result<T></code>
where T is not R. T must be convertible to R.</entry>
</row>
<row>
<entry><code>checked_result(e, msg)</code></entry>
<entry><code>checked_result<R></code></entry>
<entry>constructor with error information</entry>
</row>
<row>
<entry><code>static_cast<R>(c)</code></entry>
<entry>R</entry>
<entry>extract wrapped value - compile time error if not
possible</entry>
</row>
<row>
<entry><code>static_cast<<code><link
linkend="safe_numerics.safe_numerics_error"><code>safe_numerics_error</code></link></code>>(c)</code></entry>
<entry><link
linkend="safe_numerics.safe_numerics_error"><code>safe_numerics_error</code></link></entry>
<entry>extract wrapped value - may return <link
linkend="safe_numerics.safe_numerics_error"><code>safe_numerics_error</code></link><code>::success</code>
if there is no error</entry>
</row>
<row>
<entry><code>static_cast<const char *>(c)</code></entry>
<entry><code>const char *</code></entry>
<entry>returns pointer to the included error message</entry>
</row>
<row>
<entry><code>c.exception()</code></entry>
<entry><code>bool</code></entry>
<entry>true if <code>checked_result</code> contains an error
condition.</entry>
</row>
<row>
<entry><code><simplelist>
<member>c1 < c2</member>
<member>c1 >= c2</member>
<member>c1 > c2</member>
<member>c1 <= c2</member>
<member>c1 == c2</member>
<member>c1 != c2</member>
</simplelist></code></entry>
<entry><code>boost::logic::tribool</code></entry>
<entry>compare the wrapped values of two checked_result
instances. If the values are such that the result of such a
comparison cannot be reasonably defined, The result of the
comparison is
<code>boost::logic::tribool::indeterminant</code>.</entry>
</row>
<row>
<entry><code><simplelist>
<member>c1 + c2</member>
<member>c1 - c2</member>
<member>c1 * c2</member>
<member>c1 / c2</member>
<member>c1 % c2</member>
<member>c1 | c2</member>
<member>c1 & c2</member>
<member>c1 ^ c2</member>
<member>c1 << c2</member>
<member>c1 >> c2</member>
</simplelist></code></entry>
<entry><code>checked_result<R></code></entry>
<entry>returns a new instance of
<code>checked_result<R>.</code></entry>
</row>
<row>
<entry><code><simplelist>
<member>os << c</member>
</simplelist></code></entry>
<entry><code>OS</code></entry>
<entry>writes result to output stream. If the result is an error
it writes the string corresponding to the error message.
Otherwise, it writes the numeric value resulting from the
operation. Returns reference to output stream.</entry>
</row>
</tbody>
</tgroup>
</informaltable></para>
</section>
<section>
<title>Example of use</title>
<programlisting><xi:include href="../../example/example20.cpp"
parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
</section>
<section>
<title>See Also</title>
<para><link
linkend="safe_numerics.exception_policy">ExceptionPolicy</link></para>
</section>
<section>
<title>Header</title>
<para><ulink
url="../../include/boost/safe_numerics/checked_result.hpp"><code>#include
<boost/numeric/safe_numerics/checked_result.hpp></code></ulink></para>
<para><ulink
url="../../include/boost/safe_numerics/checked_result_operations.hpp"><code>#include
<boost/numeric/safe_numerics/checked_result_operations.hpp>
</code></ulink></para>
</section>
</section>
================================================
FILE: doc/boostbook/cpp.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.promotion_policies.cpp">
<title>cpp<int C, int S, int I, int L, int LL></title>
<section>
<title>Description</title>
<para>This policy is used to promote safe types in arithmetic expressions
according to the rules in the C++ standard. But rather than using the
native C++ standard types supported by the compiler, it uses types whose
length in number of bits is specified by the template parameters.</para>
<para>This policy is useful for running test programs which use C++
portable integer types but which are destined to run on an architecture
which is different than the one on which the test program is being built
and run. This can happen when developing code for embedded systems.
Algorithms developed or borrowed from one architecture but destined for
another can be tested on the desktop.</para>
<para>Note that this policy is only applicable to safe types whose base
type is a type fulfilling the type requirements of <link
linkend="safe_numerics.integer">Integer</link>.</para>
</section>
<section>
<title>Template Parameters</title>
<informaltable>
<tgroup cols="3">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="6*"/>
<thead>
<row>
<entry align="left">Parameter</entry>
<entry align="left">Type</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>C</code></entry>
<entry>int</entry>
<entry>Number of bits in a char</entry>
</row>
<row>
<entry><code>S</code></entry>
<entry>int</entry>
<entry>Number of bits in a short</entry>
</row>
<row>
<entry><code>I</code></entry>
<entry>int</entry>
<entry>Number of bits in an integer</entry>
</row>
<row>
<entry><code>L</code></entry>
<entry>int</entry>
<entry>Number of bits in a long</entry>
</row>
<row>
<entry><code>LL</code></entry>
<entry>int</entry>
<entry>Number of bits in a long long</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Model of</title>
<para><link
linkend="safe_numerics.promotion_policy">PromotionPolicy</link></para>
</section>
<section>
<title>Example of Use</title>
<para>Consider the following problem. One is developing software which
uses a very small microprocessor and a very limited C compiler. The chip
is so small, you can't print anything from the code, log, debug or
anything else. One debugs this code by using the "burn" and "crash" method
- you burn the chip (download the code), run the code, observe the
results, make changes and try again. This is a crude method which is
usually the one used. But it can be quite time consuming.</para>
<para>Consider an alternative. Build and compile your code in testable
modules. For each module write a test which exercises all the code and
makes it work. Finally download your code into the chip and - voilà -
working product. This sounds great, but there's one problem. Our target
processor - in this case a PIC162550 from Microchip Technology is only an
8 bit CPU. The compiler we use defines INT as 8 bits. This (and a few
other problems), make our algorithm testing environment differ from our
target environment. We can address this by defining INT as a safe integer
with a range of 8 bits. By using a custom promotion policy, we can force
the evaluation of C++ expressions in the test environment to be the same
as that in the target environment. Also in our target environment, we can
trap any overflows or other errors. So we can write and test our code on
our desktop system and download the code to the target knowing that it
just has to work. This is a huge time saver and confidence builder. For an
extended example on how this is done, look at <link
linkend="safe_numerics.safety_critical_embedded_controller">Safety
Critical Embedded Controller</link> .</para>
</section>
<section>
<title>Header</title>
<para><code><ulink
url="../../include/boost/safe_numerics/cpp.hpp"><code>#include
<boost/numeric/safe_numerics/cpp.hpp> </code></ulink></code></para>
</section>
</section>
================================================
FILE: doc/boostbook/db2epub.xsl
================================================
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- ************** HTML ************** -->
<xsl:import href="http://www.boost.org/tools/boostbook/xsl/html.xsl"/>
<!--
Make library documentation header using some elements from boostbook stylesheets.
Override boost book implemenation of header.navigation with our own
-->
<xsl:template name = "header.navigation">
<xsl:param name = "prev" select = "/foo"/>
<xsl:param name = "next" select = "/foo"/>
<xsl:param name = "nav.context"/>
<table cellpadding = "2" width = "100%"><tr>
<td valign = "top">
<img href="index.html" height="164px" src="pre-boost.jpg" alt="Library Documentation Index" />
</td>
<td><h2>Safe Numerics</h2></td>
</tr></table>
<xsl:call-template name = "navbar.spirit">
<xsl:with-param name = "prev" select = "$prev"/>
<xsl:with-param name = "next" select = "$next"/>
<xsl:with-param name = "nav.context" select = "$nav.context"/>
</xsl:call-template>
</xsl:template>
<!-- remove "Chapter 1" from first page -->
<xsl:param name="chapter.autolabel" select="0"/>
<!-- leave the html files in the directory ../html -->
<xsl:param name="base.dir" select="'../html/'"/>
<!-- ******* Table of Contents ******** -->
<!-- How far down sections get TOC's -->
<xsl:param name = "toc.section.depth" select="2" />
<!-- Max depth in each TOC: -->
<xsl:param name = "toc.max.depth" select="2" />
<!-- How far down we go with TOC's -->
<xsl:param name="generate.section.toc.level" select="2" />
<!-- ************ Chunking ************ -->
<!--
BoostBook takes a section node id like safe_numeric.safe_cast
and renders it as safe_numeric/safe_cast. Presumably they do this
so they can make a huge "book" with all the libraries in subdirectories.
But we want something different. To my mind, this should have been
done using the library "directory" attribute. But of course that
doesn't matter now. We'll just re-hack the path to eliminate
the "safe_numeric/" from the above example.
-->
<xsl:template match="*" mode="recursive-chunk-filename">
<xsl:variable name="their">
<xsl:apply-imports mode="recursive-chunk-filename" select="."/>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains($their, '/')">
<xsl:value-of select="substring-after($their, '/')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$their"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- don't make first sections special - leave TOC in different file -->
<xsl:param name="chunk.first.sections" select="3" />
<!-- How far down we chunk nested sections -->
<!--
Note: each chunk have to start with a section with an id
Otherwise the chunk (i.e. file) will be lost. There is no
checking of this
-->
<xsl:param name="chunk.section.depth" select="3" />
</xsl:stylesheet>
================================================
FILE: doc/boostbook/db2fo.xsl
================================================
<?xml version='1.0'?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0"
>
<!-- ************** FOP ************** -->
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
<xsl:param name="fop1.extensions">1</xsl:param>
<xsl:param name="sidebar.float.type">none</xsl:param>
<xsl:param name="alignment">left</xsl:param>
<!--
Make all hyperlinks blue colored:
-->
<xsl:attribute-set name="xref.properties">
<xsl:attribute name="color">blue</xsl:attribute>
</xsl:attribute-set>
<!--
Put a box around admonishments and keep them together:
-->
<xsl:attribute-set name="graphical.admonition.properties">
<xsl:attribute name="border-color">#FF8080</xsl:attribute>
<xsl:attribute name="border-width">1px</xsl:attribute>
<xsl:attribute name="border-style">solid</xsl:attribute>
<xsl:attribute name="padding-left">0.2cm</xsl:attribute>
<xsl:attribute name="padding-right">0.2cm</xsl:attribute>
<xsl:attribute name="padding-top">0.2cm</xsl:attribute>
<xsl:attribute name="padding-bottom">0.2cm</xsl:attribute>
<xsl:attribute name="keep-together.within-page">1</xsl:attribute>
<xsl:attribute name="margin-left">0pt</xsl:attribute>
<xsl:attribute name="margin-right">0pt</xsl:attribute>
</xsl:attribute-set>
<!--
Put a box around code blocks, also set the font size
and keep the block together if we can using the widows
and orphans controls. Hyphenation and line wrapping
is also turned on, so that long lines of code don't
bleed off the edge of the page, a carriage return
symbol is used as the hyphenation character:
-->
<xsl:attribute-set name="monospace.verbatim.properties">
<xsl:attribute name="border-color">#DCDCDC</xsl:attribute>
<xsl:attribute name="border-width">1px</xsl:attribute>
<xsl:attribute name="border-style">solid</xsl:attribute>
<xsl:attribute name="padding-left">0.2cm</xsl:attribute>
<xsl:attribute name="padding-right">0.2cm</xsl:attribute>
<xsl:attribute name="padding-top">0.2cm</xsl:attribute>
<xsl:attribute name="padding-bottom">0.2cm</xsl:attribute>
<xsl:attribute name="widows">6</xsl:attribute>
<xsl:attribute name="orphans">40</xsl:attribute>
<xsl:attribute name="font-size">9pt</xsl:attribute>
<xsl:attribute name="margin-left">0pt</xsl:attribute>
<xsl:attribute name="background-color">#EEEEEE</xsl:attribute>
<xsl:attribute name="margin-right">0pt</xsl:attribute>
<!--
<xsl:attribute name="hyphenate">true</xsl:attribute>
<xsl:attribute name="wrap-option">wrap</xsl:attribute>
<xsl:attribute name="hyphenation-character">↵</xsl:attribute>
-->
<xsl:attribute name="hyphenate">false</xsl:attribute>
<xsl:attribute name="wrap-option">no-wrap</xsl:attribute>
</xsl:attribute-set>
<!--Regular monospace text should have the same font size as code blocks etc-->
<xsl:attribute-set name="monospace.properties">
<xsl:attribute name="font-size">9pt</xsl:attribute>
</xsl:attribute-set>
<!--
Put some small amount of padding around table cells, and keep tables
together on one page if possible:
-->
<xsl:attribute-set name="table.cell.padding">
<xsl:attribute name="padding-left">0.2cm</xsl:attribute>
<xsl:attribute name="padding-right">0.2cm</xsl:attribute>
<xsl:attribute name="padding-top">0.2cm</xsl:attribute>
<xsl:attribute name="padding-bottom">0.2cm</xsl:attribute>
</xsl:attribute-set>
<!--Formal and informal tables have the same properties-->
<xsl:param name="table.frame.border.thickness">medium</xsl:param>
<xsl:param name="table.cell.border.thickness">medium</xsl:param>
<xsl:param name="table.frame.border.color">#DCDCDC</xsl:param>
<xsl:param name="table.cell.border.color">#DCDCDC</xsl:param>
<!--Formal and informal tables have the same properties
Using widow-and-orphan control here gives much better
results for very large tables than a simple "keep-together"
instruction
-->
<xsl:attribute-set name="table.properties">
<xsl:attribute name="keep-together.within-page">1</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="informaltable.properties">
<xsl:attribute name="keep-together.within-page">1</xsl:attribute>
</xsl:attribute-set>
<!--
General default options go here:
* Borders are mid-grey.
* Body text is not indented compared to the titles.
* Page margins are a rather small 0.5in, but we need
all the space we can get for code blocks.
* Paper size is A4: an ISO standard, slightly taller and narrower than US Letter.
* Use SVG graphics for admonishments: the bitmaps look awful in PDF's.
* Disable draft mode so we're not constantly trying to download the necessary graphic.
* Set default image paths to pull down direct from SVN: individual Jamfiles can override this
and pass an absolute path to local versions of the images, but we can't get that here, so
we'll use SVN instead so that most things "just work".
-->
<xsl:param name="body.start.indent">0pt</xsl:param>
<xsl:param name="admon.graphics">1</xsl:param>
<xsl:param name="admon.graphics.extension">.svg</xsl:param>
<xsl:param name="draft.mode">no</xsl:param>
<xsl:param name="double.sided">1</xsl:param>
<xsl:param name="show.bookmarks" select="1"></xsl:param>
<xsl:param name="page.margin.inner">0.75in</xsl:param>
<xsl:param name="page.margin.outer">0.50in</xsl:param>
<xsl:param name="body.margin.top">0.50in</xsl:param>
<xsl:param name="section.autolabel" select="1"></xsl:param>
<xsl:param name="section.autolabel.max.depth">2</xsl:param>
<xsl:param name="ulink.show" select="0"></xsl:param>
<xsl:param name="admon.graphics.path">http://svn.boost.org/svn/boost/trunk/doc/src/images/</xsl:param>
<xsl:param name="callout.graphics.path">http://svn.boost.org/svn/boost/trunk/doc/src/images/callouts/</xsl:param>
<!-- ******* Table of Contents ******** -->
<!-- How far down sections get TOC's -->
<xsl:param name = "toc.section.depth" select="3" />
<!-- Max depth in each TOC: -->
<xsl:param name = "toc.max.depth" select="3" />
<!-- How far down we go with TOC's -->
<xsl:param name="generate.section.toc.level" select="0" />
<!-- ******* Chapter Titles ******* -->
<xsl:param name="force.blank.pages" select="1"></xsl:param>
<!--
<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
<l:l10n language="en">
<l:context name="title-numbered">
<l:template name="chapter" text="%n. %t"/>
</l:context>
</l:l10n>
</l:i18n>
-->
<xsl:attribute-set name="chapter.title.properties">
<xsl:attribute name="font-family">
<xsl:value-of select="$title.font.family"/>
</xsl:attribute>
<xsl:attribute name="font-weight">bold</xsl:attribute>
<!-- font size is added dynamically by section.heading template -->
<xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.optimum">1.0em</xsl:attribute>
<xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
<xsl:attribute name="text-align">left</xsl:attribute>
<xsl:attribute name="start-indent">0pt</xsl:attribute>
</xsl:attribute-set>
<!-- ******* Section Level 5 properties ******* -->
<!-- used by bridgeheads -->
<xsl:attribute-set name="section.title.level5.properties">
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.2"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
</xsl:attribute-set>
</xsl:stylesheet>
================================================
FILE: doc/boostbook/db2html.xsl
================================================
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- ************** HTML ************** -->
<xsl:import href="http://www.boost.org/tools/boostbook/xsl/html.xsl"/>
<!--
Make library documentation header using some elements from boostbook stylesheets.
Override boost book implemenation of header.navigation with our own
-->
<xsl:template name = "header.navigation">
<xsl:param name = "prev" select = "/foo"/>
<xsl:param name = "next" select = "/foo"/>
<xsl:param name = "nav.context"/>
<table cellpadding = "2" width = "100%"><tr>
<td valign = "top">
<img href="index.html" height="164px" src="pre-boost.jpg" alt="Library Documentation Index" />
</td>
<td><h2>Safe Numerics</h2></td>
</tr></table>
<xsl:call-template name = "navbar.spirit">
<xsl:with-param name = "prev" select = "$prev"/>
<xsl:with-param name = "next" select = "$next"/>
<xsl:with-param name = "nav.context" select = "$nav.context"/>
</xsl:call-template>
</xsl:template>
<!-- remove "Chapter 1" from first page -->
<xsl:param name="chapter.autolabel" select="0"/>
<!-- leave the html files in the directory ../html -->
<xsl:param name="base.dir" select="'../html/'"/>
<!-- ******* Table of Contents ******** -->
<!-- How far down sections get TOC's -->
<xsl:param name = "toc.section.depth" select="2" />
<!-- Max depth in each TOC: -->
<xsl:param name = "toc.max.depth" select="2" />
<!-- How far down we go with TOC's -->
<xsl:param name="generate.section.toc.level" select="2" />
<!-- ************ Chunking ************ -->
<!--
BoostBook takes a section node id like safe_numeric.safe_cast
and renders it as safe_numeric/safe_cast. Presumably they do this
so they can make a huge "book" with all the libraries in subdirectories.
But we want something different. To my mind, this should have been
done using the library "directory" attribute. But of course that
doesn't matter now. We'll just re-hack the path to eliminate
the "safe_numeric/" from the above example.
-->
<xsl:template match="*" mode="recursive-chunk-filename">
<xsl:variable name="their">
<xsl:apply-imports mode="recursive-chunk-filename" select="."/>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains($their, '/')">
<xsl:value-of select="substring-after($their, '/')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$their"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- don't make first sections special - leave TOC in different file -->
<xsl:param name="chunk.first.sections" select="3" />
<!-- How far down we chunk nested sections -->
<!--
Note: each chunk have to start with a section with an id
Otherwise the chunk (i.e. file) will be lost. There is no
checking of this
-->
<xsl:param name="chunk.section.depth" select="3" />
</xsl:stylesheet>
================================================
FILE: doc/boostbook/db2pdf.xsl
================================================
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- ************** HTML ************** -->
<xsl:import href="http://www.boost.org/tools/boostbook/xsl/html.xsl"/>
<!-- remove "Chapter 1" from first page -->
<xsl:param name="chapter.autolabel" select="0"/>
<!-- leave the html files in the directory ../html -->
<xsl:param name="base.dir" select="'../html/'"/>
<!-- ******* Table of Contents ******** -->
<!-- How far down sections get TOC's -->
<xsl:param name = "toc.section.depth" select="2" />
<!-- Max depth in each TOC: -->
<xsl:param name = "toc.max.depth" select="2" />
<!-- How far down we go with TOC's -->
<xsl:param name="generate.section.toc.level" select="2" />
<!-- ************ Chunking ************ -->
<!--
BoostBook takes a section node id like safe_numeric.safe_cast
and renders it as safe_numeric/safe_cast. Presumably they do this
so they can make a huge "book" with all the libraries in subdirectories.
But we want something different. To my mind, this should have been
done using the library "directory" attribute. But of course that
doesn't matter now. We'll just re-hack the path to eliminate
the "safe_numeric/" from the above example.
-->
<xsl:template match="*" mode="recursive-chunk-filename">
<xsl:variable name="their">
<xsl:apply-imports mode="recursive-chunk-filename" select="."/>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains($their, '/')">
<xsl:value-of select="substring-after($their, '/')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$their"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- don't make first sections special - leave TOC in different file -->
<xsl:param name="chunk.first.sections" select="3" />
<!-- How far down we chunk nested sections -->
<!--
Note: each chunk have to start with a section with an id
Otherwise the chunk (i.e. file) will be lost. There is no
checking of this
-->
<xsl:param name="chunk.section.depth" select="2" />
</xsl:stylesheet>
================================================
FILE: doc/boostbook/eliminate_runtime_penalty.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.eliminate_runtime_penalty">
<title>Eliminating Runtime Penalty</title>
<para>Up until now, we've mostly focused on detecting when incorrect results
are produced and handling these occurrences either by throwing an exception
or invoking some designated function. We've achieved our goal of detecting
and handling arithmetically incorrect behavior - but at cost of checking
many arithmetic operations at runtime. It is a fact that many C++
programmers will find this trade-off unacceptable. So the question arises as
to how we might minimize or eliminate this runtime penalty.</para>
<para>The first step is to determine what parts of a program might invoke
exceptions. The following program is similar to previous examples but uses a
special exception policy: <link
linkend="safe_numerics.exception_policies.loose_trap_policy"><code>loose_trap_policy</code></link>.</para>
<para><programlisting><xi:include href="../../example/example81.cpp"
parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>Now,
any expression which <emphasis><emphasis
role="bold">might</emphasis></emphasis> fail at runtime is flagged with a
compile time error. There is no longer any need for <code>try/catch</code>
blocks. Since this program does not compile, the <emphasis
role="bold">library absolutely <emphasis role="bold">guarantees that no
arithmetic expression</emphasis> will yield incorrect results</emphasis>.
Furthermore, it is <emphasis role="bold">absolutely guaranteed that no
exception will ever be thrown</emphasis>. This is our original goal.</para>
<para>Now all we need to do is make the program compile. There are a couple
of ways to achieve this.</para>
<section id="safe_numerics.eliminate_runtime_penalty.2">
<title>Using <link linkend="safe_numerics.safe_range">safe_range</link>
and <link linkend="safe_numerics.safe_literal">safe_literal</link></title>
<para>When trying to avoid arithmetic errors of the above type,
programmers will select data types which are wide enough to hold values
large enough to be certain that results won't overflow, but are not so
large as to make the program needlessly inefficient. In the example below,
we presume we know that the values we want to work with fall in the range
[-24,82]. So we "know" the program will always result in a correct result.
But since we trust no one, and since the program could change and the
expressions be replaced with other ones, we'll still use the <link
linkend="safe_numerics.exception_policies.loose_trap_policy"><code>loose_trap_policy</code></link>
exception policy to verify at compile time that what we "know" to be true
is in fact true.</para>
<programlisting><xi:include href="../../example/example83.cpp"
parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
<para><itemizedlist>
<listitem>
<para><code><code>safe_signed_range</code></code> defines a type
which is limited to the indicated range. Out of range assignments
will be detected at compile time if possible (as in this case) or at
run time if necessary.</para>
</listitem>
<listitem>
<para>A safe range could be defined with the same minimum and
maximum value effectively restricting the type to holding one
specific value. This is what <code>safe_signed_literal</code>
does.</para>
</listitem>
<listitem>
<para>Defining constants with <code>safe_signed_literal</code>
enables the library to correctly anticipate the correct range of the
results of arithmetic expressions at compile time.</para>
</listitem>
<listitem>
<para>The usage of <code><link
linkend="safe_numerics.exception_policies.loose_trap_policy"><code>loose_trap_policy</code></link></code>
will mean that any assignment to z which could be outside its legal
range will result in a compile time error.</para>
</listitem>
<listitem>
<para>All safe integer operations are implemented as constant
expressions. The usage of <code>constexpr</code> will guarantee that
<code>z</code> will be available at compile time for any subsequent
use.</para>
</listitem>
<listitem>
<para>So if this program compiles, it's guaranteed to return a valid
result.</para>
</listitem>
</itemizedlist>The output uses a custom output manipulator,
<code>safe_format</code>, for safe types to display the underlying type
and its range as well as current value. This program produces the
following run time output.</para>
<screen>example 83:
x = <signed char>[10,10] = 10
y = <signed char>[67,67] = 67
x + y = <int>[77,77] = 77
z = <signed char>[-24,82] = 77</screen>
<para>Take note of the various variable types:<itemizedlist>
<listitem>
<para><code>x</code> and <code>y</code> are safe types with fixed
ranges which encompass one single value. They can hold only that
value which they have been assigned at compile time.</para>
</listitem>
<listitem>
<para><code>The sum x + y can also be determined at compile
time.</code></para>
</listitem>
<listitem>
<para>The type of z is defined so that It can hold only values in
the closed range -24,82. We can assign the sum of x + y because it
is in the range that <code>z</code> is guaranteed to hold. If the
sum could not be be guaranteed to fall in the range of
<code>z</code>, we would get a compile time error due to the fact we
are using the <code>loose_trap_policy</code> exception
policy.</para>
</listitem>
</itemizedlist>All this information regarding the range and values of
variables has been determined at compile time. There is no runtime
overhead. The usage of safe types does not alter the calculations or
results in anyway. So <code>safe_t</code> and <code>const_safe_t</code>
could be redefined to <code>int</code> and <code>const int</code>
respectively and the program would operate identically - although it might
We could compile the program for another machine - as is common when
building embedded systems and know (assuming the target machine
architecture was the same as our native one) that no erroneous results
would ever be produced.</para>
</section>
<section id="safe_numerics.eliminate_runtime_penalty.1">
<title>Using Automatic Type Promotion</title>
<para>The C++ standard describes how binary operations on different
integer types are handled. Here is a simplified version of the
rules:</para>
<itemizedlist>
<listitem>
<para>promote any operand smaller than <code>int</code> to an
<code>int</code> or <code>unsigned int</code>.</para>
</listitem>
<listitem>
<para>if the size of the signed operand is larger than the size of the
signed operand, the type of the result will be signed. Otherwise, the
type of the result will be unsigned.</para>
</listitem>
<listitem>
<para>Convert the type each operand to the type of the result,
expanding the size as necessary.</para>
</listitem>
<listitem>
<para>Perform the operation the two resultant operands.</para>
</listitem>
</itemizedlist>
<para>So the type of the result of some binary operation may be different
than the types of either or both of the original operands.</para>
<para>If the values are large, the result can exceed the size that the
resulting integer type can hold. This is what we call "overflow". The
C/C++ standard characterizes this as undefined behavior and leaves to
compiler implementors the decision as to how such a situation will be
handled. Usually, this means just truncating the result to fit into the
result type - which sometimes will make the result arithmetically
incorrect. However, depending on the compiler and compile time switch
settings, such cases may result in some sort of run time exception or
silently producing some arbitrary result.</para>
<para>The complete signature for a safe integer type is:</para>
<para><programlisting>template <
class T, // underlying integer type
class P = native, // type promotion policy class
class E = default_exception_policy // error handling policy class
>
safe;
</programlisting></para>
<para>The promotion rules for arithmetic operations are implemented in the
default <code><link
linkend="safe_numerics.promotion_policies.native">native</link></code>
type promotion policy are consistent with those of standard C++</para>
<para>Up until now, we've focused on detecting when an arithmetic error
occurs and invoking an exception or other kind of error handler.</para>
<para>But now we look at another option. Using the <link
linkend="safe_numerics.promotion_policies.automatic"><code>automatic</code></link>
type promotion policy, we can change the rules of C++ arithmetic for safe
types to something like the following:</para>
<para><itemizedlist>
<listitem>
<para>for any C++ numeric type, we know from <ulink
url="http://en.cppreference.com/w/cpp/types/numeric_limits"><code>std::numeric_limits</code></ulink>
what the maximum and minimum values that a variable can be - this
defines a closed interval.</para>
</listitem>
<listitem>
<para>For any binary operation on these types, we can calculate the
interval of the result at compile time.</para>
</listitem>
<listitem>
<para>From this interval we can select a new type which can be
guaranteed to hold the result and use this for the calculation. This
is more or less equivalent to the following code:</para>
<programlisting>int x, y;
int z = x + y // could overflow
// so replace with the following:
int x, y;
long z = (long)x + (long)y; // can never overflow</programlisting>
<para>One could do this by editing his code manually as above, but
such a task would be tedious, error prone, non-portable and leave
the resulting code hard to read and verify. Using the <link
linkend="safe_numerics.promotion_policies.automatic"><code>automatic</code></link>
type promotion policy will achieve the equivalent result without
these problems.</para>
</listitem>
</itemizedlist></para>
<para>When using the <link
linkend="safe_numerics.promotion_policies.automatic"><code>automatic</code></link>
type promotion policy, with a given a binary operation, we silently
promote the types of the operands to a wider result type so the result
cannot overflow. This is a fundamental departure from the C++ Standard
behavior.</para>
<para>If the interval of the result cannot be guaranteed to fit in the
largest type that the machine can handle (usually 64 bits these days), the
largest available integer type with the correct result sign is used. So
even with our "automatic" type promotion scheme, it's still possible to
overflow. So while our <link
linkend="safe_numerics.promotion_policies.automatic"><code>automatic</code></link>
type promotion policy might eliminate exceptions in our example above, it
wouldn't be guaranteed to eliminate them for all programs.</para>
<para>Using the <link
linkend="safe_numerics.exception_policies.loose_trap_policy"><code>loose_trap_policy</code></link>
exception policy will produce a compile time error anytime it's possible
for an error to occur.</para>
<para>This small example illustrates how to use automatic type promotion
to eliminate all runtime penalty.</para>
<para><programlisting><xi:include href="../../example/example82.cpp"
parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting></para>
<itemizedlist>
<listitem>
<para>the <link
linkend="safe_numerics.promotion_policies.automatic"><code>automatic</code></link>
type promotion policy has rendered the result of the sum of two
<code>integers</code> as a <code>safe<long</code>> type.</para>
</listitem>
<listitem>
<para>our program compiles without error - even when using the <link
linkend="safe_numerics.exception_policies.loose_trap_policy"><code>loose_trap_policy</code></link>
exception policy. This is because since a <code>long</code> can always
hold the result of the sum of two integers.</para>
</listitem>
<listitem>
<para>We do not need to use the <code>try/catch</code> idiom to handle
arithmetic errors - we will have no exceptions.</para>
</listitem>
<listitem>
<para>We only needed to change two lines of code to achieve our goal
of guaranteed program correctness with no runtime penalty.</para>
</listitem>
</itemizedlist>
<para>The above program produces the following output:</para>
<para><screen>example 82:
x = <int>[-2147483648,2147483647] = 2147483647
y = <int>[-2147483648,2147483647] = 2
x + y = <long>[-4294967296,4294967294] = 2147483649
</screen></para>
<para>Note that if any time in the future we were to change
safe<int> to safe<long long> the program could now overflow.
But since we're using <link
linkend="safe_numerics.exception_policies.loose_trap_policy"><code>loose_trap_policy</code></link>
the modified program would fail to compile. At this point we'd have to
alter our yet program again to eliminate run time penalty or set aside our
goal of zero run time overhead and change the exception policy to <link
linkend="safe_numerics.exception_policies.default_exception_policy"><code>default_exception_policy</code></link>
.</para>
<para>Note that once we use automatic type promotion, our programming
language isn't C/C++ anymore. So don't be tempted to so something like the
following:</para>
<programlisting>// DON'T DO THIS !
#if defined(NDEBUG)
using safe_t = boost::numeric::safe<
int,
boost::numeric::automatic, // note use of "automatic" policy!!!
boost::numeric::loose_trap_policy
>;
#else
using safe_t = boost::numeric::safe<int>;
#endif
</programlisting>
</section>
<section id="safe_numerics.eliminate_runtime_penalty.3">
<title>Mixing Approaches</title>
<para>For purposes of exposition, we've divided the discussion of how to
eliminate runtime penalties by the different approaches available. A
realistic program could likely include all techniques mentioned above.
Consider the following:</para>
<programlisting><xi:include href="../../example/example84.cpp"
parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
<para><itemizedlist>
<listitem>
<para>As before, we define a type <code>safe_t</code> to reflect our
view of legal values for this program. This uses the <link
linkend="safe_numerics.promotion_policies.automatic"><code>automatic</code></link>
type promotion policy as well as the <link
linkend="safe_numerics.exception_policies.loose_trap_policy"><code>loose_trap_policy</code></link>
exception policy to enforce elimination of runtime penalties.</para>
</listitem>
<listitem>
<para>The function <code>f</code> accepts only arguments of type
<code>safe_t</code> so there is no need to check the input values.
This performs the functionality of <emphasis><emphasis
role="bold">programming by contract</emphasis></emphasis> with no
runtime cost.</para>
</listitem>
<listitem>
<para>In addition, we define <code>input_safe_t</code> to be used
when reading variables from the program console. Clearly, these can
only be checked at runtime so they use the throw_exception policy.
When variables are read from the console they are checked for legal
values. We need no ad hoc code to do this, as these types are
guaranteed to contain legal values and will throw an exception when
this guarantee is violated. In other words, we automatically get
checking of input variables with no additional programming.</para>
</listitem>
<listitem>
<para>On calling of the function <code>f</code>, arguments of type
<code>input_safe_t</code> are converted to values of type
<code>safe_t</code> . In this particular example, it can be
determined at compile time that construction of an instance of a
<code>safe_t</code> from an <code>input_safe_t</code> can never
fail. Hence, no <code>try/catch</code> block is necessary. The usage
of the <link
linkend="safe_numerics.exception_policies.loose_trap_policy"><code>loose_trap_policy</code></link>
policy for <code>safe_t</code> types guarantees this to be true at
compile time.</para>
</listitem>
</itemizedlist>Here is the output from the program when values 12 and 32
are input from the console:</para>
<screen>example 84:
type in values in format x y:33 45
x<signed char>[-24,82] = 33
y<signed char>[-24,82] = 45
z = <short>[-48,164] = 78
(x + y) = <short>[-48,164] = 78
(x - y) = <signed char>[-106,106] = -12
<short>[-48,164] = 78
</screen>
</section>
</section>
================================================
FILE: doc/boostbook/exception.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.exception">
<title>exception</title>
<?dbhtml stop-chunking?>
<section>
<title>Description</title>
<para>Here we describe the data types used to refer to exceptional
conditions which might occur. Note that when we use the word "exception",
we don't mean the C++ term which refers to a data type, but rather the
colloquial sense of a anomaly, irregularity, deviation, special case,
isolated example, peculiarity, abnormality, oddity; misfit, aberration or
out of the ordinary occurrence. This concept of "exception" is more
complex that one would think and hence is not manifested by a single
simple type. A small number of types work together to implement this
concept within the library.</para>
<para>We've leveraged on the <ulink
url="http://en.cppreference.com/w/cpp/error/error_code">std::error_code</ulink>
which is part of the standard library. We don't use all the facilities
that it offers so it's not an exact match, but it's useful and works for
our purposes.</para>
</section>
<section id="safe_numerics.safe_numerics_error">
<title>enum class safe_numerics_error</title>
<para>The following values are those which a numeric result might return.
They resemble the standard error codes used by C++ standard exceptions.
This resemblance is coincidental and they are wholly unrelated to any
codes of similar names. The reason for the resemblance is that the library
started it's development using the standard library codes. But as
development progressed it became clear that the original codes weren't
sufficient so now they stand on their own. Here are a list of error codes.
The description of what they mean is</para>
<para><informaltable>
<tgroup cols="2">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="3*"/>
<thead>
<row>
<entry align="left">Symbol</entry>
<entry align="left">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>success</code></entry>
<entry>successful operation - no error returned</entry>
</row>
<row>
<entry><code>positive_overflow_error</code></entry>
<entry>A positive number is too large to be represented by the
data type</entry>
</row>
<row>
<entry><code>negative_overflow_error</code></entry>
<entry>The absolute value of a negative number is too large to
be represented by the data type.</entry>
</row>
<row>
<entry><code>domain_error</code></entry>
<entry>the result of an operation is outside the legal range of
the result.</entry>
</row>
<row>
<entry><code>range_error</code></entry>
<entry>an argument to a function or operator is outside the
legal range - e.g. sqrt(-1).</entry>
</row>
<row>
<entry><code>precision_overflow_error</code></entry>
<entry>precision was lost in the course of executing the
operation.</entry>
</row>
<row>
<entry><code>underflow_error</code></entry>
<entry>A number is too close to zero to be represented by the
data type.</entry>
</row>
<row>
<entry><code>uninitialized_value</code></entry>
<entry>According to the C++ standard, the result may be defined
by the application. e.g. 16 >> 10 will result the expected
result of 0 on most machines.</entry>
</row>
</tbody>
</tgroup>
</informaltable></para>
<para>The above listed codes can be transformed to a instance of type
<ulink
url="http://en.cppreference.com/w/cpp/error/error_code"><code>std::error_code</code></ulink>
with the function:</para>
<para><programlisting>std::error_code make_error_code(safe_numerics_error e)</programlisting></para>
<para>This object can be</para>
</section>
<section>
<title>enum class safe_numerics_actions</title>
<para>The above error codes are classified into groups according to how
such exceptions should be handled. The following table shows the possible
actions that an error could be mapped to.</para>
<informaltable>
<tgroup cols="2">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="3*"/>
<thead>
<row>
<entry align="left">Symbol</entry>
<entry align="left">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>no_action</code></entry>
<entry>successful operation - no action action required</entry>
</row>
<row>
<entry><code>uninitialized_value</code></entry>
<entry>report attempt to use an uninitialized value - not
currently used</entry>
</row>
<row>
<entry><code>arithmetic_error</code></entry>
<entry>report an arithmetic error</entry>
</row>
<row>
<entry><code>implementation_defined_behavior</code></entry>
<entry>report an operation which the C++ standard permits but
fails to specify</entry>
</row>
<row>
<entry><code>undefined_behavior</code></entry>
<entry>report an operation whose result is undefined by the C++
standard.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>Translation of a <code>safe_numerics_error</code> into the
corresponding <code>safe_numerics_action</code> can be accomplished with
the following function:</para>
<para><programlisting>constexpr enum safe_numerics_actions
make_safe_numerics_action(const safe_numerics_error & e);</programlisting></para>
</section>
<section>
<title>See Also</title>
<itemizedlist>
<listitem>
<para><ulink url="http://en.cppreference.com/w/cpp/error">C++ Standard
Library version</ulink> The C++ standard error handling
utilities.</para>
</listitem>
<listitem>
<para><ulink
url="http://blog.think-async.com/2010/04/system-error-support-in-c0x-part-1.html">Thinking
Asynchronously in C++</ulink> Another essential reference on the
design and usage of the error_code</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Header</title>
<para><ulink
url="../../include/boost/safe_numerics/exception.hpp"><code>#include
<boost/safe_numerics/exception.hpp></code></ulink></para>
</section>
</section>
================================================
FILE: doc/boostbook/exception_policy.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_numeric.exception_policies">
<title>exception_policy<AE, IDB, UB, UV></title>
<?dbhtml stop-chunking?>
<section>
<title>Description</title>
<para>Create a valid exception policy from 4 function objects. This
specifies the actions to be taken for different types of invalid
results.</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>e</code></entry>
<entry>instance of a the type <link
linkend="safe_numerics.safe_numerics_error">safe_numerics_error</link><code/></entry>
</row>
<row>
<entry>message</entry>
<entry>pointer to const char * error message</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Template Parameters</title>
<informaltable>
<tgroup cols="3">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="6*"/>
<colspec align="left" colwidth="9*"/>
<thead>
<row>
<entry align="left">Parameter</entry>
<entry align="left">Type Requirements</entry>
<entry>Invoked when:</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>AE</code></entry>
<entry>Function object callable with the expression AE()(e,
message)</entry>
<entry><para>The operation cannot produce valid arithmetic result
such as overflows, divide by zero, etc.</para></entry>
</row>
<row>
<entry><code>UB</code></entry>
<entry>Function object callable with the expression UB()(e,
message)</entry>
<entry><para>The result is undefined by the C++
standard</para></entry>
</row>
<row>
<entry><code>IDB</code></entry>
<entry>Function object callable with the expression
IDB()(e,</entry>
<entry><para>The result depends upon implementation defined
behavior according to the C++ standard</para></entry>
</row>
<row>
<entry><code>UV</code></entry>
<entry>Function object callable with the expression UV()(e,
message)</entry>
<entry><para>A variable is not initialized</para></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Model of</title>
<para><link
linkend="safe_numerics.exception_policy">ExceptionPolicy</link></para>
</section>
<section>
<title>Inherited Valid Expressions</title>
<para>This class implements all the valid operations from the type
requirements <link
linkend="safe_numerics.promotion_policy">ExceptionPolicy</link>. Aside
from these, there are no other operations implemented.</para>
</section>
<section>
<title>Function Objects</title>
<para>In order to create an exception policy, one needs some function
objects. The library includes some appropriate examples of these:</para>
<informaltable>
<tgroup cols="2">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="3*"/>
<thead>
<row>
<entry align="left">Name</entry>
<entry align="left">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>ignore_exception</code></entry>
<entry>Ignore any runtime exception and just return - thus
propagating the error. This is what would happen with unsafe data
types</entry>
</row>
<row>
<entry><code>throw_exception</code></entry>
<entry>throw an exception of type std::system_error</entry>
</row>
<row>
<entry><code>trap_exception</code></entry>
<entry>Invoke a function which is undefined. Compilers will
include this function if and only if there is a possibility of a
runtime error. Conversely, This will create a compile time error
if there is any possibility that the operation will fail at
runtime. Use the action to guarantee that your application will
never produce an invalid result. Any operation invoke</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>But of course one is free to provide his own. Here is an example of
a function object which would could be used exception conditions.</para>
<programlisting>// log an exception condition but continue processing as though nothing has happened
// this would emulate the behavior of an unsafe type.
struct log_runtime_exception {
log_runtime_exception() = default;
void operator () (
const boost::safe_numerics::safe_numerics_error & e,
const char * message
){
std::cout
<< "Caught system_error with code "
<< boost::safe_numerics::literal_string(e)
<< " and message " << message << '\n';
}
};
</programlisting>
</section>
<section>
<title>Policies Provided by the library</title>
<para>The above function object can be composed into an exception policy
by this class. The library provides common policies all ready to use. In
the table below, the word "loose" is used to indicate that implementation
defined and undefined behavior is not considered an exceptional condition,
while "strict" means the opposite. The word "exception" means that a
runtime exception will be thrown. The word "trap" means that the mere
possibility of an error condition will result in a compile time
error.</para>
<para><informaltable>
<tgroup cols="2">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="3*"/>
<thead>
<row>
<entry align="left">Name</entry>
<entry align="left">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry
id="safe_numerics.exception_policies.loose_exception_policy"><code>loose_exception_policy</code></entry>
<entry>Throws runtime exception on any arithmetic error.
Undefined and implementation defined behavior is permitted as
long as it does not produce an arithmetic error.</entry>
</row>
<row>
<entry
id="safe_numerics.exception_policies.loose_trap_policy"><code>loose_trap_policy</code></entry>
<entry>Invoke a compile time error in any case where it's
possible to result in an arithmetic error.</entry>
</row>
<row>
<entry
id="safe_numerics.exception_policies.strict_exception_policy"><code>strict_exception_policy</code></entry>
<entry>Throws runtime exception on any arithmetic error. Any
undefined or implementation defined behavior also results in
throwing an exception.</entry>
</row>
<row>
<entry
id="safe_numerics.exception_policies.strict_trap_policy"><code>strict_trap_policy</code></entry>
<entry>Invoke a compile time error in any case where it's
possible to result in an arithmetic error, undefined behavior or
implementation defined behavior</entry>
</row>
<row>
<entry
id="safe_numerics.exception_policies.default_exception_policy"><code>default_exception_policy</code></entry>
<entry>an alias for <code>strict_exception_policy</code></entry>
</row>
</tbody>
</tgroup>
</informaltable>If none of the above suit your needs, you're free to
create your own. Here is one where use the logging function object defined
above as a component in a loose exception policy which logs any arithmetic
errors and ignores any other types of errors.</para>
<para><programlisting>// logging policy
// log arithmetic errors but ignore them and continue to execute
// implementation defined and undefined behavior is just executed
// without logging.
using logging_exception_policy = exception_policy<
log_runtime_exception, // arithmetic error
ignore_exception, // implementation defined behavior
ignore_exception, // undefined behavior
ignore_exception // uninitialized value
>;
</programlisting></para>
</section>
<section>
<title>Header</title>
<para><ulink
url="../../include/boost/safe_numerics/exception_policies.hpp"><code>#include
<boost/numeric/safe_numerics/exception_policies.hpp></code></ulink></para>
</section>
</section>
================================================
FILE: doc/boostbook/exception_policy_concept.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.exception_policy">
<title>ExceptionPolicy<EP></title>
<?dbhtml stop-chunking?>
<section>
<title>Description</title>
<para>The exception policy specifies what is to occur when a safe
operation cannot return a valid result. A type is an ExceptionPolicy if it
has functions for handling exceptional events that occur in the course of
safe numeric operations.</para>
</section>
<section>
<title>Notation</title>
<informaltable>
<tgroup cols="2" colsep="1" rowsep="1">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="6*"/>
<tbody>
<row>
<entry><code>EP</code></entry>
<entry>A type that fulfills the requirements of an
ExceptionPolicy</entry>
</row>
<row>
<entry>e</entry>
<entry>A code from <link
linkend="safe_numerics.safe_numerics_error"><code>safe_numerics_error</code></link></entry>
</row>
<row>
<entry>message</entry>
<entry>A const char * which refers to a text message about the
cause of an exception</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Valid Expressions</title>
<para>Whenever an operation yield an invalid result, one of the following
functions will be invoked.</para>
<para><informaltable>
<tgroup cols="3">
<colspec align="left" colwidth="9*"/>
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="12*"/>
<thead>
<row>
<entry align="left">Expression</entry>
<entry>Return Value</entry>
<entry>Invoked when:</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>EP::on_arithmetic_error(e, message)</code></entry>
<entry>void</entry>
<entry>The operation cannot produce valid arithmetic result such
as overflows, divide by zero, etc.</entry>
</row>
<row>
<entry><code>EP::on_undefined_behavior(e,
message)</code></entry>
<entry>void</entry>
<entry>The result is undefined by the C++ standard</entry>
</row>
<row>
<entry><code>EP::on_implementation_defined_behavior(e,
message)</code></entry>
<entry>void</entry>
<entry>The result depends upon implementation defined behavior
according to the C++ standard</entry>
</row>
<row>
<entry><code>EP::on_uninitialized_value(e,
message)</code></entry>
<entry>void</entry>
<entry>A variable is not initialized</entry>
</row>
</tbody>
</tgroup>
</informaltable></para>
</section>
<section>
<title>dispatch<EP>(const safe_numerics_error & e, const char *
msg)</title>
<para>This function is used to invoke the exception handling policy for a
particular exception code.</para>
<section>
<title>Synopsis</title>
<para><programlisting>template<class EP>
constexpr void
dispatch<EP>(const boost::numeric::safe_numerics_error & e, char const * const & msg);</programlisting></para>
</section>
<section>
<title>Example of use</title>
<programlisting>#include <boost/safe_numerics/exception_policies.hpp"
dispatch<boost::numeric::loose_exception_policy>(
boost::numeric::safe_numerics_error::positive_overflow_error,
"operation resulted in overflow"
);</programlisting>
</section>
</section>
<section>
<title>Models</title>
<para>The library header <ulink
url="../../include/boost/safe_numerics/exception_policies.hpp"><code><boost/safe_numerics/exception_policies.hpp>
</code></ulink>contains a number of pre-made exception policies:</para>
<itemizedlist>
<listitem>
<para><code id="">boost::numeric::loose_exception_policy</code></para>
<para>Throw on arithmetic errors, ignore other errors. Some
applications ignore these issues and still work and we don't want to
update them.</para>
</listitem>
<listitem>
<para><code
id="safe_numerics.exception_policies.loose_trap_policy">boost::numeric::loose_trap_policy</code></para>
<para>Same as above in that it doesn't check for various undefined
behaviors but traps at compile time for hard arithmetic errors. This
policy would be suitable for older embedded systems which depend on
bit manipulation operations to work.</para>
</listitem>
<listitem>
<para><code
id="safe_numerics.exception_policies.strict_exception_policy">boost::numeric::strict_exception_policy</code></para>
<para>Permit just about anything, throw at runtime on any kind of
error. Recommended for new code. Check everything at compile time if
possible and runtime if necessary. Trap or Throw as appropriate.
Should guarantee code to be portable across architectures.</para>
</listitem>
<listitem>
<para><code
id="safe_numerics.exception_policies.strict_trap_policy">boost::numeric::strict_trap_policy</code></para>
<para>Same as above but requires code to be written in such a way as
to make it impossible for errors to occur. This naturally will require
extra coding effort but might be justified for embedded and/or safety
critical systems.</para>
</listitem>
<listitem>
<para><code
id="safe_numerics.exception_policies.default_exception_policy">boost::numeric::default_exception_policy</code></para>
<para>Alias for <code>strict_exception_policy</code>, One would use
this first. After experimentation, one might switch to one of the
above policies or perhaps use a custom policy.</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Header</title>
<para><ulink
url="../../include/boost/safe_numerics/concept/exception_policy.hpp"><code>#include
<boost/safe_numerics/concepts/exception_policy.hpp>
</code></ulink></para>
</section>
</section>
================================================
FILE: doc/boostbook/faq.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<section id="safe_numerics.rationale">
<title>Rationale and FAQ</title>
<qandaset defaultlabel="number">
<qandaentry>
<question>
<para>Is this really necessary? If I'm writing the program with the
requisite care and competence, problems noted in the introduction will
never arise. Should they arise, they should be fixed "at the source"
and not with a "band aid" to cover up bad practice.</para>
</question>
<answer>
<para>This surprised me when it was first raised. But some of the
feedback I've received makes me think that it's a widely held view.
The best answer is to consider the examples in the <link
linkend="safe_numerics.tutorial">Tutorials and Motivating
Examples</link> section of the library documentation. I believe they
convincingly demonstrate that any program which does not use this
library must be assumed to contain arithmetic errors.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Can safe types be used as drop-in replacements for built-in
types?</para>
</question>
<answer>
<para>Almost. Replacing all built-in types with their safe
counterparts should result in a program that will compile and run as
expected. Occasionally compile time errors will occur and adjustments
to the source code will be required. Typically these will result in
code which is more correct.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Why are there special types for literal such as
<code>safe_signed_literal<42></code>? Why not just use
std::integral_const<int, 42>?</para>
</question>
<answer>
<para>By defining our own "special" type we can simplify the
interface. Using <code>std::integral_const</code> requires one to
specify both the type <emphasis>and</emphasis> the value. Using
<code>safe_signed_literal<42></code> doesn't require a parameter
for the type. So the library can select the best type to hold the
specified value. It also means that one won't have the opportunity to
specify a type-value pair which are inconsistent.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Why is safe...literal needed at all? What's the matter with
<code>const safe<int>(42)</code>?</para>
</question>
<answer>
<para><code>const safe<int>(42)</code> looks like it might be
what we want: An immutable value which invokes the "safe" operators
when used in an expression. But there is one problem. The
<code>std::numeric_limits<safe<int>></code> is a range
from INTMIN to INTMAX even though the value is fixed to 42 at compile
time. It is this range which is used at compile time to calculate the
range of the result of the operation.</para>
<para>So when an operation is performed, the range of the result is
calculated from [INTMIN, INTMAX] rather than from [42,42].</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Are safe type operations <code>constexpr</code>? That is, can
they be invoked at compile time?</para>
</question>
<answer>
<para>Yes. safe type construction and calculations are all
<code>constexpr</code>. Note that to get maximum benefit, you'll have
to use <code>safe...literal</code> to specify the primitive values at
compile time.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Why define <link
linkend="safe_numerics.safe_literal"><code>safe_literal</code></link>?
Isn't it effectively the same as
<code>std::integral_constant</code>?</para>
</question>
<answer>
<para>Almost, but there are still good reasons to create a different
type.<itemizedlist>
<listitem>
<para><code>std::integral_constant<int, 42></code>
requires specification of type as well as value so it's less
convenient than safe_signed_literal which maps to the smallest
type required to hold the value.</para>
</listitem>
<listitem>
<para><code>std::numeric_limits<std::integral_constant<int,
42>>::is_integer</code> returns <code>false</code>. This
would complicate implementation of the library</para>
</listitem>
<listitem>
<para>type trait <code>is_safe<std::integral_constant<int,
42>></code> would have to be defined to return
<code>true</code>.</para>
</listitem>
<listitem>
<para>But globally altering the traits of
<code>std::integral_constant</code> might have unintended
side-effects related to other code. These might well be
surprises which are create errors which are hard to find and
hard to work around.</para>
</listitem>
</itemizedlist></para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Why is Boost.Convert not used?</para>
</question>
<answer>
<para>I couldn't figure out how to use it from the
documentation.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Why is the library named "safe ..." rather than something like
"checked ..." ?</para>
</question>
<answer>
<para>I used "safe" in large part because this is what has been used
by other similar libraries. Maybe a better word might have been
"correct" but that would raise similar concerns. I'm not inclined to
change this. I've tried to make it clear in the documentation what the
problem that the library addressed is.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Given that the library is called "numerics" why is floating
point arithmetic not addressed?</para>
</question>
<answer>
<para>Actually, I believe that this can/should be applied to any type
T which satisfies the type requirement <code>Numeric</code> type as
defined in the documentation. So there should be specializations
<code>safe<float></code> and related types as well as new types
like <code>safe<fixed_decimal></code> etc. But the current
version of the library only addresses integer types. Hopefully the
library will evolve to match the promise implied by its name.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Isn't putting a defensive check just before any potential
undefined behavior often considered a bad practice?</para>
</question>
<answer>
<para>By whom? Is leaving code which can produce incorrect results
better? Note that the documentation contains references to various
sources which recommend exactly this approach to mitigate the problems
created by this C/C++ behavior. See
<citation>Seacord</citation></para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>It looks like the implementation presumes two's complement
arithmetic at the hardware level. So this library is not portable -
correct? What about other hardware architectures?</para>
</question>
<answer>
<para>As far as is known as of this writing, the library does not
presume that the underlying hardware is two's complement. However,
this has yet to be verified in any rigorous way.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>According to C/C++ standards, <code>unsigned integers</code>
cannot overflow - they are modular integers which "wrap around". Yet
the safe numerics library detects and traps this behavior as errors.
Why is that?</para>
</question>
<answer>
<para>The guiding purpose of the library is to trap incorrect
arithmetic behavior - not just undefined behavior. Although a savvy
user may understand and keep present in his mind that an unsigned
integer is really a modular type, the plain reading of an arithmetic
expression conveys the idea that all operands are common integers.
Also in many cases, <code>unsigned integers</code> are used in cases
where modular arithmetic is not intended, such as array indices.
Finally, the modulus for such an integer would vary depending upon the
machine architecture. For these reasons, in the context of this
library, an <code>unsigned integer</code> is considered to be a
representation of a subset of integers. Note that this decision is
consistent with <citation>INT30-C</citation>, “Ensure that unsigned
integer operations do not wrap” in the CERT C Secure Coding Standard
<citation>Seacord</citation>.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Why does the library require C++14?</para>
</question>
<answer>
<para>The original version of the library used C++11. Feedback from
CPPCon, <ulink url="http://www.blincubator.com">Boost Library
Incubator</ulink> and Boost developer's mailing list convinced me that
I had to address the issue of run-time penalty much more seriously. I
resolved to eliminate or minimize it. This led to more elaborate
meta-programming. But this wasn't enough. It became apparent that the
only way to really minimize run-time penalty was to implement
compile-time integer range arithmetic - a pretty elaborate sub
library. By doing range arithmetic at compile-time, I could skip
runtime checking on many/most integer operations. While C++11
<code>constexpr</code> wasn't quite powerful enough to do the job,
C++14 <code>constexpr</code> is. The library currently relies very
heavily on C++14 <code>constexpr</code>. I think that those who delve
into the library will be very surprised at the extent that minor
changes in user code can produce guaranteed correct integer code with
zero run-time penalty.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>This is a C++ library - yet you refer to C/C++. Which is
it?</para>
</question>
<answer>
<para>C++ has evolved way beyond the original C language. But C++ is
still (mostly) compatible with C. So most C programs can be compiled
with a C++ compiler. The problems of incorrect arithmetic afflict both
C and C++. Suppose we have a legacy C program designed for some
embedded system.<itemizedlist>
<listitem>
<para>Replace all <code>int</code> declarations with
<code>int16_t</code> and all <code>long</code> declarations with
<code>int32_t</code>.</para>
</listitem>
<listitem>
<para>Create a file containing something like the following and
include it at the beginning of every source file.</para>
<programlisting>#ifdef TEST
// using C++ on test platform
#include <cstdint>
#include <boost/numeric/safe_numerics/safe_integer.hpp>
#include <cpp.hpp>
using pic16_promotion = boost::numeric::cpp<
8, // char
8, // short
8, // int
16, // long
32 // long long
>;
// define safe types used in the desktop version of the program.
template <typename T> // T is char, int, etc data type
using safe_t = boost::numeric::safe<
T,
pic16_promotion,
boost::numeric::default_exception_policy // use for compiling and running tests
>;
typedef safe_t<std::int_least16_t> int16_t;
typedef safe_t<std::int_least32_t> int32_t;
#else
/* using C on embedded platform */
typedef int int_least16_t;
typedef long int_least16_t;
#endif
</programlisting>
</listitem>
<listitem>
<para>Compile tests on the desktop with a C++14 compiler and
with the macro TEST defined.</para>
</listitem>
<listitem>
<para>Run the tests and change the code to address any thrown
exceptions.</para>
</listitem>
<listitem>
<para>Compile for the target C platform with the macro TEST
undefined.</para>
</listitem>
</itemizedlist></para>
<para>This example illustrates how this library, implemented with
C++14 can be useful in the development of correct code for programs
written in C.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Some compilers (including gcc and clang) include builtin
functions for checked addition, multiplication, etc. Does this library
use these intrinsics?</para>
</question>
<answer>
<para>No. I attempted to use these but they are currently not
<code>constexpr</code>. So I couldn't use these without breaking
<code>constexpr</code> compatibility for the safe numerics
primitives.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Some compilers (including gcc and clang) included a builtin
function for detecting constants. This seemed attractive to eliminate
the requirement for the safe_literal type. Alas, these builtin
functions are defined as macros. Constants passed through functions
down into the safe numerics library cannot be detected as constants.
So the opportunity to make the library even more efficient by moving
more operations to compile time doesn't exist - contrary to my hopes
and expections.</para>
</question>
</qandaentry>
</qandaset>
</section>
================================================
FILE: doc/boostbook/ignore_exception.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.exception_policies.ignore">
<title>ignore_exception</title>
<section>
<title>Description</title>
<para>This exception policy can be used to just ignore conditions which
generate incorrect arithmetic results and continue processing. Programs
using this policy along with the <link
linkend="safe_numerics.promotion_policies.native">native</link> promotion policy
should function as if the library is not even being used.</para>
</section>
<section>
<title>Model of</title>
<para><link
linkend="safe_numerics.promotion_policy">ExceptionPolicy</link></para>
</section>
<section>
<title>Header</title>
<para><code><ulink url="../../include/exception_policy.hpp"><code>#include
<boost/safe_numerics/exception_policy.hpp>
</code></ulink></code></para>
</section>
<section>
<title>Example of use</title>
<programlisting>safe<int, native, ignore_exception> st(4);</programlisting>
</section>
</section>
================================================
FILE: doc/boostbook/integer_concept.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.integer">
<title>Integer<T></title>
<?dbhtml stop-chunking?>
<section>
<title>Description</title>
<para>A type fulfills the requirements of an Integer if it has the
properties of a integer.</para>
<para>More specifically, a type T is Integer if there exists a
specialization of <code>std::numeric_limits<T> for which
std::numeric_limits<T>::is_integer</code> is equal to
<code>true</code>. See the documentation for standard library class
<code>numeric_limits</code>. The standard library includes such
specializations for all built-in numeric types. Note that this concept is
distinct from the C++ standard library type traits
<code>is_integral</code> and <code>is_arithmetic</code>. These latter
fulfill the requirements of the concept Numeric. But there are types which
fulfill this concept for which <code>is_arithmetic<T>::value ==
false</code>. For example see <code>safe<int></code>.</para>
</section>
<section>
<title>Refinement of</title>
<para><link linkend="safe_numerics.numeric_concept">Numeric</link></para>
</section>
<section>
<title>Notation</title>
<informaltable>
<tgroup cols="2" colsep="1" rowsep="1">
<colspec align="left" colwidth="2*"/>
<colspec align="left" colwidth="4*"/>
<tbody>
<row>
<entry><code>T, U, V</code></entry>
<entry>A type that is a model of an Integer type</entry>
</row>
<row>
<entry><code>t, u</code></entry>
<entry>An object of type modeling an Integer type</entry>
</row>
<row>
<entry><code>OS, IS</code></entry>
<entry>A type that is a model of an output or input stream</entry>
</row>
<row>
<entry><code>os, is</code></entry>
<entry>An object of a type modeling output or input stream</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Valid Expressions</title>
<para>In addition to the expressions defined in Integer, the following
expression must be true. <table>
<title>General</title>
<tgroup cols="2">
<colspec align="left" colwidth="2*"/>
<colspec align="left" colwidth="2*"/>
<thead>
<row>
<entry align="left">Expression</entry>
<entry>Value</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>std::numeric_limits<T>::is_integer</code></entry>
<entry>true</entry>
</row>
</tbody>
</tgroup>
</table>Any or all of the following unary operators MAY be defined. Any
such defined operators shall implement the semantics as described
below<table>
<title>Unary Operator</title>
<tgroup cols="3">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="4*"/>
<thead>
<row>
<entry align="left">Expression</entry>
<entry>Return Type</entry>
<entry>Semantics</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>~t</code></entry>
<entry><code>T</code></entry>
<entry>bitwise complement</entry>
</row>
</tbody>
</tgroup>
</table>Any or all of the following binary operators MAY be defined. Any
defined operators shall implement the semantics as described bellow<table>
<title>Binary Operators</title>
<tgroup cols="3">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="4*"/>
<thead>
<row>
<entry align="left">Expression</entry>
<entry>Return Type</entry>
<entry>Semantics</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>t % u</code></entry>
<entry><code>T</code></entry>
<entry>t modulus u. t can be a Numeric type.</entry>
</row>
<row>
<entry><code>t << u</code></entry>
<entry><code>T</code></entry>
<entry>shift t left u bits</entry>
</row>
<row>
<entry><code>t >> u</code></entry>
<entry><code>T</code></entry>
<entry>shift t right by u bits</entry>
</row>
<row>
<entry><code>t & u</code></entry>
<entry><code>V</code></entry>
<entry>and of t and u padded out to max # bits in t, u</entry>
</row>
<row>
<entry><code>t | u</code></entry>
<entry><code>V</code></entry>
<entry>or of t and u padded out to max # bits in t, u</entry>
</row>
<row>
<entry><code>t ^ u</code></entry>
<entry><code>V</code></entry>
<entry>exclusive or of t and u padded out to max # bits in t,
u</entry>
</row>
<row>
<entry><code>t <<= u</code></entry>
<entry><code>T</code></entry>
<entry>left shift the value of t by u bits</entry>
</row>
<row>
<entry><code>t >>= u</code></entry>
<entry><code>T</code></entry>
<entry>right shift the value of t by u bits</entry>
</row>
<row>
<entry><code>t &= u</code></entry>
<entry><code>T</code></entry>
<entry>and the value of t with u and assign to t</entry>
</row>
<row>
<entry><code>t |= u</code></entry>
<entry><code>T</code></entry>
<entry>or the value of t with u and assign to t</entry>
</row>
<row>
<entry><code>t ^= u</code></entry>
<entry><code>T</code></entry>
<entry>exclusive or the value of t with u and assign to
t</entry>
</row>
<row>
<entry><code>os << t</code></entry>
<entry><code><code>OS &</code></code></entry>
<entry>write contents of t to output stream</entry>
</row>
<row>
<entry><code>is >> t</code></entry>
<entry><code><code>IS &</code></code></entry>
<entry>read contents of an input stream into t</entry>
</row>
</tbody>
</tgroup>
</table></para>
</section>
<section>
<title>Models</title>
<para><code>int, safe<int>, safe_unsigned_range<0, 11>,
checked_result<int> etc.</code></para>
</section>
<section>
<title>Header</title>
<para><ulink
url="../../include/boost/safe_numerics/concept/numeric.hpp"><code>#include
<boost/safe_numerics/concepts/integer.hpp> </code></ulink></para>
</section>
</section>
================================================
FILE: doc/boostbook/interval.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.interval">
<title>interval<R></title>
<?dbhtml stop-chunking?>
<section>
<title>Description</title>
<para>A closed arithmetic interval represented by a pair of elements of
type R. In principle, one should be able to use Boost.Interval library for
this. But the functions in this library are not <code>constexpr</code>.
Also, this Boost.Interval is more complex and does not support certain
operations such bit operations. Perhaps some time in the future,
Boost.Interval will be used instead of this <code>interval<R></code>
type.</para>
</section>
<section>
<title>Template Parameters</title>
<para>R must model the type requirements of <link
linkend="safe_numerics.numeric">Numeric</link>. Note this in principle
includes any numeric type including floating point numbers and instances
of <link
linkend="safenumerics.checked_result"><code>checked_result<R></code></link>.</para>
</section>
<section>
<title>Notation</title>
<informaltable>
<tgroup cols="2">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="4*"/>
<thead>
<row>
<entry align="left">Symbol</entry>
<entry align="left">Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>I</code></entry>
<entry>An interval type</entry>
</row>
<row>
<entry><code>i, j</code></entry>
<entry>An instance of interval type</entry>
</row>
<row>
<entry><code>R</code></entry>
<entry>Numeric types which can be used to make an interval</entry>
</row>
<row>
<entry><code>r</code></entry>
<entry>An instance of type R</entry>
</row>
<row>
<entry><code>p</code></entry>
<entry>An instance of std::pair<R, R></entry>
</row>
<row>
<entry><code>l, u</code></entry>
<entry>Lowermost and uppermost values in an interval</entry>
</row>
<row>
<entry><code>os</code></entry>
<entry>std::basic_ostream<class CharT, class Traits =
std::char_traits<CharT>></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Associated Types</title>
<informaltable>
<tgroup cols="2">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="4*"/>
<tbody>
<row>
<entry><link
linkend="safenumerics.checked_result"><code>checked_result</code></link></entry>
<entry>holds either the result of an operation or information as
to why it failed</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Valid Expressions</title>
<para>Note that all expressions are constexpr.</para>
<para><informaltable>
<tgroup cols="3">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="3*"/>
<thead>
<row>
<entry align="left">Expression</entry>
<entry>Return Type</entry>
<entry>Semantics</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>interval<R>(l, u)</code></entry>
<entry><code>interval<R></code></entry>
<entry>construct a new interval from a pair of limits</entry>
</row>
<row>
<entry><code>interval<R>(p)</code></entry>
<entry><code>interval<R></code></entry>
<entry>construct a new interval from a pair of limits</entry>
</row>
<row>
<entry><code>interval<R>(i)</code></entry>
<entry><code>interval<R></code></entry>
<entry>copy constructor</entry>
</row>
<row>
<entry><code>make_interval<R>()</code></entry>
<entry><code>interval<R></code></entry>
<entry>return new interval with
std::numric_limits<R>::min() and
std::numric_limits<R>::max()</entry>
</row>
<row>
<entry><code>make_interval<R>(const R
&r)</code></entry>
<entry><code>interval<R></code></entry>
<entry>return new interval with
std::numric_limits<R>::min() and
std::numric_limits<R>::max()</entry>
</row>
<row>
<entry><code>i.l</code></entry>
<entry><code>R</code></entry>
<entry>lowermost value in the interval i</entry>
</row>
<row>
<entry><code>i.u</code></entry>
<entry><code>R</code></entry>
<entry>uppermost value in the interval i</entry>
</row>
<row>
<entry><code>i.includes(j)</code></entry>
<entry><code>boost::logic::tribool</code></entry>
<entry>return true if interval i includes interval j</entry>
</row>
<row>
<entry><code>i.excludes(j)</code></entry>
<entry><code>boost::logic::tribool</code></entry>
<entry>return true if interval i includes interval j</entry>
</row>
<row>
<entry><code>i.includes(t)</code></entry>
<entry><code>bool</code></entry>
<entry>return true if interval i includes value t</entry>
</row>
<row>
<entry><code>i.excludes(t)</code></entry>
<entry><code>bool</code></entry>
<entry>return true if interval i includes value t</entry>
</row>
<row>
<entry><code>i + j</code></entry>
<entry><code>interval<R></code></entry>
<entry>add two intervals and return the result</entry>
</row>
<row>
<entry><code>i - j</code></entry>
<entry><code>interval<R></code></entry>
<entry>subtract two intervals and return the result</entry>
</row>
<row>
<entry><code>i * j</code></entry>
<entry><code>interval<R></code></entry>
<entry>multiply two intervals and return the result</entry>
</row>
<row>
<entry><code>i / j</code></entry>
<entry><code>interval<R></code></entry>
<entry>divide one interval by another and return the
result</entry>
</row>
<row>
<entry><code>i % j</code></entry>
<entry><code>interval<R></code></entry>
<entry>calculate modulus of one interval by another and return
the result</entry>
</row>
<row>
<entry><code>i << j</code></entry>
<entry><code>interval<R></code></entry>
<entry>calculate the range that would result from shifting one
interval by another</entry>
</row>
<row>
<entry><code>i >> j</code></entry>
<entry><code>interval<R></code></entry>
<entry>calculate the range that would result from shifting one
interval by another</entry>
</row>
<row>
<entry><code>i | j</code></entry>
<entry><code>interval<R></code></entry>
<entry>range of values which can result from applying | to any
pair of operands from I and j</entry>
</row>
<row>
<entry><code>i & j</code></entry>
<entry><code>interval<R></code></entry>
<entry>range of values which can result from applying & to
any pair of operands from I and j</entry>
</row>
<row>
<entry><code>i ^ j</code></entry>
<entry><code>interval<R></code></entry>
<entry>range of values which can result from applying ^ to any
pair of operands from I and j</entry>
</row>
<row>
<entry><code>t < u</code></entry>
<entry><code>boost::logic::tribool</code></entry>
<entry>true if every element in t is less than every element in
u</entry>
</row>
<row>
<entry><code>t > u</code></entry>
<entry><code>boost::logic::tribool</code></entry>
<entry>true if every element in t is greater than every element
in u</entry>
</row>
<row>
<entry><code>t <= u</code></entry>
<entry><code>boost::logic::tribool</code></entry>
<entry>true if every element in t is less than or equal to every
element in u</entry>
</row>
<row>
<entry><code>t >= u</code></entry>
<entry><code>boost::logic::tribool</code></entry>
<entry>true if every element in t is greater than or equal to
every element in u</entry>
</row>
<row>
<entry><code>t == u</code></entry>
<entry><code>bool</code></entry>
<entry>true if limits are equal</entry>
</row>
<row>
<entry><code>t != u</code></entry>
<entry><code>bool</code></entry>
<entry>true if limits are not equal</entry>
</row>
<row>
<entry><code>os << i</code></entry>
<entry><code>os &</code></entry>
<entry>print interval to output stream</entry>
</row>
</tbody>
</tgroup>
</informaltable></para>
</section>
<section>
<title>Example of use</title>
<programlisting>#include <iostream>
#include <cstdint>
#include <cassert>
#include <boost/numeric/safe_numerics/interval.hpp>
int main(){
std::cout << "test1" << std::endl;
interval<std::int16_t> x = {-64, 63};
std::cout << "x = " << x << std::endl;
interval<std::int16_t> y(-128, 126);
std::cout << "y = " << y << std::endl;
assert(static_cast<interval<std::int16_t>>(add<std::int16_t>(x,x)) == y);
std::cout << "x + x =" << add<std::int16_t>(x, x) << std::endl;
std::cout << "x - x = " << subtract<std::int16_t>(x, x) << std::endl;
return 0;
}</programlisting>
</section>
<section>
<title>Header</title>
<para><ulink
url="../../include/boost/safe_numerics/interval.hpp"><code>#include
<boost/numeric/safe_numerics/interval.hpp></code></ulink></para>
</section>
</section>
================================================
FILE: doc/boostbook/makeepub.sh
================================================
if test x = x$BOOST_ROOT
then
echo BOOST_ROOT not set
exit 1
fi
xsltproc --nonet --xinclude bb2db.xsl safe_numerics.xml | xsltproc --xinclude --nonet --stringparam base.dir ebooktmp db2epub.xsl -
cp *.png ebooktmp/OEBPS/
xsltproc --xinclude --nonet opf.xsl ebooktmp/OEBPS/package.opf >ebooktmp/OEBPS/t.opf
# mv ebooktmp/OEBPS/t.opf ebooktmp/OEBPS/package.opf
cd ebooktmp
zip -r -X ../book.epub mimetype META-INF OEBPS
cd -
================================================
FILE: doc/boostbook/makehtml.bat
================================================
if x == x%BOOST_ROOT% goto abort
xsltproc --nonet --xinclude bb2db.xsl safe_numerics.xml | xsltproc --nonet db2html.xsl -
xcopy /i /q /y *.jpg ..\html
if not exist ..\html md ..\html
xcopy /i /q /y %BOOST_ROOT%\doc\src\boostbook.css ..\html
if not exist ..\html md ..\html\images
xcopy /i /q /y /s %BOOST_ROOT%\doc\html\images ..\html\images
exit
:abort
echo BOOST_ROOT not set
exit
================================================
FILE: doc/boostbook/makehtml.sh
================================================
if test x = x$BOOST_ROOT
then
echo BOOST_ROOT not set
exit 1
fi
xsltproc --nonet --xinclude bb2db.xsl safe_numerics.xml | xsltproc --nonet db2html.xsl -
cp pre-boost.jpg ../html
cp pre-boost.jpg ../html/eliminate_runtime_penalty
cp pre-boost.jpg ../html/promotion_policies
cp pre-boost.jpg ../html/tutorial
cp StepperMotor.gif ../html/
cp stepper_profile.png ../html/
cp $BOOST_ROOT/doc/src/boostbook.css ../html
cp -R $BOOST_ROOT/doc/html/images ../html
================================================
FILE: doc/boostbook/makepdf.sh
================================================
if test x = x$BOOST_ROOT
then
echo BOOST_ROOT not set
exit 1
fi
#use -r switch on fop for relaxed validation
xsltproc --xinclude --nonet bb2db.xsl safe_numerics.xml \
| fop -r -dpi 300 -xsl db2fo.xsl -xml - -pdf ../safe_numerics.pdf
# equivalent alternative?
# xsltproc --xinclude --nonet bb2db.xsl safe_numerics.xml \
# | xsltproc --xinclude --nonet db2fo.xsl - \
# | fop -r -dpi 300 -fo - -pdf safe_numerics.pdf
================================================
FILE: doc/boostbook/makeproposal.sh
================================================
if test x = x$BOOST_ROOT
then
echo BOOST_ROOT not set
exit 1
fi
#use -r switch on fop for relaxed validation
xsltproc --xinclude --nonet bb2db.xsl proposal.xml \
| fop -r -dpi 300 -xsl db2fo.xsl -xml - -pdf proposal.pdf
# equivalent alternative?
# xsltproc --xinclude --nonet bb2db.xsl safe_numerics.xml \
# | xsltproc --xinclude --nonet db2fo.xsl - \
# | fop -r -dpi 300 -fo - -pdf safe_numerics.pdf
================================================
FILE: doc/boostbook/motor.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.safety_critical_embedded_controller">
<title>Safety Critical Embedded Controller</title>
<?dbhtml stop-chunking?>
<para>Suppose we are given the task of creating stepper motor driver
software to drive a robotic hand to be used in robotic micro surgery. The
processor that has been selected by the engineers is the <ulink
url="http://www.microchip.com/wwwproducts/en/PIC18F2520">PIC18F2520</ulink>
manufactured by <ulink url="http://www.microchip.com">Microchip
Corporation</ulink>. This processor has 32KB of program memory. On a
processor this small, it's common to use a mixture of 8, 16, and 32 bit data
types in order to minimize memory footprint and program run time. The type
<code>int</code> has 16 bits. It's programmed in C. Since this program is
going to be running life critical function, it must be demonstrably correct.
This implies that it needs to be verifiable and testable. Since the target
micro processor is inconvenient for accomplishing these goals, we will build
and test the code on the desktop.</para>
<section>
<title>How a Stepper Motor Works</title>
<figure float="0">
<title>Stepper Motor</title>
<mediaobject>
<imageobject>
<imagedata align="left" contentwidth="216"
fileref="StepperMotor.gif" format="GIF" width="50%"/>
</imageobject>
</mediaobject>
</figure>
<para>A stepper motor controller emits a pulse which causes the motor to
move one step. It seems simple, but in practice it turns out to be quite
intricate to get right as one has to time the pulses individually to
smoothly accelerate the rotation of the motor from a standing start until
it reaches the some maximum velocity. Failure to do this will either limit
the stepper motor to very low speed or result in skipped steps when the
motor is under load. Similarly, a loaded motor must be slowly decelerated
down to a stop.</para>
<para><figure>
<title>Motion Profile</title>
<mediaobject>
<imageobject>
<imagedata fileref="stepper_profile.png" format="PNG" width="100%"/>
</imageobject>
</mediaobject>
</figure></para>
<para>This implies the the width of the pulses must decrease as the motor
accelerates. That is the pulse with has to be computed while the motor is
in motion. This is illustrated in the above drawing. A program to
accomplish this might look something like the following:</para>
<literallayout class="normal" linenumbering="unnumbered">setup registers and step to zero position
specify target position
set initial time to interrupt
enable interrupts
On interrupt
if at target position
disable interrupts and return
calculate width of next step
change current winding according to motor direction
s
gitextract_uxocpujy/
├── .drone/
│ └── drone.sh
├── .drone.star
├── .github/
│ └── workflows/
│ ├── posix.yml
│ └── windows.yml
├── .travis.yml
├── CMakeLists.txt
├── LICENSE_1_0.txt
├── README.md
├── appveyor.yml
├── b2.log
├── build.jam
├── doc/
│ ├── boostbook/
│ │ ├── HTML.manifest
│ │ ├── accu/
│ │ │ ├── accu.xml
│ │ │ ├── bb2db.xsl
│ │ │ ├── db2epub.xsl
│ │ │ ├── db2fo.xsl
│ │ │ ├── db2html.xsl
│ │ │ ├── makehtml.sh
│ │ │ └── makepdf.sh
│ │ ├── acknowledgements.xml
│ │ ├── automatic.xml
│ │ ├── bb2db.xsl
│ │ ├── bibliography.xml
│ │ ├── checked.xml
│ │ ├── checked_result.xml
│ │ ├── cpp.xml
│ │ ├── db2epub.xsl
│ │ ├── db2fo.xsl
│ │ ├── db2html.xsl
│ │ ├── db2pdf.xsl
│ │ ├── eliminate_runtime_penalty.xml
│ │ ├── exception.xml
│ │ ├── exception_policy.xml
│ │ ├── exception_policy_concept.xml
│ │ ├── faq.xml
│ │ ├── ignore_exception.xml
│ │ ├── integer_concept.xml
│ │ ├── interval.xml
│ │ ├── makeepub.sh
│ │ ├── makehtml.bat
│ │ ├── makehtml.sh
│ │ ├── makepdf.sh
│ │ ├── makeproposal.sh
│ │ ├── motor.xml
│ │ ├── native.xml
│ │ ├── no_exception_support.xml
│ │ ├── notes.xml
│ │ ├── numeric_concept.xml
│ │ ├── overflow.xml
│ │ ├── pending.xml
│ │ ├── promotion_policy_concept.xml
│ │ ├── proposal.xml
│ │ ├── rational.xml
│ │ ├── safe.xml
│ │ ├── safe_cast.xml
│ │ ├── safe_compare.xml
│ │ ├── safe_introduction.xml
│ │ ├── safe_literal.xml
│ │ ├── safe_numerics.xml
│ │ ├── safe_range.xml
│ │ ├── trap_exception.xml
│ │ └── tutorial.xml
│ └── html/
│ ├── acknowledgements.html
│ ├── bibliography.html
│ ├── boostbook.css
│ ├── case_studies.html
│ ├── change_log.html
│ ├── checked_arithmetic.html
│ ├── checked_integer_arithmetic.html
│ ├── checked_result.html
│ ├── composition_with_other_libraries.html
│ ├── concepts.html
│ ├── eliminate_runtime_penalty/
│ │ ├── 1.html
│ │ ├── 2.html
│ │ └── 3.html
│ ├── eliminate_runtime_penalty.html
│ ├── exception.html
│ ├── exception_policies.html
│ ├── exception_policy.html
│ ├── exception_safety.html
│ ├── index.html
│ ├── integer.html
│ ├── integer_concept.html
│ ├── interval.html
│ ├── introduction.html
│ ├── library_implementation.html
│ ├── notes.html
│ ├── numeric.html
│ ├── numeric_concept.html
│ ├── pending_issues.html
│ ├── performance_tests.html
│ ├── promotion_policies/
│ │ ├── automatic.html
│ │ ├── cpp.html
│ │ └── native.html
│ ├── promotion_policies.html
│ ├── promotion_policy.html
│ ├── rationale.html
│ ├── safe.html
│ ├── safe_literal.html
│ ├── safe_numeric_concept.html
│ ├── safe_numerics_error.html
│ ├── safe_range.html
│ ├── safety_critical_embedded_controller.html
│ ├── tutorial/
│ │ ├── 1.html
│ │ ├── 10.html
│ │ ├── 2.html
│ │ ├── 3.html
│ │ ├── 4.html
│ │ ├── 5.html
│ │ ├── 6.html
│ │ ├── 7.html
│ │ ├── 8.html
│ │ └── 9.html
│ ├── tutorial.html
│ └── types.html
├── example/
│ ├── CMakeLists.txt
│ ├── Jamfile.v2
│ ├── Motor.c
│ ├── example1.cpp
│ ├── example10.cpp
│ ├── example11.cpp
│ ├── example13.cpp
│ ├── example14.cpp
│ ├── example15.cpp
│ ├── example16.cpp
│ ├── example17.cpp
│ ├── example18.cpp
│ ├── example19.cpp
│ ├── example2.cpp
│ ├── example20.cpp
│ ├── example3.cpp
│ ├── example4.cpp
│ ├── example5.cpp
│ ├── example6.cpp
│ ├── example7.cpp
│ ├── example8.cpp
│ ├── example81.cpp
│ ├── example82.cpp
│ ├── example83.cpp
│ ├── example84.cpp
│ ├── example91.cpp
│ ├── example92.cpp
│ ├── example93.cpp
│ ├── links.html
│ ├── motor1.c
│ ├── motor2.c
│ ├── motor3.c
│ ├── motor_test1.c
│ ├── motor_test2.c
│ ├── motor_test3.c
│ ├── picsfr.h
│ └── safe_format.hpp
├── html
├── include/
│ └── boost/
│ └── safe_numerics/
│ ├── CMakeLists.txt
│ ├── automatic.hpp
│ ├── checked_default.hpp
│ ├── checked_float.hpp
│ ├── checked_integer.hpp
│ ├── checked_result.hpp
│ ├── checked_result_operations.hpp
│ ├── concept/
│ │ ├── CMakeLists.txt
│ │ ├── exception_policy.hpp
│ │ ├── integer.hpp
│ │ ├── numeric.hpp
│ │ └── promotion_policy.hpp
│ ├── cpp.hpp
│ ├── exception.hpp
│ ├── exception_policies.hpp
│ ├── interval.hpp
│ ├── native.hpp
│ ├── range_value.hpp
│ ├── safe_base.hpp
│ ├── safe_base_operations.hpp
│ ├── safe_common.hpp
│ ├── safe_compare.hpp
│ ├── safe_integer.hpp
│ ├── safe_integer_literal.hpp
│ ├── safe_integer_range.hpp
│ └── utility.hpp
├── index.html
├── meta/
│ └── libraries.json
└── test/
├── CMakeLists.txt
├── Jamfile.v2
├── check_symmetry.hpp
├── test0.cpp
├── test_add.hpp
├── test_add_automatic.cpp
├── test_add_automatic_constexpr.cpp
├── test_add_automatic_results.hpp
├── test_add_constexpr.hpp
├── test_add_native.cpp
├── test_add_native_constexpr.cpp
├── test_add_native_results.hpp
├── test_and.hpp
├── test_and_automatic.cpp
├── test_and_automatic_constexpr.cpp
├── test_and_native.cpp
├── test_and_native_constexpr.cpp
├── test_assignment.cpp
├── test_assignment.hpp
├── test_auto.cpp
├── test_cast.cpp
├── test_cast_constexpr.cpp
├── test_checked_add.cpp
├── test_checked_add.hpp
├── test_checked_add_constexpr.cpp
├── test_checked_and.cpp
├── test_checked_and.hpp
├── test_checked_and_constexpr.cpp
├── test_checked_cast.cpp
├── test_checked_cast.hpp
├── test_checked_cast_constexpr.cpp
├── test_checked_comparison.hpp
├── test_checked_divide.cpp
├── test_checked_divide.hpp
├── test_checked_divide_constexpr.cpp
├── test_checked_equal_to.cpp
├── test_checked_equal_to_constexpr.cpp
├── test_checked_left_shift.cpp
├── test_checked_left_shift.hpp
├── test_checked_left_shift_constexpr.cpp
├── test_checked_less_than.cpp
├── test_checked_less_than_constexpr.cpp
├── test_checked_modulus.cpp
├── test_checked_modulus.hpp
├── test_checked_modulus_constexpr.cpp
├── test_checked_multiply.cpp
├── test_checked_multiply.hpp
├── test_checked_multiply_constexpr.cpp
├── test_checked_or.cpp
├── test_checked_or.hpp
├── test_checked_or_constexpr.cpp
├── test_checked_right_shift.cpp
├── test_checked_right_shift.hpp
├── test_checked_right_shift_constexpr.cpp
├── test_checked_subtract.cpp
├── test_checked_subtract.hpp
├── test_checked_subtract_constexpr.cpp
├── test_checked_values.hpp
├── test_checked_xor.cpp
├── test_checked_xor.hpp
├── test_checked_xor_constexpr.cpp
├── test_compare_automatic.hpp
├── test_compare_native.hpp
├── test_concept_integer.cpp
├── test_concept_numeric.cpp
├── test_constexpr.cpp
├── test_construction.cpp
├── test_cpp.cpp
├── test_custom_exception.cpp
├── test_divide.hpp
├── test_divide_automatic.cpp
├── test_divide_automatic_constexpr.cpp
├── test_divide_automatic_results.hpp
├── test_divide_constexpr.hpp
├── test_divide_native.cpp
├── test_divide_native_constexpr.cpp
├── test_divide_native_results.hpp
├── test_equal.hpp
├── test_equal_automatic.cpp
├── test_equal_automatic_constexpr.cpp
├── test_equal_constexpr.hpp
├── test_equal_native.cpp
├── test_equal_native_constexpr.cpp
├── test_float.cpp
├── test_interval.cpp
├── test_left_shift.hpp
├── test_left_shift_automatic.cpp
├── test_left_shift_automatic_constexpr.cpp
├── test_left_shift_automatic_results.hpp
├── test_left_shift_constexpr.hpp
├── test_left_shift_native.cpp
├── test_left_shift_native_constexpr.cpp
├── test_left_shift_native_results.hpp
├── test_less_than.hpp
├── test_less_than_automatic.cpp
├── test_less_than_automatic_constexpr.cpp
├── test_less_than_constexpr.hpp
├── test_less_than_native.cpp
├── test_less_than_native_constexpr.cpp
├── test_modulus.hpp
├── test_modulus_automatic.cpp
├── test_modulus_automatic_constexpr.cpp
├── test_modulus_automatic_results.hpp
├── test_modulus_constexpr.hpp
├── test_modulus_native.cpp
├── test_modulus_native_constexpr.cpp
├── test_modulus_native_results.hpp
├── test_multiply.hpp
├── test_multiply_automatic.cpp
├── test_multiply_automatic_constexpr.cpp
├── test_multiply_automatic_results.hpp
├── test_multiply_constexpr.hpp
├── test_multiply_native.cpp
├── test_multiply_native_constexpr.cpp
├── test_multiply_native_results.hpp
├── test_notepad.hpp
├── test_or.hpp
├── test_or_automatic.cpp
├── test_or_automatic_constexpr.cpp
├── test_or_constexpr.hpp
├── test_or_native.cpp
├── test_or_native_constexpr.cpp
├── test_performance.cpp
├── test_range.cpp
├── test_rational.cpp
├── test_right_shift.hpp
├── test_right_shift_automatic.cpp
├── test_right_shift_automatic_constexpr.cpp
├── test_right_shift_automatic_results.hpp
├── test_right_shift_constexpr.hpp
├── test_right_shift_native.cpp
├── test_right_shift_native_constexpr.cpp
├── test_right_shift_native_results.hpp
├── test_safe_compare.cpp
├── test_stream_overload.cpp
├── test_subtract.hpp
├── test_subtract_automatic.cpp
├── test_subtract_automatic_constexpr.cpp
├── test_subtract_automatic_results.hpp
├── test_subtract_constexpr.hpp
├── test_subtract_native.cpp
├── test_subtract_native_constexpr.cpp
├── test_subtract_native_results.hpp
├── test_trap.cpp
├── test_values.hpp
├── test_xor.hpp
├── test_xor_automatic.cpp
├── test_xor_automatic_constexpr.cpp
├── test_xor_constexpr.hpp
├── test_xor_native.cpp
├── test_xor_native_constexpr.cpp
└── test_z.cpp
Condensed preview — 332 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,898K chars).
[
{
"path": ".drone/drone.sh",
"chars": 1266,
"preview": "#!/bin/bash\n\n# Copyright 2020 Rene Rivera, Sam Darwin\n# Distributed under the Boost Software License, Version 1.0.\n# (Se..."
},
{
"path": ".drone.star",
"chars": 4200,
"preview": "# Use, modification, and distribution are\n# subject to the Boost Software License, Version 1.0. (See accompanying\n# file..."
},
{
"path": ".github/workflows/posix.yml",
"chars": 1797,
"preview": "name: POSIX\n\non:\n pull_request:\n push:\n branches:\n - master\n - develop\n - feature/**\n\nenv:\n LIBRARY..."
},
{
"path": ".github/workflows/windows.yml",
"chars": 1498,
"preview": "name: Windows\n\non:\n pull_request:\n push:\n branches:\n - master\n - develop\n - feature/**\n\nenv:\n LIBRA..."
},
{
"path": ".travis.yml",
"chars": 3833,
"preview": "# Copyright 2018 Peter Dimov\n# Distributed under the Boost Software License, Version 1.0.\n\nlanguage: cpp\n\nbranches:\n on..."
},
{
"path": "CMakeLists.txt",
"chars": 4996,
"preview": "if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)\n\n# Generated by `boostdep --cmake safe_numerics`\n# Copyright..."
},
{
"path": "LICENSE_1_0.txt",
"chars": 1338,
"preview": "Boost Software License - Version 1.0 - August 17th, 2003\n\nPermission is hereby granted, free of charge, to any person or..."
},
{
"path": "README.md",
"chars": 1648,
"preview": "safe_numerics\n=============\n\nArithmetic operations in C++ are NOT guaranteed to yield a correct mathematical result. Thi..."
},
{
"path": "appveyor.yml",
"chars": 987,
"preview": "# Copyright 2018 Peter Dimov\n# Distributed under the Boost Software License, Version 1.0.\n\nversion: 1.0.{build}-{branch}..."
},
{
"path": "b2.log",
"chars": 0,
"preview": ""
},
{
"path": "build.jam",
"chars": 728,
"preview": "# Copyright René Ferdinand Rivera Morell 2023-2024\n# Distributed under the Boost Software License, Version 1.0.\n# (See a..."
},
{
"path": "doc/boostbook/HTML.manifest",
"chars": 1391,
"preview": "../html/index.html\n../html/introduction.html\n../html/tutorial.html\n../html/tutorial/1.html\n../html/tutorial/2.html\n../ht..."
},
{
"path": "doc/boostbook/accu/accu.xml",
"chars": 6124,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE article PUBLIC \"-//OASIS//DTD DocBook XML V4.5//EN\"\n\"http://www.oasis-o..."
},
{
"path": "doc/boostbook/accu/bb2db.xsl",
"chars": 349,
"preview": "<?xml version='1.0'?>\n<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n <xsl:import href..."
},
{
"path": "doc/boostbook/accu/db2epub.xsl",
"chars": 2918,
"preview": "<?xml version='1.0'?>\n<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n\n<!-- ************..."
},
{
"path": "doc/boostbook/accu/db2fo.xsl",
"chars": 7552,
"preview": "<?xml version='1.0'?>\n<xsl:stylesheet \n xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" \n xmlns:fo=\"http://www.w3.org..."
},
{
"path": "doc/boostbook/accu/db2html.xsl",
"chars": 2918,
"preview": "<?xml version='1.0'?>\n<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n\n<!-- ************..."
},
{
"path": "doc/boostbook/accu/makehtml.sh",
"chars": 288,
"preview": "if test x = x$BOOST_ROOT \nthen\n echo BOOST_ROOT not set\nfi\nmkdir html\nxsltproc --xinclude --nonet bb2db.xsl accu.xml..."
},
{
"path": "doc/boostbook/accu/makepdf.sh",
"chars": 178,
"preview": "#use -r switch on fop for relaxed validation\nxsltproc --xinclude --nonet bb2db.xsl accu.xml > accudocbook4.xml\nfop -r -d..."
},
{
"path": "doc/boostbook/acknowledgements.xml",
"chars": 2876,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//OASIS//DTD DocBook XML V4.5//EN\"\n\"http://www.oasis-o..."
},
{
"path": "doc/boostbook/automatic.xml",
"chars": 4463,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/bb2db.xsl",
"chars": 349,
"preview": "<?xml version='1.0'?>\n<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n <xsl:import href..."
},
{
"path": "doc/boostbook/bibliography.xml",
"chars": 14634,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//OASIS//DTD DocBook XML V4.5//EN\"\n\"http://www.oasis-o..."
},
{
"path": "doc/boostbook/checked.xml",
"chars": 4697,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/checked_result.xml",
"chars": 10702,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/cpp.xml",
"chars": 4799,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/db2epub.xsl",
"chars": 2918,
"preview": "<?xml version='1.0'?>\n<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n\n<!-- ************..."
},
{
"path": "doc/boostbook/db2fo.xsl",
"chars": 7415,
"preview": "<?xml version='1.0'?>\n<xsl:stylesheet \n xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" \n xmlns:fo=\"http://www.w3.org..."
},
{
"path": "doc/boostbook/db2html.xsl",
"chars": 2918,
"preview": "<?xml version='1.0'?>\n<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n\n<!-- ************..."
},
{
"path": "doc/boostbook/db2pdf.xsl",
"chars": 2058,
"preview": "<?xml version='1.0'?>\n<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n\n<!-- ************..."
},
{
"path": "doc/boostbook/eliminate_runtime_penalty.xml",
"chars": 18217,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/exception.xml",
"chars": 7191,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/exception_policy.xml",
"chars": 9512,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/exception_policy_concept.xml",
"chars": 6654,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/faq.xml",
"chars": 14541,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//OASIS//DTD DocBook XML V4.5//EN\"\n\"http://www.oasis-o..."
},
{
"path": "doc/boostbook/ignore_exception.xml",
"chars": 1180,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/integer_concept.xml",
"chars": 7569,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/interval.xml",
"chars": 11681,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/makeepub.sh",
"chars": 433,
"preview": "if test x = x$BOOST_ROOT \nthen\n echo BOOST_ROOT not set\n exit 1\nfi\nxsltproc --nonet --xinclude bb2db.xsl safe_nume..."
},
{
"path": "doc/boostbook/makehtml.bat",
"chars": 385,
"preview": "if x == x%BOOST_ROOT% goto abort\n\nxsltproc --nonet --xinclude bb2db.xsl safe_numerics.xml | xsltproc --nonet db2html.xsl..."
},
{
"path": "doc/boostbook/makehtml.sh",
"chars": 464,
"preview": "if test x = x$BOOST_ROOT \nthen\n echo BOOST_ROOT not set\n exit 1\nfi\nxsltproc --nonet --xinclude bb2db.xsl safe_nume..."
},
{
"path": "doc/boostbook/makepdf.sh",
"chars": 425,
"preview": "if test x = x$BOOST_ROOT \nthen\n echo BOOST_ROOT not set\n exit 1\nfi\n#use -r switch on fop for relaxed validation\nxs..."
},
{
"path": "doc/boostbook/makeproposal.sh",
"chars": 412,
"preview": "if test x = x$BOOST_ROOT \nthen\n echo BOOST_ROOT not set\n exit 1\nfi\n#use -r switch on fop for relaxed validation\nxs..."
},
{
"path": "doc/boostbook/motor.xml",
"chars": 25821,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/native.xml",
"chars": 3524,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/no_exception_support.xml",
"chars": 4094,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/notes.xml",
"chars": 3289,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//OASIS//DTD DocBook XML V4.5//EN\"\n\"http://www.oasis-o..."
},
{
"path": "doc/boostbook/numeric_concept.xml",
"chars": 13986,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/overflow.xml",
"chars": 1825,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/pending.xml",
"chars": 4083,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/promotion_policy_concept.xml",
"chars": 8878,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/proposal.xml",
"chars": 19758,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE article PUBLIC \"-//OASIS//DTD DocBook XML V4.5//EN\"\n\"http://www.oasis-o..."
},
{
"path": "doc/boostbook/rational.xml",
"chars": 3653,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//OASIS//DTD DocBook XML V4.5//EN\"\n\"http://www.oasis-o..."
},
{
"path": "doc/boostbook/safe.xml",
"chars": 11738,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/safe_cast.xml",
"chars": 2534,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/safe_compare.xml",
"chars": 2885,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//OASIS//DTD DocBook XML V4.5//EN\"\n\"http://www.oasis-o..."
},
{
"path": "doc/boostbook/safe_introduction.xml",
"chars": 13009,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/safe_literal.xml",
"chars": 5351,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/safe_numerics.xml",
"chars": 13955,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE library PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/safe_range.xml",
"chars": 6228,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/trap_exception.xml",
"chars": 1494,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.boost..."
},
{
"path": "doc/boostbook/tutorial.xml",
"chars": 16224,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE section PUBLIC \"-//Boost//DTD BoostBook XML V1.1//EN\"\n\"http://www.oasis..."
},
{
"path": "doc/html/acknowledgements.html",
"chars": 4173,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Acknowledgements</title>\n<link..."
},
{
"path": "doc/html/bibliography.html",
"chars": 16387,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Bibliography</title>\n<link rel=..."
},
{
"path": "doc/html/boostbook.css",
"chars": 17619,
"preview": "\n/*=============================================================================\nCopyright (c) 2004 Joel de Guzman\nhttp:..."
},
{
"path": "doc/html/case_studies.html",
"chars": 2436,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Case Studies</title>\n<link rel=..."
},
{
"path": "doc/html/change_log.html",
"chars": 2763,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Release Log</title>\n<link rel=\"..."
},
{
"path": "doc/html/checked_arithmetic.html",
"chars": 20903,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Checked Arithmetic</title>\n<lin..."
},
{
"path": "doc/html/checked_integer_arithmetic.html",
"chars": 12274,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>safe_compare<T, U></title..."
},
{
"path": "doc/html/checked_result.html",
"chars": 18075,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>checked_result<R></title>..."
},
{
"path": "doc/html/composition_with_other_libraries.html",
"chars": 16526,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Composition with Other Librarie..."
},
{
"path": "doc/html/concepts.html",
"chars": 2430,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Type Requirements</title>\n<link..."
},
{
"path": "doc/html/eliminate_runtime_penalty/1.html",
"chars": 18585,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Using Automatic Type Promotion<..."
},
{
"path": "doc/html/eliminate_runtime_penalty/2.html",
"chars": 15474,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Using safe_range and safe_liter..."
},
{
"path": "doc/html/eliminate_runtime_penalty/3.html",
"chars": 18916,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Mixing Approaches</title>\n<link..."
},
{
"path": "doc/html/eliminate_runtime_penalty.html",
"chars": 7586,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Eliminating Runtime Penalty</ti..."
},
{
"path": "doc/html/exception.html",
"chars": 10050,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>exception</title>\n<link rel=\"st..."
},
{
"path": "doc/html/exception_policies.html",
"chars": 14332,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>exception_policy<AE, IDB, UB..."
},
{
"path": "doc/html/exception_policy.html",
"chars": 10427,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>ExceptionPolicy<EP></titl..."
},
{
"path": "doc/html/exception_safety.html",
"chars": 2215,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Exception Safety</title>\n<link..."
},
{
"path": "doc/html/index.html",
"chars": 7417,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Safe Numerics</title>\n<link rel..."
},
{
"path": "doc/html/integer.html",
"chars": 10323,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Integer<T></title>\n<link..."
},
{
"path": "doc/html/integer_concept.html",
"chars": 10426,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Integer<T></title>\n<link..."
},
{
"path": "doc/html/interval.html",
"chars": 19357,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>interval<R></title>\n<link..."
},
{
"path": "doc/html/introduction.html",
"chars": 20100,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Introduction</title>\n<link rel=..."
},
{
"path": "doc/html/library_implementation.html",
"chars": 10034,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Library Implementation</title>..."
},
{
"path": "doc/html/notes.html",
"chars": 5048,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Background</title>\n<link rel=\"s..."
},
{
"path": "doc/html/numeric.html",
"chars": 16609,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Numeric<T></title>\n<link..."
},
{
"path": "doc/html/numeric_concept.html",
"chars": 17697,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Numeric<T></title>\n<link..."
},
{
"path": "doc/html/pending_issues.html",
"chars": 8169,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Pending Issues</title>\n<link re..."
},
{
"path": "doc/html/performance_tests.html",
"chars": 3361,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Performance Tests</title>\n<link..."
},
{
"path": "doc/html/promotion_policies/automatic.html",
"chars": 8395,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>automatic</title>\n<link rel=\"st..."
},
{
"path": "doc/html/promotion_policies/cpp.html",
"chars": 6871,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>cpp<int C, int S, int I, int..."
},
{
"path": "doc/html/promotion_policies/native.html",
"chars": 11666,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>native</title>\n<link rel=\"style..."
},
{
"path": "doc/html/promotion_policies.html",
"chars": 2434,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Promotion Policies</title>\n<lin..."
},
{
"path": "doc/html/promotion_policy.html",
"chars": 15440,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>PromotionPolicy<PP></titl..."
},
{
"path": "doc/html/rationale.html",
"chars": 26020,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Rationale and FAQ</title>\n<link..."
},
{
"path": "doc/html/safe.html",
"chars": 30198,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>safe<T, PP, EP></title>\n<..."
},
{
"path": "doc/html/safe_literal.html",
"chars": 10522,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>safe_signed_literal<Value, P..."
},
{
"path": "doc/html/safe_numeric_concept.html",
"chars": 16030,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>SafeNumeric<T></title>\n<l..."
},
{
"path": "doc/html/safe_numerics_error.html",
"chars": 5335,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">\n<title>enum class safe_numerics_err..."
},
{
"path": "doc/html/safe_range.html",
"chars": 18961,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>safe_signed_range<MIN, MAX,..."
},
{
"path": "doc/html/safety_critical_embedded_controller.html",
"chars": 131558,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Safety Critical Embedded Contro..."
},
{
"path": "doc/html/tutorial/1.html",
"chars": 11824,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Arithmetic Expressions Can Yiel..."
},
{
"path": "doc/html/tutorial/10.html",
"chars": 18319,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Programming by Contract is Too..."
},
{
"path": "doc/html/tutorial/2.html",
"chars": 9917,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Arithmetic Operations Can Overf..."
},
{
"path": "doc/html/tutorial/3.html",
"chars": 12382,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Arithmetic on Unsigned Integers..."
},
{
"path": "doc/html/tutorial/4.html",
"chars": 15917,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Implicit Conversions Can Lead t..."
},
{
"path": "doc/html/tutorial/5.html",
"chars": 11546,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Mixing Data Types Can Create Su..."
},
{
"path": "doc/html/tutorial/6.html",
"chars": 11116,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Array Index Value Can Exceed Ar..."
},
{
"path": "doc/html/tutorial/7.html",
"chars": 11430,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Checking of Input Values Can Be..."
},
{
"path": "doc/html/tutorial/8.html",
"chars": 10521,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Cannot Recover From Arithmetic..."
},
{
"path": "doc/html/tutorial/9.html",
"chars": 11106,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Compile Time Arithmetic is Not..."
},
{
"path": "doc/html/tutorial.html",
"chars": 3264,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Tutorial and Motivating Example..."
},
{
"path": "doc/html/types.html",
"chars": 2736,
"preview": "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Types</title>\n<link rel=\"styles..."
},
{
"path": "example/CMakeLists.txt",
"chars": 1252,
"preview": "# CMake build control file for safe numerics Library Examples\n\n###########################\n# examples\n\nmessage( STATUS \"..."
},
{
"path": "example/Jamfile.v2",
"chars": 870,
"preview": "# Boost.SafeNumerics Library test Jamfile\n#\n# Copyright (c) 2017 Robert Ramey\n#\n# Distributed under the Boost Softwar..."
},
{
"path": "example/Motor.c",
"chars": 5183,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example1.cpp",
"chars": 1362,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example10.cpp",
"chars": 1405,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example11.cpp",
"chars": 1361,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example13.cpp",
"chars": 1363,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example14.cpp",
"chars": 1443,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example15.cpp",
"chars": 1638,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example16.cpp",
"chars": 524,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example17.cpp",
"chars": 599,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example18.cpp",
"chars": 644,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example19.cpp",
"chars": 1997,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example2.cpp",
"chars": 1290,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example20.cpp",
"chars": 845,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example3.cpp",
"chars": 1539,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example4.cpp",
"chars": 1778,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example5.cpp",
"chars": 1582,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example6.cpp",
"chars": 1513,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example7.cpp",
"chars": 3038,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example8.cpp",
"chars": 1472,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example81.cpp",
"chars": 681,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example82.cpp",
"chars": 907,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example83.cpp",
"chars": 1585,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example84.cpp",
"chars": 2180,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "example/example91.cpp",
"chars": 3076,
"preview": "//////////////////////////////////////////////////////////////////\n// example91.cpp\n//\n// Copyright (c) 2015 Robert Rame..."
},
{
"path": "example/example92.cpp",
"chars": 5697,
"preview": "//////////////////////////////////////////////////////////////////\n// example92.cpp\n//\n// Copyright (c) 2015 Robert Rame..."
},
{
"path": "example/example93.cpp",
"chars": 8702,
"preview": "//////////////////////////////////////////////////////////////////\n// example93.cpp\n//\n// Copyright (c) 2015 Robert Rame..."
},
{
"path": "example/links.html",
"chars": 19357,
"preview": "<html>\n<head>\n<title>Boost Library Status Error Log</title>\n</head>\n<body bgcolor=\"#ffffff\" text=\"#000000\">\n<table borde..."
},
{
"path": "example/motor1.c",
"chars": 5466,
"preview": "/*\n * david austin\n * http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profi..."
},
{
"path": "example/motor2.c",
"chars": 6177,
"preview": "/*\n * david austin\n * http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profi..."
},
{
"path": "example/motor3.c",
"chars": 6411,
"preview": "/*\n * david austin\n * http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profi..."
},
{
"path": "example/motor_test1.c",
"chars": 1137,
"preview": "/*\n * david austin\n * http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profi..."
},
{
"path": "example/motor_test2.c",
"chars": 1263,
"preview": "/*\n * david austin\n * http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profi..."
},
{
"path": "example/motor_test3.c",
"chars": 1530,
"preview": "/*\n * david austin\n * http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profi..."
},
{
"path": "example/picsfr.h",
"chars": 761,
"preview": "//////////////////////////////////////////////////////////////////\n// picsfr.h\n// Copyright (c) 2015 Robert Ramey\n//\n//..."
},
{
"path": "example/safe_format.hpp",
"chars": 1510,
"preview": "// Copyright (c) 2018 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "include/boost/safe_numerics/CMakeLists.txt",
"chars": 260,
"preview": "####################\n# add include headers to IDE\n\nfile(GLOB include_files \n RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"..."
},
{
"path": "include/boost/safe_numerics/automatic.hpp",
"chars": 17772,
"preview": "#ifndef BOOST_NUMERIC_AUTOMATIC_HPP\n#define BOOST_NUMERIC_AUTOMATIC_HPP\n\n// Copyright (c) 2012 Robert Ramey\n//\n// Distr..."
},
{
"path": "include/boost/safe_numerics/checked_default.hpp",
"chars": 7260,
"preview": "#ifndef BOOST_NUMERIC_CHECKED_DEFAULT_HPP\n#define BOOST_NUMERIC_CHECKED_DEFAULT_HPP\n\n// Copyright (c) 2017 Robert Ramey..."
},
{
"path": "include/boost/safe_numerics/checked_float.hpp",
"chars": 5203,
"preview": "#ifndef BOOST_NUMERIC_CHECKED_FLOAT_HPP\n#define BOOST_NUMERIC_CHECKED_FLOAT_HPP\n\n// Copyright (c) 2017 Robert Ramey\n//..."
},
{
"path": "include/boost/safe_numerics/checked_integer.hpp",
"chars": 27148,
"preview": "#ifndef BOOST_NUMERIC_CHECKED_INTEGER_HPP\n#define BOOST_NUMERIC_CHECKED_INTEGER_HPP\n\n// Copyright (c) 2012 Robert Ramey..."
},
{
"path": "include/boost/safe_numerics/checked_result.hpp",
"chars": 3090,
"preview": "#ifndef BOOST_NUMERIC_CHECKED_RESULT\n#define BOOST_NUMERIC_CHECKED_RESULT\n\n// Copyright (c) 2012 Robert Ramey\n//\n// Dis..."
},
{
"path": "include/boost/safe_numerics/checked_result_operations.hpp",
"chars": 42336,
"preview": "#ifndef BOOST_NUMERIC_CHECKED_RESULT_OPERATIONS\n#define BOOST_NUMERIC_CHECKED_RESULT_OPERATIONS\n\n// Copyright (c) 2012..."
},
{
"path": "include/boost/safe_numerics/concept/CMakeLists.txt",
"chars": 339,
"preview": "####################\n# add include headers to IDE\n\nset(USE_FOLDERS TRUE)\n\nfile(GLOB include_files\n RELATIVE \"${CMAKE_CU..."
},
{
"path": "include/boost/safe_numerics/concept/exception_policy.hpp",
"chars": 761,
"preview": "#ifndef BOOST_NUMERIC_CONCEPT_EXCEPTION_POLICY_HPP\n#define BOOST_NUMERIC_CONCEPT_EXCEPTION_POLICY_HPP\n\n// Copyright (c)..."
},
{
"path": "include/boost/safe_numerics/concept/integer.hpp",
"chars": 542,
"preview": "#ifndef BOOST_NUMERIC_CONCEPT_INTEGER_HPP\n#define BOOST_NUMERIC_CONCEPT_INTEGER_HPP\n\n// Copyright (c) 2012 Robert Ramey..."
},
{
"path": "include/boost/safe_numerics/concept/numeric.hpp",
"chars": 567,
"preview": "#ifndef BOOST_NUMERIC_CONCEPT_NUMERIC_HPP\n#define BOOST_NUMERIC_CONCEPT_NUMERIC_HPP\n\n// Copyright (c) 2021 Robert Ramey..."
},
{
"path": "include/boost/safe_numerics/concept/promotion_policy.hpp",
"chars": 1252,
"preview": "#ifndef BOOST_NUMERIC_CONCEPT_PROMOTION_POLICY_HPP\n#define BOOST_NUMERIC_CONCEPT_PROMOTION_POLICY_HPP\n\n// Copyright (c)..."
},
{
"path": "include/boost/safe_numerics/cpp.hpp",
"chars": 6802,
"preview": "#ifndef BOOST_NUMERIC_CPP_HPP\n#define BOOST_NUMERIC_CPP_HPP\n\n// Copyright (c) 2012 Robert Ramey\n//\n// Distributed under..."
},
{
"path": "include/boost/safe_numerics/exception.hpp",
"chars": 7815,
"preview": "#ifndef BOOST_NUMERIC_EXCEPTION\n#define BOOST_NUMERIC_EXCEPTION\n\n// Copyright (c) 2012 Robert Ramey\n//\n// Distributed u..."
},
{
"path": "include/boost/safe_numerics/exception_policies.hpp",
"chars": 5511,
"preview": "#ifndef BOOST_NUMERIC_EXCEPTION_POLICIES_HPP\n#define BOOST_NUMERIC_EXCEPTION_POLICIES_HPP\n\n// Copyright (c) 2015 Robert..."
},
{
"path": "include/boost/safe_numerics/interval.hpp",
"chars": 8268,
"preview": "#ifndef BOOST_SAFE_NUMERICS_INTERVAL_HPP\n#define BOOST_SAFE_NUMERICS_INTERVAL_HPP\n\n// Copyright (c) 2012 Robert Ramey\n/..."
},
{
"path": "include/boost/safe_numerics/native.hpp",
"chars": 3201,
"preview": "#ifndef BOOST_SAFE_NUMERICS_NATIVE_HPP\n#define BOOST_SAFE_NUMERICS_NATIVE_HPP\n\n// Copyright (c) 2012 Robert Ramey\n//\n//..."
},
{
"path": "include/boost/safe_numerics/range_value.hpp",
"chars": 1498,
"preview": "#ifndef BOOST_RANGE_VALUE_HPP\n#define BOOST_RANGE_VALUE_HPP\n\n// Copyright (c) 2015 Robert Ramey\n//\n// Distributed under..."
},
{
"path": "include/boost/safe_numerics/safe_base.hpp",
"chars": 8961,
"preview": "#ifndef BOOST_NUMERIC_SAFE_BASE_HPP\n#define BOOST_NUMERIC_SAFE_BASE_HPP\n\n// Copyright (c) 2012 Robert Ramey\n//\n// Distr..."
},
{
"path": "include/boost/safe_numerics/safe_base_operations.hpp",
"chars": 58588,
"preview": "#ifndef BOOST_NUMERIC_SAFE_BASE_OPERATIONS_HPP\n#define BOOST_NUMERIC_SAFE_BASE_OPERATIONS_HPP\n\n// Copyright (c) 2012 Ro..."
},
{
"path": "include/boost/safe_numerics/safe_common.hpp",
"chars": 913,
"preview": "#ifndef BOOST_NUMERIC_SAFE_COMMON_HPP\n#define BOOST_NUMERIC_SAFE_COMMON_HPP\n\n// Copyright (c) 2012 Robert Ramey\n//\n// D..."
},
{
"path": "include/boost/safe_numerics/safe_compare.hpp",
"chars": 4898,
"preview": "#ifndef BOOST_NUMERIC_SAFE_COMPARE_HPP\n#define BOOST_NUMERIC_SAFE_COMPARE_HPP\n\n// Copyright (c) 2012 Robert Ramey\n//\n//..."
},
{
"path": "include/boost/safe_numerics/safe_integer.hpp",
"chars": 956,
"preview": "#ifndef BOOST_NUMERIC_SAFE_INTEGER_HPP\n#define BOOST_NUMERIC_SAFE_INTEGER_HPP\n\n// Copyright (c) 2012 Robert Ramey\n//\n//..."
},
{
"path": "include/boost/safe_numerics/safe_integer_literal.hpp",
"chars": 7060,
"preview": "#ifndef BOOST_NUMERIC_SAFE_INTEGER_LITERAL_HPP\n#define BOOST_NUMERIC_SAFE_INTEGER_LITERAL_HPP\n\n// Copyright (c) 2012 Ro..."
},
{
"path": "include/boost/safe_numerics/safe_integer_range.hpp",
"chars": 1600,
"preview": "#ifndef BOOST_NUMERIC_SAFE_INTEGER_RANGE_HPP\n#define BOOST_NUMERIC_SAFE_INTEGER_RANGE_HPP\n\n// Copyright (c) 2012 Robert..."
},
{
"path": "include/boost/safe_numerics/utility.hpp",
"chars": 7540,
"preview": "#ifndef BOOST_NUMERIC_UTILITY_HPP\n#define BOOST_NUMERIC_UTILITY_HPP\n\n// Copyright (c) 2015 Robert Ramey\n//\n// Distribut..."
},
{
"path": "index.html",
"chars": 451,
"preview": "<html>\n<!--\n(C) Copyright 2017 Robert Ramey - http://www.rrsd.com .\nUse, modification and distribution is subject to the..."
},
{
"path": "meta/libraries.json",
"chars": 323,
"preview": "{\n \"key\": \"safe_numerics\",\n \"name\": \"Safe Numerics\",\n \"authors\": [\n \"Robert Ramey\"\n ],\n \"descripti..."
},
{
"path": "test/CMakeLists.txt",
"chars": 4088,
"preview": "# CMake build control file for safe numerics Library tests\n\n###########################\n# test targets\n\nmessage( STATUS..."
},
{
"path": "test/Jamfile.v2",
"chars": 4073,
"preview": "# Boost.SafeNumerics Library test Jamfile\n#\n# Copyright (c) 2017 Robert Ramey\n#\n# Distributed under the Boost Softwar..."
},
{
"path": "test/check_symmetry.hpp",
"chars": 368,
"preview": "// given an array of values of a particular type\ntemplate<typename T, unsigned int N>\nconstexpr bool check_symmetry(cons..."
},
{
"path": "test/test0.cpp",
"chars": 3041,
"preview": "// Copyright (c) 2012 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "test/test_add.hpp",
"chars": 4628,
"preview": "#ifndef BOOST_TEST_ADD_HPP\n#define BOOST_TEST_ADD_HPP\n\n// Copyright (c) 2015 Robert Ramey\n//\n// Distributed under the B..."
},
{
"path": "test/test_add_automatic.cpp",
"chars": 2117,
"preview": "// Copyright (c) 2012 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "test/test_add_automatic_constexpr.cpp",
"chars": 1481,
"preview": "// Copyright (c) 2019 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "test/test_add_automatic_results.hpp",
"chars": 2149,
"preview": "#ifndef BOOST_SAFE_NUMERICS_TEST_ADD_AUTOMATIC_RESULTS_HPP\n#define BOOST_SAFE_NUMERICS_TEST_ADD_AUTOMATIC_RESULTS_HPP\n\n/..."
},
{
"path": "test/test_add_constexpr.hpp",
"chars": 835,
"preview": "#ifndef BOOST_TEST_ADD_CONSTEXPR_HPP\n#define BOOST_TEST_ADD_CONSTEXPR_HPP\n\n// Copyright (c) 2015 Robert Ramey\n//\n// Dis..."
},
{
"path": "test/test_add_native.cpp",
"chars": 2074,
"preview": "// Copyright (c) 2012 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "test/test_add_native_constexpr.cpp",
"chars": 1467,
"preview": "// Copyright (c) 2019 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "test/test_add_native_results.hpp",
"chars": 2192,
"preview": "#ifndef BOOST_SAFE_NUMERICS_TEST_ADD_NATIVE_RESULTS_HPP\n#define BOOST_SAFE_NUMERICS_TEST_ADD_NATIVE_RESULTS_HPP\n\n// Cop..."
},
{
"path": "test/test_and.hpp",
"chars": 4639,
"preview": "#ifndef BOOST_TEST_AND_HPP\n#define BOOST_TEST_AND_HPP\n\n// Copyright (c) 2015 Robert Ramey\n//\n// Distributed under the B..."
},
{
"path": "test/test_and_automatic.cpp",
"chars": 1863,
"preview": "// Copyright (c) 2012 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "test/test_and_automatic_constexpr.cpp",
"chars": 1512,
"preview": "// Copyright (c) 2019 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "test/test_and_native.cpp",
"chars": 1857,
"preview": "// Copyright (c) 2012 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "test/test_and_native_constexpr.cpp",
"chars": 1497,
"preview": "// Copyright (c) 2019 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "test/test_assignment.cpp",
"chars": 4127,
"preview": "// Copyright (c) 2017 Robert Ramey\n//\n// Distributed under the Boost Software License, Version 1.0. (See\n// accompanyin..."
},
{
"path": "test/test_assignment.hpp",
"chars": 3104,
"preview": "#ifndef BOOST_TEST_ASSIGNMENT_HPP\n#define BOOST_TEST_ASSIGNMENT_HPP\n\n// Copyright (c) 2015 Robert Ramey\n//\n// Distribut..."
},
{
"path": "test/test_auto.cpp",
"chars": 2056,
"preview": "#include <iostream>\n#include <cassert>\n#include <boost/core/demangle.hpp>\n\n#include <boost/safe_numerics/safe_integer.hp..."
}
]
// ... and 132 more files (download for full content)
About this extraction
This page contains the full source code of the boostorg/safe_numerics GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 333 files (1.7 MB), approximately 472.0k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.