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