1 // Copyright (c) 2015 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 #ifndef BOOST_TEST_LESS_THAN_HPP
8 #define BOOST_TEST_LESS_THAN_HPP
9
10 #include <iostream>
11
12 #include <boost/safe_numerics/safe_integer.hpp>
13 #include <boost/safe_numerics/range_value.hpp>
14
15 // works for both GCC and clang
16 #pragma GCC diagnostic push
17 #pragma GCC diagnostic ignored "-Wunused-value"
18
19 template<class T1, class T2>
test_less_than(T1 v1,T2 v2,const char * av1,const char * av2,char expected_result)20 bool test_less_than(
21 T1 v1,
22 T2 v2,
23 const char *av1,
24 const char *av2,
25 char expected_result
26 ){
27 using namespace boost::safe_numerics;
28 std::cout << "testing"<< std::boolalpha << std::endl;
29 {
30 safe_t<T1> t1 = v1;
31 std::cout << "safe<" << av1 << "> < " << av2 << " -> ";
32 static_assert(
33 boost::safe_numerics::is_safe<safe_t<T1> >::value,
34 "safe_t not safe!"
35 );
36 try{
37 // use auto to avoid checking assignment.
38 auto result = t1 < v2;
39 std::cout << make_result_display(result);
40 if(expected_result == 'x'){
41 std::cout
42 << " ! = "<< av1 << " < " << av2
43 << " failed to detect error in less than"
44 << std::endl;
45 t1 < v2;
46 return false;
47 }
48 if(result != (expected_result == '<')){
49 std::cout
50 << " ! = "<< av1 << " < " << av2
51 << " produced the wrong answer"
52 << std::endl;
53 t1 < v2;
54 return false;
55 }
56 std::cout << std::endl;
57 }
58 catch(const std::exception &){
59 if(expected_result != 'x'){
60 std::cout
61 << " == "<< av1 << " < " << av2
62 << " erroneously detected error in less than"
63 << std::endl;
64 try{
65 t1 < v2;
66 }
67 catch(const std::exception &){}
68 return false;
69 }
70 std::cout << std::endl;
71 }
72 }
73 {
74 safe_t<T2> t2 = v2;
75 std::cout << av1 << " < " << "safe<" << av2 << "> -> ";
76 static_assert(
77 boost::safe_numerics::is_safe<safe_t<T2> >::value,
78 "safe_t not safe!"
79 );
80 try{
81 // use auto to avoid checking assignment.
82 auto result = v1 < t2;
83 std::cout << make_result_display(result);
84 if(expected_result == 'x'){
85 std::cout
86 << " ! = "<< av1 << " < " << av2
87 << " failed to detect error in less than"
88 << std::endl;
89 v1 < t2;
90 return false;
91 }
92 if(result != (expected_result == '<')){
93 std::cout
94 << " ! = "<< av1 << " < " << av2
95 << " produced the wrong answer"
96 << std::endl;
97 v1 < t2;
98 return false;
99 }
100 std::cout << std::endl;
101 }
102 catch(const std::exception &){
103 if(expected_result != 'x'){
104 std::cout
105 << " == "<< av1 << " < " << av2
106 << " erroneously detected error in less than"
107 << std::endl;
108 try{
109 v1 < t2;
110 }
111 catch(const std::exception &){}
112 return false;
113 }
114 std::cout << std::endl;
115 }
116 }
117 {
118 safe_t<T1> t1 = v1;
119 safe_t<T2> t2 = v2;
120 std::cout << "safe<" << av1 << "> < " << "safe<" << av2 << "> -> ";
121
122 try{
123 // use auto to avoid checking assignment.
124 auto result = t1 < t2;
125 std::cout << make_result_display(result);
126 if(expected_result == 'x'){
127 std::cout
128 << " ! = "<< av1 << " < " << av2
129 << " failed to detect error in less than"
130 << std::endl;
131 t1 < t2;
132 return false;
133 }
134 if(result != (expected_result == '<')){
135 std::cout
136 << " ! = "<< av1 << " < " << av2
137 << " produced the wrong answer"
138 << std::endl;
139 t1 < t2;
140 return false;
141 }
142 std::cout << std::endl;
143 }
144 catch(const std::exception &){
145 if(expected_result == '.'){
146 std::cout
147 << " == "<< av1 << " < " << av2
148 << " erroneously detected error in less than"
149 << std::endl;
150 try{
151 t1 < t2;
152 }
153 catch(const std::exception &){}
154 return false;
155 }
156 std::cout << std::endl;
157 }
158 }
159 return true; // correct result
160 }
161 #pragma GCC diagnostic pop
162
163 #endif // BOOST_TEST_SUBTRACT
164