• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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