diff --git a/include/automatic.hpp b/include/automatic.hpp index 656e6d3..493ad37 100644 --- a/include/automatic.hpp +++ b/include/automatic.hpp @@ -247,24 +247,60 @@ struct automatic { E >::type type; }; + template struct multiplication_result { - typedef typename base_type::type t_base_type; - typedef typename base_type::type u_base_type; - SAFE_NUMERIC_CONSTEXPR static const interval t = { + typedef typename base_type::type base_type_t; + typedef typename base_type::type base_type_u; + + SAFE_NUMERIC_CONSTEXPR static const interval t = { base_value(std::numeric_limits::min()), base_value(std::numeric_limits::max()) }; - SAFE_NUMERIC_CONSTEXPR static const interval u = { + + SAFE_NUMERIC_CONSTEXPR static const interval u = { base_value(std::numeric_limits::min()), base_value(std::numeric_limits::max()) }; - typedef decltype(t_base_type() * u_base_type()) r_base_type; - SAFE_NUMERIC_CONSTEXPR static const interval r - = operator*(t, u); + typedef calculate_max_t max_t; - typedef safe_base type; + SAFE_NUMERIC_CONSTEXPR static const interval< max_t> r + = operator*(t, u); + + SAFE_NUMERIC_CONSTEXPR static const max_t newmin = r.l.is_valid() ? + static_cast(r.l) + : + std::numeric_limits::min() + ; + + SAFE_NUMERIC_CONSTEXPR static const max_t newmax = r.u.is_valid() ? + static_cast(r.u) + : + std::numeric_limits::max() + ; + + // typedef typename print::type p_max_t; + // typedef typename print>::type p_newmin; + // typedef typename print>::type p_newmax; + + static_assert( + newmin < newmax, + "new minimumum must be less than new maximum" + ); + + static_assert( + std::numeric_limits::min() >= 0 || std::is_signed::value, + "newmin < 0 and unsigned can't happen" + ); + + typedef typename safe_range< + max_t, + newmin, + newmax, + P, + E + >::type type; }; template struct division_result { diff --git a/include/interval.hpp b/include/interval.hpp index e5a91e9..23a87b9 100644 --- a/include/interval.hpp +++ b/include/interval.hpp @@ -98,22 +98,22 @@ SAFE_NUMERIC_CONSTEXPR interval operator*(const interval & t, const interv interval( min( min( - checked::multiply(static_cast(t.l), static_cast(u.l)), - checked::multiply(static_cast(t.l), static_cast(u.u)) + checked::multiply(static_cast(t.l), static_cast(u.l)), + checked::multiply(static_cast(t.l), static_cast(u.u)) ), min( - checked::multiply(static_cast(t.u), static_cast(u.l)), - checked::multiply(static_cast(t.u), static_cast(u.u)) + checked::multiply(static_cast(t.u), static_cast(u.l)), + checked::multiply(static_cast(t.u), static_cast(u.u)) ) ), max( max( - checked::multiply(static_cast(t.l), static_cast(u.l)), - checked::multiply(static_cast(t.l), static_cast(u.u)) + checked::multiply(static_cast(t.l), static_cast(u.l)), + checked::multiply(static_cast(t.l), static_cast(u.u)) ), max( - checked::multiply(static_cast(t.u), static_cast(u.l)), - checked::multiply(static_cast(t.u), static_cast(u.u)) + checked::multiply(static_cast(t.u), static_cast(u.l)), + checked::multiply(static_cast(t.u), static_cast(u.u)) ) ) ); @@ -135,22 +135,22 @@ SAFE_NUMERIC_CONSTEXPR interval operator/(const interval & t, const interv interval( min( min( - checked::divide(static_cast(t.l), static_cast(u.l)), - checked::divide(static_cast(t.l), static_cast(u.u)) + checked::divide(static_cast(t.l), static_cast(u.l)), + checked::divide(static_cast(t.l), static_cast(u.u)) ), min( - checked::divide(static_cast(t.u), static_cast(u.l)), - checked::divide(static_cast(t.u), static_cast(u.u)) + checked::divide(static_cast(t.u), static_cast(u.l)), + checked::divide(static_cast(t.u), static_cast(u.u)) ) ), max( max( - checked::divide(static_cast(t.l), static_cast(u.l)), - checked::divide(static_cast(t.l), static_cast(u.u)) + checked::divide(static_cast(t.l), static_cast(u.l)), + checked::divide(static_cast(t.l), static_cast(u.u)) ), max( - checked::divide(static_cast(t.u), static_cast(u.l)), - checked::divide(static_cast(t.u), static_cast(u.u)) + checked::divide(static_cast(t.u), static_cast(u.l)), + checked::divide(static_cast(t.u), static_cast(u.u)) ) ) ) diff --git a/include/safe_base_operations.hpp b/include/safe_base_operations.hpp index 6c91ff6..ee8ac2d 100644 --- a/include/safe_base_operations.hpp +++ b/include/safe_base_operations.hpp @@ -439,7 +439,10 @@ SAFE_NUMERIC_CONSTEXPR operator*(const T & t, const U & u){ // if no over/under flow possible if(r_interval.no_exception()) - return result_type(base_value(t) * base_value(u)); + return result_type( + static_cast(base_value(t)) + * static_cast(base_value(u)) + ); // otherwise do the multiplication checking for overflow checked_result r = checked::multiply( diff --git a/test/test_multiply.cpp b/test/test_multiply.cpp index 7e2f7be..bec8052 100644 --- a/test/test_multiply.cpp +++ b/test/test_multiply.cpp @@ -6,7 +6,7 @@ #include #include -#include // is_same +#include #include "../include/safe_integer.hpp" @@ -20,137 +20,159 @@ bool test_multiply( const char *av2, char expected_result ){ - std::cout - << "testing " - << av1 << " * " << av2 - << std::endl; + using namespace boost::numeric; + auto unsafe_result = v1 + v2; { - boost::numeric::safe t1 = v1; - // presuming native policy - boost::numeric::safe result; + std::cout << "testing safe<" << av1 << "> * " << av2 << " -> "; + static_assert(boost::numeric::is_safe >::value, "safe not safe!"); + + safe t1 = v1; + + using result_type = decltype(t1 * v2); + result_type result; + + static_assert( + boost::numeric::is_safe::value, + "Expression failed to return safe type" + ); try{ result = t1 * v2; - static_assert( - boost::numeric::is_safe::value, - "Expression failed to return safe type" - ); - + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; if(expected_result == 'x'){ + const std::type_info & ti = typeid(result); + int status; std::cout - << "failed to detect error in multiplication " - << std::hex << result << "(" << std::dec << result << ")" - << " ! = "<< av1 << " * " << av2 + << "*** failed to detect error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' << std::endl; try{ t1 * v2; } catch(std::exception){} + assert(result != unsafe_result); return false; } } catch(std::exception){ + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; if(expected_result == '.'){ + const std::type_info & ti = typeid(result); + int status; std::cout - << "erroneously detected error in multiplication " - << std::hex << result << "(" << std::dec << result << ")" - << " == "<< av1 << " * " << av2 + << "*** erroneously detected error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' << std::endl; try{ t1 * v2; } catch(std::exception){} + assert(result == unsafe_result); return false; } } } { - boost::numeric::safe t2 = v2; - // presuming native policy - boost::numeric::safe result; + std::cout << "testing " << av1 << " * " << "safe<"<< av2 << "> -> "; + static_assert(boost::numeric::is_safe >::value, "safe not safe!"); + + safe t2 = v2; + + using result_type = decltype(v1 * t2); + result_type result; + + static_assert( + boost::numeric::is_safe::value, + "Expression failed to return safe type" + ); try{ result = v1 * t2; - static_assert( - boost::numeric::is_safe::value, - "Expression failed to return safe type" - ); - + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; if(expected_result == 'x'){ + const std::type_info & ti = typeid(result); + int status; std::cout - << "failed to detect error in multiplication " - << std::hex << result << "(" << std::dec << result << ")" - << " ! = "<< av1 << " * " << av2 + << "*** failed to detect error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' << std::endl; try{ v1 * t2; } catch(std::exception){} + assert(result != unsafe_result); return false; } } catch(std::exception){ + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; if(expected_result == '.'){ + const std::type_info & ti = typeid(result); + int status; std::cout - << "erroneously detected error in multiplication " - << std::hex << result << "(" << std::dec << result << ")" - << " == "<< av1 << " * " << av2 + << "*** erroneously detected error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' << std::endl; try{ v1 * t2; } catch(std::exception){} + assert(result == unsafe_result); return false; } } } { - boost::numeric::safe t1 = v1; - boost::numeric::safe t2 = v2; + std::cout << "testing safe<" << av1 << "> * safe<" << av2 << "> -> "; + safe t1 = v1; + safe t2 = v2; - // presuming native policy - boost::numeric::safe result; + using result_type = decltype(t1 * t2); + result_type result; static_assert( - std::is_same< - boost::numeric::safe, - decltype(t1 * t2) - >::value, - "unexpected result type" + boost::numeric::is_safe::value, + "Expression failed to return safe type" ); try{ result = t1 * t2; - - static_assert( - boost::numeric::is_safe::value, - "Expression failed to return safe type" - ); - + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; if(expected_result == 'x'){ + const std::type_info & ti = typeid(result); + int status; std::cout - << "failed to detect error in multiplication " - << std::hex << result << "(" << std::dec << result << ")" - << " ! = "<< av1 << " * " << av2 + << "*** failed to detect error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' << std::endl; try{ t1 * t2; } catch(std::exception){} + assert(result != unsafe_result); return false; } } catch(std::exception){ + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; if(expected_result == '.'){ + const std::type_info & ti = typeid(result); + int status; std::cout - << "erroneously detected error in multiplication " - << std::hex << result << "(" << std::dec << result << ")" - << " == "<< av1 << " * " << av2 + << "*** erroneously detected error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' << std::endl; try{ t1 * t2; } catch(std::exception){} + assert(result == unsafe_result); return false; } } diff --git a/test/test_multiply_auto.cpp b/test/test_multiply_auto.cpp new file mode 100644 index 0000000..c7b1453 --- /dev/null +++ b/test/test_multiply_auto.cpp @@ -0,0 +1,275 @@ +// Copyright (c) 2012 Robert Ramey +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include + +#include "../include/safe_integer.hpp" +#include "../include/automatic.hpp" + +template +using safe_t = boost::numeric::safe< + T, + boost::numeric::automatic +>; + +template +bool test_multiply_auto( + T1 v1, + T2 v2, + const char *av1, + const char *av2, + char expected_result +){ + using namespace boost::numeric; + auto unsafe_result = v1 + v2; + { + std::cout << "testing safe<" << av1 << "> * " << av2 << " -> "; + static_assert(is_safe >::value, "safe_t not safe!"); + + safe_t t1 = v1; + + using result_type = decltype(t1 * v2); + result_type result; + + static_assert( + is_safe::value, + "Expression failed to return safe type" + ); + + try{ + result = t1 * v2; + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == 'x'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** failed to detect error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + t1 * v2; + } + catch(std::exception){} + assert(result != unsafe_result); + return false; + } + } + catch(std::exception){ + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == '.'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** erroneously detected error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + t1 * v2; + } + catch(std::exception){} + assert(result == unsafe_result); + return false; + } + } + } + { + std::cout << "testing " << av1 << " * " << "safe<"<< av2 << "> -> "; + static_assert(is_safe >::value, "safe_t not safe!"); + + safe_t t2 = v2; + + using result_type = decltype(v1 * t2); + result_type result; + + static_assert( + is_safe::value, + "Expression failed to return safe type" + ); + + try{ + result = v1 * t2; + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == 'x'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** failed to detect error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + v1 * t2; + } + catch(std::exception){} + assert(result != unsafe_result); + return false; + } + } + catch(std::exception){ + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == '.'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** erroneously detected error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + v1 * t2; + } + catch(std::exception){} + assert(result == unsafe_result); + return false; + } + } + } + { + std::cout << "testing safe<" << av1 << "> * safe<" << av2 << "> -> "; + safe_t t1 = v1; + safe_t t2 = v2; + + using result_type = decltype(t1 * t2); + result_type result; + + static_assert( + is_safe::value, + "Expression failed to return safe type" + ); + + try{ + result = t1 * t2; + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == 'x'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** failed to detect error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + t1 * t2; + } + catch(std::exception){} + assert(result != unsafe_result); + return false; + } + } + catch(std::exception){ + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == '.'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** erroneously detected error in multiplication " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + t1 * t2; + } + catch(std::exception){} + assert(result == unsafe_result); + return false; + } + } + } + return true; // correct result +} + +#include "test.hpp" +#include "test_values.hpp" + +// note: same test matrix as used in test_checked. Here we test all combinations +// safe and unsafe integers. in test_checked we test all combinations of +// integer primitives + +const char *test_multiplication_result[VALUE_ARRAY_SIZE] = { +// 0 0 0 0 +// 01234567012345670123456701234567 +// 01234567890123456789012345678901 +/* 0*/ "................................", +/* 1*/ ".............xx..............xxx", +/* 2*/ ".............xx.............xxxx", +/* 3*/ "..............x.............xxxx", +/* 4*/ "................................", +/* 5*/ ".............xx..............xxx", +/* 6*/ ".............xx.............xxxx", +/* 7*/ "..............x.............xxxx", + +/* 8*/ "................................", +/* 9*/ ".............xx..............xxx", +/*10*/ ".............xx.............xxxx", +/*11*/ "..............x.............xxxx", +/*12*/ "................................", +/*13*/ ".xx..xx..xx..xx..xxx.xxx.xxx.xxx", +/*14*/ ".xxx.xxx.xxx.xxx.xxx.xxx.xxxxxxx", +/*15*/ "..............x.............xxxx", + +// 0 0 0 0 +// 01234567012345670123456701234567 +// 01234567890123456789012345678901 +/*16*/ "................................", +/*17*/ ".............xx..............xxx", +/*18*/ ".............xx..............xxx", +/*19*/ ".............xx..............xxx", +/*20*/ "................................", +/*21*/ ".............xx..............xxx", +/*22*/ ".............xx..............xxx", +/*23*/ ".............xx..............xxx", + +/*24*/ "................................", +/*25*/ ".............xx..............xxx", +/*26*/ ".............xx..............xxx", +/*27*/ ".............xx..............xxx", +/*28*/ "..xx..xx..xx..xx................", +/*29*/ ".xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx", +/*30*/ ".xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx", +/*31*/ ".xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx" +}; + +#define TEST_PRINT(i1, i2) \ + (std::cout << i1 << ',' << i2 << ' ' \ + << test_multiplication_result[i1][i2] \ + << std::endl); + + +#define TEST_IMPL(v1, v2, result) \ + rval &= test_multiply_auto( \ + v1, \ + v2, \ + BOOST_PP_STRINGIZE(v1), \ + BOOST_PP_STRINGIZE(v2), \ + result \ + ); +/**/ + +#define TESTX(value_index1, value_index2) \ + TEST_PRINT(value_index1, value_index2); \ + TEST_IMPL( \ + BOOST_PP_ARRAY_ELEM(value_index1, VALUES), \ + BOOST_PP_ARRAY_ELEM(value_index2, VALUES), \ + test_multiplication_result[value_index1][value_index2] \ + ) +/**/ + +int main(int argc, char * argv[]){ + // sanity check on test matrix - should be symetrical + for(int i = 0; i < VALUE_ARRAY_SIZE; ++i) + for(int j = i + 1; j < VALUE_ARRAY_SIZE; ++j) + if(test_multiplication_result[i][j] != test_multiplication_result[j][i]){ + std::cout << i << ',' << j << std::endl; + return 1; + } + bool rval = true; + TEST_EACH_VALUE_PAIR + return ! rval ; +} diff --git a/test/test_subtract_auto.cpp b/test/test_subtract_auto.cpp new file mode 100644 index 0000000..d9f0062 --- /dev/null +++ b/test/test_subtract_auto.cpp @@ -0,0 +1,261 @@ +// Copyright (c) 2012 Robert Ramey +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include + +#include "../include/safe_integer.hpp" +#include "../include/automatic.hpp" + +template +using safe_t = boost::numeric::safe< + T, + boost::numeric::automatic +>; + +template +bool test_subtract_auto( + T1 v1, + T2 v2, + const char *av1, + const char *av2, + char expected_result +){ + auto unsafe_result = v1 + v2; + { + std::cout << "testing safe<" << av1 << "> - " << av2 << " -> "; + static_assert(boost::numeric::is_safe >::value, "safe_t not safe!"); + + safe_t t1 = v1; + + using result_type = decltype(t1 - v2); + result_type result; + + static_assert( + boost::numeric::is_safe::value, + "Expression failed to return safe type" + ); + + try{ + result = t1 - v2; + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == 'x'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** failed to detect error in subtraction " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + t1 - v2; + } + catch(std::exception){} + assert(result != unsafe_result); + return false; + } + } + catch(std::exception){ + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == '.'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** erroneously detected error in subtraction " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + t1 - v2; + } + catch(std::exception){} + assert(result == unsafe_result); + return false; + } + } + } + { + std::cout << "testing " << av1 << " - " << "safe<"<< av2 << "> -> "; + static_assert(boost::numeric::is_safe >::value, "safe_t not safe!"); + + safe_t t2 = v2; + + using result_type = decltype(v1 - t2); + result_type result; + + static_assert( + boost::numeric::is_safe::value, + "Expression failed to return safe type" + ); + + try{ + result = v1 - t2; + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == 'x'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** failed to detect error in subtraction " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + v1 - t2; + } + catch(std::exception){} + assert(result != unsafe_result); + return false; + } + } + catch(std::exception){ + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == '.'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** erroneously detected error in subtraction " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + v1 - t2; + } + catch(std::exception){} + assert(result == unsafe_result); + return false; + } + } + } + { + std::cout << "testing safe<" << av1 << "> - safe<" << av2 << "> -> "; + safe_t t1 = v1; + safe_t t2 = v2; + + using result_type = decltype(t1 - t2); + result_type result; + + static_assert( + boost::numeric::is_safe::value, + "Expression failed to return safe type" + ); + + try{ + result = t1 - t2; + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == 'x'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** failed to detect error in subtraction " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + t1 - t2; + } + catch(std::exception){} + assert(result != unsafe_result); + return false; + } + } + catch(std::exception){ + std::cout << std::hex << result << "(" << std::dec << result << ")" + << std::endl; + if(expected_result == '.'){ + const std::type_info & ti = typeid(result); + int status; + std::cout + << "*** erroneously detected error in subtraction " + << abi::__cxa_demangle(ti.name(),0,0,&status) << '\n' + << std::endl; + try{ + t1 - t2; + } + catch(std::exception){} + assert(result == unsafe_result); + return false; + } + } + } + return true; // correct result +} + +#include "test.hpp" +#include "test_values.hpp" + +// note: same test matrix as used in test_checked. Here we test all combinations +// safe and unsafe integers. in test_checked we test all combinations of +// integer primitives + +const char *test_subtraction_result[VALUE_ARRAY_SIZE] = { +// 0 0 0 0 +// 01234567012345670123456701234567 +// 01234567890123456789012345678901 +/* 0*/ "..............x..............xxx", +/* 1*/ "..............x..............xxx", +/* 2*/ ".............x..............xxxx", +/* 3*/ "............................xxxx", +/* 4*/ "..............x..............xxx", +/* 5*/ "..............x..............xxx", +/* 6*/ ".............x..............xxxx", +/* 7*/ "............................xxxx", + +/* 8*/ "..............x..............xxx", +/* 9*/ "..............x..............xxx", +/*10*/ ".............x..............xxxx", +/*11*/ "............................xxxx", +/*12*/ "..............x..............xxx", +/*13*/ "..xx..xx..xx..xx..............xx", +/*14*/ "xx..xx..xx..xx..xxxxxxxxxxxxxxxx", +/*15*/ "............................xxxx", + +// 0 0 0 0 +// 01234567012345670123456701234567 +// 01234567890123456789012345678901 +/*16*/ "..............x..xxx.xxx.xxx.xxx", +/*17*/ "..............x...xx.xxx.xxx.xxx", +/*18*/ "..............x....x.xxx.xxx.xxx", +/*19*/ "..............x......xxx.xxx.xxx", +/*20*/ "..............x..xxx.xxx.xxx.xxx", +/*21*/ "..............x.......xx.xxx.xxx", +/*22*/ "..............x........x.xxx.xxx", +/*23*/ "..............x..........xxx.xxx", + +/*24*/ "..............x..xxx.xxx.xxx.xxx", +/*25*/ "..............x...........xx.xxx", +/*26*/ "..............x............x.xxx", +/*27*/ "..............x..............xxx", +/*28*/ ".xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx", +/*29*/ "..xx..xx..xx..xx..............xx", +/*30*/ "..xx..xx..xx..xx...............x", +/*31*/ "..xx..xx..xx..xx................" +}; + +#define TEST_IMPL(v1, v2, result) \ + rval &= test_subtract_auto( \ + v1, \ + v2, \ + BOOST_PP_STRINGIZE(v1), \ + BOOST_PP_STRINGIZE(v2), \ + result \ + ); +/**/ + +#define TESTX(value_index1, value_index2) \ + (std::cout << value_index1 << ',' << value_index2 << std::endl); \ + TEST_IMPL( \ + BOOST_PP_ARRAY_ELEM(value_index1, VALUES), \ + BOOST_PP_ARRAY_ELEM(value_index2, VALUES), \ + test_subtraction_result[value_index1][value_index2] \ + ) +/**/ + +int main(int argc, char * argv[]){ + bool rval = true; + TEST_EACH_VALUE_PAIR + return ! rval ; +} diff --git a/test/test_z.cpp b/test/test_z.cpp index 4b05e38..2a2ac3f 100644 --- a/test/test_z.cpp +++ b/test/test_z.cpp @@ -14,7 +14,7 @@ int main(){ void >::type result_type; - print p_rt; + //print p_rt; return 0; }