• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2012 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 <iostream>
8 
9 #include <boost/core/demangle.hpp>
10 #include <boost/safe_numerics/checked_result_operations.hpp>
11 #include <boost/safe_numerics/checked_integer.hpp>
12 
13 template<class T>
test_checked_modulus(T v1,T v2,char expected_result)14 bool test_checked_modulus(
15     T v1,
16     T v2,
17     char expected_result
18 ){
19     using namespace boost::safe_numerics;
20 
21     const T result = v1 % v2;
22     std::cout
23         << v1 << " % " << v2 << " -> " << result
24         << std::endl;
25 
26     switch(expected_result){
27     case '.':
28     case '0':
29         if(result.exception()){
30             std::cout
31                 << "erroneously detected error in division"
32                 << std::endl;
33             v1 % v2;
34             return false;
35         }
36         if(expected_result == '0'
37         && result != T(0)
38         ){
39             std::cout
40                 << "failed to get expected zero result "
41                 << std::endl;
42             v1 % v2;
43             return false;
44         }
45         return true;
46     case '-':
47         if(safe_numerics_error::negative_overflow_error == result.m_e)
48             return true;
49         break;
50     case '+':
51         if(safe_numerics_error::positive_overflow_error == result.m_e)
52             return true;
53         break;
54     case '!':
55         if(safe_numerics_error::range_error == result.m_e)
56             return true;
57         break;
58     }
59     std::cout
60         << "failed to detect error in modulus "
61         << std::hex << result << "(" << std::dec << result << ")"
62         << " != "<< v1 << " % " << v2
63         << std::endl;
64     v1 % v2;
65     return false;
66 }
67 
68 #include "test_checked_modulus.hpp"
69 
70 template<typename T, typename First, typename Second>
71 struct test_signed_pair {
operator ()test_signed_pair72     bool operator()() const {
73         std::size_t i = First();
74         std::size_t j = Second();
75         std::cout << std::dec << i << ',' << j << ','
76         << "testing " << boost::core::demangle(typeid(T).name()) << ' ';
77         return test_checked_modulus(
78             signed_values<T>[i],
79             signed_values<T>[j],
80             signed_modulus_results[i][j]
81         );
82     };
83 };
84 
85 template<typename T, typename First, typename Second>
86 struct test_unsigned_pair {
operator ()test_unsigned_pair87     bool operator()() const {
88         std::size_t i = First();
89         std::size_t j = Second();
90         std::cout << std::dec << i << ',' << j << ','
91         << "testing " << boost::core::demangle(typeid(T).name()) << ' ';
92         return test_checked_modulus(
93             unsigned_values<T>[i],
94             unsigned_values<T>[j],
95             unsigned_modulus_results[i][j]
96         );
97     };
98 };
99 
100 #include <boost/mp11/algorithm.hpp>
101 
main()102 int main(){
103     using namespace boost::mp11;
104 
105     bool rval = true;
106 
107     std::cout << "*** testing signed values\n";
108     mp_for_each<
109         mp_product<
110             test_signed_pair,
111             signed_test_types,
112             signed_value_indices,
113             signed_value_indices
114         >
115     >([&](auto I){
116         rval &= I();
117     });
118 
119     std::cout << "*** testing unsigned values\n";
120     mp_for_each<
121         mp_product<
122             test_unsigned_pair,
123             unsigned_test_types,
124             unsigned_value_indices, unsigned_value_indices
125         >
126     >([&](auto I){
127         rval &= I();
128     });
129 
130     std::cout << (rval ? "success!" : "failure") << std::endl;
131     return rval ? 0 : 1;
132 }
133