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