1 #ifndef BOOST_TEST_RIGHT_SHIFT_HPP
2 #define BOOST_TEST_RIGHT_SHIFT_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_right_shift(T1 v1,T2 v2,const char * av1,const char * av2,char expected_result)16 bool test_right_shift(
17 T1 v1,
18 T2 v2,
19 const char *av1,
20 const char *av2,
21 char expected_result
22 ){
23 std::cout
24 << "testing "
25 << av1 << " >> " << av2
26 << std::endl;
27 {
28 safe_t<T1> t1 = v1;
29 using result_type = decltype(t1 >> v2);
30 std::cout << "safe<" << av1 << "> << " << av2 << " -> ";
31 static_assert(
32 boost::safe_numerics::is_safe<result_type>::value,
33 "Expression failed to return safe type"
34 );
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 right shift"
44 << std::endl;
45 t1 >> v2;
46 return false;
47 }
48 std::cout << std::endl;
49 }
50 catch(const std::exception & e){
51 if(expected_result == '.'){
52 std::cout
53 << " == "<< av1 << " >> " << av2
54 << " erroneously detected error in right shift"
55 << ' ' << e.what()
56 << std::endl;
57 try{
58 t1 >> v2;
59 }
60 catch(const std::exception &){}
61 return false;
62 }
63 std::cout << std::endl;
64 }
65 }
66 {
67 safe_t<T2> t2 = v2;
68 using result_type = decltype(v1 >> t2);
69 std::cout << av1 << " >> " << "safe<" << av2 << "> -> ";
70 static_assert(
71 boost::safe_numerics::is_safe<result_type>::value,
72 "Expression failed to return safe type"
73 );
74
75 try{
76 // use auto to avoid checking assignment.
77 auto result = v1 >> t2;
78 std::cout << make_result_display(result);
79 if(expected_result == 'x'){
80 std::cout
81 << " ! = "<< av1 << " >> " << av2
82 << " failed to detect error in right shift"
83 << std::hex << result << "(" << std::dec << result << ")"
84 << std::endl;
85 v1 >> t2;
86 return false;
87 }
88 std::cout << std::endl;
89 }
90 catch(const std::exception & e){
91 if(expected_result == '.'){
92 std::cout
93 << " == "<< av1 << " >> " << av2
94 << " erroneously detected error in right shift"
95 << ' ' << e.what()
96 << std::endl;
97 try{
98 v1 >> t2;
99 }
100 catch(const std::exception &){}
101 return false;
102 }
103 std::cout << std::endl;
104 }
105 }
106 {
107 safe_t<T1> t1 = v1;
108 safe_t<T2> t2 = v2;
109 using result_type = decltype(t1 >> t2);
110 std::cout << "safe<" << av1 << "> >> " << "safe<" << av2 << "> -> ";
111 static_assert(
112 boost::safe_numerics::is_safe<result_type>::value,
113 "Expression failed to return safe type"
114 );
115
116 try{
117 // use auto to avoid checking assignment.
118 auto result = t1 >> t2;
119 std::cout << make_result_display(result);
120 if(expected_result == 'x'){
121 std::cout
122 << " ! = "<< av1 << " << " << av2
123 << " failed to detect error in right shift"
124 << std::endl;
125 t1 >> t2;
126 return false;
127 }
128 std::cout << std::endl;
129 }
130 catch(const std::exception & e){
131 if(expected_result == '.'){
132 std::cout
133 << " == "<< av1 << " << " << av2
134 << " erroneously detected error in right shift"
135 << ' ' << e.what()
136 << std::endl;
137 try{
138 t1 >> t2;
139 }
140 catch(const std::exception &){}
141 return false;
142 }
143 std::cout << std::endl;
144 }
145 }
146 return true; // correct result
147 }
148
149 #endif // BOOST_TEST_RIGHT_SHIFT_HPP
150