├── .drone.star ├── .drone └── drone.sh ├── .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 │ ├── StepperMotor.gif │ ├── accu │ │ ├── accu.pdf │ │ ├── accu.xml │ │ ├── accu_logo.png │ │ ├── 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 │ ├── images │ │ ├── annot-close.png │ │ ├── annot-open.png │ │ ├── blank.png │ │ ├── callouts │ │ │ ├── 1.png │ │ │ ├── 10.png │ │ │ ├── 11.png │ │ │ ├── 12.png │ │ │ ├── 13.png │ │ │ ├── 14.png │ │ │ ├── 15.png │ │ │ ├── 2.png │ │ │ ├── 3.png │ │ │ ├── 4.png │ │ │ ├── 5.png │ │ │ ├── 6.png │ │ │ ├── 7.png │ │ │ ├── 8.png │ │ │ └── 9.png │ │ ├── caution.png │ │ ├── draft.png │ │ ├── home.png │ │ ├── important.png │ │ ├── next.png │ │ ├── note.png │ │ ├── prev.png │ │ ├── tip.png │ │ ├── toc-blank.png │ │ ├── toc-minus.png │ │ ├── toc-plus.png │ │ ├── up.png │ │ └── warning.png │ ├── 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 │ ├── pre-boost.jpg │ ├── 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 │ ├── stepper_profile.png │ ├── trap_exception.xml │ └── tutorial.xml ├── html │ ├── StepperMotor.gif │ ├── 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.html │ ├── eliminate_runtime_penalty │ │ ├── 1.html │ │ ├── 2.html │ │ ├── 3.html │ │ └── pre-boost.jpg │ ├── exception.html │ ├── exception_policies.html │ ├── exception_policy.html │ ├── exception_safety.html │ ├── images │ │ ├── blank.png │ │ ├── caution.png │ │ ├── draft.png │ │ ├── home.png │ │ ├── important.png │ │ ├── next.png │ │ ├── next_disabled.png │ │ ├── note.png │ │ ├── prev.png │ │ ├── prev_disabled.png │ │ ├── tip.png │ │ ├── toc-blank.png │ │ ├── toc-minus.png │ │ ├── toc-plus.png │ │ ├── up.png │ │ ├── up_disabled.png │ │ └── warning.png │ ├── 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 │ ├── pre-boost.jpg │ ├── promotion_policies.html │ ├── promotion_policies │ │ ├── automatic.html │ │ ├── cpp.html │ │ ├── native.html │ │ └── pre-boost.jpg │ ├── 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 │ ├── stepper_profile.png │ ├── tutorial.html │ ├── tutorial │ │ ├── 1.html │ │ ├── 10.html │ │ ├── 2.html │ │ ├── 3.html │ │ ├── 4.html │ │ ├── 5.html │ │ ├── 6.html │ │ ├── 7.html │ │ ├── 8.html │ │ ├── 9.html │ │ └── pre-boost.jpg │ └── types.html ├── images │ ├── annot-close.png │ ├── annot-open.png │ ├── blank.png │ ├── callouts │ │ ├── 1.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ └── 9.png │ ├── caution.png │ ├── draft.png │ ├── home.png │ ├── important.png │ ├── next.png │ ├── note.png │ ├── prev.png │ ├── tip.png │ ├── toc-blank.png │ ├── toc-minus.png │ ├── toc-plus.png │ ├── up.png │ └── warning.png └── safe_numerics.pdf ├── 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 └── stepper-motor.pdf ├── 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 /.drone/drone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2020 Rene Rivera, Sam Darwin 4 | # Distributed under the Boost Software License, Version 1.0. 5 | # (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt) 6 | 7 | set -e 8 | export TRAVIS_BUILD_DIR=$(pwd) 9 | export DRONE_BUILD_DIR=$(pwd) 10 | export TRAVIS_BRANCH=$DRONE_BRANCH 11 | export VCS_COMMIT_ID=$DRONE_COMMIT 12 | export GIT_COMMIT=$DRONE_COMMIT 13 | export REPO_NAME=$DRONE_REPO 14 | export PATH=~/.local/bin:/usr/local/bin:$PATH 15 | 16 | if [ "$DRONE_JOB_BUILDTYPE" == "boost" ]; then 17 | 18 | echo '==================================> INSTALL' 19 | 20 | BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true 21 | cd .. 22 | git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost 23 | cd boost 24 | git submodule update --init tools/build 25 | git submodule update --init libs/config 26 | git submodule update --init tools/boostdep 27 | git submodule update --init tools/boost_install 28 | git submodule update --init libs/headers 29 | mkdir -p libs/safe_numerics 30 | cp -r $TRAVIS_BUILD_DIR/* libs/safe_numerics 31 | python tools/boostdep/depinst/depinst.py safe_numerics 32 | ./bootstrap.sh 33 | ./b2 headers 34 | 35 | echo '==================================> SCRIPT' 36 | 37 | echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam 38 | ./b2 -j 3 libs/safe_numerics/test toolset=$TOOLSET cxxstd=$CXXSTD 39 | 40 | fi 41 | -------------------------------------------------------------------------------- /.github/workflows/posix.yml: -------------------------------------------------------------------------------- 1 | name: POSIX 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | - develop 9 | - feature/** 10 | 11 | env: 12 | LIBRARY: safe_numerics 13 | UBSAN_OPTIONS: print_stacktrace=1 14 | 15 | jobs: 16 | CI: 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | include: 21 | - toolset: gcc-6 22 | cxxstd: "14,1z" 23 | os: ubuntu-16.04 24 | install: g++-6 25 | - toolset: gcc-7 26 | cxxstd: "14,17" 27 | os: ubuntu-18.04 28 | - toolset: gcc-8 29 | cxxstd: "14,17,2a" 30 | os: ubuntu-18.04 31 | - toolset: gcc-9 32 | cxxstd: "14,17,2a" 33 | os: ubuntu-18.04 34 | - toolset: gcc-10 35 | cxxstd: "14,17,2a" 36 | os: ubuntu-18.04 37 | - toolset: clang 38 | cxxstd: "14,17,2a" 39 | os: ubuntu-18.04 40 | - toolset: clang 41 | cxxstd: "14,17,2a" 42 | os: macos-10.15 43 | 44 | runs-on: ${{matrix.os}} 45 | 46 | steps: 47 | - uses: actions/checkout@v2 48 | 49 | - name: Install packages 50 | if: matrix.install 51 | run: sudo apt install ${{matrix.install}} 52 | 53 | - name: Setup Boost 54 | run: | 55 | REF=${GITHUB_BASE_REF:-$GITHUB_REF} 56 | BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true 57 | cd .. 58 | git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root 59 | cd boost-root 60 | cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY 61 | git submodule update --init tools/boostdep 62 | python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY 63 | ./bootstrap.sh 64 | ./b2 -d0 headers 65 | 66 | - name: Run tests 67 | run: | 68 | cd ../boost-root 69 | ./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release 70 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | - develop 9 | - feature/** 10 | 11 | env: 12 | LIBRARY: safe_numerics 13 | 14 | jobs: 15 | CI: 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | include: 20 | - toolset: msvc-14.1 21 | cxxstd: "14,17,latest" 22 | addrmd: 32,64 23 | os: windows-2016 24 | - toolset: msvc-14.2 25 | cxxstd: "14,17,latest" 26 | addrmd: 32,64 27 | os: windows-2019 28 | - toolset: gcc 29 | cxxstd: "14,17,2a" 30 | addrmd: 64 31 | os: windows-2019 32 | 33 | runs-on: ${{matrix.os}} 34 | 35 | steps: 36 | - uses: actions/checkout@v2 37 | 38 | - name: Setup Boost 39 | shell: cmd 40 | run: | 41 | if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF% 42 | set BOOST_BRANCH=develop 43 | if "%GITHUB_BASE_REF%" == "master" set BOOST_BRANCH=master 44 | cd .. 45 | git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root 46 | cd boost-root 47 | xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ 48 | git submodule update --init tools/boostdep 49 | python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY% 50 | cmd /c bootstrap 51 | b2 -d0 headers 52 | 53 | - name: Run tests 54 | shell: cmd 55 | run: | 56 | cd ../boost-root 57 | b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release 58 | -------------------------------------------------------------------------------- /LICENSE_1_0.txt: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | safe_numerics 2 | ============= 3 | 4 | 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. 5 | 6 | Note: This is the subject of a various presentations at CPPCon. 7 | 8 | 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 9 | 10 | 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 . 11 | 12 | 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 13 | 14 | If you use this libary and find it useful, please add a star. I need motivation!!! 15 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Peter Dimov 2 | # Distributed under the Boost Software License, Version 1.0. 3 | 4 | version: 1.0.{build}-{branch} 5 | 6 | shallow_clone: true 7 | 8 | branches: 9 | only: 10 | - master 11 | - develop 12 | 13 | environment: 14 | matrix: 15 | - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 16 | TOOLSET: msvc-14.1 17 | CXXSTD: 14,17 18 | 19 | install: 20 | - cd .. 21 | - git clone -b %APPVEYOR_REPO_BRANCH% https://github.com/boostorg/boost.git boost 22 | - cd boost 23 | - git submodule update --init tools/build 24 | - git submodule update --init libs/config 25 | - git submodule update --init tools/boostdep 26 | - git submodule update --init tools/boost_install 27 | - git submodule update --init libs/headers 28 | - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\safe_numerics\ 29 | - python tools/boostdep/depinst/depinst.py safe_numerics 30 | - cmd /c bootstrap 31 | - b2 headers 32 | 33 | build: off 34 | 35 | test_script: 36 | - PATH=%ADDPATH%%PATH% 37 | - if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% 38 | - b2 -j 3 libs/safe_numerics/test toolset=%TOOLSET% %CXXSTD% 39 | -------------------------------------------------------------------------------- /b2.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/b2.log -------------------------------------------------------------------------------- /build.jam: -------------------------------------------------------------------------------- 1 | # Copyright René Ferdinand Rivera Morell 2023-2024 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # (See accompanying file LICENSE_1_0.txt or copy at 4 | # http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | require-b2 5.2 ; 7 | 8 | constant boost_dependencies : 9 | /boost/concept_check//boost_concept_check 10 | /boost/config//boost_config 11 | /boost/core//boost_core 12 | /boost/integer//boost_integer 13 | /boost/logic//boost_logic 14 | /boost/mp11//boost_mp11 ; 15 | 16 | project /boost/safe_numerics 17 | : common-requirements 18 | include 19 | ; 20 | 21 | explicit 22 | [ alias boost_safe_numerics : : : : $(boost_dependencies) ] 23 | [ alias all : boost_safe_numerics example test ] 24 | ; 25 | 26 | call-if : boost-library safe_numerics 27 | ; 28 | 29 | -------------------------------------------------------------------------------- /doc/boostbook/HTML.manifest: -------------------------------------------------------------------------------- 1 | ../html/index.html 2 | ../html/introduction.html 3 | ../html/tutorial.html 4 | ../html/tutorial/1.html 5 | ../html/tutorial/2.html 6 | ../html/tutorial/3.html 7 | ../html/tutorial/4.html 8 | ../html/tutorial/5.html 9 | ../html/tutorial/6.html 10 | ../html/tutorial/7.html 11 | ../html/tutorial/8.html 12 | ../html/tutorial/9.html 13 | ../html/tutorial/10.html 14 | ../html/eliminate_runtime_penalty.html 15 | ../html/eliminate_runtime_penalty/2.html 16 | ../html/eliminate_runtime_penalty/1.html 17 | ../html/eliminate_runtime_penalty/3.html 18 | ../html/case_studies.html 19 | ../html/composition_with_other_libraries.html 20 | ../html/safety_critical_embedded_controller.html 21 | ../html/notes.html 22 | ../html/concepts.html 23 | ../html/numeric_concept.html 24 | ../html/integer_concept.html 25 | ../html/promotion_policy.html 26 | ../html/exception_policy.html 27 | ../html/types.html 28 | ../html/safe.html 29 | ../html/safe_range.html 30 | ../html/safe_literal.html 31 | ../html/exception.html 32 | ../html/exception_policies.html 33 | ../html/promotion_policies.html 34 | ../html/promotion_policies/native.html 35 | ../html/promotion_policies/automatic.html 36 | ../html/promotion_policies/cpp.html 37 | ../html/exception_safety.html 38 | ../html/library_implementation.html 39 | ../html/checked_result.html 40 | ../html/checked_arithmetic.html 41 | ../html/interval.html 42 | ../html/checked_integer_arithmetic.html 43 | ../html/performance_tests.html 44 | ../html/rationale.html 45 | ../html/pending_issues.html 46 | ../html/acknowledgements.html 47 | ../html/change_log.html 48 | ../html/bibliography.html 49 | -------------------------------------------------------------------------------- /doc/boostbook/StepperMotor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/StepperMotor.gif -------------------------------------------------------------------------------- /doc/boostbook/accu/accu.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/accu/accu.pdf -------------------------------------------------------------------------------- /doc/boostbook/accu/accu_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/accu/accu_logo.png -------------------------------------------------------------------------------- /doc/boostbook/accu/bb2db.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /doc/boostbook/accu/makehtml.sh: -------------------------------------------------------------------------------- 1 | if test x = x$BOOST_ROOT 2 | then 3 | echo BOOST_ROOT not set 4 | fi 5 | mkdir html 6 | xsltproc --xinclude --nonet bb2db.xsl accu.xml > accudocbook4.xml 7 | xsltproc --nonet db2html.xsl accudocbook4.xml 8 | cp accu_logo.png html 9 | cp $BOOST_ROOT/doc/src/boostbook.css html 10 | cp -R $BOOST_ROOT/doc/html/images html 11 | -------------------------------------------------------------------------------- /doc/boostbook/accu/makepdf.sh: -------------------------------------------------------------------------------- 1 | #use -r switch on fop for relaxed validation 2 | xsltproc --xinclude --nonet bb2db.xsl accu.xml > accudocbook4.xml 3 | fop -r -dpi 300 -xsl db2fo.xsl -xml accudocbook4.xml -pdf accu.pdf 4 | -------------------------------------------------------------------------------- /doc/boostbook/bb2db.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /doc/boostbook/ignore_exception.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 |
5 | ignore_exception 6 | 7 |
8 | Description 9 | 10 | This exception policy can be used to just ignore conditions which 11 | generate incorrect arithmetic results and continue processing. Programs 12 | using this policy along with the native promotion policy 14 | should function as if the library is not even being used. 15 |
16 | 17 |
18 | Model of 19 | 20 | ExceptionPolicy 22 |
23 | 24 |
25 | Header 26 | 27 | #include 28 | <boost/safe_numerics/exception_policy.hpp> 29 | 30 |
31 | 32 |
33 | Example of use 34 | 35 | safe<int, native, ignore_exception> st(4); 36 |
37 |
38 | -------------------------------------------------------------------------------- /doc/boostbook/images/annot-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/annot-close.png -------------------------------------------------------------------------------- /doc/boostbook/images/annot-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/annot-open.png -------------------------------------------------------------------------------- /doc/boostbook/images/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/blank.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/1.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/10.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/11.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/12.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/13.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/14.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/15.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/2.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/3.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/4.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/5.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/6.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/7.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/8.png -------------------------------------------------------------------------------- /doc/boostbook/images/callouts/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/callouts/9.png -------------------------------------------------------------------------------- /doc/boostbook/images/caution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/caution.png -------------------------------------------------------------------------------- /doc/boostbook/images/draft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/draft.png -------------------------------------------------------------------------------- /doc/boostbook/images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/home.png -------------------------------------------------------------------------------- /doc/boostbook/images/important.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/important.png -------------------------------------------------------------------------------- /doc/boostbook/images/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/next.png -------------------------------------------------------------------------------- /doc/boostbook/images/note.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/note.png -------------------------------------------------------------------------------- /doc/boostbook/images/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/prev.png -------------------------------------------------------------------------------- /doc/boostbook/images/tip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/tip.png -------------------------------------------------------------------------------- /doc/boostbook/images/toc-blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/toc-blank.png -------------------------------------------------------------------------------- /doc/boostbook/images/toc-minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/toc-minus.png -------------------------------------------------------------------------------- /doc/boostbook/images/toc-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/toc-plus.png -------------------------------------------------------------------------------- /doc/boostbook/images/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/up.png -------------------------------------------------------------------------------- /doc/boostbook/images/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/images/warning.png -------------------------------------------------------------------------------- /doc/boostbook/makeepub.sh: -------------------------------------------------------------------------------- 1 | if test x = x$BOOST_ROOT 2 | then 3 | echo BOOST_ROOT not set 4 | exit 1 5 | fi 6 | xsltproc --nonet --xinclude bb2db.xsl safe_numerics.xml | xsltproc --xinclude --nonet --stringparam base.dir ebooktmp db2epub.xsl - 7 | cp *.png ebooktmp/OEBPS/ 8 | xsltproc --xinclude --nonet opf.xsl ebooktmp/OEBPS/package.opf >ebooktmp/OEBPS/t.opf 9 | # mv ebooktmp/OEBPS/t.opf ebooktmp/OEBPS/package.opf 10 | cd ebooktmp 11 | zip -r -X ../book.epub mimetype META-INF OEBPS 12 | cd - 13 | -------------------------------------------------------------------------------- /doc/boostbook/makehtml.bat: -------------------------------------------------------------------------------- 1 | if x == x%BOOST_ROOT% goto abort 2 | 3 | xsltproc --nonet --xinclude bb2db.xsl safe_numerics.xml | xsltproc --nonet db2html.xsl - 4 | xcopy /i /q /y *.jpg ..\html 5 | if not exist ..\html md ..\html 6 | xcopy /i /q /y %BOOST_ROOT%\doc\src\boostbook.css ..\html 7 | if not exist ..\html md ..\html\images 8 | xcopy /i /q /y /s %BOOST_ROOT%\doc\html\images ..\html\images 9 | exit 10 | 11 | :abort 12 | echo BOOST_ROOT not set 13 | exit 14 | -------------------------------------------------------------------------------- /doc/boostbook/makehtml.sh: -------------------------------------------------------------------------------- 1 | if test x = x$BOOST_ROOT 2 | then 3 | echo BOOST_ROOT not set 4 | exit 1 5 | fi 6 | xsltproc --nonet --xinclude bb2db.xsl safe_numerics.xml | xsltproc --nonet db2html.xsl - 7 | cp pre-boost.jpg ../html 8 | cp pre-boost.jpg ../html/eliminate_runtime_penalty 9 | cp pre-boost.jpg ../html/promotion_policies 10 | cp pre-boost.jpg ../html/tutorial 11 | cp StepperMotor.gif ../html/ 12 | cp stepper_profile.png ../html/ 13 | cp $BOOST_ROOT/doc/src/boostbook.css ../html 14 | cp -R $BOOST_ROOT/doc/html/images ../html 15 | -------------------------------------------------------------------------------- /doc/boostbook/makepdf.sh: -------------------------------------------------------------------------------- 1 | if test x = x$BOOST_ROOT 2 | then 3 | echo BOOST_ROOT not set 4 | exit 1 5 | fi 6 | #use -r switch on fop for relaxed validation 7 | xsltproc --xinclude --nonet bb2db.xsl safe_numerics.xml \ 8 | | fop -r -dpi 300 -xsl db2fo.xsl -xml - -pdf ../safe_numerics.pdf 9 | 10 | # equivalent alternative? 11 | # xsltproc --xinclude --nonet bb2db.xsl safe_numerics.xml \ 12 | # | xsltproc --xinclude --nonet db2fo.xsl - \ 13 | # | fop -r -dpi 300 -fo - -pdf safe_numerics.pdf 14 | 15 | -------------------------------------------------------------------------------- /doc/boostbook/makeproposal.sh: -------------------------------------------------------------------------------- 1 | if test x = x$BOOST_ROOT 2 | then 3 | echo BOOST_ROOT not set 4 | exit 1 5 | fi 6 | #use -r switch on fop for relaxed validation 7 | xsltproc --xinclude --nonet bb2db.xsl proposal.xml \ 8 | | fop -r -dpi 300 -xsl db2fo.xsl -xml - -pdf proposal.pdf 9 | 10 | # equivalent alternative? 11 | # xsltproc --xinclude --nonet bb2db.xsl safe_numerics.xml \ 12 | # | xsltproc --xinclude --nonet db2fo.xsl - \ 13 | # | fop -r -dpi 300 -fo - -pdf safe_numerics.pdf 14 | 15 | -------------------------------------------------------------------------------- /doc/boostbook/overflow.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 |
5 | overflow 6 | 7 |
8 | Synopsis 9 | 10 | This function is invoked by the library whenever it is not possible 11 | to produce a result for an arithmetic operation. 12 | 13 | void overflow(char const * const msg); 14 |
15 | 16 |
17 | Description 18 | 19 | If environment supports C++ exceptions, this function throws the 20 | exception . 21 | 22 | If the environment does not support C++ exceptions, the user should 23 | implement this function and expect it to be called when 24 | appropriate. 25 | 26 | boost/config.hpp defines BOOST_NO_EXCEPTIONS 27 | when the environment doesn't support exceptions. It is by checking for the 28 | definition of this macro that the system determines whether or not 29 | exceptions are supported. 30 |
31 | 32 |
33 | Header 34 | 35 | #include 36 | <boost/safe_numerics/overflow.hpp> 37 |
38 | 39 |
40 | Example of use 41 | 42 | #include <cstdio> 43 | 44 | void overflow(char const * const msg){ 45 | std::fputs("safe_numerics overflow error:, std::stderr); 46 | std::fputs(msg, std::stderr); 47 | std::fputc('\n', std::stderr); 48 | } 49 |
50 | 51 |
52 | See Also 53 | 54 | See rationale for more 56 | information on this function 57 |
58 |
59 | -------------------------------------------------------------------------------- /doc/boostbook/pre-boost.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/pre-boost.jpg -------------------------------------------------------------------------------- /doc/boostbook/stepper_profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/boostbook/stepper_profile.png -------------------------------------------------------------------------------- /doc/boostbook/trap_exception.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 |
5 | trap_exception 6 | 7 |
8 | Description 9 | 10 | This exception policy will trap at compile time any operation that 11 | COULD result in a 12 | runtime exception. It can be used in an environment which can tolerate 13 | neither arithmetic errors nor runtime overhead. Usage of this policy will 14 | almost always require altering one's program to avoid exceptions. 15 |
16 | 17 |
18 | Model of 19 | 20 | ExceptionPolicy 22 |
23 | 24 |
25 | Header 26 | 27 | #include 28 | <boost/safe_numerics/exception_policy.hpp> 29 | 30 |
31 | 32 |
33 | Example of use 34 | 35 | #include "../../include/safe_integer.hpp" 36 | #include "../../include/automatic.hpp" 37 | #include "../../include/exception_policies.hpp" 38 | 39 | int main(){ 40 | using namespace boost::numeric; 41 | safe<char, automatic, trap_exception> x, y; 42 | y = x * x; // compile error here !!! 43 | auto z = x * x; // compile OK 44 | return 0; 45 | } 46 |
47 |
48 | -------------------------------------------------------------------------------- /doc/html/StepperMotor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/StepperMotor.gif -------------------------------------------------------------------------------- /doc/html/eliminate_runtime_penalty/pre-boost.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/eliminate_runtime_penalty/pre-boost.jpg -------------------------------------------------------------------------------- /doc/html/images/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/blank.png -------------------------------------------------------------------------------- /doc/html/images/caution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/caution.png -------------------------------------------------------------------------------- /doc/html/images/draft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/draft.png -------------------------------------------------------------------------------- /doc/html/images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/home.png -------------------------------------------------------------------------------- /doc/html/images/important.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/important.png -------------------------------------------------------------------------------- /doc/html/images/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/next.png -------------------------------------------------------------------------------- /doc/html/images/next_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/next_disabled.png -------------------------------------------------------------------------------- /doc/html/images/note.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/note.png -------------------------------------------------------------------------------- /doc/html/images/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/prev.png -------------------------------------------------------------------------------- /doc/html/images/prev_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/prev_disabled.png -------------------------------------------------------------------------------- /doc/html/images/tip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/tip.png -------------------------------------------------------------------------------- /doc/html/images/toc-blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/toc-blank.png -------------------------------------------------------------------------------- /doc/html/images/toc-minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/toc-minus.png -------------------------------------------------------------------------------- /doc/html/images/toc-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/toc-plus.png -------------------------------------------------------------------------------- /doc/html/images/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/up.png -------------------------------------------------------------------------------- /doc/html/images/up_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/up_disabled.png -------------------------------------------------------------------------------- /doc/html/images/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/images/warning.png -------------------------------------------------------------------------------- /doc/html/pre-boost.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/pre-boost.jpg -------------------------------------------------------------------------------- /doc/html/promotion_policies/pre-boost.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/promotion_policies/pre-boost.jpg -------------------------------------------------------------------------------- /doc/html/stepper_profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/stepper_profile.png -------------------------------------------------------------------------------- /doc/html/tutorial/pre-boost.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/html/tutorial/pre-boost.jpg -------------------------------------------------------------------------------- /doc/images/annot-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/annot-close.png -------------------------------------------------------------------------------- /doc/images/annot-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/annot-open.png -------------------------------------------------------------------------------- /doc/images/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/blank.png -------------------------------------------------------------------------------- /doc/images/callouts/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/1.png -------------------------------------------------------------------------------- /doc/images/callouts/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/10.png -------------------------------------------------------------------------------- /doc/images/callouts/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/11.png -------------------------------------------------------------------------------- /doc/images/callouts/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/12.png -------------------------------------------------------------------------------- /doc/images/callouts/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/13.png -------------------------------------------------------------------------------- /doc/images/callouts/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/14.png -------------------------------------------------------------------------------- /doc/images/callouts/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/15.png -------------------------------------------------------------------------------- /doc/images/callouts/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/2.png -------------------------------------------------------------------------------- /doc/images/callouts/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/3.png -------------------------------------------------------------------------------- /doc/images/callouts/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/4.png -------------------------------------------------------------------------------- /doc/images/callouts/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/5.png -------------------------------------------------------------------------------- /doc/images/callouts/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/6.png -------------------------------------------------------------------------------- /doc/images/callouts/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/7.png -------------------------------------------------------------------------------- /doc/images/callouts/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/8.png -------------------------------------------------------------------------------- /doc/images/callouts/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/callouts/9.png -------------------------------------------------------------------------------- /doc/images/caution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/caution.png -------------------------------------------------------------------------------- /doc/images/draft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/draft.png -------------------------------------------------------------------------------- /doc/images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/home.png -------------------------------------------------------------------------------- /doc/images/important.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/important.png -------------------------------------------------------------------------------- /doc/images/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/next.png -------------------------------------------------------------------------------- /doc/images/note.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/note.png -------------------------------------------------------------------------------- /doc/images/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/prev.png -------------------------------------------------------------------------------- /doc/images/tip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/tip.png -------------------------------------------------------------------------------- /doc/images/toc-blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/toc-blank.png -------------------------------------------------------------------------------- /doc/images/toc-minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/toc-minus.png -------------------------------------------------------------------------------- /doc/images/toc-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/toc-plus.png -------------------------------------------------------------------------------- /doc/images/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/up.png -------------------------------------------------------------------------------- /doc/images/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/images/warning.png -------------------------------------------------------------------------------- /doc/safe_numerics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/doc/safe_numerics.pdf -------------------------------------------------------------------------------- /example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # CMake build control file for safe numerics Library Examples 2 | 3 | ########################### 4 | # examples 5 | 6 | message( STATUS "Runtimes are stored in ${CMAKE_CURRENT_BINARY_DIR}" ) 7 | 8 | set(run_examples_list 9 | example1 10 | example2 11 | example3 12 | example4 13 | example5 14 | example6 15 | example7 16 | example8 17 | example82 18 | example83 19 | example84 20 | example10 21 | example11 22 | example13 23 | example14 24 | example15 25 | example16 26 | example18 27 | example19 28 | example20 29 | example92 30 | example93 31 | ) 32 | 33 | foreach(test_name ${run_examples_list}) 34 | test_run_pass(${test_name}) 35 | set_target_properties(${test_name} PROPERTIES FOLDER "run test examples") 36 | endforeach(test_name) 37 | 38 | test_compile_fail(example17) 39 | set_target_properties(example17 PROPERTIES FOLDER "safe numeric compile fail tests") 40 | test_compile_fail(example81) 41 | set_target_properties(example81 PROPERTIES FOLDER "safe numeric compile fail tests") 42 | 43 | # end examples targets 44 | #################### 45 | 46 | ########################### 47 | # add misc files to IDE 48 | 49 | file(GLOB misc_files 50 | RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" 51 | "${CMAKE_CURRENT_SOURCE_DIR}/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/*.c" 52 | ) 53 | add_custom_target(miscellaneous SOURCES ${misc_files}) 54 | set_target_properties(miscellaneous PROPERTIES FOLDER "examples") 55 | 56 | # end headers in IDE 57 | #################### 58 | -------------------------------------------------------------------------------- /example/Jamfile.v2: -------------------------------------------------------------------------------- 1 | # Boost.SafeNumerics Library test Jamfile 2 | # 3 | # Copyright (c) 2017 Robert Ramey 4 | # 5 | # Distributed under the Boost Software License, Version 1.0. 6 | # See accompanying file LICENSE_1_0.txt or copy at 7 | # http://www.boost.org/LICENSE_1_0.txt 8 | 9 | import testing ; 10 | 11 | project : requirements /boost/safe_numerics//boost_safe_numerics ; 12 | 13 | run example1.cpp ; 14 | run example2.cpp ; 15 | run example3.cpp ; 16 | run example4.cpp ; 17 | run example5.cpp ; 18 | run example6.cpp ; 19 | run example7.cpp ; 20 | run example8.cpp ; 21 | compile-fail example81.cpp ; 22 | run example82.cpp ; 23 | run example83.cpp ; 24 | run example84.cpp ; 25 | run example10.cpp ; 26 | run example11.cpp ; 27 | run example13.cpp ; 28 | run example14.cpp ; 29 | run example15.cpp : : : /boost/rational//boost_rational ; 30 | run example16.cpp ; 31 | compile-fail example17.cpp ; 32 | run example18.cpp ; 33 | run example19.cpp ; 34 | run example20.cpp ; 35 | run example92.cpp ; 36 | run example93.cpp ; 37 | 38 | -------------------------------------------------------------------------------- /example/example1.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | int main(int, const char *[]){ 12 | std::cout << "example 1:"; 13 | std::cout << "undetected erroneous expression evaluation" << std::endl; 14 | std::cout << "Not using safe numerics" << std::endl; 15 | try{ 16 | std::int8_t x = 127; 17 | std::int8_t y = 2; 18 | std::int8_t z; 19 | // this produces an invalid result ! 20 | z = x + y; 21 | std::cout << "error NOT detected!" << std::endl; 22 | std::cout << (int)z << " != " << (int)x << " + " << (int)y << std::endl; 23 | } 24 | catch(const std::exception &){ 25 | std::cout << "error detected!" << std::endl; 26 | } 27 | // solution: replace int with safe 28 | std::cout << "Using safe numerics" << std::endl; 29 | try{ 30 | using namespace boost::safe_numerics; 31 | safe x = INT_MAX; 32 | safe y = 2; 33 | safe z; 34 | // rather than producing an invalid result an exception is thrown 35 | z = x + y; 36 | } 37 | catch(const std::exception & e){ 38 | // which we can catch here 39 | std::cout << "error detected:" << e.what() << std::endl; 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /example/example10.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | using namespace std; 13 | using namespace boost::safe_numerics; 14 | 15 | void f(const unsigned int & x, const int8_t & y){ 16 | cout << x * y << endl; 17 | } 18 | void safe_f( 19 | const safe & x, 20 | const safe & y 21 | ){ 22 | cout << x * y << endl; 23 | } 24 | 25 | int main(){ 26 | cout << "example 4: "; 27 | cout << "mixing types produces surprising results" << endl; 28 | try { 29 | std::cout << "Not using safe numerics" << std::endl; 30 | // problem: mixing types produces surprising results. 31 | f(100, 100); // works as expected 32 | f(100, -100); // wrong result - unnoticed 33 | cout << "error NOT detected!" << endl;; 34 | } 35 | catch(const std::exception & e){ 36 | // never arrive here 37 | cout << "error detected:" << e.what() << endl;; 38 | } 39 | try { 40 | // solution: use safe types 41 | std::cout << "Using safe numerics" << std::endl; 42 | safe_f(100, 100); // works as expected 43 | safe_f(100, -100); // throw error 44 | cout << "error NOT detected!" << endl;; 45 | } 46 | catch(const std::exception & e){ 47 | cout << "error detected:" << e.what() << endl;; 48 | } 49 | return 0; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /example/example11.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | int main(int, const char * []){ 12 | std::cout << "example 1:"; 13 | std::cout << "undetected erroneous expression evaluation" << std::endl; 14 | std::cout << "Not using safe numerics" << std::endl; 15 | // problem: arithmetic operations can yield incorrect results. 16 | try{ 17 | std::int8_t x = 127; 18 | std::int8_t y = 2; 19 | std::int8_t z; 20 | // this produces an invalid result ! 21 | z = x + y; 22 | std::cout << z << " != " << x + y << std::endl; 23 | std::cout << "error NOT detected!" << std::endl; 24 | } 25 | catch(const std::exception &){ 26 | std::cout << "error detected!" << std::endl; 27 | } 28 | // solution: replace std::int8_t with safe 29 | std::cout << "Using safe numerics" << std::endl; 30 | try{ 31 | using namespace boost::safe_numerics; 32 | safe x = 127; 33 | safe y = 2; 34 | // rather than producing and invalid result an exception is thrown 35 | x + y; 36 | } 37 | catch(const std::exception & e){ 38 | // which can catch here 39 | std::cout << e.what() << std::endl; 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /example/example13.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | int main(int, const char *[]){ 13 | // problem: cannot recover from arithmetic errors 14 | std::cout << "example 7: "; 15 | std::cout << "cannot recover from arithmetic errors" << std::endl; 16 | std::cout << "Not using safe numerics" << std::endl; 17 | 18 | try{ 19 | // can't do this as it will crash the program with no 20 | // opportunity for recovery - comment out for example 21 | // int x = 1; 22 | // int y = 0; 23 | // std::cout << x / y; 24 | std::cout << "error cannot be handled at runtime!" << std::endl; 25 | } 26 | catch(const std::exception &){ 27 | std::cout << "error handled at runtime!" << std::endl; 28 | } 29 | // solution: replace int with safe 30 | std::cout << "Using safe numerics" << std::endl; 31 | try{ 32 | using namespace boost::safe_numerics; 33 | const safe x = 1; 34 | const safe y = 0; 35 | std::cout << x / y; 36 | std::cout << "error NOT detected!" << std::endl; 37 | } 38 | catch(const std::exception & e){ 39 | std::cout << "error handled at runtime!" << e.what() << std::endl; 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /example/example14.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | int main(int, const char *[]){ 13 | // problem: cannot recover from arithmetic errors 14 | std::cout << "example 14: "; 15 | std::cout << "cannot detect compile time arithmetic errors" << std::endl; 16 | std::cout << "Not using safe numerics" << std::endl; 17 | 18 | try{ 19 | const int x = 1; 20 | const int y = 0; 21 | // will emit warning at compile time 22 | // will leave an invalid result at runtime. 23 | std::cout << x / y; // will display "0"! 24 | std::cout << "error NOT detected!" << std::endl; 25 | } 26 | catch(const std::exception &){ 27 | std::cout << "error detected!" << std::endl; 28 | } 29 | // solution: replace int with safe 30 | std::cout << "Using safe numerics" << std::endl; 31 | try{ 32 | using namespace boost::safe_numerics; 33 | const safe x = 1; 34 | const safe y = 0; 35 | // constexpr const safe z = x / y; // note constexpr here! 36 | std::cout << x / y; // error would be detected at runtime 37 | std::cout << " error NOT detected!" << std::endl; 38 | } 39 | catch(const std::exception & e){ 40 | std::cout << "error detected:" << e.what() << std::endl; 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /example/example15.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | int main(int, const char *[]){ 14 | // simple demo of rational library 15 | const boost::rational r {1, 2}; 16 | std::cout << "r = " << r << std::endl; 17 | const boost::rational q {-2, 4}; 18 | std::cout << "q = " << q << std::endl; 19 | // display the product 20 | std::cout << "r * q = " << r * q << std::endl; 21 | 22 | // problem: rational doesn't handle integer overflow well 23 | const boost::rational c {1, INT_MAX}; 24 | std::cout << "c = " << c << std::endl; 25 | const boost::rational d {1, 2}; 26 | std::cout << "d = " << d << std::endl; 27 | // display the product - wrong answer 28 | std::cout << "c * d = " << c * d << std::endl; 29 | 30 | // solution: use safe integer in rational definition 31 | using safe_rational = boost::rational< 32 | boost::safe_numerics::safe 33 | >; 34 | 35 | // use rationals created with safe_t 36 | const safe_rational sc {1, std::numeric_limits::max()}; 37 | 38 | std::cout << "c = " << sc << std::endl; 39 | const safe_rational sd {1, 2}; 40 | std::cout << "d = " << sd << std::endl; 41 | std::cout << "c * d = "; 42 | try { 43 | // multiply them. This will overflow 44 | std::cout << (sc * sd) << std::endl; 45 | } 46 | catch (std::exception const& e) { 47 | // catch exception due to multiplication overflow 48 | std::cout << e.what() << std::endl; 49 | } 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /example/example16.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | using namespace boost::safe_numerics; 9 | 10 | int f(int i){ 11 | return i; 12 | } 13 | 14 | using safe_t = safe; 15 | 16 | int main(){ 17 | const long x = 97; 18 | f(x); // OK - implicit conversion to int 19 | const safe_t y = 97; 20 | f(y); // Also OK - checked implicit conversion to int 21 | return 0; 22 | } -------------------------------------------------------------------------------- /example/example17.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include // uint8_t 9 | using namespace boost::safe_numerics; 10 | 11 | uint8_t f(uint8_t i){ 12 | return i; 13 | } 14 | 15 | using safe_t = safe; 16 | 17 | int main(){ 18 | const long x = 97; 19 | f(x); // OK - implicit conversion to int can never fail 20 | const safe_t y = 97; 21 | f(y); // could overflow so trap at compile time 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /example/example18.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | using namespace boost::safe_numerics; 11 | 12 | int f(int i){ 13 | return i; 14 | } 15 | 16 | template 17 | using safe_literal = safe_signed_literal; 18 | 19 | int main(){ 20 | const long x = 97; 21 | f(x); // OK - implicit conversion to int 22 | const safe_literal<97> y; 23 | f(y); // OK - y is a type with min/max = 97; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /example/example2.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | int main(int, const char *[]){ 12 | std::cout << "example 2:"; 13 | std::cout << "undetected overflow in data type" << std::endl; 14 | // problem: undetected overflow 15 | std::cout << "Not using safe numerics" << std::endl; 16 | try{ 17 | int x = INT_MAX; 18 | // the following silently produces an incorrect result 19 | ++x; 20 | std::cout << x << " != " << INT_MAX << " + 1" << std::endl; 21 | std::cout << "error NOT detected!" << std::endl; 22 | } 23 | catch(const std::exception &){ 24 | std::cout << "error detected!" << std::endl; 25 | } 26 | // solution: replace int with safe 27 | std::cout << "Using safe numerics" << std::endl; 28 | try{ 29 | using namespace boost::safe_numerics; 30 | safe x = INT_MAX; 31 | // throws exception when result is past maximum possible 32 | ++x; 33 | assert(false); // never arrive here 34 | } 35 | catch(const std::exception & e){ 36 | std::cout << e.what() << std::endl; 37 | std::cout << "error detected!" << std::endl; 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /example/example20.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | int main(){ 13 | using ext_uint = boost::safe_numerics::checked_result; 14 | const ext_uint x{4}; 15 | const ext_uint y{3}; 16 | 17 | // operation is a success! 18 | std::cout << "success! x - y = " << x - y; 19 | 20 | // subtraction would result in -1, and invalid result for an unsigned value 21 | std::cout << "problem: y - x = " << y - x; 22 | 23 | const ext_uint z = y - x; 24 | std::cout << "z = " << z; 25 | // sum of two negative overflows is a negative overflow. 26 | std::cout << "z + z" << z + z; 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /example/example3.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | int main(int, const char *[]){ 12 | std::cout << "example 3:"; 13 | std::cout << "undetected underflow in data type" << std::endl; 14 | std::cout << "Not using safe numerics" << std::endl; 15 | // problem: decrement can yield incorrect result 16 | try{ 17 | unsigned int x = 0; 18 | // the following silently produces an incorrect result 19 | --x; 20 | std::cout << x << " != " << -1 << std::endl; 21 | 22 | // when comparing int and unsigned int, C++ converts 23 | // the int to unsigned int so the following assertion 24 | // fails to detect the above error! 25 | assert(x == -1); 26 | 27 | std::cout << "error NOT detected!" << std::endl; 28 | } 29 | catch(const std::exception &){ 30 | // never arrive here 31 | std::cout << "error detected!" << std::endl; 32 | } 33 | // solution: replace unsigned int with safe 34 | std::cout << "Using safe numerics" << std::endl; 35 | try{ 36 | using namespace boost::safe_numerics; 37 | safe x = 0; 38 | // decrement unsigned to less than zero throws exception 39 | --x; 40 | assert(false); // never arrive here 41 | } 42 | catch(const std::exception & e){ 43 | std::cout << e.what() << std::endl; 44 | std::cout << "error detected!" << std::endl; 45 | } 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /example/example4.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | int main(){ 12 | std::cout << "example 4: "; 13 | std::cout << "implicit conversions change data values" << std::endl; 14 | std::cout << "Not using safe numerics" << std::endl; 15 | 16 | // problem: implicit conversions change data values 17 | try{ 18 | signed int a{-1}; 19 | unsigned int b{1}; 20 | std::cout << "a is " << a << " b is " << b << '\n'; 21 | if(a < b){ 22 | std::cout << "a is less than b\n"; 23 | } 24 | else{ 25 | std::cout << "b is less than a\n"; 26 | } 27 | std::cout << "error NOT detected!" << std::endl; 28 | } 29 | catch(const std::exception &){ 30 | // never arrive here - just produce the wrong answer! 31 | std::cout << "error detected!" << std::endl; 32 | return 1; 33 | } 34 | 35 | // solution: replace int with safe and unsigned int with safe 36 | std::cout << "Using safe numerics" << std::endl; 37 | try{ 38 | using namespace boost::safe_numerics; 39 | safe a{-1}; 40 | safe b{1}; 41 | std::cout << "a is " << a << " b is " << b << '\n'; 42 | if(a < b){ 43 | std::cout << "a is less than b\n"; 44 | } 45 | else{ 46 | std::cout << "b is less than a\n"; 47 | } 48 | std::cout << "error NOT detected!" << std::endl; 49 | return 1; 50 | } 51 | catch(const std::exception & e){ 52 | // never arrive here - just produce the correct answer! 53 | std::cout << e.what() << std::endl; 54 | std::cout << "error detected!" << std::endl; 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /example/example5.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | void detected_msg(bool detected){ 14 | std::cout << (detected ? "error detected!" : "error NOT detected! ") << std::endl; 15 | } 16 | 17 | int main(int, const char *[]){ 18 | // problem: array index values can exceed array bounds 19 | std::cout << "example 5: "; 20 | std::cout << "array index values can exceed array bounds" << std::endl; 21 | std::cout << "Not using safe numerics" << std::endl; 22 | std::array i_array; 23 | 24 | // unsigned int i_index = 43; 25 | // the following corrupts memory. 26 | // This may or may not be detected at run time. 27 | // i_array[i_index] = 84; // comment this out so it can be tested! 28 | std::cout << "error NOT detected!" << std::endl; 29 | 30 | // solution: replace unsigned array index with safe_unsigned_range 31 | std::cout << "Using safe numerics" << std::endl; 32 | try{ 33 | using namespace boost::safe_numerics; 34 | using i_index_t = safe_unsigned_range<0, i_array.size() - 1>; 35 | i_index_t i_index; 36 | i_index = 36; // this works fine 37 | i_array[i_index] = 84; 38 | i_index = 43; // throw exception here! 39 | std::cout << "error NOT detected!" << std::endl; // so we never arrive here 40 | } 41 | catch(const std::exception & e){ 42 | std::cout << "error detected:" << e.what() << std::endl; 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /example/example6.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | int main(int, const char *[]){ 14 | // problem: checking of externally produced value can be overlooked 15 | std::cout << "example 6: "; 16 | std::cout << "checking of externally produced value can be overlooked" << std::endl; 17 | std::cout << "Not using safe numerics" << std::endl; 18 | 19 | std::istringstream is("12317289372189 1231287389217389217893"); 20 | 21 | try{ 22 | int x, y; 23 | is >> x >> y; // get integer values from the user 24 | std::cout << x << ' ' << y << std::endl; 25 | std::cout << "error NOT detected!" << std::endl; 26 | } 27 | catch(const std::exception &){ 28 | std::cout << "error detected!" << std::endl; 29 | } 30 | 31 | // solution: assign externally retrieved values to safe equivalents 32 | std::cout << "Using safe numerics" << std::endl; 33 | { 34 | using namespace boost::safe_numerics; 35 | safe x, y; 36 | is.seekg(0); 37 | try{ 38 | is >> x >> y; // get integer values from the user 39 | std::cout << x << ' ' << y << std::endl; 40 | std::cout << "error NOT detected!" << std::endl; 41 | } 42 | catch(const std::exception & e){ 43 | std::cout << "error detected:" << e.what() << std::endl; 44 | } 45 | } 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /example/example8.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | int main(int, const char *[]){ 12 | std::cout << "example 8:"; 13 | std::cout << "undetected erroneous expression evaluation" << std::endl; 14 | std::cout << "Not using safe numerics" << std::endl; 15 | try{ 16 | unsigned int x = 127; 17 | unsigned int y = 2; 18 | unsigned int z; 19 | // this produces an invalid result ! 20 | z = y - x; 21 | std::cout << "error NOT detected!" << std::endl; 22 | std::cout << z << " != " << y << " - " << x << std::endl; 23 | } 24 | catch(const std::exception &){ 25 | std::cout << "error detected!" << std::endl; 26 | } 27 | // solution: replace int with safe 28 | std::cout << "Using safe numerics" << std::endl; 29 | try{ 30 | using namespace boost::safe_numerics; 31 | safe x = 127; 32 | safe y = 2; 33 | safe z; 34 | // rather than producing an invalid result an exception is thrown 35 | z = y - x; 36 | std::cout << "error NOT detected!" << std::endl; 37 | std::cout << z << " != " << y << " - " << x << std::endl; 38 | } 39 | catch(const std::exception & e){ 40 | // which we can catch here 41 | std::cout << "error detected:" << e.what() << std::endl; 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /example/example81.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include // include exception policies 11 | 12 | using safe_t = boost::safe_numerics::safe< 13 | int, 14 | boost::safe_numerics::native, 15 | boost::safe_numerics::loose_trap_policy // note use of "loose_trap_exception" policy! 16 | >; 17 | 18 | int main(){ 19 | std::cout << "example 81:\n"; 20 | safe_t x(INT_MAX); 21 | safe_t y(2); 22 | safe_t z = x + y; // will fail to compile ! 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /example/example82.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include "safe_format.hpp" // prints out range and value of any type 13 | 14 | using safe_t = boost::safe_numerics::safe< 15 | int, 16 | boost::safe_numerics::automatic, // note use of "automatic" policy!!! 17 | boost::safe_numerics::loose_trap_policy 18 | >; 19 | 20 | int main(int, const char *[]){ 21 | std::cout << "example 82:\n"; 22 | safe_t x(INT_MAX); 23 | safe_t y = 2; 24 | std::cout << "x = " << safe_format(x) << std::endl; 25 | std::cout << "y = " << safe_format(y) << std::endl; 26 | std::cout << "x + y = " << safe_format(x + y) << std::endl; 27 | return 0; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /example/example83.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "safe_format.hpp" // prints out range and value of any type 14 | 15 | using namespace boost::safe_numerics; 16 | 17 | // create a type for holding small integers in a specific range 18 | using safe_t = safe_signed_range< 19 | -24, 20 | 82, 21 | native, // C++ type promotion rules work OK for this example 22 | loose_trap_policy // catch problems at compile time 23 | >; 24 | 25 | // create a type to hold one specific value 26 | template 27 | using const_safe_t = safe_signed_literal; 28 | 29 | // We "know" that C++ type promotion rules will work such that 30 | // addition will never overflow. If we change the program to break this, 31 | // the usage of the loose_trap_policy promotion policy will prevent compilation. 32 | int main(int, const char *[]){ 33 | std::cout << "example 83:\n"; 34 | 35 | constexpr const const_safe_t<10> x; 36 | std::cout << "x = " << safe_format(x) << std::endl; 37 | constexpr const const_safe_t<67> y; 38 | std::cout << "y = " << safe_format(y) << std::endl; 39 | auto zx = x + y; 40 | const safe_t z = zx; 41 | //auto z = x + y; 42 | std::cout << "x + y = " << safe_format(x + y) << std::endl; 43 | std::cout << "z = " << safe_format(z) << std::endl; 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /example/motor_test1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * david austin 3 | * http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time 4 | * DECEMBER 30, 2004 5 | * 6 | * Demo program for stepper motor control with linear ramps 7 | * Hardware: PIC18F252, L6219 8 | * 9 | * Compile with on Microchip XC8 compiler with the command line: 10 | * XC8 --chip=18F252 motor_test1.c 11 | * 12 | * Copyright (c) 2015 Robert Ramey 13 | * 14 | * Distributed under the Boost Software License, Version 1.0. (See 15 | * accompanying file LICENSE_1_0.txt or copy at 16 | * http://www.boost.org/LICENSE_1_0.txt) 17 | */ 18 | 19 | #include 20 | #include 21 | #include /* For true/false definition */ 22 | 23 | typedef int8_t int8; 24 | typedef int16_t int16; 25 | typedef int32_t int32; 26 | typedef uint8_t uint8; 27 | typedef uint16_t uint16; 28 | typedef uint32_t uint32; 29 | 30 | // 1st step=50ms; max speed=120rpm (based on 1MHz timer, 1.8deg steps) 31 | #define C0 (50000 << 8) 32 | #define C_MIN (2500 << 8) 33 | 34 | #include "motor1.c" 35 | 36 | void main() { 37 | initialize(); 38 | while (1) { // repeat 5 revs forward & back 39 | motor_run(1000); 40 | while (run_flg); 41 | motor_run(0); 42 | while (run_flg); 43 | } 44 | } // main() 45 | -------------------------------------------------------------------------------- /example/motor_test2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * david austin 3 | * http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time 4 | * DECEMBER 30, 2004 5 | * 6 | * Demo program for stepper motor control with linear ramps 7 | * Hardware: PIC18F252, L6219 8 | * 9 | * Compile with on Microchip XC8 compiler with the command line: 10 | * XC8 --chip=18F252 motor_test2.c 11 | * 12 | * Copyright (c) 2015 Robert Ramey 13 | * 14 | * Distributed under the Boost Software License, Version 1.0. (See 15 | * accompanying file LICENSE_1_0.txt or copy at 16 | * http://www.boost.org/LICENSE_1_0.txt) 17 | */ 18 | 19 | #include 20 | #include 21 | #include /* For true/false definition */ 22 | 23 | // *************************** 24 | // alias integer types standard C integer types 25 | typedef int8_t int8; 26 | typedef int16_t int16; 27 | typedef int32_t int32; 28 | typedef uint8_t uint8; 29 | typedef uint16_t uint16; 30 | typedef uint32_t uint32; 31 | 32 | // 1st step=50ms; max speed=120rpm (based on 1MHz timer, 1.8deg steps) 33 | #define C0 (50000*8l) 34 | #define C_MIN (2500*8) 35 | 36 | #include "motor2.c" 37 | 38 | void main() { 39 | initialize(); 40 | while (1) { // repeat 5 revs forward & back 41 | motor_run(1000); 42 | while (run_flg); 43 | motor_run(0); 44 | while (run_flg); 45 | motor_run(50000); 46 | while (run_flg); 47 | } 48 | } // main() 49 | -------------------------------------------------------------------------------- /example/motor_test3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * david austin 3 | * http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time 4 | * DECEMBER 30, 2004 5 | * 6 | * Demo program for stepper motor control with linear ramps 7 | * Hardware: PIC18F252, L6219 8 | * 9 | * Compile with on Microchip XC8 compiler with the command line: 10 | * XC8 --chip=18F252 motor_test3.c 11 | * 12 | * Copyright (c) 2015 Robert Ramey 13 | * 14 | * Distributed under the Boost Software License, Version 1.0. (See 15 | * accompanying file LICENSE_1_0.txt or copy at 16 | * http://www.boost.org/LICENSE_1_0.txt) 17 | */ 18 | 19 | #include 20 | 21 | // 8 MHz internal clock 22 | #define _XTAL_FREQ 8000000 23 | 24 | #include 25 | #include /* For true/false definition */ 26 | 27 | // *************************** 28 | // nullify macro for literals 29 | #define literal(n) n 30 | 31 | // *************************** 32 | // map strong types to appropriate underlying types. 33 | typedef uint16_t position_t; 34 | typedef int16_t step_t; 35 | typedef uint32_t ccpr_t; 36 | typedef int32_t c_t; 37 | typedef uint16_t phase_t; 38 | typedef uint8_t phase_ix_t; 39 | typedef int8_t direction_t; 40 | 41 | // 1st step=10ms; max speed=300rpm (based on 1MHz timer, 1.8deg steps) 42 | #define C_MIN literal((1000 << 8)) 43 | #define C0 literal((10000 << 8)) 44 | 45 | #include "motor3.c" 46 | 47 | void main() { 48 | initialize(); 49 | // move motor to position 200 50 | motor_run(200); 51 | while(busy()) __delay_ms(100); 52 | // move motor to position 1000 53 | motor_run(1000); 54 | while(busy()) __delay_ms(100); 55 | // move back to position 0 56 | motor_run(200); 57 | while(busy()) __delay_ms(100); 58 | } // main() 59 | -------------------------------------------------------------------------------- /example/picsfr.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////// 2 | // picsfr.h 3 | // Copyright (c) 2015 Robert Ramey 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. (See 6 | // accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // Put these in a separate file so they can conditionally included. 10 | // This is necessary since their mere inclusion will cause syntax 11 | // errors on some compilers. 12 | 13 | #ifndef PICSFR_H 14 | #define PICSFR_H 15 | 16 | #byte TRISC = 0xf94 17 | #byte T3CON = 0xfb1 18 | #byte CCP2CON = 0xfba 19 | #byte CCPR2L = 0xfbb 20 | #byte CCPR2H = 0xfbc 21 | #byte CCP1CON = 0xfbd 22 | #byte CCPR1L = 0xfbe 23 | #byte CCPR1H = 0xfbf 24 | #byte T1CON = 0xfcd 25 | #byte TMR1L = 0xfce 26 | #byte TMR1H = 0xfcf 27 | #bit TMR1ON = T1CON.0 28 | 29 | #endif // PICSFR_H 30 | -------------------------------------------------------------------------------- /example/safe_format.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #ifndef BOOST_SAFE_FORMAT_HPP 8 | #define BOOST_SAFE_FORMAT_HPP 9 | 10 | // Copyright (c) 2015 Robert Ramey 11 | // 12 | // Distributed under the Boost Software License, Version 1.0. (See 13 | // accompanying file LICENSE_1_0.txt or copy at 14 | // http://www.boost.org/LICENSE_1_0.txt) 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | namespace { 24 | 25 | // create an output manipulator which prints variable type and limits 26 | // as well as value 27 | template 28 | struct safe_format_impl { 29 | const T & m_t; 30 | safe_format_impl(const T & t) : 31 | m_t(t) 32 | {} 33 | template 34 | friend std::basic_ostream & 35 | operator<<( 36 | std::basic_ostream & os, 37 | const safe_format_impl & f 38 | ){ 39 | return os 40 | << "<" 41 | << boost::core::demangle(typeid( 42 | typename boost::safe_numerics::base_type::type 43 | ).name() 44 | ) 45 | << ">[" 46 | << std::numeric_limits::min() << "," 47 | << std::numeric_limits::max() << "] = " 48 | << f.m_t; 49 | } 50 | }; 51 | 52 | } // anonymous namespace 53 | 54 | template 55 | auto safe_format(const T & t){ 56 | return safe_format_impl(t); 57 | } 58 | 59 | #endif // BOOST_SAFE_FORMAT_HPP 60 | -------------------------------------------------------------------------------- /example/stepper-motor.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/example/stepper-motor.pdf -------------------------------------------------------------------------------- /html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/safe_numerics/c46d7a33fa6efc10e3d35526e9fcf6673936ed41/html -------------------------------------------------------------------------------- /include/boost/safe_numerics/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #################### 2 | # add include headers to IDE 3 | 4 | file(GLOB include_files 5 | RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" 6 | "*.hpp" 7 | ) 8 | add_custom_target(safe_numerics SOURCES ${include_files}) 9 | 10 | add_subdirectory("concept") 11 | 12 | # end headers in IDE 13 | #################### 14 | -------------------------------------------------------------------------------- /include/boost/safe_numerics/concept/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #################### 2 | # add include headers to IDE 3 | 4 | set(USE_FOLDERS TRUE) 5 | 6 | file(GLOB include_files 7 | RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" 8 | "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp" 9 | ) 10 | add_custom_target(concept SOURCES ${include_files}) 11 | set_target_properties(concept PROPERTIES FOLDER "safe_numerics") 12 | 13 | # end headers in IDE 14 | #################### 15 | -------------------------------------------------------------------------------- /include/boost/safe_numerics/concept/exception_policy.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_NUMERIC_CONCEPT_EXCEPTION_POLICY_HPP 2 | #define BOOST_NUMERIC_CONCEPT_EXCEPTION_POLICY_HPP 3 | 4 | // Copyright (c) 2015 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | namespace boost { 11 | namespace safe_numerics { 12 | 13 | template 14 | struct ExceptionPolicy { 15 | const char * message; 16 | /* 17 | BOOST_CONCEPT_USAGE(ExceptionPolicy){ 18 | EP::on_arithmetic_error(e, message); 19 | EP::on_undefined_behavior(e, message) 20 | EP::on_implementation_defined_behavior(e, message) 21 | EP::on_uninitialized_value(e, message) 22 | } 23 | */ 24 | }; 25 | 26 | } // safe_numerics 27 | } // boost 28 | 29 | #endif // BOOST_NUMERIC_CONCEPT_EXCEPTION_POLICY_HPP 30 | -------------------------------------------------------------------------------- /include/boost/safe_numerics/concept/integer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_NUMERIC_CONCEPT_INTEGER_HPP 2 | #define BOOST_NUMERIC_CONCEPT_INTEGER_HPP 3 | 4 | // Copyright (c) 2012 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include "numeric.hpp" 11 | 12 | namespace boost { 13 | namespace safe_numerics { 14 | 15 | template 16 | using Integer = std::integral_constant() && std::numeric_limits::is_integer>; 17 | 18 | } // safe_numerics 19 | } // boost 20 | 21 | #endif // BOOST_NUMERIC_CONCEPT_INTEGER_HPP 22 | -------------------------------------------------------------------------------- /include/boost/safe_numerics/concept/numeric.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_NUMERIC_CONCEPT_NUMERIC_HPP 2 | #define BOOST_NUMERIC_CONCEPT_NUMERIC_HPP 3 | 4 | // Copyright (c) 2021 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace boost { 15 | namespace safe_numerics { 16 | 17 | template 18 | using Numeric = std::integral_constant::is_specialized>; 19 | 20 | } // safe_numerics 21 | } // boost 22 | 23 | #endif // BOOST_NUMERIC_CONCEPT_NUMERIC_HPP 24 | -------------------------------------------------------------------------------- /include/boost/safe_numerics/concept/promotion_policy.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_NUMERIC_CONCEPT_PROMOTION_POLICY_HPP 2 | #define BOOST_NUMERIC_CONCEPT_PROMOTION_POLICY_HPP 3 | 4 | // Copyright (c) 2015 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | namespace boost { 11 | namespace safe_numerics { 12 | 13 | template 14 | struct PromotionPolicy { 15 | using T = int; 16 | using U = int; 17 | using a_type = typename PP::template addition_result; 18 | using s_type = typename PP::template subtraction_result; 19 | using m_type = typename PP::template multiplication_result; 20 | using d_type = typename PP::template division_result; 21 | using mod_type = typename PP::template modulus_result; 22 | using ls_type = typename PP::template left_shift_result; 23 | using rs_type = typename PP::template right_shift_result; 24 | using cc_type = typename PP::template comparison_result; 25 | using baw_type = typename PP::template bitwise_and_result; 26 | using bow_type = typename PP::template bitwise_or_result; 27 | using bxw_type = typename PP::template bitwise_xor_result; 28 | }; 29 | 30 | } // safe_numerics 31 | } // boost 32 | 33 | #endif // BOOST_NUMERIC_CONCEPT_EXCEPTION_POLICY_HPP 34 | -------------------------------------------------------------------------------- /include/boost/safe_numerics/range_value.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_RANGE_VALUE_HPP 2 | #define BOOST_RANGE_VALUE_HPP 3 | 4 | // Copyright (c) 2015 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | 12 | // print range and value to a standard stream 13 | // make a simple wrapper 14 | template 15 | struct range_value { 16 | // type requirement - a numeric type 17 | const T & m_t; 18 | 19 | constexpr range_value(const T & t) 20 | : m_t(t) 21 | {} 22 | 23 | }; 24 | 25 | template 26 | constexpr range_value make_range_value(const T & t){ 27 | return range_value(t); 28 | } 29 | 30 | #include "interval.hpp" 31 | 32 | template< 33 | class CharT, 34 | class Traits, 35 | class T 36 | > 37 | std::basic_ostream & operator<<( 38 | std::basic_ostream & os, 39 | const range_value & t 40 | ){ 41 | return os 42 | << boost::safe_numerics::make_interval() 43 | << t.m_t; 44 | } 45 | 46 | template 47 | struct result_display { 48 | const T & m_t; 49 | result_display(const T & t) : 50 | m_t(t) 51 | {} 52 | }; 53 | 54 | template 55 | inline result_display make_result_display(const T & t){ 56 | return result_display(t); 57 | } 58 | 59 | template 60 | inline std::basic_ostream & 61 | operator<<( 62 | std::basic_ostream & os, 63 | const result_display & r 64 | ){ 65 | return os 66 | << std::hex 67 | << make_range_value(r.m_t) 68 | << "(" << std::dec << r.m_t << ")"; 69 | } 70 | 71 | #endif // BOOST_RANGE_VALUE_HPP 72 | -------------------------------------------------------------------------------- /include/boost/safe_numerics/safe_common.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_NUMERIC_SAFE_COMMON_HPP 2 | #define BOOST_NUMERIC_SAFE_COMMON_HPP 3 | 4 | // Copyright (c) 2012 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | 12 | namespace boost { 13 | namespace safe_numerics { 14 | 15 | // default implementations for required meta-functions 16 | template 17 | struct is_safe : public std::false_type 18 | {}; 19 | 20 | template 21 | struct base_type { 22 | using type = T; 23 | }; 24 | 25 | template 26 | constexpr const typename base_type::type & base_value(const T & t) { 27 | return static_cast::type & >(t); 28 | } 29 | 30 | template 31 | struct get_promotion_policy { 32 | using type = void; 33 | }; 34 | 35 | template 36 | struct get_exception_policy { 37 | using type = void; 38 | }; 39 | 40 | 41 | } // safe_numerics 42 | } // boost 43 | 44 | #endif // BOOST_NUMERIC_SAFE_COMMON_HPP 45 | -------------------------------------------------------------------------------- /include/boost/safe_numerics/safe_integer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_NUMERIC_SAFE_INTEGER_HPP 2 | #define BOOST_NUMERIC_SAFE_INTEGER_HPP 3 | 4 | // Copyright (c) 2012 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | // not actually used here - but needed for integer arithmetic 11 | // so this is a good place to include it 12 | #include "checked_integer.hpp" 13 | #include "checked_result_operations.hpp" 14 | 15 | #include "safe_base.hpp" 16 | #include "safe_base_operations.hpp" 17 | 18 | #include "native.hpp" 19 | #include "exception_policies.hpp" 20 | 21 | // specialization for meta functions with safe argument 22 | namespace boost { 23 | namespace safe_numerics { 24 | 25 | template < 26 | class T, 27 | class P = native, 28 | class E = default_exception_policy 29 | > 30 | using safe = safe_base< 31 | T, 32 | ::std::numeric_limits::min(), 33 | ::std::numeric_limits::max(), 34 | P, 35 | E 36 | >; 37 | 38 | } // safe_numerics 39 | } // boost 40 | 41 | 42 | #endif // BOOST_NUMERIC_SAFE_INTEGER_HPP 43 | -------------------------------------------------------------------------------- /include/boost/safe_numerics/safe_integer_range.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_NUMERIC_SAFE_INTEGER_RANGE_HPP 2 | #define BOOST_NUMERIC_SAFE_INTEGER_RANGE_HPP 3 | 4 | // Copyright (c) 2012 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include // intmax_t, uintmax_t 11 | 12 | #include "utility.hpp" 13 | #include "safe_integer.hpp" 14 | #include "native.hpp" 15 | #include "exception_policies.hpp" 16 | 17 | ///////////////////////////////////////////////////////////////// 18 | // higher level types implemented in terms of safe_base 19 | 20 | namespace boost { 21 | namespace safe_numerics { 22 | 23 | ///////////////////////////////////////////////////////////////// 24 | // safe_signed_range 25 | 26 | template < 27 | std::intmax_t Min, 28 | std::intmax_t Max, 29 | class P = native, 30 | class E = default_exception_policy 31 | > 32 | using safe_signed_range = safe_base< 33 | typename utility::signed_stored_type, 34 | static_cast >(Min), 35 | static_cast >(Max), 36 | P, 37 | E 38 | >; 39 | 40 | ///////////////////////////////////////////////////////////////// 41 | // safe_unsigned_range 42 | 43 | template < 44 | std::uintmax_t Min, 45 | std::uintmax_t Max, 46 | class P = native, 47 | class E = default_exception_policy 48 | > 49 | using safe_unsigned_range = safe_base< 50 | typename utility::unsigned_stored_type, 51 | static_cast >(Min), 52 | static_cast >(Max), 53 | P, 54 | E 55 | >; 56 | 57 | } // safe_numerics 58 | } // boost 59 | 60 | #endif // BOOST_NUMERIC_SAFE_RANGE_HPP 61 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | Automatic redirection failed, please go to 13 | doc/html/index.html. 14 | 15 | 16 | -------------------------------------------------------------------------------- /meta/libraries.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": "safe_numerics", 3 | "name": "Safe Numerics", 4 | "authors": [ 5 | "Robert Ramey" 6 | ], 7 | "description": "Guaranteed Correct Integer Arithmetic", 8 | "category": [ 9 | "Math", 10 | "Correctness" 11 | ], 12 | "maintainers": [ 13 | "Robert Ramey " 14 | ], 15 | "cxxstd": "14" 16 | } 17 | -------------------------------------------------------------------------------- /test/check_symmetry.hpp: -------------------------------------------------------------------------------- 1 | // given an array of values of a particular type 2 | template 3 | constexpr bool check_symmetry(const T (&value)[N]) { 4 | using namespace boost::safe_numerics; 5 | // for each pair of values p1, p2 (100) 6 | for(unsigned int i = 0; i < N; i++) 7 | for(unsigned int j = 0; j < N; j++) 8 | assert(value[i][j] == value[j][i]); 9 | return true; 10 | } 11 | -------------------------------------------------------------------------------- /test/test_add_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_add_automatic_results.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::automatic 15 | >; 16 | 17 | #include "test_add_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_add_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_addition_automatic_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | #include "check_symmetry.hpp" 35 | 36 | int main(){ 37 | using namespace boost::mp11; 38 | 39 | static_assert( 40 | check_symmetry(test_addition_automatic_result), 41 | "sanity check on test matrix - should be symmetrical" 42 | ); 43 | 44 | using value_indices = mp_iota_c::value>; 45 | 46 | static_assert( 47 | mp_all_of< 48 | mp_product< 49 | test_pair, 50 | value_indices, 51 | value_indices 52 | >, 53 | mp_to_bool 54 | >(), 55 | "all values for all integer types correctly added" 56 | ); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /test/test_add_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_TEST_ADD_CONSTEXPR_HPP 2 | #define BOOST_TEST_ADD_CONSTEXPR_HPP 3 | 4 | // Copyright (c) 2015 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | 12 | template 13 | constexpr bool test_add_constexpr( 14 | T1 v1, 15 | T2 v2, 16 | char expected_result 17 | ){ 18 | using namespace boost::safe_numerics; 19 | // if we don't expect the operation to pass, we can't 20 | // check the constexpr version of the calculation so 21 | // just return success. 22 | if(expected_result == 'x') 23 | return true; 24 | safe_t(v1) + v2; 25 | v1 + safe_t(v2); 26 | safe_t(v1) + safe_t(v2); 27 | return true; // correct result 28 | } 29 | 30 | #endif // BOOST_TEST_ADD_CONSTEXPR_HPP 31 | -------------------------------------------------------------------------------- /test/test_add_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | #include "test_add_native_results.hpp" 11 | 12 | template 13 | using safe_t = boost::safe_numerics::safe< 14 | T, 15 | boost::safe_numerics::native 16 | >; 17 | 18 | #include "test_add_constexpr.hpp" 19 | 20 | using namespace boost::mp11; 21 | 22 | template 23 | struct test_pair { 24 | static const std::size_t i = First(); 25 | static const std::size_t j = Second(); 26 | constexpr static const bool value = test_add_constexpr( 27 | mp_at_c()(), 28 | mp_at_c()(), 29 | test_addition_native_result[i][j] 30 | ); 31 | }; 32 | 33 | #include 34 | #include 35 | #include "check_symmetry.hpp" 36 | 37 | int main(){ 38 | using namespace boost::mp11; 39 | 40 | static_assert( 41 | check_symmetry(test_addition_native_result), 42 | "sanity check on test matrix - should be symmetrical" 43 | ); 44 | 45 | using value_indices = mp_iota_c::value>; 46 | 47 | static_assert( 48 | mp_all_of< 49 | mp_product< 50 | test_pair, 51 | value_indices, 52 | value_indices 53 | >, 54 | mp_to_bool 55 | >(), 56 | "all values for all integer types correctly added" 57 | ); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /test/test_and_automatic.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | template 13 | using safe_t = boost::safe_numerics::safe< 14 | T, 15 | boost::safe_numerics::automatic 16 | >; 17 | #include "test_and.hpp" 18 | 19 | #include "test_values.hpp" 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace boost::mp11; 25 | 26 | template 27 | struct test { 28 | static_assert(mp_is_list(), "must be a list of integral constants"); 29 | bool m_error; 30 | test(bool b = true) : m_error(b) {} 31 | operator bool(){ 32 | return m_error; 33 | } 34 | template 35 | void operator()(const T &){ 36 | static_assert(mp_is_list(), "must be a list of two integral constants"); 37 | constexpr size_t i1 = mp_first(); // index of first argument 38 | constexpr size_t i2 = mp_second();// index of second argument 39 | std::cout << i1 << ',' << i2 << ','; 40 | using T1 = typename mp_at_c::value_type; 41 | using T2 = typename mp_at_c::value_type; 42 | m_error &= test_and( 43 | mp_at_c()(), // value of first argument 44 | mp_at_c()(), // value of second argument 45 | boost::core::demangle(typeid(T1).name()).c_str(), 46 | boost::core::demangle(typeid(T2).name()).c_str(), 47 | '.' 48 | ); 49 | } 50 | }; 51 | 52 | int main(){ 53 | test rval(true); 54 | 55 | using value_indices = mp_iota_c::value>; 56 | mp_for_each< 57 | mp_product 58 | >(rval); 59 | 60 | std::cout << (rval ? "success!" : "failure") << std::endl; 61 | return ! rval ; 62 | } 63 | -------------------------------------------------------------------------------- /test/test_and_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include "test_add_automatic_results.hpp" 12 | 13 | template 14 | using safe_t = boost::safe_numerics::safe< 15 | T, 16 | boost::safe_numerics::automatic 17 | >; 18 | 19 | #include "test_add_constexpr.hpp" 20 | 21 | using namespace boost::mp11; 22 | 23 | template 24 | struct test_pair { 25 | static const std::size_t i = First(); 26 | static const std::size_t j = Second(); 27 | constexpr static const bool value = test_add_constexpr( 28 | typename boost::mp11::mp_at_c()(), 29 | typename boost::mp11::mp_at_c()(), 30 | test_addition_automatic_result[i][j] 31 | ); 32 | }; 33 | 34 | #include 35 | #include 36 | #include "check_symmetry.hpp" 37 | 38 | int main(){ 39 | using namespace boost::mp11; 40 | 41 | // sanity check on test matrix - should be symetrical 42 | check_symmetry(test_addition_automatic_result); 43 | 44 | using value_indices = mp_iota_c::value>; 45 | 46 | static_assert( 47 | mp_all_of< 48 | mp_product< 49 | test_pair, 50 | value_indices, 51 | value_indices 52 | >, 53 | mp_to_bool 54 | >(), 55 | "all values for all integer types correctly added" 56 | ); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /test/test_and_native.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | template 13 | using safe_t = boost::safe_numerics::safe< 14 | T, 15 | boost::safe_numerics::native 16 | >; 17 | #include "test_and.hpp" 18 | 19 | #include "test_values.hpp" 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace boost::mp11; 25 | 26 | template 27 | struct test { 28 | static_assert(mp_is_list(), "must be a list of integral constants"); 29 | bool m_error; 30 | test(bool b = true) : m_error(b) {} 31 | operator bool(){ 32 | return m_error; 33 | } 34 | template 35 | void operator()(const T &){ 36 | static_assert(mp_is_list(), "must be a list of two integral constants"); 37 | constexpr size_t i1 = mp_first(); // index of first argument 38 | constexpr size_t i2 = mp_second();// index of second argument 39 | std::cout << i1 << ',' << i2 << ','; 40 | using T1 = typename mp_at_c::value_type; 41 | using T2 = typename mp_at_c::value_type; 42 | m_error &= test_and( 43 | mp_at_c()(), // value of first argument 44 | mp_at_c()(), // value of second argument 45 | boost::core::demangle(typeid(T1).name()).c_str(), 46 | boost::core::demangle(typeid(T2).name()).c_str(), 47 | '.' 48 | ); 49 | } 50 | }; 51 | 52 | int main(){ 53 | test rval(true); 54 | 55 | using value_indices = mp_iota_c::value>; 56 | mp_for_each< 57 | mp_product 58 | >(rval); 59 | 60 | std::cout << (rval ? "success!" : "failure") << std::endl; 61 | return ! rval ; 62 | } 63 | -------------------------------------------------------------------------------- /test/test_and_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 10 | #include 11 | 12 | #include "test_add_native_results.hpp" 13 | 14 | template 15 | using safe_t = boost::safe_numerics::safe< 16 | T, 17 | boost::safe_numerics::native 18 | >; 19 | 20 | #include "test_add_constexpr.hpp" 21 | 22 | using namespace boost::mp11; 23 | 24 | template 25 | struct test_pair { 26 | static const std::size_t i = First(); 27 | static const std::size_t j = Second(); 28 | constexpr static const bool value = test_add_constexpr( 29 | typename boost::mp11::mp_at_c()(), 30 | typename boost::mp11::mp_at_c()(), 31 | test_addition_native_result[i][j] 32 | ); 33 | }; 34 | 35 | #include 36 | #include 37 | #include "check_symmetry.hpp" 38 | 39 | int main(){ 40 | using namespace boost::mp11; 41 | 42 | // sanity check on test matrix - should be symetrical 43 | check_symmetry(test_addition_native_result); 44 | 45 | using value_indices = mp_iota_c::value>; 46 | 47 | static_assert( 48 | mp_all_of< 49 | mp_product< 50 | test_pair, 51 | value_indices, 52 | value_indices 53 | >, 54 | mp_to_bool 55 | >(), 56 | "all values for all integer types correctly added" 57 | ); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /test/test_checked_add.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_SAFE_NUMERICS_TEST_CHECKED_ADD_HPP 2 | #define BOOST_SAFE_NUMERICS_TEST_CHECKED_ADD_HPP 3 | 4 | // Copyright (c) 2018 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include "test_checked_values.hpp" 11 | 12 | // test result matrices 13 | 14 | // key 15 | // . success 16 | // - negative_overflow_error 17 | // + positive_overflow_error 18 | // ! range_error 19 | 20 | constexpr const char * signed_addition_results[] = { 21 | // 012345678 22 | /* 0*/ "!!!!!!!!!", 23 | /* 1*/ "!!!!!!!!!", 24 | /* 2*/ "!!++++++!", 25 | /* 3*/ "!!+++...-", 26 | /* 4*/ "!!++....-", 27 | /* 5*/ "!!+.....-", 28 | /* 6*/ "!!+....--", 29 | /* 7*/ "!!+...---", 30 | /* 8*/ "!!!------", 31 | }; 32 | 33 | constexpr const char * unsigned_addition_results[] = { 34 | // 0123456 35 | /* 0*/ "!!!!!!!", 36 | /* 1*/ "!!!!!!!", 37 | /* 2*/ "!!++++!", 38 | /* 3*/ "!!+++.-", 39 | /* 4*/ "!!++..-", 40 | /* 5*/ "!!+...-", 41 | /* 6*/ "!!!----", 42 | }; 43 | 44 | #endif // BOOST_SAFE_NUMERICS_TEST_CHECKED_ADD_HPP 45 | -------------------------------------------------------------------------------- /test/test_checked_and.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_SAFE_NUMERICS_TEST_CHECKED_AND_HPP 2 | #define BOOST_SAFE_NUMERICS_TEST_CHECKED_AND_HPP 3 | 4 | // Copyright (c) 2018 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include "test_checked_values.hpp" 11 | 12 | // test result matrices 13 | 14 | // key 15 | // . success 16 | // - negative_overflow_error 17 | // + positive_overflow_error 18 | // ? range_error 19 | 20 | constexpr const char * signed_and_results[] = { 21 | // 012345678 22 | /* 0*/ "!!!!!!!!!", 23 | /* 1*/ "!!!!!!!!!", 24 | /* 2*/ "!!!!!!!!!", 25 | /* 3*/ "!!!.....!", 26 | /* 4*/ "!!!.....!", 27 | /* 5*/ "!!!.....!", 28 | /* 6*/ "!!!.....!", 29 | /* 7*/ "!!!.....!", 30 | /* 8*/ "!!!!!!!!!", 31 | }; 32 | 33 | constexpr const char * unsigned_and_results[] = { 34 | // 0123456 35 | /* 0*/ "!!!!!!!", 36 | /* 1*/ "!!!!!!!", 37 | /* 2*/ "!!!!!!!", 38 | /* 3*/ "!!!...!", 39 | /* 4*/ "!!!...!", 40 | /* 5*/ "!!!...!", 41 | /* 6*/ "!!!!!!!", 42 | }; 43 | 44 | #endif // BOOST_SAFE_NUMERICS_TEST_CHECKED_AND_HPP 45 | -------------------------------------------------------------------------------- /test/test_checked_cast.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_SAFE_NUMERICS_TEST_CHECKED_CAST_HPP 2 | #define BOOST_SAFE_NUMERICS_TEST_CHECKED_CAST_HPP 3 | 4 | // Copyright (c) 2018 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | #include "test_values.hpp" 12 | 13 | // note: the types indexed on the left side of the table are gathered 14 | // by filtering the test_values list. So the types are in the same 15 | // sequence 16 | 17 | constexpr const char *test_result_cast[boost::mp11::mp_size::value] = { 18 | // 0 0 0 0 19 | // 01234567012345670123456701234567 20 | // 01234567890123456789012345678901 21 | /* 0*/ ".....xx..xx..xx...xx.xxx.xxx.xxx", 22 | /* 1*/ ".........xx..xx.......xx.xxx.xxx", 23 | /* 2*/ ".............xx...........xx.xxx", 24 | /* 3*/ "..............................xx", 25 | /* 4*/ "..xx.xxx.xxx.xxx.....xxx.xxx.xxx", 26 | /* 5*/ "..xx..xx.xxx.xxx.........xxx.xxx", 27 | /* 6*/ "..xx..xx..xx.xxx.............xxx", 28 | /* 7*/ "..xx..xx..xx..xx................" 29 | }; 30 | 31 | #endif // BOOST_SAFE_NUMERICS_TEST_CHECKED_CAST_HPP 32 | -------------------------------------------------------------------------------- /test/test_checked_comparison.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_SAFE_NUMERICS_TEST_CHECKED_COMPARISON_HPP 2 | #define BOOST_SAFE_NUMERICS_TEST_CHECKED_COMPARISON_HPP 3 | 4 | // Copyright (c) 2018 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include "test_checked_values.hpp" 11 | 12 | // test result matrices 13 | 14 | // key 15 | // < less than 16 | // > greater than 17 | // = equal to 18 | // ! indeterminant 19 | 20 | constexpr const char * signed_comparison_results[] = { 21 | // 012345678 22 | /* 0*/ "!!!!!!!!!", 23 | /* 1*/ "!!!!!!!!!", 24 | /* 2*/ "!!!>>>>>>", 25 | /* 3*/ "!!<=>>>>>", 26 | /* 4*/ "!!<<=>>>>", 27 | /* 5*/ "!!<<<=>>>", 28 | /* 6*/ "!!<<<<=>>", 29 | /* 7*/ "!!<<<<<=>", 30 | /* 8*/ "!!<<<<<>>>", 38 | /* 3*/ "!!<=>>>", 39 | /* 4*/ "!!<<=>>", 40 | /* 5*/ "!!<<<=>", 41 | /* 6*/ "!!<<<::value 5 | ] = { 6 | // 0 0 0 0 7 | // 012345670123456701234567012345670 8 | // 012345678901234567890123456789012 9 | /* 0*/ "=<>>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>", 10 | /* 1*/ ">=>>><>>><>>><>>>=<<><<<><<<><<<>", 11 | /* 2*/ "<<=<<<><<<><<<><<<<<<<<=<<>=<<>=<<>=<<<<<<<>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>", 14 | /* 5*/ ">>>>>=>>><>>><>>>>>>>=<<><<<><<<>", 15 | /* 6*/ "<<<<<<=<<<><<<><<<<<<<<=<<>=<<>=<<>=<<<<<<<>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>", 19 | /* 9*/ ">>>>>>>>>=>>><>>>>>>>>>>>=<<><<<>", 20 | /*10*/ "<<<<<<<<<<=<<<><<<<<<<<=<<>=<<>=<<>=<<<<<<<>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>", 23 | /*13*/ ">>>>>>>>>>>>>=>>>>>>>>>>>>>>>=<<>", 24 | /*14*/ "<<<<<<<<<<<<<<=<<<<<<<<<<<<=<<>=<<>=<<>=<<<<<<<<<<<>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>", 31 | /*17*/ ">=>>><>>><>>><>>>=<<><<<><<<><<<>", 32 | /*18*/ ">>>>><>>><>>><>>>>=<><<<><<<><<<>", 33 | /*19*/ ">>>>><>>><>>><>>>>>=><<<><<<><<<>", 34 | /*20*/ "=<>>=<>>=<>>=<>>=<<<=<<<=<<<=<<<>", 35 | /*21*/ ">>>>>=>>><>>><>>>>>>>=<<><<<><<<>", 36 | /*22*/ ">>>>>>>>><>>><>>>>>>>>=<><<<><<<>", 37 | /*23*/ ">>>>>>>>><>>><>>>>>>>>>=><<<><<<>", 38 | 39 | /*24*/ "=>=<<<=<<<=<<<=<<<>", 40 | /*25*/ ">>xx>>xx>=xx><>>>>>>>>>>>=<<><<<>", 41 | /*26*/ ">>xx>>xx>>xx><>>>>>>>>>>>>=<><<<>", 42 | /*27*/ ">>xx>>xx>>xx><>>>>>>>>>>>>>=><<<>", 43 | /*28*/ "=", 44 | /*29*/ ">>xx>>xx>>xx>=xx>>>>>>>>>>>>>=<<>", 45 | /*30*/ ">>xx>>xx>>xx>>xx>>>>>>>>>>>>>>=<>", 46 | /*31*/ ">>xx>>xx>>xx>>xx>>>>>>>>>>>>>>>=>", 47 | /*32*/ "<<>><<>><<>><<>><<<<<<<<<<<<<<<<=" 48 | }; 49 | -------------------------------------------------------------------------------- /test/test_concept_integer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // test Numeric concept - compile only test 8 | 9 | #include 10 | #include 11 | #include "test_checked_values.hpp" 12 | 13 | // test that all intrinsic signed integers are detected as Numeric 14 | using namespace boost::mp11; 15 | static_assert( 16 | mp_all_of< 17 | signed_test_types, 18 | boost::safe_numerics::Integer 19 | >(), 20 | "Integer concept fails on at least one signed integer type" 21 | ); 22 | // test that all intrinsic unigned integers are detected as Numeric 23 | static_assert( 24 | mp_all_of< 25 | unsigned_test_types, 26 | boost::safe_numerics::Integer 27 | >(), 28 | "Integer concept fails on at least one unsigned integer type" 29 | ); 30 | 31 | struct X {}; 32 | 33 | static_assert( 34 | ! boost::safe_numerics::Integer(), 35 | "Type w/o std::numeric_limits entry erroneously detected as Numeric" 36 | ); 37 | 38 | #include 39 | #include 40 | 41 | int main(){ 42 | boost::safe_numerics::safe s; 43 | std::cout << s; 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /test/test_concept_numeric.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // test Numeric concept - compile only test 8 | 9 | #include 10 | #include 11 | #include "test_checked_values.hpp" 12 | 13 | // test that all intrinsic signed integers are detected as Numeric 14 | using namespace boost::mp11; 15 | static_assert( 16 | mp_all_of< 17 | signed_test_types, 18 | boost::safe_numerics::Numeric 19 | >(), 20 | "Numeric concept fails on at least one signed integer type" 21 | ); 22 | // test that all intrinsic unigned integers are detected as Numeric 23 | static_assert( 24 | mp_all_of< 25 | unsigned_test_types, 26 | boost::safe_numerics::Numeric 27 | >(), 28 | "Numeric concept fails on at least one unsigned integer type" 29 | ); 30 | 31 | // test types without a std::numeric_limits entry are NOT detected as Numeric 32 | struct X {}; 33 | 34 | static_assert( 35 | ! boost::safe_numerics::Numeric(), 36 | "Type w/o std::numeric_limits entry erroneously detected as Numeric" 37 | ); 38 | 39 | #include 40 | #include 41 | 42 | int main(){ 43 | boost::safe_numerics::safe s; 44 | std::cout << s; 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /test/test_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | // Test constexpr operations on literals 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace boost::safe_numerics; 16 | 17 | template 18 | using compile_time_value = safe_unsigned_literal; 19 | 20 | int main(){ 21 | constexpr const compile_time_value<1000> x; 22 | constexpr const compile_time_value<1> y; 23 | 24 | // should compile and execute without problem 25 | std::cout << x << '\n'; 26 | 27 | // all the following statements should compile 28 | constexpr auto x_plus_y = x + y; 29 | static_assert(1001 == x_plus_y, "1001 == x + y"); 30 | 31 | constexpr auto x_minus_y = x - y; 32 | static_assert(999 == x_minus_y, "999 == x - y"); 33 | 34 | constexpr auto x_times_y = x * y; 35 | static_assert(1000 == x_times_y, "1000 == x * y"); 36 | 37 | constexpr auto x_and_y = x & y; 38 | static_assert(0 == x_and_y, "0 == x & y"); 39 | 40 | constexpr auto x_or_y = x | y; 41 | static_assert(1001 == x_or_y, "1001 == x | y"); 42 | 43 | constexpr auto x_xor_y = x ^ y; 44 | static_assert(1001 == x_xor_y, "1001 == x ^ y"); 45 | 46 | constexpr auto x_divided_by_y = x / y; 47 | static_assert(1000 == x_divided_by_y, "1000 == x / y"); 48 | 49 | constexpr auto x_mod_y = x % y; 50 | static_assert(0 == x_mod_y, "0 == x % y"); 51 | 52 | // this should fail compilation since a positive unsigned number 53 | // can't be converted to a negative value of the same type 54 | constexpr auto minus_x = -x; 55 | 56 | // should compile OK since the negative inverse of a zero is still zero 57 | constexpr const compile_time_value<0> x0; 58 | constexpr auto minus_x0 = -x0; // should compile OK 59 | static_assert(0 == minus_x0, "0 == -x where x == 0"); 60 | 61 | constexpr auto not_x = ~x; 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /test/test_cpp.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | // include headers to support safe integers 11 | #include 12 | 13 | using promotion_policy = boost::safe_numerics::cpp< 14 | 8, // char 8 bits 15 | 16, // short 16 bits 16 | 16, // int 16 bits 17 | 16, // long 32 bits 18 | 32 // long long 32 bits 19 | >; 20 | 21 | template 22 | struct test { 23 | using ResultType = promotion_policy::result_type; 24 | //boost::safe_numerics::utility::print_type pt; 25 | static_assert( 26 | std::is_same::value, 27 | "is_same" 28 | ); 29 | }; 30 | 31 | test t1; 32 | 33 | int main(){ 34 | return 0; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /test/test_divide_automatic.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include "test_divide_automatic_results.hpp" 12 | 13 | template 14 | using safe_t = boost::safe_numerics::safe< 15 | T, 16 | boost::safe_numerics::automatic 17 | >; 18 | #include "test_divide.hpp" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace boost::mp11; 25 | 26 | template 27 | struct test { 28 | static_assert(mp_is_list(), "must be a list of integral constants"); 29 | bool m_error; 30 | test(bool b = true) : m_error(b) {} 31 | operator bool(){ 32 | return m_error; 33 | } 34 | template 35 | void operator()(const T &){ 36 | static_assert(mp_is_list(), "must be a list of two integral constants"); 37 | constexpr size_t i1 = mp_first(); // index of first argument 38 | constexpr size_t i2 = mp_second();// index of second argument 39 | std::cout << i1 << ',' << i2 << ','; 40 | using T1 = typename mp_at_c::value_type; 41 | using T2 = typename mp_at_c::value_type; 42 | m_error &= test_divide( 43 | boost::mp11::mp_at_c()(), // value of first argument 44 | boost::mp11::mp_at_c()(), // value of second argument 45 | boost::core::demangle(typeid(T1).name()).c_str(), 46 | boost::core::demangle(typeid(T2).name()).c_str(), 47 | test_division_automatic_result[i1][i2] 48 | ); 49 | } 50 | }; 51 | 52 | int main(){ 53 | test rval(true); 54 | 55 | using value_indices = mp_iota_c::value>; 56 | mp_for_each< 57 | mp_product 58 | >(rval); 59 | 60 | std::cout << (rval ? "success!" : "failure") << std::endl; 61 | return ! rval ; 62 | } 63 | -------------------------------------------------------------------------------- /test/test_divide_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_divide_automatic_results.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::automatic 15 | >; 16 | 17 | #include "test_divide_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_divide_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_division_automatic_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly divided" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_divide_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_TEST_DIVIDE_CONSTEXPR_HPP 2 | #define BOOST_TEST_DIVIDE_CONSTEXPR_HPP 3 | 4 | // Copyright (c) 2015 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | 12 | template 13 | constexpr bool test_divide_constexpr( 14 | T1 v1, 15 | T2 v2, 16 | char expected_result 17 | ){ 18 | using namespace boost::safe_numerics; 19 | // if we don't expect the operation to pass, we can't 20 | // check the constexpr version of the calculation so 21 | // just return success. 22 | if(expected_result == 'x') 23 | return true; 24 | safe_t(v1) / v2; 25 | v1 / safe_t(v2); 26 | safe_t(v1) / safe_t(v2); 27 | return true; // correct result 28 | } 29 | 30 | #endif // BOOST_TEST_DIVIDE_CONSTEXPR_HPP 31 | -------------------------------------------------------------------------------- /test/test_divide_native.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include "test_divide_native_results.hpp" 12 | 13 | template 14 | using safe_t = boost::safe_numerics::safe< 15 | T, 16 | boost::safe_numerics::native 17 | >; 18 | #include "test_divide.hpp" 19 | 20 | using namespace boost::mp11; 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | template 28 | struct test { 29 | static_assert(mp_is_list(), "must be a list of integral constants"); 30 | bool m_error; 31 | test(bool b = true) : m_error(b) {} 32 | operator bool(){ 33 | return m_error; 34 | } 35 | template 36 | void operator()(const T &){ 37 | static_assert(mp_is_list(), "must be a list of two integral constants"); 38 | constexpr size_t i1 = mp_first(); // index of first argument 39 | constexpr size_t i2 = mp_second();// index of second argument 40 | std::cout << i1 << ',' << i2 << ','; 41 | using T1 = typename mp_at_c::value_type; 42 | using T2 = typename mp_at_c::value_type; 43 | m_error &= test_divide( 44 | mp_at_c()(), // value of first argument 45 | mp_at_c()(), // value of second argument 46 | boost::core::demangle(typeid(T1).name()).c_str(), 47 | boost::core::demangle(typeid(T2).name()).c_str(), 48 | test_division_native_result[i1][i2] 49 | ); 50 | } 51 | }; 52 | 53 | int main(){ 54 | test rval(true); 55 | 56 | using value_indices = mp_iota_c::value>; 57 | mp_for_each< 58 | mp_product 59 | >(rval); 60 | 61 | std::cout << (rval ? "success!" : "failure") << std::endl; 62 | return ! rval ; 63 | } 64 | -------------------------------------------------------------------------------- /test/test_divide_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | #include "test_divide_native_results.hpp" 11 | 12 | template 13 | using safe_t = boost::safe_numerics::safe< 14 | T, 15 | boost::safe_numerics::native 16 | >; 17 | 18 | #include "test_divide_constexpr.hpp" 19 | 20 | using namespace boost::mp11; 21 | 22 | template 23 | struct test_pair { 24 | static const std::size_t i = First(); 25 | static const std::size_t j = Second(); 26 | constexpr static const bool value = test_divide_constexpr( 27 | mp_at_c()(), 28 | mp_at_c()(), 29 | test_division_native_result[i][j] 30 | ); 31 | }; 32 | 33 | #include 34 | #include 35 | 36 | int main(){ 37 | using namespace boost::mp11; 38 | 39 | using value_indices = mp_iota_c::value>; 40 | 41 | static_assert( 42 | mp_all_of< 43 | mp_product< 44 | test_pair, 45 | value_indices, 46 | value_indices 47 | >, 48 | mp_to_bool 49 | >(), 50 | "all values for all integer types correctly divided" 51 | ); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /test/test_equal_automatic.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | template 13 | using safe_t = boost::safe_numerics::safe< 14 | T, 15 | boost::safe_numerics::automatic 16 | >; 17 | #include "test_equal.hpp" 18 | 19 | #include 20 | #include 21 | #include "test_compare_automatic.hpp" 22 | 23 | using namespace boost::mp11; 24 | 25 | template 26 | struct test { 27 | static_assert(mp_is_list(), "must be a list of integral constants"); 28 | bool m_error; 29 | test(bool b = true) : m_error(b) {} 30 | operator bool(){ 31 | return m_error; 32 | } 33 | template 34 | void operator()(const T &){ 35 | static_assert(mp_is_list(), "must be a list of two integral constants"); 36 | constexpr size_t i1 = mp_first(); // index of first argument 37 | constexpr size_t i2 = mp_second();// index of second argument 38 | std::cout << i1 << ',' << i2 << ','; 39 | using T1 = typename mp_at_c::value_type; 40 | using T2 = typename mp_at_c::value_type; 41 | m_error &= test_equal( 42 | mp_at_c()(), // value of first argument 43 | mp_at_c()(), // value of second argument 44 | boost::core::demangle(typeid(T1).name()).c_str(), 45 | boost::core::demangle(typeid(T2).name()).c_str(), 46 | test_compare_automatic_result[i1][i2] 47 | ); 48 | } 49 | }; 50 | 51 | int main(){ 52 | test rval(true); 53 | 54 | using value_indices = mp_iota_c::value>; 55 | mp_for_each< 56 | mp_product 57 | >(rval); 58 | 59 | std::cout << (rval ? "success!" : "failure") << std::endl; 60 | return ! rval ; 61 | } 62 | -------------------------------------------------------------------------------- /test/test_equal_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_compare_automatic.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::automatic 15 | >; 16 | 17 | #include "test_equal_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_equal_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_compare_automatic_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly compared for equality" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_equal_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_TEST_EQUAL_CONSTEXPR_HPP 2 | #define BOOST_TEST_EQUAL_CONSTEXPR_HPP 3 | 4 | // Copyright (c) 2015 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include // BOOST_CLANG 11 | #include 12 | 13 | #if BOOST_CLANG == 1 14 | #pragma GCC diagnostic push 15 | #pragma GCC diagnostic ignored "-Wunused-comparison" 16 | #endif 17 | 18 | template 19 | constexpr bool test_equal_constexpr( 20 | T1 v1, 21 | T2 v2, 22 | char expected_result 23 | ){ 24 | using namespace boost::safe_numerics; 25 | // if we don't expect the operation to pass, we can't 26 | // check the constexpr version of the calculation so 27 | // just return success. 28 | if(expected_result == 'x') 29 | return true; 30 | safe_t(v1) == v2; 31 | v1 == safe_t(v2); 32 | safe_t(v1) == safe_t(v2); 33 | return true; // correct result 34 | } 35 | 36 | #if BOOST_CLANG == 1 37 | #pragma GCC diagnostic pop 38 | #endif 39 | 40 | #endif // BOOST_TEST_EQUAL_CONSTEXPR_HPP 41 | -------------------------------------------------------------------------------- /test/test_equal_native.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::native 15 | >; 16 | #include "test_equal.hpp" 17 | 18 | #include 19 | #include 20 | #include "test_compare_native.hpp" 21 | 22 | using namespace boost::mp11; 23 | 24 | template 25 | struct test { 26 | static_assert(mp_is_list(), "must be a list of integral constants"); 27 | bool m_error; 28 | test(bool b = true) : m_error(b) {} 29 | operator bool(){ 30 | return m_error; 31 | } 32 | template 33 | void operator()(const T &){ 34 | static_assert(mp_is_list(), "must be a list of two integral constants"); 35 | constexpr size_t i1 = mp_first(); // index of first argument 36 | constexpr size_t i2 = mp_second();// index of second argument 37 | std::cout << i1 << ',' << i2 << ','; 38 | using T1 = typename mp_at_c::value_type; 39 | using T2 = typename mp_at_c::value_type; 40 | m_error &= test_equal( 41 | mp_at_c()(), // value of first argument 42 | mp_at_c()(), // value of second argument 43 | boost::core::demangle(typeid(T1).name()).c_str(), 44 | boost::core::demangle(typeid(T2).name()).c_str(), 45 | test_compare_native_result[i1][i2] 46 | ); 47 | } 48 | }; 49 | 50 | int main(){ 51 | test rval(true); 52 | 53 | using value_indices = mp_iota_c::value>; 54 | mp_for_each< 55 | mp_product 56 | >(rval); 57 | 58 | std::cout << (rval ? "success!" : "failure") << std::endl; 59 | return ! rval ; 60 | } 61 | -------------------------------------------------------------------------------- /test/test_equal_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_compare_native.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::native 15 | >; 16 | 17 | #include "test_equal_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_equal_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_compare_native_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly compared for equality" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_float.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // testing floating point 8 | 9 | // this is a compile only test - but since many build systems 10 | // can't handle a compile-only test - make sure it passes trivially. 11 | #include 12 | #include 13 | 14 | template 15 | void test(){ 16 | T t; 17 | U u; 18 | float x = t; 19 | t = x; 20 | t + u; 21 | t - u; 22 | t * u; 23 | t / u; 24 | /**/ 25 | // the operators below are restricted to integral types 26 | } 27 | int main(){ 28 | using namespace boost::safe_numerics; 29 | /* 30 | test, float>(); 31 | test,float>(); 32 | test, float>(); 33 | test, float>(); 34 | */ 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /test/test_left_shift_automatic.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include "test_left_shift_automatic_results.hpp" 12 | 13 | template 14 | using safe_t = boost::safe_numerics::safe< 15 | T, 16 | boost::safe_numerics::automatic 17 | >; 18 | #include "test_left_shift.hpp" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace boost::mp11; 25 | 26 | template 27 | struct test { 28 | static_assert(mp_is_list(), "must be a list of integral constants"); 29 | bool m_error; 30 | test(bool b = true) : m_error(b) {} 31 | operator bool(){ 32 | return m_error; 33 | } 34 | template 35 | void operator()(const T &){ 36 | static_assert(mp_is_list(), "must be a list of two integral constants"); 37 | constexpr size_t i1 = mp_first(); // index of first argument 38 | constexpr size_t i2 = mp_second();// index of second argument 39 | std::cout << i1 << ',' << i2 << ','; 40 | using T1 = typename mp_at_c::value_type; 41 | using T2 = typename mp_at_c::value_type; 42 | m_error &= test_left_shift( 43 | mp_at_c()(), // value of first argument 44 | mp_at_c()(), // value of second argument 45 | boost::core::demangle(typeid(T1).name()).c_str(), 46 | boost::core::demangle(typeid(T2).name()).c_str(), 47 | test_left_shift_automatic_result[i1][i2] 48 | ); 49 | } 50 | }; 51 | 52 | int main(){ 53 | test rval(true); 54 | 55 | using value_indices = mp_iota_c::value>; 56 | mp_for_each< 57 | mp_product 58 | >(rval); 59 | 60 | std::cout << (rval ? "success!" : "failure") << std::endl; 61 | return ! rval ; 62 | } 63 | -------------------------------------------------------------------------------- /test/test_left_shift_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_left_shift_automatic_results.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::automatic 15 | >; 16 | 17 | #include "test_left_shift_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_left_shift_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_left_shift_automatic_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly shifted to the left" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_left_shift_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_TEST_LEFT_SHIFT_CONSTEXPR_HPP 2 | #define BOOST_TEST_LEFT_SHIFT_CONSTEXPR_HPP 3 | 4 | // Copyright (c) 2019 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | 12 | template 13 | constexpr bool test_left_shift_constexpr( 14 | T1 v1, 15 | T2 v2, 16 | char expected_result 17 | ){ 18 | using namespace boost::safe_numerics; 19 | // if we don't expect the operation to pass, we can't 20 | // check the constexpr version of the calculation so 21 | // just return success. 22 | if(expected_result == 'x') 23 | return true; 24 | safe_t(v1) << v2; 25 | v1 << safe_t(v2); 26 | safe_t(v1) << safe_t(v2); 27 | return true; // correct result 28 | } 29 | 30 | #endif // BOOST_TEST_LEFT_SHIFT_CONSTEXPR_HPP 31 | -------------------------------------------------------------------------------- /test/test_left_shift_native.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include "test_left_shift_native_results.hpp" 12 | 13 | template 14 | using safe_t = boost::safe_numerics::safe< 15 | T, 16 | boost::safe_numerics::native 17 | >; 18 | #include "test_left_shift.hpp" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace boost::mp11; 25 | 26 | template 27 | struct test { 28 | static_assert(mp_is_list(), "must be a list of integral constants"); 29 | bool m_error; 30 | test(bool b = true) : m_error(b) {} 31 | operator bool(){ 32 | return m_error; 33 | } 34 | template 35 | void operator()(const T &){ 36 | static_assert(mp_is_list(), "must be a list of two integral constants"); 37 | constexpr size_t i1 = mp_first(); // index of first argument 38 | constexpr size_t i2 = mp_second();// index of second argument 39 | std::cout << i1 << ',' << i2 << ','; 40 | using T1 = typename mp_at_c::value_type; 41 | using T2 = typename mp_at_c::value_type; 42 | m_error &= test_left_shift( 43 | mp_at_c()(), // value of first argument 44 | mp_at_c()(), // value of second argument 45 | boost::core::demangle(typeid(T1).name()).c_str(), 46 | boost::core::demangle(typeid(T2).name()).c_str(), 47 | test_left_shift_native_result[i1][i2] 48 | ); 49 | } 50 | }; 51 | 52 | int main(){ 53 | test rval(true); 54 | 55 | using value_indices = mp_iota_c::value>; 56 | mp_for_each< 57 | mp_product 58 | >(rval); 59 | 60 | std::cout << (rval ? "success!" : "failure") << std::endl; 61 | return ! rval ; 62 | } 63 | -------------------------------------------------------------------------------- /test/test_left_shift_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | #include "test_left_shift_native_results.hpp" 11 | 12 | template 13 | using safe_t = boost::safe_numerics::safe< 14 | T, 15 | boost::safe_numerics::native 16 | >; 17 | 18 | #include "test_left_shift_constexpr.hpp" 19 | 20 | using namespace boost::mp11; 21 | 22 | template 23 | struct test_pair { 24 | static const std::size_t i = First(); 25 | static const std::size_t j = Second(); 26 | constexpr static const bool value = test_left_shift_constexpr( 27 | mp_at_c()(), 28 | mp_at_c()(), 29 | test_left_shift_native_result[i][j] 30 | ); 31 | }; 32 | 33 | #include 34 | #include 35 | 36 | int main(){ 37 | using namespace boost::mp11; 38 | 39 | using value_indices = mp_iota_c::value>; 40 | 41 | static_assert( 42 | mp_all_of< 43 | mp_product< 44 | test_pair, 45 | value_indices, 46 | value_indices 47 | >, 48 | mp_to_bool 49 | >(), 50 | "all values for all integer types correctly shifted to the left" 51 | ); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /test/test_less_than_automatic.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | template 13 | using safe_t = boost::safe_numerics::safe< 14 | T, 15 | boost::safe_numerics::automatic 16 | >; 17 | #include "test_less_than.hpp" 18 | 19 | #include 20 | #include 21 | #include "test_compare_automatic.hpp" 22 | 23 | using namespace boost::mp11; 24 | 25 | template 26 | struct test { 27 | static_assert(mp_is_list(), "must be a list of integral constants"); 28 | bool m_error; 29 | test(bool b = true) : m_error(b) {} 30 | operator bool(){ 31 | return m_error; 32 | } 33 | template 34 | void operator()(const T &){ 35 | static_assert(mp_is_list(), "must be a list of two integral constants"); 36 | constexpr size_t i1 = mp_first(); // index of first argument 37 | constexpr size_t i2 = mp_second();// index of second argument 38 | std::cout << i1 << ',' << i2 << ','; 39 | using T1 = typename mp_at_c::value_type; 40 | using T2 = typename mp_at_c::value_type; 41 | m_error &= test_less_than( 42 | mp_at_c()(), // value of first argument 43 | mp_at_c()(), // value of second argument 44 | boost::core::demangle(typeid(T1).name()).c_str(), 45 | boost::core::demangle(typeid(T2).name()).c_str(), 46 | test_compare_automatic_result[i1][i2] 47 | ); 48 | } 49 | }; 50 | 51 | int main(){ 52 | test rval(true); 53 | 54 | using value_indices = mp_iota_c::value>; 55 | mp_for_each< 56 | mp_product 57 | >(rval); 58 | 59 | std::cout << (rval ? "success!" : "failure") << std::endl; 60 | return ! rval ; 61 | } 62 | -------------------------------------------------------------------------------- /test/test_less_than_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_compare_automatic.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::automatic 15 | >; 16 | 17 | #include "test_less_than_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_less_than_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_compare_automatic_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly compared" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_less_than_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_TEST_LESS_THAN_CONSTEXPR_HPP 2 | #define BOOST_TEST_LESS_THAN_CONSTEXPR_HPP 3 | 4 | // Copyright (c) 2019 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include // BOOST_CLANG 11 | #include 12 | 13 | #if BOOST_CLANG==1 14 | #pragma GCC diagnostic push 15 | #pragma GCC diagnostic ignored "-Wunused-comparison" 16 | #endif 17 | 18 | template 19 | constexpr bool test_less_than_constexpr( 20 | T1 v1, 21 | T2 v2, 22 | char expected_result 23 | ){ 24 | using namespace boost::safe_numerics; 25 | // if we don't expect the operation to pass, we can't 26 | // check the constexpr version of the calculation so 27 | // just return success. 28 | if(expected_result == 'x') 29 | return true; 30 | safe_t(v1) < v2; 31 | v1 < safe_t(v2); 32 | safe_t(v1) < safe_t(v2); 33 | return true; // correct result 34 | } 35 | 36 | #if BOOST_CLANG==1 37 | #pragma GCC diagnostic pop 38 | #endif 39 | 40 | #endif // BOOST_TEST_LESS_THAN_CONSTEXPR_HPP 41 | -------------------------------------------------------------------------------- /test/test_less_than_native.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::native 15 | >; 16 | #include "test_less_than.hpp" 17 | 18 | #include 19 | #include 20 | #include "test_compare_native.hpp" 21 | 22 | using namespace boost::mp11; 23 | 24 | template 25 | struct test { 26 | static_assert(mp_is_list(), "must be a list of integral constants"); 27 | bool m_error; 28 | test(bool b = true) : m_error(b) {} 29 | operator bool(){ 30 | return m_error; 31 | } 32 | template 33 | void operator()(const T &){ 34 | static_assert(mp_is_list(), "must be a list of two integral constants"); 35 | constexpr size_t i1 = mp_first(); // index of first argument 36 | constexpr size_t i2 = mp_second();// index of second argument 37 | std::cout << i1 << ',' << i2 << ','; 38 | using T1 = typename mp_at_c::value_type; 39 | using T2 = typename mp_at_c::value_type; 40 | m_error &= test_less_than( 41 | mp_at_c(), // value of first argument 42 | mp_at_c(), // value of second argument 43 | boost::core::demangle(typeid(T1).name()).c_str(), 44 | boost::core::demangle(typeid(T2).name()).c_str(), 45 | test_compare_native_result[i1][i2] 46 | ); 47 | } 48 | }; 49 | 50 | int main(){ 51 | test rval(true); 52 | 53 | using value_indices = mp_iota_c::value>; 54 | mp_for_each< 55 | mp_product 56 | >(rval); 57 | 58 | std::cout << (rval ? "success!" : "failure") << std::endl; 59 | return ! rval ; 60 | } 61 | -------------------------------------------------------------------------------- /test/test_less_than_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_compare_native.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::native 15 | >; 16 | 17 | #include "test_less_than_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_less_than_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_compare_native_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly compared" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_modulus_automatic.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include "test_modulus_automatic_results.hpp" 12 | 13 | template 14 | using safe_t = boost::safe_numerics::safe< 15 | T, 16 | boost::safe_numerics::automatic 17 | >; 18 | #include "test_modulus.hpp" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace boost::mp11; 25 | 26 | template 27 | struct test { 28 | static_assert(mp_is_list(), "must be a list of integral constants"); 29 | bool m_error; 30 | test(bool b = true) : m_error(b) {} 31 | operator bool(){ 32 | return m_error; 33 | } 34 | template 35 | void operator()(const T &){ 36 | static_assert(mp_is_list(), "must be a list of two integral constants"); 37 | constexpr size_t i1 = mp_first(); // index of first argument 38 | constexpr size_t i2 = mp_second();// index of second argument 39 | std::cout << i1 << ',' << i2 << ','; 40 | using T1 = typename mp_at_c::value_type; 41 | using T2 = typename mp_at_c::value_type; 42 | m_error &= test_modulus( 43 | mp_at_c()(), // value of first argument 44 | mp_at_c()(), // value of second argument 45 | boost::core::demangle(typeid(T1).name()).c_str(), 46 | boost::core::demangle(typeid(T2).name()).c_str(), 47 | test_modulus_automatic_result[i1][i2] 48 | ); 49 | } 50 | }; 51 | 52 | int main(){ 53 | test rval(true); 54 | 55 | using value_indices = mp_iota_c::value>; 56 | mp_for_each< 57 | mp_product 58 | >(rval); 59 | 60 | std::cout << (rval ? "success!" : "failure") << std::endl; 61 | return ! rval ; 62 | } 63 | -------------------------------------------------------------------------------- /test/test_modulus_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_modulus_automatic_results.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::automatic 15 | >; 16 | 17 | #include "test_modulus_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_modulus_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_modulus_automatic_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly invoked modulus" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_modulus_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_TEST_ADD_CONSTEXPR_HPP 2 | #define BOOST_TEST_ADD_CONSTEXPR_HPP 3 | 4 | // Copyright (c) 2015 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | 12 | template 13 | constexpr bool test_modulus_constexpr( 14 | T1 v1, 15 | T2 v2, 16 | char expected_result 17 | ){ 18 | using namespace boost::safe_numerics; 19 | // if we don't expect the operation to pass, we can't 20 | // check the constexpr version of the calculation so 21 | // just return success. 22 | if(expected_result == 'x') 23 | return true; 24 | safe_t(v1) % v2; 25 | v1 % safe_t(v2); 26 | safe_t(v1) % safe_t(v2); 27 | return true; // correct result 28 | } 29 | 30 | #endif // BOOST_TEST_ADD_CONSTEXPR_HPP 31 | -------------------------------------------------------------------------------- /test/test_modulus_native.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include "test_modulus_native_results.hpp" 11 | 12 | template 13 | using safe_t = boost::safe_numerics::safe< 14 | T, 15 | boost::safe_numerics::native 16 | >; 17 | #include "test_modulus.hpp" 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | using namespace boost::mp11; 24 | 25 | template 26 | struct test { 27 | static_assert(mp_is_list(), "must be a list of integral constants"); 28 | bool m_error; 29 | test(bool b = true) : m_error(b) {} 30 | operator bool(){ 31 | return m_error; 32 | } 33 | template 34 | void operator()(const T &){ 35 | static_assert(mp_is_list(), "must be a list of two integral constants"); 36 | constexpr size_t i1 = mp_first(); // index of first argument 37 | constexpr size_t i2 = mp_second();// index of second argument 38 | std::cout << i1 << ',' << i2 << ','; 39 | using T1 = typename mp_at_c::value_type; 40 | using T2 = typename mp_at_c::value_type; 41 | m_error &= test_modulus( 42 | mp_at_c()(), // value of first argument 43 | mp_at_c()(), // value of second argument 44 | boost::core::demangle(typeid(T1).name()).c_str(), 45 | boost::core::demangle(typeid(T2).name()).c_str(), 46 | test_modulus_native_result[i1][i2] 47 | ); 48 | } 49 | }; 50 | 51 | int main(){ 52 | test rval(true); 53 | 54 | using value_indices = mp_iota_c::value>; 55 | mp_for_each< 56 | mp_product 57 | >(rval); 58 | 59 | std::cout << (rval ? "success!" : "failure") << std::endl; 60 | return ! rval ; 61 | } 62 | -------------------------------------------------------------------------------- /test/test_modulus_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_modulus_native_results.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::native 15 | >; 16 | 17 | #include "test_modulus_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_modulus_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_modulus_native_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly invoked modulus" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_multiply_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_multiply_automatic_results.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::automatic 15 | >; 16 | 17 | #include "test_multiply_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_multiply_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_multiplication_automatic_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | #include "check_symmetry.hpp" 35 | 36 | int main(){ 37 | static_assert( 38 | check_symmetry(test_multiplication_automatic_result), 39 | "sanity check on test matrix - should be symmetrical" 40 | ); 41 | 42 | using namespace boost::mp11; 43 | using value_indices = mp_iota_c::value>; 44 | 45 | static_assert( 46 | mp_all_of< 47 | mp_product< 48 | test_pair, 49 | value_indices, 50 | value_indices 51 | >, 52 | mp_to_bool 53 | >(), 54 | "all values for all integer types correctly multiplied" 55 | ); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /test/test_multiply_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_TEST_MULTIPLY_CONSTEXPR_HPP 2 | #define BOOST_TEST_MULTIPLY_CONSTEXPR_HPP 3 | 4 | // Copyright (c) 2019 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | 12 | template 13 | constexpr bool test_multiply_constexpr( 14 | T1 v1, 15 | T2 v2, 16 | char expected_result 17 | ){ 18 | using namespace boost::safe_numerics; 19 | // if we don't expect the operation to pass, we can't 20 | // check the constexpr version of the calculation so 21 | // just return success. 22 | if(expected_result == 'x') 23 | return true; 24 | safe_t(v1) * v2; 25 | v1 * safe_t(v2); 26 | safe_t(v1) * safe_t(v2); 27 | return true; // correct result 28 | } 29 | 30 | #endif // BOOST_TEST_MULTIPLY_CONSTEXPR_HPP 31 | -------------------------------------------------------------------------------- /test/test_multiply_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_multiply_native_results.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::native 15 | >; 16 | 17 | #include "test_multiply_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_multiply_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_multiplication_native_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | #include "check_symmetry.hpp" 35 | 36 | int main(){ 37 | static_assert( 38 | check_symmetry(test_multiplication_native_result), 39 | "sanity check on test matrix - should be symmetrical" 40 | ); 41 | using namespace boost::mp11; 42 | using value_indices = mp_iota_c::value>; 43 | 44 | static_assert( 45 | mp_all_of< 46 | mp_product< 47 | test_pair, 48 | value_indices, 49 | value_indices 50 | >, 51 | mp_to_bool 52 | >(), 53 | "all values for all integer types correctly multiplied" 54 | ); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /test/test_multiply_native_results.hpp: -------------------------------------------------------------------------------- 1 | #include "test_values.hpp" 2 | 3 | constexpr const char *test_multiplication_native_result[ 4 | boost::mp11::mp_size::value 5 | ] = { 6 | // 0 0 0 0 7 | // 012345670123456701234567012345670 8 | // 012345678901234567890123456789012 9 | /* 0*/ ".................................", 10 | /* 1*/ ".........xx..xx..........xxx.xxx.", 11 | /* 2*/ ".........xx..xx.........xxxxxxxx.", 12 | /* 3*/ "..........x...x.........xxxxxxxx.", 13 | /* 4*/ ".................................", 14 | /* 5*/ ".........xx..xx..........xxx.xxx.", 15 | /* 6*/ ".........xx..xx.........xxxxxxxx.", 16 | /* 7*/ "..........x...x.........xxxxxxxx.", 17 | 18 | /* 8*/ ".................................", 19 | /* 9*/ ".xx..xx..xx..xx..xxx.xxx.xxx.xxx.", 20 | /*10*/ ".xxx.xxx.xxx.xx..xxx.xxxxxxxxxxx.", 21 | /*11*/ "..........x...x.........xxxxxxxx.", 22 | /*12*/ ".................................", 23 | /*13*/ ".xx..xx..xx..xx..xxx.xxx.xxx.xxx.", 24 | /*14*/ ".xxx.xxx.xxx.xxx.xxx.xxx.xxxxxxx.", 25 | /*15*/ "..............x.............xxxx.", 26 | 27 | // 0 0 0 0 28 | // 012345670123456701234567012345670 29 | // 012345678901234567890123456789012 30 | /*16*/ ".................................", 31 | /*17*/ ".........xx..xx..........xxx.xxx.", 32 | /*18*/ ".........xx..xx..........xxx.xxx.", 33 | /*19*/ ".........xx..xx..........xxx.xxx.", 34 | /*20*/ ".................................", 35 | /*21*/ ".........xx..xx..........xxx.xxx.", 36 | /*22*/ ".........xx..xx..........xxx.xxx.", 37 | /*23*/ ".........xx..xx........x.xxx.xxx.", 38 | 39 | /*24*/ "..xx..xx..xx.....................", 40 | /*25*/ ".xxx.xxx.xxx.xx..xxx.xxx.xxx.xxx.", 41 | /*26*/ ".xxx.xxx.xxx.xx..xxx.xxx.xxx.xxx.", 42 | /*27*/ ".xxx.xxx.xxx.xx..xxx.xxx.xxx.xxx.", 43 | /*28*/ "..xx..xx..xx..xx.................", 44 | /*29*/ ".xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.", 45 | /*30*/ ".xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.", 46 | /*31*/ ".xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.", 47 | /*31*/ "................................." 48 | }; 49 | -------------------------------------------------------------------------------- /test/test_notepad.hpp: -------------------------------------------------------------------------------- 1 | // this is a hack to workaround the limititation of template 2 | // expansion depth in the MSVC compiler. 3 | template 4 | BOOST_MP11_CONSTEXPR mp_if_c::value <= 1024, F> mp_for_each_1( F && f ){ 5 | return detail::mp_for_each_impl( mp_rename(), std::forward(f) ); 6 | } 7 | template 8 | BOOST_MP11_CONSTEXPR mp_if_c::value >= 1025, F> mp_for_each_1( F && f ){ 9 | mp_for_each>( std::forward(f) ); 10 | return mp_for_each_1>( std::forward(f) ); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /test/test_or_automatic.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | template 13 | using safe_t = boost::safe_numerics::safe< 14 | T, 15 | boost::safe_numerics::automatic 16 | >; 17 | #include "test_or.hpp" 18 | 19 | #include "test_values.hpp" 20 | #include 21 | #include 22 | 23 | using namespace boost::mp11; 24 | 25 | template 26 | struct test { 27 | static_assert(mp_is_list(), "must be a list of integral constants"); 28 | bool m_error; 29 | test(bool b = true) : m_error(b) {} 30 | operator bool(){ 31 | return m_error; 32 | } 33 | template 34 | void operator()(const T &){ 35 | static_assert(mp_is_list(), "must be a list of two integral constants"); 36 | constexpr size_t i1 = mp_first(); // index of first argument 37 | constexpr size_t i2 = mp_second();// index of second argument 38 | std::cout << i1 << ',' << i2 << ','; 39 | using T1 = typename mp_at_c::value_type; 40 | using T2 = typename mp_at_c::value_type; 41 | m_error &= test_or( 42 | mp_at_c()(), // value of first argument 43 | mp_at_c()(), // value of second argument 44 | boost::core::demangle(typeid(T1).name()).c_str(), 45 | boost::core::demangle(typeid(T2).name()).c_str(), 46 | '.' 47 | ); 48 | } 49 | }; 50 | 51 | int main(){ 52 | //TEST_EACH_VALUE_PAIR 53 | test rval(true); 54 | 55 | using value_indices = mp_iota_c::value>; 56 | mp_for_each< 57 | mp_product 58 | >(rval); 59 | 60 | std::cout << (rval ? "success!" : "failure") << std::endl; 61 | return ! rval ; 62 | } 63 | -------------------------------------------------------------------------------- /test/test_or_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | template 11 | using safe_t = boost::safe_numerics::safe< 12 | T, 13 | boost::safe_numerics::automatic 14 | >; 15 | 16 | #include "test_or_constexpr.hpp" 17 | 18 | #include "test_values.hpp" 19 | 20 | using namespace boost::mp11; 21 | 22 | template 23 | struct test_pair { 24 | static const std::size_t i = First(); 25 | static const std::size_t j = Second(); 26 | constexpr static const bool value = test_or_constexpr( 27 | mp_at_c()(), 28 | mp_at_c()(), 29 | '.' 30 | ); 31 | }; 32 | 33 | #include 34 | #include 35 | 36 | int main(){ 37 | using namespace boost::mp11; 38 | 39 | using value_indices = mp_iota_c::value>; 40 | 41 | static_assert( 42 | mp_all_of< 43 | mp_product< 44 | test_pair, 45 | value_indices, 46 | value_indices 47 | >, 48 | mp_to_bool 49 | >(), 50 | "all values for all integer types correctly or'ed" 51 | ); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /test/test_or_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_TEST_ADD_CONSTEXPR_HPP 2 | #define BOOST_TEST_ADD_CONSTEXPR_HPP 3 | 4 | // Copyright (c) 2015 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | 12 | template 13 | constexpr bool test_or_constexpr( 14 | T1 v1, 15 | T2 v2, 16 | char expected_result 17 | ){ 18 | using namespace boost::safe_numerics; 19 | // if we don't expect the operation to pass, we can't 20 | // check the constexpr version of the calculation so 21 | // just return success. 22 | if(expected_result == 'x') 23 | return true; 24 | safe_t(v1) | v2; 25 | v1 | safe_t(v2); 26 | safe_t(v1) | safe_t(v2); 27 | return true; // correct result 28 | } 29 | 30 | #endif // BOOST_TEST_ADD_CONSTEXPR_HPP 31 | -------------------------------------------------------------------------------- /test/test_or_native.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::native 15 | >; 16 | #include "test_or.hpp" 17 | #include "test_values.hpp" 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | using namespace boost::mp11; 24 | 25 | template 26 | struct test { 27 | static_assert(mp_is_list(), "must be a list of integral constants"); 28 | bool m_error; 29 | test(bool b = true) : m_error(b) {} 30 | operator bool(){ 31 | return m_error; 32 | } 33 | template 34 | void operator()(const T &){ 35 | static_assert(mp_is_list(), "must be a list of two integral constants"); 36 | constexpr size_t i1 = mp_first(); // index of first argument 37 | constexpr size_t i2 = mp_second();// index of second argument 38 | std::cout << i1 << ',' << i2 << ','; 39 | using T1 = typename mp_at_c::value_type; 40 | using T2 = typename mp_at_c::value_type; 41 | m_error &= test_or( 42 | mp_at_c(), // value of first argument 43 | mp_at_c(), // value of second argument 44 | boost::core::demangle(typeid(T1).name()).c_str(), 45 | boost::core::demangle(typeid(T2).name()).c_str(), 46 | '.' 47 | ); 48 | } 49 | }; 50 | 51 | int main(){ 52 | //TEST_EACH_VALUE_PAIR 53 | test rval(true); 54 | 55 | using value_indices = mp_iota_c::value>; 56 | mp_for_each< 57 | mp_product 58 | >(rval); 59 | 60 | std::cout << (rval ? "success!" : "failure") << std::endl; 61 | return ! rval ; 62 | } 63 | -------------------------------------------------------------------------------- /test/test_or_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | template 11 | using safe_t = boost::safe_numerics::safe< 12 | T, 13 | boost::safe_numerics::native 14 | >; 15 | 16 | #include "test_or_constexpr.hpp" 17 | 18 | #include "test_values.hpp" 19 | 20 | using namespace boost::mp11; 21 | 22 | template 23 | struct test_pair { 24 | static const std::size_t i = First(); 25 | static const std::size_t j = Second(); 26 | constexpr static const bool value = test_or_constexpr( 27 | mp_at_c()(), 28 | mp_at_c()(), 29 | '.' 30 | ); 31 | }; 32 | 33 | #include 34 | #include 35 | 36 | int main(){ 37 | using namespace boost::mp11; 38 | 39 | using value_indices = mp_iota_c::value>; 40 | 41 | static_assert( 42 | mp_all_of< 43 | mp_product< 44 | test_pair, 45 | value_indices, 46 | value_indices 47 | >, 48 | mp_to_bool 49 | >(), 50 | "all values for all integer types correctly or'ed" 51 | ); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /test/test_right_shift_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_right_shift_automatic_results.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::automatic 15 | >; 16 | 17 | #include "test_right_shift_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_right_shift_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_right_shift_automatic_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly right shifted" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_right_shift_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_TEST_RIGHT_SHIFT_CONSTEXPR_HPP 2 | #define BOOST_TEST_RIGHT_SHIFT_CONSTEXPR_HPP 3 | 4 | // Copyright (c) 2015 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | 12 | template 13 | constexpr bool test_right_shift_constexpr( 14 | T1 v1, 15 | T2 v2, 16 | char expected_result 17 | ){ 18 | using namespace boost::safe_numerics; 19 | // if we don't expect the operation to pass, we can't 20 | // check the constexpr version of the calculation so 21 | // just return success. 22 | if(expected_result == 'x') 23 | return true; 24 | safe_t(v1) >> v2; 25 | v1 >> safe_t(v2); 26 | safe_t(v1) >> safe_t(v2); 27 | return true; // correct result 28 | } 29 | 30 | #endif // BOOST_TEST_RIGHT_SHIFT_CONSTEXPR_HPP 31 | -------------------------------------------------------------------------------- /test/test_right_shift_native.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include "test_right_shift_native_results.hpp" 11 | 12 | template 13 | using safe_t = boost::safe_numerics::safe< 14 | T, 15 | boost::safe_numerics::native 16 | >; 17 | #include "test_right_shift.hpp" 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | using namespace boost::mp11; 24 | 25 | template 26 | struct test { 27 | static_assert(mp_is_list(), "must be a list of integral constants"); 28 | bool m_error; 29 | test(bool b = true) : m_error(b) {} 30 | operator bool(){ 31 | return m_error; 32 | } 33 | template 34 | void operator()(const T &){ 35 | static_assert(mp_is_list(), "must be a list of two integral constants"); 36 | constexpr size_t i1 = mp_first(); // index of first argument 37 | constexpr size_t i2 = mp_second();// index of second argument 38 | std::cout << i1 << ',' << i2 << ','; 39 | using T1 = typename mp_at_c::value_type; 40 | using T2 = typename mp_at_c::value_type; 41 | m_error &= test_right_shift( 42 | mp_at_c(), // value of first argument 43 | mp_at_c(), // value of second argument 44 | boost::core::demangle(typeid(T1).name()).c_str(), 45 | boost::core::demangle(typeid(T2).name()).c_str(), 46 | test_right_shift_native_result[i1][i2] 47 | ); 48 | } 49 | }; 50 | 51 | int main(){ 52 | //TEST_EACH_VALUE_PAIR 53 | test rval(true); 54 | 55 | using value_indices = mp_iota_c::value>; 56 | mp_for_each< 57 | mp_product 58 | >(rval); 59 | 60 | std::cout << (rval ? "success!" : "failure") << std::endl; 61 | return ! rval ; 62 | } 63 | -------------------------------------------------------------------------------- /test/test_right_shift_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_right_shift_native_results.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::native 15 | >; 16 | 17 | #include "test_right_shift_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_right_shift_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_right_shift_native_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly right shifted" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_stream_overload.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // test stream overload of >> and << for some non-numeric type 8 | 9 | // this is a compile only test - but since many build systems 10 | #include 11 | 12 | struct X {}; 13 | 14 | using I = boost::safe_numerics::safe; 15 | 16 | void operator>>(X, I){}; 17 | void operator<<(X, I){}; 18 | 19 | 20 | void f(X x, I i) { 21 | x << i; 22 | x >> i; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /test/test_subtract_automatic.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include "test_subtract_automatic_results.hpp" 12 | 13 | template 14 | using safe_t = boost::safe_numerics::safe< 15 | T, 16 | boost::safe_numerics::automatic 17 | >; 18 | 19 | #include "test_subtract.hpp" 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | using namespace boost::mp11; 26 | 27 | template 28 | struct test { 29 | static_assert(mp_is_list(), "must be a list of integral constants"); 30 | bool m_error; 31 | test(bool b = true) : m_error(b) {} 32 | operator bool(){ 33 | return m_error; 34 | } 35 | template 36 | void operator()(const T &){ 37 | static_assert(mp_is_list(), "must be a list of two integral constants"); 38 | constexpr size_t i1 = mp_first(); // index of first argument 39 | constexpr size_t i2 = mp_second();// index of second argument 40 | std::cout << i1 << ',' << i2 << ','; 41 | using T1 = typename mp_at_c::value_type; 42 | using T2 = typename mp_at_c::value_type; 43 | m_error &= test_subtract( 44 | mp_at_c(), // value of first argument 45 | mp_at_c(), // value of second argument 46 | boost::core::demangle(typeid(T1).name()).c_str(), 47 | boost::core::demangle(typeid(T2).name()).c_str(), 48 | test_subtraction_automatic_result[i1][i2] 49 | ); 50 | } 51 | }; 52 | 53 | int main(){ 54 | //TEST_EACH_VALUE_PAIR 55 | test rval(true); 56 | 57 | using value_indices = mp_iota_c::value>; 58 | mp_for_each< 59 | mp_product 60 | >(rval); 61 | 62 | std::cout << (rval ? "success!" : "failure") << std::endl; 63 | return ! rval ; 64 | } 65 | -------------------------------------------------------------------------------- /test/test_subtract_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include "test_subtract_automatic_results.hpp" 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::automatic 15 | >; 16 | 17 | #include "test_subtract_constexpr.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_subtract_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | test_subtraction_automatic_result[i][j] 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly subtracted" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_subtract_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_TEST_SUBTRACT_CONSTEXPR_HPP 2 | #define BOOST_TEST_SUBTRACT_CONSTEXPR_HPP 3 | 4 | // Copyright (c) 2019 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | 12 | template 13 | constexpr bool test_subtract_constexpr( 14 | T1 v1, 15 | T2 v2, 16 | char expected_result 17 | ){ 18 | using namespace boost::safe_numerics; 19 | // if we don't expect the operation to pass, we can't 20 | // check the constexpr version of the calculation so 21 | // just return success. 22 | if(expected_result == 'x') 23 | return true; 24 | safe_t(v1) - v2; 25 | v1 - safe_t(v2); 26 | safe_t(v1) - safe_t(v2); 27 | return true; // correct result 28 | } 29 | 30 | #endif // BOOST_TEST_SUBTRACT_CONSTEXPR_HPP 31 | -------------------------------------------------------------------------------- /test/test_subtract_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | #include "test_subtract_native_results.hpp" 11 | 12 | template 13 | using safe_t = boost::safe_numerics::safe< 14 | T, 15 | boost::safe_numerics::native 16 | >; 17 | 18 | #include "test_subtract_constexpr.hpp" 19 | 20 | using namespace boost::mp11; 21 | 22 | #include 23 | #include 24 | 25 | template 26 | struct test_pair { 27 | static const std::size_t i = First(); 28 | static const std::size_t j = Second(); 29 | constexpr static const bool value = test_subtract_constexpr( 30 | mp_at_c()(), 31 | mp_at_c()(), 32 | test_subtraction_native_result[i][j] 33 | ); 34 | }; 35 | 36 | int main(){ 37 | using namespace boost::mp11; 38 | 39 | using value_indices = mp_iota_c::value>; 40 | 41 | static_assert( 42 | mp_all_of< 43 | mp_product< 44 | test_pair, 45 | value_indices, 46 | value_indices 47 | >, 48 | mp_to_bool 49 | >(), 50 | "all values for all integer types correctly subtracted" 51 | ); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /test/test_subtract_native_results.hpp: -------------------------------------------------------------------------------- 1 | #include "test_values.hpp" 2 | 3 | constexpr const char *test_subtraction_native_result[ 4 | boost::mp11::mp_size::value 5 | ] = { 6 | // 0 0 0 0 7 | // 012345670123456701234567012345670 8 | // 012345678901234567890123456789012 9 | /* 0*/ "..........x...x..........xxx.xxx.", 10 | /* 1*/ "..........x...x..........xxx.xxx.", 11 | /* 2*/ ".........x...x..........xxxxxxxx.", 12 | /* 3*/ "........................xxxxxxxx.", 13 | /* 4*/ "..........x...x..........xxx.xxx.", 14 | /* 5*/ "..........x...x..........xxx.xxx.", 15 | /* 6*/ ".........x...x..........xxxxxxxx.", 16 | /* 7*/ "........................xxxxxxxx.", 17 | 18 | /* 8*/ "..........x...x..........xxx.xxx.", 19 | /* 9*/ "..xx..xx..xx..x...........xx.xxx.", 20 | /*10*/ "xx..xx..xx...x..xxxxxxxxxxxxxxxx.", 21 | /*11*/ "........................xxxxxxxx.", 22 | /*12*/ "..............x..............xxx.", 23 | /*13*/ "..xx..xx..xx..xx..............xx.", 24 | /*14*/ "xx..xx..xx..xx..xxxxxxxxxxxxxxxx.", 25 | /*15*/ "............................xxxx.", 26 | 27 | // 0 0 0 0 28 | // 012345670123456701234567012345670 29 | // 012345678901234567890123456789012 30 | /*16*/ "..........x...x..........xxx.xxx.", 31 | /*17*/ "..........x...x..........xxx.xxx.", 32 | /*18*/ "..........x...x..........xxx.xxx.", 33 | /*19*/ "..........x...x..........xxx.xxx.", 34 | /*20*/ "..........x...x..........xxx.xxx.", 35 | /*21*/ "..........x...x..........xxx.xxx.", 36 | /*22*/ "..........x...x..........xxx.xxx.", 37 | /*23*/ "..........x...x..........xxx.xxx.", 38 | 39 | /*24*/ ".xxx.xxx.xxx..x..xxx.xxx.xxx.xxx.", 40 | /*25*/ "..xx..xx..xx..x...........xx.xxx.", 41 | /*26*/ "..xx..xx..xx..x............x.xxx.", 42 | /*27*/ "..xx..xx..xx..x..............xxx.", 43 | /*28*/ ".xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.", 44 | /*29*/ "..xx..xx..xx..xx..............xx.", 45 | /*30*/ "..xx..xx..xx..xx...............x.", 46 | /*31*/ "..xx..xx..xx..xx.................", 47 | /*32*/ "..........x...x.........xxxxxxxx." 48 | }; 49 | -------------------------------------------------------------------------------- /test/test_trap.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // testing trap 8 | 9 | // this is a compile only test - but since many build systems 10 | // can't handle a compile-only test - make sure it passes trivially. 11 | 12 | #include 13 | #include 14 | 15 | using namespace boost::safe_numerics; 16 | template // T is char, int, etc data type 17 | using safe_t = safe< 18 | T, 19 | native, 20 | loose_trap_policy // use for compiling and running tests 21 | >; 22 | 23 | template 24 | void test(){ 25 | safe_t t; 26 | safe_t u; 27 | t + u; 28 | t - u; 29 | t * u; 30 | t / u; // could fail regardless of data type 31 | t % u; // could fail regardless of data type 32 | t << u; 33 | t >> u; 34 | t | u; 35 | t & u; 36 | t ^ u; 37 | } 38 | int main(int, char *[]){ 39 | test(); // should compile 40 | test(); // should compile 41 | test(); // should fail to compile 42 | test(); // should fail to compile 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /test/test_xor_automatic.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | template 11 | using safe_t = boost::safe_numerics::safe< 12 | T, 13 | boost::safe_numerics::automatic 14 | >; 15 | #include "test_xor.hpp" 16 | #include "test_values.hpp" 17 | 18 | #include 19 | #include 20 | 21 | using namespace boost::mp11; 22 | 23 | template 24 | struct test { 25 | static_assert(mp_is_list(), "must be a list of integral constants"); 26 | bool m_error; 27 | test(bool b = true) : m_error(b) {} 28 | operator bool(){ 29 | return m_error; 30 | } 31 | template 32 | void operator()(const T &){ 33 | static_assert(mp_is_list(), "must be a list of two integral constants"); 34 | constexpr size_t i1 = mp_first(); // index of first argument 35 | constexpr size_t i2 = mp_second();// index of second argument 36 | std::cout << i1 << ',' << i2 << ','; 37 | using T1 = typename mp_at_c::value_type; 38 | using T2 = typename mp_at_c::value_type; 39 | m_error &= test_xor( 40 | mp_at_c()(), // value of first argument 41 | mp_at_c()(), // value of second argument 42 | boost::core::demangle(typeid(T1).name()).c_str(), 43 | boost::core::demangle(typeid(T2).name()).c_str(), 44 | '.' 45 | ); 46 | } 47 | }; 48 | 49 | int main(){ 50 | //TEST_EACH_VALUE_PAIR 51 | test rval(true); 52 | 53 | using value_indices = mp_iota_c::value>; 54 | mp_for_each< 55 | mp_product 56 | >(rval); 57 | 58 | std::cout << (rval ? "success!" : "failure") << std::endl; 59 | return ! rval ; 60 | } 61 | -------------------------------------------------------------------------------- /test/test_xor_automatic_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | template 11 | using safe_t = boost::safe_numerics::safe< 12 | T, 13 | boost::safe_numerics::automatic 14 | >; 15 | 16 | #include "test_xor_constexpr.hpp" 17 | #include "test_values.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_xor_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | '.' 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | 38 | using value_indices = mp_iota_c::value>; 39 | 40 | static_assert( 41 | mp_all_of< 42 | mp_product< 43 | test_pair, 44 | value_indices, 45 | value_indices 46 | >, 47 | mp_to_bool 48 | >(), 49 | "all values for all integer types correctly xor'ed" 50 | ); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/test_xor_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BOOST_TEST_XOR_CONSTEXPR_HPP 2 | #define BOOST_TEST_XOR_CONSTEXPR_HPP 3 | 4 | // Copyright (c) 2019 Robert Ramey 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. (See 7 | // accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #include 11 | 12 | template 13 | constexpr bool test_xor_constexpr( 14 | T1 v1, 15 | T2 v2, 16 | char expected_result 17 | ){ 18 | using namespace boost::safe_numerics; 19 | // if we don't expect the operation to pass, we can't 20 | // check the constexpr version of the calculation so 21 | // just return success. 22 | if(expected_result == 'x') 23 | return true; 24 | safe_t(v1) ^ v2; 25 | v1 ^ safe_t(v2); 26 | safe_t(v1) ^ safe_t(v2); 27 | return true; // correct result 28 | } 29 | 30 | #endif // BOOST_TEST_XOR_CONSTEXPR_HPP 31 | -------------------------------------------------------------------------------- /test/test_xor_native.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | #include 10 | 11 | template 12 | using safe_t = boost::safe_numerics::safe< 13 | T, 14 | boost::safe_numerics::native 15 | >; 16 | #include "test_xor.hpp" 17 | #include "test_values.hpp" 18 | 19 | #include 20 | #include 21 | 22 | using namespace boost::mp11; 23 | 24 | template 25 | struct test { 26 | static_assert(mp_is_list(), "must be a list of integral constants"); 27 | bool m_error; 28 | test(bool b = true) : m_error(b) {} 29 | operator bool(){ 30 | return m_error; 31 | } 32 | template 33 | void operator()(const T &){ 34 | static_assert(mp_is_list(), "must be a list of two integral constants"); 35 | constexpr size_t i1 = mp_first(); // index of first argument 36 | constexpr size_t i2 = mp_second();// index of second argument 37 | std::cout << i1 << ',' << i2 << ','; 38 | using T1 = typename mp_at_c::value_type; 39 | using T2 = typename mp_at_c::value_type; 40 | m_error &= test_xor( 41 | mp_at_c(), // value of first argument 42 | mp_at_c(), // value of second argument 43 | boost::core::demangle(typeid(T1).name()).c_str(), 44 | boost::core::demangle(typeid(T2).name()).c_str(), 45 | '.' 46 | ); 47 | } 48 | }; 49 | 50 | int main(){ 51 | //TEST_EACH_VALUE_PAIR 52 | test rval(true); 53 | 54 | using value_indices = mp_iota_c::value>; 55 | mp_for_each< 56 | mp_product 57 | >(rval); 58 | 59 | std::cout << (rval ? "success!" : "failure") << std::endl; 60 | return ! rval ; 61 | } 62 | -------------------------------------------------------------------------------- /test/test_xor_native_constexpr.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 Robert Ramey 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | template 11 | using safe_t = boost::safe_numerics::safe< 12 | T, 13 | boost::safe_numerics::native 14 | >; 15 | 16 | #include "test_xor_constexpr.hpp" 17 | #include "test_values.hpp" 18 | 19 | using namespace boost::mp11; 20 | 21 | template 22 | struct test_pair { 23 | static const std::size_t i = First(); 24 | static const std::size_t j = Second(); 25 | constexpr static const bool value = test_xor_constexpr( 26 | mp_at_c()(), 27 | mp_at_c()(), 28 | '.' 29 | ); 30 | }; 31 | 32 | #include 33 | #include 34 | 35 | int main(){ 36 | using namespace boost::mp11; 37 | using value_indices = mp_iota_c::value>; 38 | 39 | static_assert( 40 | mp_all_of< 41 | mp_product< 42 | test_pair, 43 | value_indices, 44 | value_indices 45 | >, 46 | mp_to_bool 47 | >(), 48 | "all values for all integer types correctly xor'ed" 49 | ); 50 | return 0; 51 | } 52 | --------------------------------------------------------------------------------