diff --git a/CMake/CMakeLists.txt b/CMake/CMakeLists.txt
index 4c05aa3..c4c1b22 100644
--- a/CMake/CMakeLists.txt
+++ b/CMake/CMakeLists.txt
@@ -115,12 +115,25 @@ link_directories("${Boost_LIBRARY_DIRS}")
###########################
###########################
-# testing
+# testing and submitting test results
-enable_testing()
+include (CTest)
+
+# the include above includes enable_testing() so the following line isn't
+# necessary
+# enable_testing()
+
+message(STATUS "test_cast")
+add_executable( test_cast
+ ../test/test_cast.hpp
+ ../test/test_cast.cpp
+)
+target_link_libraries( test_cast ${Boost_LIBRARIES} )
+add_test(NAME test_cast COMMAND test_cast)
message(STATUS "test_add")
- add_executable( test_add
+add_executable( test_add
+ ../test/test_add.hpp
../test/test_add.cpp
../test/test_add1.cpp
../test/test_add2.cpp
@@ -128,10 +141,10 @@ message(STATUS "test_add")
)
target_link_libraries( test_add ${Boost_LIBRARIES} )
add_test(NAME test_add COMMAND test_add)
-add_custom_target(test_add_header SOURCES ../test/test_add.hpp)
message(STATUS "test_subtract")
-add_executable( test_subtract
+add_executable( test_subtract
+ ../test/test_subtract.hpp
../test/test_subtract.cpp
../test/test_subtract1.cpp
../test/test_subtract2.cpp
@@ -139,10 +152,10 @@ add_executable( test_subtract
)
target_link_libraries( test_subtract ${Boost_LIBRARIES} )
add_test(NAME test_subtract COMMAND test_subtract)
-add_custom_target(test_subtract_header SOURCES ../test/test_subtract.hpp)
message(STATUS "test_multiply")
-add_executable( test_multiply
+add_executable( test_multiply
+ ../test/test_multiply.hpp
../test/test_multiply.cpp
../test/test_multiply1.cpp
../test/test_multiply2.cpp
@@ -150,10 +163,10 @@ add_executable( test_multiply
)
target_link_libraries( test_multiply ${Boost_LIBRARIES} )
add_test(NAME test_multiply COMMAND test_multiply)
-add_custom_target(test_multiply_header SOURCES ../test/test_multiply.hpp)
message(STATUS "test_divide")
-add_executable( test_divide
+add_executable( test_divide
+ ../test/test_divide.hpp
../test/test_divide.cpp
../test/test_divide1.cpp
../test/test_divide2.cpp
@@ -161,10 +174,10 @@ add_executable( test_divide
)
target_link_libraries( test_divide ${Boost_LIBRARIES} )
add_test(NAME test_divide COMMAND test_divide)
-add_custom_target(test_divide_header SOURCES ../test/test_divide.hpp)
message(STATUS "test_modulus")
add_executable( test_modulus
+ ../test/test_modulus.hpp
../test/test_modulus.cpp
../test/test_modulus1.cpp
../test/test_modulus2.cpp
@@ -172,7 +185,6 @@ add_executable( test_modulus
)
target_link_libraries( test_modulus ${Boost_LIBRARIES} )
add_test(NAME test_modulus COMMAND test_modulus)
-add_custom_target(test_modulus_header SOURCES ../test/test_modulus.hpp)
message(STATUS "test_compare")
add_executable( test_compare ../test/test_compare.cpp)
diff --git a/doc/boostbook/numeric_concept.xml b/doc/boostbook/numeric_concept.xml
index f82028d..6644b93 100644
--- a/doc/boostbook/numeric_concept.xml
+++ b/doc/boostbook/numeric_concept.xml
@@ -228,7 +228,7 @@
V
- Invert sign
+ subtract u from t
@@ -236,7 +236,7 @@
V
- unary plus - a no op
+ add u to t
diff --git a/doc/boostbook/safe_numerics.xml b/doc/boostbook/safe_numerics.xml
index aae6196..ad36419 100644
--- a/doc/boostbook/safe_numerics.xml
+++ b/doc/boostbook/safe_numerics.xml
@@ -65,8 +65,8 @@
- I was a lot of code in one header - 6400 lines. Very unwieldy to
- understand and modify.
+ It was a lot of code in one header - 6400 lines. Very unwieldy
+ to understand and modify.
@@ -75,12 +75,12 @@
- I didn't use Boost
+ It didn't use Boost
conventions for naming.
- I required porting to different compilers.
+ It required porting to different compilers.
@@ -150,7 +150,7 @@
Why does a binary operation on two
- safe<int> values not necessarily return another
+ safe<int> values not return another
safe type ?
@@ -159,7 +159,7 @@
- it was hard to implement.
+ it was too hard to implement.
diff --git a/doc/boostbook/safe_signed_range.xml b/doc/boostbook/safe_signed_range.xml
index 4a01ea0..a69baaa 100644
--- a/doc/boostbook/safe_signed_range.xml
+++ b/doc/boostbook/safe_signed_range.xml
@@ -66,6 +66,12 @@
Model of
Numeric
+
+ The usage of this type in an arithmetic expression will result in
+ another type fulfilling the Numeric concept. This will be the
+ smallest signed integer type of sufficient size to hold the result of the
+ operation.
@@ -85,6 +91,12 @@ void f(){
i = 0; // error
i = 9; // ok
i *= 9; // throws overflow exception
+
+ std::int8_t j = 4;
+ auto k = i + j;
+ // since i can vary between 7 and 24 and j can vary between 0 and 255
+ // the smallest unsigned integer which can hold the result std::int16_t
+ // j will be of type std::int16_t
}
@@ -92,5 +104,7 @@ void f(){
See Also
std::out_of_range
+
+ safe_unsigned_range
diff --git a/doc/boostbook/safe_unsigned_range.xml b/doc/boostbook/safe_unsigned_range.xml
index 2e12ad0..6221bb7 100644
--- a/doc/boostbook/safe_unsigned_range.xml
+++ b/doc/boostbook/safe_unsigned_range.xml
@@ -9,7 +9,7 @@
This type holds a integer in the range [MIN, MAX]. It will throw a
std::out_of_range exception for any operation which would
- result in assigning an integer value outside of this range.
+ result in assigning an integer value outside of this range.
@@ -66,6 +66,12 @@
Model of
Numeric
+
+ The usage of this type in an arithmetic expression with another
+ unsigned type will result in another unsigned type fulfilling the Numeric concept. This will be the
+ smallest unsigned integer type of sufficient size to hold the result of
+ the operation.
@@ -86,6 +92,13 @@ void f(){
i = 9; // ok
i *= 9; // throws out_of_range exception
i = -1; // throws out_of_range exception
+
+ std::uint8_t j = 4;
+ auto k = i + j;
+ // since i can vary between 7 and 24 and j can vary between 0 and 255
+ // the smallest unsigned integer which can hold the result std::uint16_t
+ // j will be of type std::uint16_t
+
}
@@ -93,5 +106,7 @@ void f(){
See Also
std::out_of_range
+
+ safe_signed_range
diff --git a/include/numeric.hpp b/include/numeric.hpp
index 0337f7f..970f41f 100644
--- a/include/numeric.hpp
+++ b/include/numeric.hpp
@@ -187,6 +187,7 @@ struct max_bits : public
>::type
{};
+
// return # of bit in the result of an addition of two types
template
struct addition_result_bits : public
diff --git a/include/safe_cast.hpp b/include/safe_cast.hpp
index 917ac3d..d71c14e 100644
--- a/include/safe_cast.hpp
+++ b/include/safe_cast.hpp
@@ -16,42 +16,57 @@
#include
#include
#include
+#include
+#include
+
#include "numeric.hpp"
#include "overflow.hpp"
+#include "safe_compare.hpp"
namespace boost {
namespace numeric {
namespace detail {
- // simple case when signess are the same.
+ // default signature
template
- struct safe_cast {
+ struct safe_cast;
+
+ // T signed <- U signed
+ template<>
+ struct safe_cast {
template
inline static T invoke(const U & u){
- if(u > std::numeric_limits::max())
+ if(safe_compare::greater_than(u, std::numeric_limits::max()))
overflow("safe range overflow");
- if(u < std::numeric_limits::min())
+
+ if(safe_compare::less_than(u, std::numeric_limits::min()))
overflow("safe range underflow");
return static_cast(u);
}
};
+ // T unsigned <- U unsigned
+ template<>
+ struct safe_cast {
+ template
+ inline static T invoke(const U & u){
+ if(safe_compare::greater_than(u, std::numeric_limits::max()))
+ overflow("safe range overflow");
+ if(safe_compare::less_than(u, std::numeric_limits::min()))
+ overflow("safe range underflow");
+ return static_cast(u);
+ }
+
+ };
+
+
// T signed <- U unsigned
template<>
struct safe_cast {
template
struct sbits : public
boost::mpl::min<
- typename boost::mpl::integral_c<
- int,
- std::numeric_limits::digits
- >,
- typename boost::mpl::plus<
- typename boost::mpl::integral_c<
- int,
- std::numeric_limits::digits
- >,
- typename boost::mpl::integral_c
- >
+ boost::numeric::bits,
+ boost::numeric::bits
>::type
{};
template
diff --git a/include/safe_integer.hpp b/include/safe_integer.hpp
index 79d1a38..806fa6a 100644
--- a/include/safe_integer.hpp
+++ b/include/safe_integer.hpp
@@ -12,30 +12,34 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#include
-#include
-#include "safe_range.hpp"
-
#include // BOOST_NOEXCEPT
+#include
+#include
+#include
+
+#include "safe_range.hpp"
+#include "numeric.hpp"
namespace boost {
namespace numeric {
namespace detail{
- template
- struct safe_integer_base {
- typedef typename boost::mpl::if_c<
- std::numeric_limits::is_signed,
- safe_signed_range<
- boost::integer_traits::const_min,
- boost::integer_traits::const_max
- >,
- safe_unsigned_range<
- boost::integer_traits::const_min,
- boost::integer_traits::const_max
- >
- >::type type;
- };
+
+template
+struct safe_integer_base {
+ typedef typename boost::mpl::if_<
+ boost::numeric::is_signed,
+ boost::numeric::safe_signed_range<
+ static_cast(boost::integer_traits::const_min),
+ static_cast(boost::integer_traits::const_max)
+ >,
+ boost::numeric::safe_unsigned_range<
+ static_cast(boost::integer_traits::const_min),
+ static_cast(boost::integer_traits::const_max)
+ >
+ >::type type;
+};
+
} // detail
template
@@ -79,5 +83,4 @@ public:
} // std
-
#endif // BOOST_NUMERIC_SAFE_INTEGER_HPP
diff --git a/include/safe_range.hpp b/include/safe_range.hpp
index 92040e0..31eed3a 100644
--- a/include/safe_range.hpp
+++ b/include/safe_range.hpp
@@ -12,7 +12,6 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-//#include
#include "numeric.hpp"
#include "safe_compare.hpp"
#include "safe_cast.hpp"
@@ -25,17 +24,25 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
#include
#include
+#include
+#include
#include
#include
#include
+// we could have used decltype and auto for C++11 but we've decided
+// to use boost/typeof to be compatible with older compilers
+#include
+
namespace boost {
namespace numeric {
@@ -47,12 +54,11 @@ namespace detail {
template<>
struct check_addition_overflow {
template
- static typename addition_result_type::type
- add(const T & t, const U & u){
- typedef typename addition_result_type::type result_type;
- result_type tmp;
- tmp = static_cast(t) + static_cast(u);
- if(safe_compare::less_than(tmp, t))
+ static BOOST_TYPEOF_TPL(T() + U())
+ add(const T & t, const U & u) {
+ BOOST_AUTO_TPL(tmp, t + u);
+ if(safe_compare::less_than(tmp, t)
+ || safe_compare::less_than(tmp, u))
overflow("safe range addition out of range");
return tmp;
}
@@ -61,38 +67,84 @@ namespace detail {
template<>
struct check_addition_overflow {
template
- static typename addition_result_type::type
+ static BOOST_TYPEOF_TPL(T() + U())
add(const T & t, const U & u){
- if(u > 0)
- return check_addition_overflow::add(t, u);
+ typedef BOOST_TYPEOF_TPL(T() + U()) result_type;
+ if(boost::numeric::is_unsigned::value){
+ if(u < 0)
+ overflow("safe range addition out of range");
+ else
+ //if(u > 0)
+ return check_addition_overflow::add(
+ t,
+ static_cast::type>(u)
+ );
+ }
+ else{
+ if(u > 0){
+ auto tmp = t + u;
+ if(tmp <= 0)
+ overflow("safe range addition out of range");
+ return t + u;
+ }
+ }
return t + u;
+ /*
+ if(u > 0)
+ return check_addition_overflow::add(
+ t,
+ static_cast::type>(u)
+ );
+ BOOST_AUTO_TPL(tmp, t + u);
+ return tmp;
+ */
}
};
// T signed, U unsigned
template<>
struct check_addition_overflow {
template
- static typename addition_result_type::type
+ static BOOST_TYPEOF_TPL(T() + U())
add(const T & t, const U & u){
- if(t > 0)
- return check_addition_overflow::add(t, u);
- return t + u;
+ typedef BOOST_TYPEOF_TPL(T() + U()) result_type;
+ if(boost::numeric::is_unsigned::value){
+ if(t < 0)
+ overflow("safe range addition out of range");
+ else
+ //if(t > 0)
+ return check_addition_overflow::add(
+ static_cast::type>(t),
+ u
+ );
+ }
+ else{
+ if(t > 0){
+ auto tmp = t + u;
+ if(tmp < 0)
+ overflow("safe range addition out of range");
+ }
+ }
+
+ BOOST_AUTO_TPL(tmp, t + u);
+ return tmp;
}
};
// both arguments signed
template<>
struct check_addition_overflow {
template
- static typename addition_result_type::type
+ static BOOST_TYPEOF_TPL(T() + U())
add(const T & t, const U & u){
- if(t > 0)
- check_addition_overflow::add(t, u);
- if(u < 0){
- typedef typename addition_result_type::type result_type;
- result_type tmp;
- tmp = static_cast(t) + static_cast(u);
- if(safe_compare::greater_than(tmp, t))
- overflow("safe range addition out of range");
+ if(t > 0 && u > 0){
+ auto tmp = t + u;
+ if(tmp < 0)
+ overflow("safe range addition out of range");
+ return tmp;
+ }
+ if(t < 0 && u < 0){
+ auto tmp = t + u;
+ if(tmp >= 0)
+ overflow("safe range addition out of range");
return tmp;
}
return t + u;
@@ -309,29 +361,28 @@ public:
/////////////////////////////////////////////////////////////////
// addition
// case 1 - no overflow possible
+#if 0
template
typename boost::enable_if<
- typename boost::mpl::less_equal<
- addition_result_bits,
- // note presumption that size(boost::uintmax) == size(boost::intmax)
- bits
+ typename boost::mpl::greater<
+ typename boost::mpl::sizeof_< BOOST_TYPEOF_TPL(U() + Stored()) >,
+ typename boost::mpl::sizeof_
>,
- typename addition_result_type::type
+ BOOST_TYPEOF_TPL(U() + Stored())
>::type
inline operator+(const U & rhs) const {
- typedef typename addition_result_type::type result_type;
- return static_cast(m_t) + static_cast(rhs);
+ return m_t + rhs;
}
// case 2 - overflow possible - must be checked at run time
template
typename boost::enable_if<
typename boost::mpl::greater<
- addition_result_bits,
+ bits,
// note presumption that size(boost::uintmax) == size(boost::intmax)
bits
>,
- typename addition_result_type::type
+ BOOST_TYPEOF_TPL(U() + Stored())
>::type
inline operator+(const U & rhs) const {
return detail::check_addition_overflow<
@@ -339,6 +390,15 @@ public:
boost::numeric::is_signed::value
>::add(m_t, rhs);
}
+#endif
+ template
+ BOOST_TYPEOF_TPL(U() + Stored())
+ inline operator+(const U & rhs) const {
+ return detail::check_addition_overflow<
+ boost::numeric::is_signed::value,
+ boost::numeric::is_signed::value
+ >::add(m_t, rhs);
+ }
/////////////////////////////////////////////////////////////////
// subtraction
template
@@ -754,9 +814,7 @@ public:
template
stored_type validate(const T & t) const {
const boost::uintmax_t tx = t;
- if(MAX < tx
- || MIN > tx
- )
+ if(MAX < tx)
overflow("safe range out of range");
return static_cast(t);
}
diff --git a/test/test.cpp b/test/test.cpp
index 3e8bb47..9448b6b 100644
--- a/test/test.cpp
+++ b/test/test.cpp
@@ -8,6 +8,7 @@
#include // EXIT_SUCCESS
#include
+
#include "../include/safe_range.hpp"
#include "../include/safe_integer.hpp"
@@ -36,7 +37,6 @@ bool test1(){
int
>::type
>::type t3;
-
zi = x + yi;
bool success = false;
diff --git a/test/test.hpp b/test/test.hpp
index b5f4c4a..56d4c43 100644
--- a/test/test.hpp
+++ b/test/test.hpp
@@ -1,116 +1,40 @@
-#include
-#include
-#include
+#ifndef SAFE_NUMERIC_TEST_HPP
+#define SAFE_NUMERIC_TEST_HPP
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+// 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
-#include
-#include
-#include
-#include
-#include "../include/safe_integer.hpp"
-#include "../include/safe_cast.hpp"
+#define VALUE_ARRAY_SIZE BOOST_PP_ARRAY_SIZE(VALUES)
-#define VALUES (20, ( \
- 0x10, \
- 0x20, \
- 0x7f, \
- 0x80, \
- 0xff, \
- 0x1000, \
- 0x2000, \
- 0x7fff, \
- 0x8000, \
- 0xffff, \
- 0x10000000, \
- 0x20000000, \
- 0x7fffffff, \
- 0x80000000, \
- 0xffffffff, \
- 0x100000000000, \
- 0x200000000000, \
- 0x7fffffffffff, \
- 0x80000000ffff, \
- 0xffffffffffff \
-))
+#define TEST_EACH_VALUE2(z, value_index2, value_index1) \
+ TESTX(value_index1, value_index2)
/**/
-inline unsigned int
-count_bits(boost::uintmax_t t){
- unsigned int i = 0;
- while(t != 0){
- ++i;
- t >>= 1;
- }
- return i;
-}
-
-inline unsigned int
-count_bits(boost::intmax_t t){
- if(t < 0)
- t = -t;
- unsigned int i = 0;
- while(t != 0){
- ++i;
- t >>= 1;
- }
- return i;
-}
-
-#define EACH_VALUE2(z, l, list) \
- BOOST_PP_EXPAND( \
- TESTX \
- BOOST_PP_LIST_TO_TUPLE( \
- BOOST_PP_LIST_CONS( \
- BOOST_PP_ARRAY_ELEM(l, VALUES), \
- list \
- ) \
- ) \
- ) \
+#define TEST_EACH_VALUE1(z, value_index1, nothing) \
+ BOOST_PP_REPEAT( \
+ BOOST_PP_ARRAY_SIZE(VALUES), \
+ TEST_EACH_VALUE2, \
+ value_index1 \
+ )
/**/
-#define EACH_VALUE1(z, k, types) \
- BOOST_PP_REPEAT( \
- BOOST_PP_ARRAY_SIZE(VALUES), \
- EACH_VALUE2, \
- BOOST_PP_LIST_CONS( \
- BOOST_PP_ARRAY_ELEM(k, VALUES), \
- types \
- ) \
- ) \
-/**/
-
-#define EACH_TYPE2(i, j) \
- BOOST_PP_REPEAT( \
- BOOST_PP_ARRAY_SIZE(VALUES), \
- EACH_VALUE1, \
- (i, (j, BOOST_PP_NIL)) \
- ) \
-/**/
-
-#define EACH_TYPE1(i) \
- EACH_TYPE2(i, boost::int8_t) \
- EACH_TYPE2(i, boost::uint8_t) \
- EACH_TYPE2(i, boost::int16_t) \
- EACH_TYPE2(i, boost::uint16_t) \
- EACH_TYPE2(i, boost::int32_t) \
- EACH_TYPE2(i, boost::uint32_t) \
- EACH_TYPE2(i, boost::int64_t) \
- EACH_TYPE2(i, boost::uint64_t) \
-/**/
-
-#define TEST \
- EACH_TYPE1(boost::int8_t) \
- EACH_TYPE1(boost::uint8_t) \
- EACH_TYPE1(boost::int16_t) \
- EACH_TYPE1(boost::uint16_t) \
- EACH_TYPE1(boost::int32_t) \
- EACH_TYPE1(boost::uint32_t) \
- EACH_TYPE1(boost::int64_t) \
- EACH_TYPE1(boost::uint64_t) \
+#define TEST_EACH_VALUE_PAIR \
+ BOOST_PP_REPEAT( \
+ BOOST_PP_ARRAY_SIZE(VALUES), \
+ TEST_EACH_VALUE1, \
+ 0 \
+ )
/**/
+#endif
diff --git a/test/test_add.cpp b/test/test_add.cpp
index d023267..146a3bf 100644
--- a/test/test_add.cpp
+++ b/test/test_add.cpp
@@ -4,14 +4,139 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-bool test_add1();
-bool test_add2();
-bool test_add3();
+#include
+#include
-int main(int argc, char * argv[]){
- bool result = true;
- result = test_add1();
- result &= test_add2();
- result &= test_add3();
- return ! result ;
+// we could have used decltype and auto for C++11 but we've decided
+// to use boost/typeof to be compatible with older compilers
+#include
+
+#include "../include/safe_integer.hpp"
+
+template
+bool test_add(
+ T1 v1,
+ T2 v2,
+ const char *av1,
+ const char *av2,
+ char expected_result
+){
+ std::cout
+ << "testing "
+ << av1 << " + " << av2
+ << std::endl;
+
+ boost::numeric::safe t1 = v1;
+ BOOST_TYPEOF_TPL(T1() +T2()) result;
+
+ try{
+ result = t1 + v2;
+
+ if(expected_result == 'x'){
+ std::cout
+ << "failed to detect error in addition "
+ << std::hex << result << "(" << std::dec << result << ")"
+ << " ! = "<< av1 << " + " << av2
+ << std::endl;
+ try{
+ result = t1 + v2;
+ }
+ catch(...){}
+ return false;
+ }
+ }
+ catch(std::range_error){
+ if(expected_result == '.'){
+ std::cout
+ << "erroneously detected error in addition "
+ << std::hex << result << "(" << std::dec << result << ")"
+ << " == "<< av1 << " + " << av2
+ << std::endl;
+ try{
+ result = t1 + v2;
+ }
+ catch(...){}
+ return false;
+ }
+ }
+
+ return true; // correct result
+}
+
+#include "test.hpp"
+#include "test_values.hpp"
+
+const char *test_addition_result[VALUE_ARRAY_SIZE] = {
+// 0 0 0 0
+// 01234567012345670123456701234567
+// 01234567890123456789012345678901
+/* 0*/ ".........x...x.............x...x",
+/* 1*/ ".........x...x.............x...x",
+/* 2*/ "..........x...x.........xxxxxxxx",
+/* 3*/ "..........x...x.........xxxxxxxx",
+/* 4*/ ".........x...x.............x...x",
+/* 5*/ ".........x...x.............x...x",
+/* 6*/ "..........x...x.........xxxxxxxx",
+/* 7*/ "..........x...x.........xxxxxxxx",
+
+/* 8*/ ".........x...x.............x...x",
+/* 9*/ "xx..xx..xx...x..xxxxxxxx...x...x",
+/*10*/ "..xx..xx..xx..x.........xxxxxxxx",
+/*11*/ "..........x...x.........xxxxxxxx",
+/*12*/ ".............x.................x",
+/*13*/ "xx..xx..xx..xx..xxxxxxxxxxxx...x",
+/*14*/ "..xx..xx..xx..xx............xxxx",
+/*15*/ "..............x.............xxxx",
+
+// 0 0 0 0
+// 01234567012345670123456701234567
+// 01234567890123456789012345678901
+/*16*/ ".........x...x.............x...x",
+/*17*/ ".........x...x.............x...x",
+/*18*/ ".........x...x.............x...x",
+/*19*/ ".........x...x.............x...x",
+/*20*/ ".........x...x.............x...x",
+/*21*/ ".........x...x.............x...x",
+/*22*/ ".........x...x.............x...x",
+/*23*/ ".........x...x.............x...x",
+
+/*24*/ "..xx..xx..xx.x.............x...x",
+/*25*/ "..xx..xx..xx.x.............x...x",
+/*26*/ "..xx..xx..xx.x............xx...x",
+/*27*/ "xxxxxxxxxxxx.x..xxxxxxxxxxxx...x",
+/*28*/ "..xx..xx..xx..xx...............x",
+/*29*/ "..xx..xx..xx..xx...............x",
+/*30*/ "..xx..xx..xx..xx..............xx",
+/*31*/ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+};
+
+#define TEST_IMPL(v1, v2, result) \
+ rval &= test_add( \
+ v1, \
+ v2, \
+ BOOST_PP_STRINGIZE(v1), \
+ BOOST_PP_STRINGIZE(v2), \
+ result \
+ );
+/**/
+
+#define TESTX(value_index1, value_index2) \
+ (std::cout << value_index1 << ',' << value_index2 << ','); \
+ TEST_IMPL( \
+ BOOST_PP_ARRAY_ELEM(value_index1, VALUES), \
+ BOOST_PP_ARRAY_ELEM(value_index2, VALUES), \
+ test_addition_result[value_index1][value_index2] \
+ )
+/**/
+
+#define COUNT sizeof(test_addition_result)
+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)
+ assert(test_addition_result[i][j] == test_addition_result[j][i]);
+
+ bool rval = true;
+ TEST_EACH_VALUE_PAIR
+ return ! rval ;
}
diff --git a/test/test_add.hpp b/test/test_add.hpp
index a48ade2..baba6b1 100644
--- a/test/test_add.hpp
+++ b/test/test_add.hpp
@@ -13,166 +13,52 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include
-#include
-#include
-#include
+#include // max
+#include "../include/numeric.hpp"
#include "../include/safe_integer.hpp"
-#include "../include/safe_cast.hpp"
-#include "../include/safe_compare.hpp"
#include "test.hpp"
-template
+template
bool test_add(
- V v1,
- V v2,
- const char *at1,
- const char *at2,
+ T1 v1,
+ T2 v2,
const char *av1,
- const char *av2
+ const char *av2,
+ char expected_result
){
- bool success;
+ std::cout
+ << "testing "
+ << av1 << " + " << av2
+ << std::endl;
- T1 t1;
- try{
- t1 = boost::numeric::safe_cast(v1);
- success = true;
- }
- catch(std::range_error){
- success = false;
- }
- if(success){
- if(boost::numeric::safe_compare::greater_than(
- v1,
- std::numeric_limits::max()
- )
- || boost::numeric::safe_compare::less_than(
- v1,
- std::numeric_limits::min()
- )
- ){
- std::cout
- << "constructed invalid value "
- << at1 << ' ' << av1
- << std::endl;
- return false;
- }
- }
- else{
- if(! boost::numeric::safe_compare::greater_than(
- v1,
- std::numeric_limits::max()
- )
- && ! boost::numeric::safe_compare::less_than(
- v1,
- std::numeric_limits::min()
- )
- ){
- std::cout
- << "failed to construct valid value "
- << at1 << ' ' << av1
- << std::endl;
- return false;
- }
- return true;
- }
+ typename boost::numeric::addition_result_type::type result;
- T2 t2;
try{
- t2 = boost::numeric::safe_cast(v2);
- success = true;
- }
- catch(std::range_error){
- success = false;
- }
- if(success){
- if(boost::numeric::safe_compare::greater_than(
- v2,
- std::numeric_limits::max()
- )
- || boost::numeric::safe_compare::less_than(
- v2,
- std::numeric_limits::min()
- )){
- std::cout
- << "constructed invalid value "
- << at2 << ' ' << av2
- << std::endl;
- return false;
- }
- }
- else{
- if(!boost::numeric::safe_compare::greater_than(
- v2,
- std::numeric_limits::max()
- )
- && !boost::numeric::safe_compare::less_than(
- v2,
- std::numeric_limits::min()
- )){
- std::cout
- << "failed to construct valid value "
- << at2 << ' ' << av2
- << std::endl;
- return false;
- }
- return true;
- }
+ boost::numeric::safe t1 = v1;
+ result = t1 + v2;
- V result;
- try{
- result = t1 + t2;
- success = true;
- }
- catch(std::range_error){
- success = false;
- }
- if(success){
- if(result != v1 + v2){
+ if(expected_result == 'x'){
std::cout
<< "failed to detect error in addition "
- << at1 << ' ' << at2 << ' ' << av1 << ' ' << av2
+ << av1 << " + " << av2
<< std::endl;
+ result = t1 + v2;
return false;
}
}
- else{
- if(boost::numeric::safe_compare::greater_than_equal(
- boost::numeric::bits::value,
- std::max(count_bits(v1),count_bits(v2))
- )){
+ catch(std::range_error){
+ if(expected_result != 'x'){
std::cout
<< "erroneously detected error in addition "
- << at1 << ' ' << at2 << ' ' << av1 << ' ' << av2
+ << av1 << " + " << av2
<< std::endl;
return false;
}
}
+
return true; // correct result
}
-template
-struct add_result {
- typedef typename boost::mpl::if_<
- boost::mpl::or_<
- boost::numeric::is_signed,
- boost::numeric::is_signed
- >,
- boost::intmax_t,
- boost::uintmax_t
- >::type type;
-};
-
-#define TEST_IMPL(a, b, c, d) \
- rval &= test_add( \
- (static_cast::type>(a)), \
- (static_cast::type>(b)), \
- BOOST_PP_STRINGIZE(d), \
- BOOST_PP_STRINGIZE(c), \
- BOOST_PP_STRINGIZE(b), \
- BOOST_PP_STRINGIZE(a) \
- ); \
-/**/
-
#endif // TEST_ADD_HPP
diff --git a/test/test_add1.cpp b/test/test_add1.cpp
deleted file mode 100644
index c670746..0000000
--- a/test/test_add1.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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 "test_add.hpp"
-
-#define TESTX(a, b, c, d) \
- TEST_IMPL( \
- a, \
- b, \
- boost::numeric::safe, \
- boost::numeric::safe \
- ) \
-/**/
-
-bool test_add1(){
- bool rval = true;
- #pragma message("0")
- EACH_TYPE1(boost::int8_t);
- #pragma message("1")
- EACH_TYPE1(boost::uint8_t);
- #pragma message("2")
- EACH_TYPE1(boost::int16_t);
- #pragma message("3")
- EACH_TYPE1(boost::uint16_t);
- #pragma message("4")
- EACH_TYPE1(boost::int32_t);
- #pragma message("5")
- EACH_TYPE1(boost::uint32_t);
- #pragma message("6")
- EACH_TYPE1(boost::int64_t);
- #pragma message("7")
- EACH_TYPE1(boost::uint64_t);
- return rval;
-}
diff --git a/test/test_add3.cpp b/test/test_add3.cpp
deleted file mode 100644
index 94a9020..0000000
--- a/test/test_add3.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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 "test_add.hpp"
-
-#define TESTX(a, b, c, d) \
- TEST_IMPL( \
- a, \
- b, \
- c, \
- boost::numeric::safe \
- ) \
-/**/
-
-bool test_add3(){
- bool rval = true;
- #pragma message("0")
- EACH_TYPE1(boost::int8_t);
- #if 0
- #pragma message("1")
- EACH_TYPE1(boost::uint8_t);
- #pragma message("2")
- EACH_TYPE1(boost::int16_t);
- #pragma message("3")
- EACH_TYPE1(boost::uint16_t);
- #pragma message("4")
- EACH_TYPE1(boost::int32_t);
- #pragma message("5")
- EACH_TYPE1(boost::uint32_t);
- #pragma message("6")
- EACH_TYPE1(boost::int64_t);
- #pragma message("7")
- EACH_TYPE1(boost::uint64_t);
- #endif
-
- return rval;
-}
-
diff --git a/test/test_cast.cpp b/test/test_cast.cpp
new file mode 100644
index 0000000..e7ebca5
--- /dev/null
+++ b/test/test_cast.cpp
@@ -0,0 +1,82 @@
+// 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
+#include
+#include
+#include
+
+#include
+
+#include "../include/safe_cast.hpp"
+#include "../include/safe_compare.hpp"
+#include "../include/safe_integer.hpp"
+
+#include "test_types.hpp"
+#include "test_values.hpp"
+
+// test conversion to T2 from different literal types
+template
+bool test_cast(V v, const char *t_name, const char *v_name){
+ /* test conversion constructor to T1 */
+ T1 t1;
+ try{
+ t1 = boost::numeric::safe_cast(v);
+ if(! boost::numeric::safe_compare::equal(t1, v)){
+ std::cout
+ << "failed to detect error in construction "
+ << t_name << "<-" << v_name
+ << std::endl;
+ return false;
+ }
+ }
+ catch(std::range_error e){
+ if(boost::numeric::safe_compare::equal(t1, v)){
+ std::cout
+ << "failed to detect error in construction "
+ << t_name << "<-" << v_name
+ << std::endl;
+ return false;
+ }
+ }
+ return true; // passed test
+}
+
+#define TEST_CAST(T1, v) \
+ test_cast( \
+ v, \
+ BOOST_PP_STRINGIZE(T1), \
+ BOOST_PP_STRINGIZE(v) \
+ );
+/**/
+
+#define EACH_VALUE(z, value_index, type_index) \
+ TEST_CAST( \
+ BOOST_PP_ARRAY_ELEM(type_index, TYPES), \
+ BOOST_PP_ARRAY_ELEM(value_index, VALUES) \
+ ) \
+/**/
+
+#define EACH_TYPE1(z, type_index, nothing) \
+ BOOST_PP_REPEAT( \
+ BOOST_PP_ARRAY_SIZE(VALUES), \
+ EACH_VALUE, \
+ type_index \
+ ) \
+/**/
+
+int main(int argc, char *argv[]){
+ BOOST_PP_REPEAT(
+ BOOST_PP_ARRAY_SIZE(TYPES),
+ EACH_TYPE1,
+ nothing
+ )
+ return 0;
+}
diff --git a/test/test_conversion.cpp b/test/test_conversion.cpp
index f74bff4..c197f09 100644
--- a/test/test_conversion.cpp
+++ b/test/test_conversion.cpp
@@ -4,177 +4,77 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
+// test construction conversions
+
#include
+
#include
-#include
#include
#include
#include
-#include
#include
-#include
-
-#include "../include/safe_cast.hpp"
+#include "../include/safe_compare.hpp"
#include "../include/safe_integer.hpp"
-#define TYPES (8, ( \
- boost::int8_t, \
- boost::uint8_t, \
- boost::int16_t, \
- boost::uint16_t, \
- boost::int32_t, \
- boost::uint32_t, \
- boost::int64_t, \
- boost::uint64_t \
-))
+#include "test_types.hpp"
+#include "test_values.hpp"
-#define VALUES (20, ( \
- 0x10, \
- 0x20, \
- 0x7f, \
- 0x80, \
- 0xff, \
- 0x1000, \
- 0x2000, \
- 0x7fff, \
- 0x8000, \
- 0xffff, \
- 0x10000000, \
- 0x20000000, \
- 0x7fffffff, \
- 0x80000000, \
- 0xffffffff, \
- 0x100000000000, \
- 0x200000000000, \
- 0x7fffffffffff, \
- 0x80000000ffff, \
- 0xffffffffffff \
-))
-
-// test conversion
-template
-bool test_conversion(V v, const char *a1, const char *a2, const char *a3){
- bool success;
- boost::numeric::safe t2;
- /* test conversion constructor */
+// test conversion to T2 from different literal types
+template
+bool test_conversion(V v, const char *t_name, const char *v_name){
+ /* test conversion constructor to T1 */
+ boost::numeric::safe t1;
try{
- t2 = v;
- success = true;
- }
- catch(std::range_error e){
- success = false;
- }
- if(success){
- if(t2 > std::numeric_limits::max()
- || t2 < std::numeric_limits::min()){
+ t1 = v;
+ if(! boost::numeric::safe_compare::equal(t1, v)){
std::cout
<< "failed to detect error in construction "
- << a1 << ' ' << a2
+ << t_name << "<-" << v_name
<< std::endl;
return false;
}
}
- else{
- if(v <= std::numeric_limits::max()
- && v >= std::numeric_limits::min()){
- std::cout
- << "erroneasly detected error in construction "
- << a1 << ' ' << a2
- << std::endl;
- return false;
- }
- return true; // correctly detected error
- }
-
- T1 t1;
- try{
- //t1 = t2;
- t1 = boost::numeric::safe_cast(t2);
- success = true;
- }
catch(std::range_error e){
- success = false;
- }
- if(success){
- if(t1 > std::numeric_limits::max()
- || t1 < std::numeric_limits::min()){
- std::cout
- << "failed to detect error in conversion "
- << a1 << ' ' << a2 << ' ' << a3
- << std::endl;
- return false;
- }
- }
- else{
- if(t2 <= std::numeric_limits::max()
- && t2 >= std::numeric_limits::min()){
+ if(boost::numeric::safe_compare::equal(t1, v)){
std::cout
- << "erroneasly detected error in conversion "
- << a1 << ' ' << a2 << ' ' << a3
+ << "failed to detect error in construction "
+ << t_name << "<-" << v_name
<< std::endl;
return false;
}
- return true; // correctly detected error
}
return true; // passed test
}
-template
-struct test_value {
- typedef typename boost::mpl::if_<
- boost::is_signed,
- boost::intmax_t,
- boost::uintmax_t
- >::type type;
-};
-
-#define TEST_CONVERSION(T1, T2, v) \
- test_conversion( \
- static_cast::type>(v), \
- BOOST_PP_STRINGIZE(T1), \
- BOOST_PP_STRINGIZE(T2), \
- BOOST_PP_STRINGIZE(v) \
- );
-
-#define TEST(z, k, ij) \
- TEST_CONVERSION( \
- BOOST_PP_ARRAY_ELEM( \
- BOOST_PP_TUPLE_ELEM(2, 0, ij),\
- TYPES \
- ), \
- BOOST_PP_ARRAY_ELEM( \
- BOOST_PP_TUPLE_ELEM(2, 1, ij),\
- TYPES \
- ), \
- BOOST_PP_ARRAY_ELEM(k, VALUES) \
- )
-
-#define EACH_VALUE(z, j, i) \
- BOOST_PP_REPEAT( \
- BOOST_PP_ARRAY_SIZE(VALUES), \
- TEST, \
- (i, j) \
- ) \
+#define TEST_CONVERSION(T1, v) \
+ test_conversion( \
+ v, \
+ BOOST_PP_STRINGIZE(T1), \
+ BOOST_PP_STRINGIZE(v) \
+ );
/**/
-#define EACH_TYPE1(z, i, x) \
- BOOST_PP_REPEAT( \
- BOOST_PP_ARRAY_SIZE(TYPES), \
- EACH_VALUE, \
- i \
- ) \
+#define EACH_VALUE(z, value_index, type_index) \
+ TEST_CONVERSION( \
+ BOOST_PP_ARRAY_ELEM(type_index, TYPES), \
+ BOOST_PP_ARRAY_ELEM(value_index, VALUES) \
+ ) \
+/**/
+
+#define EACH_TYPE1(z, type_index, nothing) \
+ BOOST_PP_REPEAT( \
+ BOOST_PP_ARRAY_SIZE(VALUES), \
+ EACH_VALUE, \
+ type_index \
+ ) \
/**/
int main(int argc, char *argv[]){
BOOST_PP_REPEAT(
BOOST_PP_ARRAY_SIZE(TYPES),
EACH_TYPE1,
- x
+ nothing
)
- /*
- TEST(0, 0, (0, 1));
- TEST_CONVERSION(boost::uint8_t, boost::uint8_t, 0x80)
- */
return 0;
}
diff --git a/test/test_subtract.cpp b/test/test_subtract.cpp
index bf52a50..70bf528 100644
--- a/test/test_subtract.cpp
+++ b/test/test_subtract.cpp
@@ -4,14 +4,14 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-bool test_subtract1();
-bool test_subtract2();
-bool test_subtract3();
+#include "test_subtract.hpp"
+
+#define TESTX(a, b) \
+ rval &= test_subtract(a, b, BOOST_PP_STRINGIZE(a), BOOST_PP_STRINGIZE(b));
+/**/
int main(int argc, char * argv[]){
- bool result = true;
- result = test_subtract1();
- result &= test_subtract2();
- result &= test_subtract3();
- return ! result ;
+ bool rval = true;
+ TEST_ALL
+ return ! rval ;
}
diff --git a/test/test_subtract.hpp b/test/test_subtract.hpp
index be0be05..59eb077 100644
--- a/test/test_subtract.hpp
+++ b/test/test_subtract.hpp
@@ -14,144 +14,16 @@
#include
#include
-#include
-#include
+#include
+#include
#include "../include/safe_integer.hpp"
#include "../include/safe_cast.hpp"
#include "../include/safe_compare.hpp"
+#include "../include/numeric.hpp"
#include "test.hpp"
-template
-bool test_subtract(
- V v1,
- V v2,
- const char *at1,
- const char *at2,
- const char *av1,
- const char *av2
-){
- bool success;
-
- T1 t1;
- try{
- t1 = boost::numeric::safe_cast(v1);
- success = true;
- }
- catch(std::range_error){
- success = false;
- }
- if(success){
- if(boost::numeric::safe_compare::greater_than(
- v1,
- std::numeric_limits::max()
- )
- || boost::numeric::safe_compare::less_than(
- v1,
- std::numeric_limits::min()
- )
- ){
- std::cout
- << "constructed invalid value "
- << at1 << ' ' << av1
- << std::endl;
- return false;
- }
- }
- else{
- if(! boost::numeric::safe_compare::greater_than(
- v1,
- std::numeric_limits::max()
- )
- && ! boost::numeric::safe_compare::less_than(
- v1,
- std::numeric_limits::min()
- )
- ){
- std::cout
- << "failed to construct valid value "
- << at1 << ' ' << av1
- << std::endl;
- return false;
- }
- return true;
- }
-
- T2 t2;
- try{
- t2 = boost::numeric::safe_cast(v2);
- success = true;
- }
- catch(std::range_error){
- success = false;
- }
- if(success){
- if(boost::numeric::safe_compare::greater_than(
- v2,
- std::numeric_limits::max()
- )
- || boost::numeric::safe_compare::less_than(
- v2,
- std::numeric_limits::min()
- )){
- std::cout
- << "constructed invalid value "
- << at2 << ' ' << av2
- << std::endl;
- return false;
- }
- }
- else{
- if(!boost::numeric::safe_compare::greater_than(
- v2,
- std::numeric_limits::max()
- )
- && !boost::numeric::safe_compare::less_than(
- v2,
- std::numeric_limits::min()
- )){
- std::cout
- << "failed to construct valid value "
- << at2 << ' ' << av2
- << std::endl;
- return false;
- }
- return true;
- }
-
- V result;
- try{
- result = t1 - t2;
- success = true;
- }
- catch(std::range_error){
- success = false;
- }
- if(success){
- if(result != v1 - v2){
- std::cout
- << "failed to detect error in subtraction "
- << at1 << ' ' << at2 << ' ' << av1 << ' ' << av2
- << std::endl;
- return false;
- }
- }
- else{
- if(boost::numeric::safe_compare::greater_than_equal(
- boost::numeric::bits::value,
- std::max(count_bits(v1),count_bits(v2))
- )){
- std::cout
- << "erroneously detected error in subtraction "
- << at1 << ' ' << at2 << ' ' << av1 << ' ' << av2
- << std::endl;
- return false;
- }
- }
- return true; // correct result
-}
-
template
struct subtract_result {
typedef typename boost::mpl::if_<
@@ -164,15 +36,43 @@ struct subtract_result {
>::type type;
};
-#define TEST_IMPL(a, b, c, d) \
- rval &= test_subtract( \
- (static_cast::type>(a)), \
- (static_cast::type>(b)), \
- BOOST_PP_STRINGIZE(d), \
- BOOST_PP_STRINGIZE(c), \
- BOOST_PP_STRINGIZE(b), \
- BOOST_PP_STRINGIZE(a) \
- ); \
-/**/
+template
+bool test_subtract(
+ T1 v1,
+ T2 v2,
+ const char *av1,
+ const char *av2
+){
+ typename subtract_result::type result;
+ try{
+ boost::numeric::safe t1 = v1;
+
+ result = t1 - v2;
+ if(boost::numeric::safe_compare::less_than(
+ boost::numeric::bits::value,
+ std::max(count_bits(v1),count_bits(v2))
+ )){
+ std::cout
+ << "failed to detect error in subtraction "
+ << av1 << " - " << av2
+ << std::endl;
+ return false;
+ }
+ }
+ catch(std::range_error){
+ if(boost::numeric::safe_compare::greater_than_equal(
+ boost::numeric::bits::value,
+ std::max(count_bits(v1),count_bits(v2))
+ )){
+ std::cout
+ << "erroneously detected error in subtraction "
+ << av1 << " - " << av2
+ << std::endl;
+ return false;
+ }
+ }
+ return true; // correct result
+}
+
#endif // TEST_SUBTRACT_HPP
diff --git a/test/test_types.hpp b/test/test_types.hpp
new file mode 100644
index 0000000..23cd730
--- /dev/null
+++ b/test/test_types.hpp
@@ -0,0 +1,22 @@
+//
+// test_types.hpp
+//
+// Created by Robert Ramey on 3/27/14.
+//
+//
+
+#ifndef test_types_hpp
+#define test_types_hpp
+
+#define TYPES (8, ( \
+ boost::int8_t, \
+ boost::uint8_t, \
+ boost::int16_t, \
+ boost::uint16_t, \
+ boost::int32_t, \
+ boost::uint32_t, \
+ boost::int64_t, \
+ boost::uint64_t \
+))
+
+#endif
diff --git a/test/test_values.hpp b/test/test_values.hpp
new file mode 100644
index 0000000..95807bd
--- /dev/null
+++ b/test/test_values.hpp
@@ -0,0 +1,48 @@
+//
+// test_values.hpp
+//
+// Created by Robert Ramey on 3/27/14.
+//
+//
+
+#ifndef test_values_hpp
+#define test_values_hpp
+
+#include
+
+#define VALUES (32, ( \
+ (std::int8_t)0x01, \
+ (std::int8_t)0x7f, \
+ (std::int8_t)0x80, \
+ (std::int8_t)0xff, \
+ (std::int16_t)0x0001, \
+ (std::int16_t)0x7fff, \
+ (std::int16_t)0x8000, \
+ (std::int16_t)0xffff, \
+ (std::int32_t)0x00000001, \
+ (std::int32_t)0x7fffffff, \
+ (std::int32_t)0x80000000, \
+ (std::int32_t)0xffffffff, \
+ (std::int64_t)0x0000000000000001, \
+ (std::int64_t)0x7fffffffffffffff, \
+ (std::int64_t)0x8000000000000000, \
+ (std::int64_t)0xffffffffffffffff, \
+ (std::uint8_t)0x01, \
+ (std::uint8_t)0x7f, \
+ (std::uint8_t)0x80, \
+ (std::uint8_t)0xff, \
+ (std::uint16_t)0x0001, \
+ (std::uint16_t)0x7fff, \
+ (std::uint16_t)0x8000, \
+ (std::uint16_t)0xffff, \
+ (std::uint32_t)0x00000001, \
+ (std::uint32_t)0x7fffffff, \
+ (std::uint32_t)0x80000000, \
+ (std::uint32_t)0xffffffff, \
+ (std::uint64_t)0x0000000000000001,\
+ (std::uint64_t)0x7fffffffffffffff,\
+ (std::uint64_t)0x8000000000000000,\
+ (std::uint64_t)0xffffffffffffffff \
+))
+
+#endif