From 321c7bbba0f73eaf8dfb4a6a68c3653450bb9693 Mon Sep 17 00:00:00 2001 From: Robert Ramey Date: Thu, 30 Jul 2015 13:26:48 -0700 Subject: [PATCH] updated tests to be sure that n op safe is covered - --- examples/example9.cpp | 5 +--- include/cpp.hpp | 2 ++ include/safe_base_operations.hpp | 11 +++++---- test/test_cpp.cpp | 1 - test/test_divide.cpp | 39 ++++++++++++++++++++++++++++++ test/test_modulus.cpp | 41 ++++++++++++++++++++++++++++++++ test/test_multiply.cpp | 40 +++++++++++++++++++++++++++++++ test/test_range.cpp | 5 ++-- test/test_subtract.cpp | 2 +- 9 files changed, 132 insertions(+), 14 deletions(-) diff --git a/examples/example9.cpp b/examples/example9.cpp index d11f51a..0c56280 100644 --- a/examples/example9.cpp +++ b/examples/example9.cpp @@ -24,7 +24,7 @@ template // T is char, int, etc data type using safe_t = boost::numeric::safe< T, pic16_promotion, - boost::numeric::trap_exception // use for running tests + boost::numeric::throw_exception // use for running tests >; using int8 = safe_t; @@ -179,9 +179,6 @@ Use the formula: */ uint16 get_stopping_distance(LEMPARAMETER velocity){ int32 d; - d = velocity; - //d *= velocity; - d = velocity * velocity; d /= lem.acceleration; d /= 2; diff --git a/include/cpp.hpp b/include/cpp.hpp index da7c50c..c2d544e 100755 --- a/include/cpp.hpp +++ b/include/cpp.hpp @@ -22,6 +22,8 @@ #include // integer type selection #include +#include "safe_common.hpp" + // forward declaration - safe type template< class Stored, diff --git a/include/safe_base_operations.hpp b/include/safe_base_operations.hpp index 2c2616c..6c91ff6 100644 --- a/include/safe_base_operations.hpp +++ b/include/safe_base_operations.hpp @@ -265,7 +265,6 @@ SAFE_NUMERIC_CONSTEXPR inline operator+(const T & t, const U & u){ typedef addition_result ar; typedef typename ar::P::exception_policy exception_policy; typedef typename ar::type result_type; - typedef typename base_type::type result_base_type; static_assert( boost::numeric::is_safe::value, "Promotion failed to return safe type" @@ -273,6 +272,7 @@ SAFE_NUMERIC_CONSTEXPR inline operator+(const T & t, const U & u){ //typedef print p_result_type; //typedef print p_result_base_type; + typedef typename base_type::type result_base_type; typedef typename base_type::type t_base_type; typedef typename base_type::type u_base_type; @@ -314,8 +314,6 @@ SAFE_NUMERIC_CONSTEXPR inline operator+(const T & t, const U & u){ r.template dispatch(); return result_type(static_cast(r)); - //return result_type(r); - } ///////////////////////////////////////////////////////////////// @@ -368,8 +366,11 @@ SAFE_NUMERIC_CONSTEXPR operator-(const T & t, const U & u){ = operator-(t_interval, u_interval); // if no over/under flow possible - if(r_interval.no_exception()) - return result_type(base_value(t) - base_value(u)); + if(r_interval.no_exception()){ + result_base_type t_value = base_value(t); + result_base_type u_value = base_value(u); + return result_type(t_value - u_value); + } // otherwise do the subtraction checking for overflow checked_result r = checked::subtract( diff --git a/test/test_cpp.cpp b/test/test_cpp.cpp index c395e6c..9c3e37b 100644 --- a/test/test_cpp.cpp +++ b/test/test_cpp.cpp @@ -78,7 +78,6 @@ BOOST_PP_REPEAT( EACH_TYPE1, nothing ) -#endif int main(int argc, char *argv[]){ // this is a compile only test - but since many build systems diff --git a/test/test_divide.cpp b/test/test_divide.cpp index ccaf606..a3ab4fd 100644 --- a/test/test_divide.cpp +++ b/test/test_divide.cpp @@ -60,6 +60,45 @@ bool test_divide( } } } + { + boost::numeric::safe t2 = v2; + // presuming native policy + boost::numeric::safe result; + + try{ + result = v1 / t2; + static_assert( + boost::numeric::is_safe::value, + "Expression failed to return safe type" + ); + if(expected_result == 'x'){ + std::cout + << "failed to detect error in division " + << std::hex << result << "(" << std::dec << result << ")" + << " ! = "<< av1 << " / " << av2 + << std::endl; + try{ + v1 / t2; + } + catch(std::exception){} + return false; + } + } + catch(std::exception){ + if(expected_result == '.'){ + std::cout + << "erroneously detected error in division " + << std::hex << result << "(" << std::dec << result << ")" + << " == "<< av1 << " / " << av2 + << std::endl; + try{ + v1 / t2; + } + catch(std::exception){} + return false; + } + } + } { boost::numeric::safe t1 = v1; boost::numeric::safe t2 = v2; diff --git a/test/test_modulus.cpp b/test/test_modulus.cpp index 2d50e0f..68fc060 100644 --- a/test/test_modulus.cpp +++ b/test/test_modulus.cpp @@ -62,6 +62,47 @@ bool test_modulus( } } } + { + boost::numeric::safe t2 = v2; + // presuming native policy + boost::numeric::safe result; + + try{ + result = v1 % t2; + + static_assert( + boost::numeric::is_safe::value, + "Expression failed to return safe type" + ); + + if(expected_result != '.'){ + std::cout + << "failed to detect error in division " + << std::hex << result << "(" << std::dec << result << ")" + << " ! = "<< av1 << " % " << av2 + << std::endl; + try{ + v1 % t2; + } + catch(std::exception){} + return false; + } + } + catch(std::exception){ + if(expected_result != 'x'){ + std::cout + << "erroneously detected error in division " + << std::hex << result << "(" << std::dec << result << ")" + << " == "<< av1 << " % " << av2 + << std::endl; + try{ + v1 % t2; + } + catch(std::exception){} + return false; + } + } + } { boost::numeric::safe t1 = v1; boost::numeric::safe t2 = v2; diff --git a/test/test_multiply.cpp b/test/test_multiply.cpp index d36c98d..7e2f7be 100644 --- a/test/test_multiply.cpp +++ b/test/test_multiply.cpp @@ -64,6 +64,46 @@ bool test_multiply( } } } + { + boost::numeric::safe t2 = v2; + // presuming native policy + boost::numeric::safe result; + + try{ + result = v1 * t2; + static_assert( + boost::numeric::is_safe::value, + "Expression failed to return safe type" + ); + + if(expected_result == 'x'){ + std::cout + << "failed to detect error in multiplication " + << std::hex << result << "(" << std::dec << result << ")" + << " ! = "<< av1 << " * " << av2 + << std::endl; + try{ + v1 * t2; + } + catch(std::exception){} + return false; + } + } + catch(std::exception){ + if(expected_result == '.'){ + std::cout + << "erroneously detected error in multiplication " + << std::hex << result << "(" << std::dec << result << ")" + << " == "<< av1 << " * " << av2 + << std::endl; + try{ + v1 * t2; + } + catch(std::exception){} + return false; + } + } + } { boost::numeric::safe t1 = v1; boost::numeric::safe t2 = v2; diff --git a/test/test_range.cpp b/test/test_range.cpp index 6a659ff..079a0f9 100644 --- a/test/test_range.cpp +++ b/test/test_range.cpp @@ -37,7 +37,7 @@ bool test_log(){ assert(log(-129) == 9); // 8 bits + 1 sign bit assert(log(-255) == 9); // 8 bits + 1 sign bit assert(log(-256) == 9); // 8 bits + 1 sign bit - return 0; + return true; } bool test1(){ @@ -53,10 +53,9 @@ bool test1(){ "this range should be unsigned" ); - //typedef ::print::type p_t2; - return 0; + return true; } #include "../include/automatic.hpp" diff --git a/test/test_subtract.cpp b/test/test_subtract.cpp index 3a18e15..02ba69b 100644 --- a/test/test_subtract.cpp +++ b/test/test_subtract.cpp @@ -109,7 +109,7 @@ bool test_subtract( boost::numeric::safe t2 = v2; // presuming native policy - boost::numeric::safe result; + boost::numeric::safe result; try{ result = t1 - t2;