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 <boost/safe_numerics/checked_result.hpp>
8 #include <boost/safe_numerics/checked_result_operations.hpp>
9 #include <boost/safe_numerics/checked_integer.hpp>
10
11 template<class T>
test_checked_multiply(T v1,T v2,char expected_result)12 constexpr bool test_checked_multiply(
13 T v1,
14 T v2,
15 char expected_result
16 ){
17 using namespace boost::safe_numerics;
18 const T result = v1 * v2;
19 switch(expected_result){
20 case '0':
21 case '.':
22 if(result.exception()){
23 return false;
24 }
25 if(expected_result == '0'
26 && result != T(0)
27 ){
28 return false;
29 }
30 return true;
31 case '-':
32 return safe_numerics_error::negative_overflow_error == result.m_e;
33 case '+':
34 return safe_numerics_error::positive_overflow_error == result.m_e;
35 case '!':
36 return safe_numerics_error::range_error == result.m_e;
37 }
38 return false;
39 }
40
41 #include "test_checked_multiply.hpp"
42
43 template<typename T, typename First, typename Second>
44 struct test_signed_pair {
45 static const std::size_t i = First();
46 static const std::size_t j = Second();
47 // note: is constexpr really required here? compilers disagree!
48 constexpr static const bool value = test_checked_multiply(
49 signed_values<T>[i],
50 signed_values<T>[j],
51 signed_multiplication_results[i][j]
52 );
53 };
54
55 template<typename T, typename First, typename Second>
56 struct test_unsigned_pair {
57 static const std::size_t i = First();
58 static const std::size_t j = Second();
59 // note: is constexpr really required here? compilers disagree!
60 constexpr static const bool value = test_checked_multiply(
61 unsigned_values<T>[i],
62 unsigned_values<T>[j],
63 unsigned_multiplication_results[i][j]
64 );
65 };
66
67 #include "check_symmetry.hpp"
68 #include <boost/mp11/algorithm.hpp>
69
main()70 int main(){
71 static_assert(
72 check_symmetry(signed_multiplication_results),
73 "sanity check on test matrix - should be symmetrical"
74 );
75 static_assert(
76 check_symmetry(unsigned_multiplication_results),
77 "sanity check on test matrix - should be symmetrical"
78 );
79 using namespace boost::mp11;
80
81 static_assert(
82 mp_all_of<
83 mp_product<
84 test_signed_pair,
85 signed_test_types,
86 signed_value_indices, signed_value_indices
87 >,
88 mp_to_bool
89 >(),
90 "all values for all signed types correctly multiplied"
91 );
92
93 static_assert(
94 mp_all_of<
95 mp_product<
96 test_unsigned_pair,
97 unsigned_test_types,
98 unsigned_value_indices, unsigned_value_indices
99 >,
100 mp_to_bool
101 >(),
102 "all values for all unsigned types correctly multiplied"
103 );
104 return 0;
105 }
106