1 #ifndef BOOST_TEST_MODULUS_HPP
2 #define BOOST_TEST_MODULUS_HPP
3
4 // Copyright (c) 2015 Robert Ramey
5 //
6 // Distributed under the Boost Software License, Version 1.0. (See
7 // accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9
10 #include <iostream>
11
12 #include <boost/safe_numerics/safe_integer.hpp>
13 #include <boost/safe_numerics/range_value.hpp>
14
15 template<class T1, class T2>
test_modulus(T1 v1,T2 v2,const char * av1,const char * av2,char expected_result)16 bool test_modulus(
17 T1 v1,
18 T2 v2,
19 const char *av1,
20 const char *av2,
21 char expected_result
22 ){
23 std::cout << "testing"<< std::endl;
24 {
25 safe_t<T1> t1 = v1;
26 using result_type = decltype(t1 % v2);
27 std::cout << "safe<" << av1 << "> % " << av2 << " -> ";
28 static_assert(
29 boost::safe_numerics::is_safe<safe_t<T1> >::value,
30 "safe_t not safe!"
31 );
32 static_assert(
33 boost::safe_numerics::is_safe<result_type>::value,
34 "Expression failed to return safe type"
35 );
36
37 try{
38 // use auto to avoid checking assignment.
39 auto result = t1 % v2;
40 std::cout << make_result_display(result);
41 if(expected_result == 'x'){
42 std::cout
43 << " ! = "<< av1 << " % " << av2
44 << " failed to detect error in modulus"
45 << std::endl;
46 t1 % v2;
47 return false;
48 }
49 std::cout << std::endl;
50 }
51 catch(const std::exception &){
52 if(expected_result == '.'){
53 std::cout
54 << " == "<< av1 << " % " << av2
55 << " erroneously detected error in modulus"
56 << std::endl;
57 try{
58 t1 % v2;
59 }
60 catch(const std::exception &){}
61 return false;
62 }
63 }
64 }
65 {
66 safe_t<T2> t2 = v2;
67 using result_type = decltype(v1 % t2);
68 std::cout << av1 << " % " << "safe<" << av2 << "> -> ";
69 static_assert(
70 boost::safe_numerics::is_safe<safe_t<T2> >::value,
71 "safe_t not safe!"
72 );
73 static_assert(
74 boost::safe_numerics::is_safe<result_type>::value,
75 "Expression failed to return safe type"
76 );
77
78 try{
79 // use auto to avoid checking assignment.
80 auto result = v1 % t2;
81 std::cout << make_result_display(result);
82 if(expected_result =='x'){
83 std::cout
84 << " ! = "<< av1 << " % " << av2
85 << " failed to detect error in modulus"
86 << std::endl;
87 try{
88 v1 % t2;
89 }
90 catch(const std::exception &){}
91 return false;
92 }
93 std::cout << std::endl;
94 }
95 catch(const std::exception &){
96 if(expected_result != 'x'){
97 std::cout
98 << " == "<< av1 << " % " << av2
99 << " erroneously detected error in modulus"
100 << std::endl;
101 try{
102 v1 % t2;
103 }
104 catch(const std::exception &){}
105 return false;
106 }
107 }
108 }
109 {
110 safe_t<T1> t1 = v1;
111 safe_t<T2> t2 = v2;
112 using result_type = decltype(t1 + t2);
113 std::cout << "safe<" << av1 << "> % " << "safe<" << av2 << "> -> ";
114 static_assert(
115 boost::safe_numerics::is_safe<result_type>::value,
116 "Expression failed to return safe type"
117 );
118
119 try{
120 // use auto to avoid checking assignment.
121 auto result = t1 % t2;
122 std::cout << make_result_display(result);
123 if(expected_result != '.'){
124 std::cout
125 << " ! = "<< av1 << " % " << av2
126 << " failed to detect error in modulus"
127 << std::endl;
128 try{
129 t1 % t2;
130 }
131 catch(const std::exception &){}
132 return false;
133 }
134 std::cout << std::endl;
135 }
136 catch(const std::exception &){
137 if(expected_result != 'x'){
138 std::cout
139 << " == "<< av1 << " % " << av2
140 << " erroneously detected error in modulus"
141 << std::endl;
142 try{
143 t1 % t2;
144 }
145 catch(const std::exception &){}
146 return false;
147 }
148 }
149 }
150 return true;
151 }
152
153 #endif // BOOST_TEST_MODULUS
154