• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BOOST_TEST_LEFT_SHIFT_HPP
2 #define BOOST_TEST_LEFT_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_left_shift(T1 v1,T2 v2,const char * av1,const char * av2,char expected_result)16 bool test_left_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         try{
36             // use auto to avoid checking assignment.
37             auto result = t1 << v2;
38             std::cout << make_result_display(result);
39             if(expected_result == 'x'){
40                 std::cout
41                     << " ! = "<< av1 << " << " << av2
42                     << " failed to detect arithmetic error in left shift"
43                     << std::endl;
44                 t1 << v2;
45                 return false;
46             }
47             std::cout << std::endl;
48         }
49         catch(const std::exception & e){
50             if(expected_result == '.'){
51                 std::cout
52                     << "erroneously detected arithmetic error in left shift"
53                     << " == "<< av1 << " << " << av2
54                     << ' ' << e.what()
55                     << std::endl;
56                 try{
57                     t1 << v2;
58                 }
59                 catch(const std::exception &){}
60                 return false;
61             }
62             std::cout << std::endl;
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<result_type>::value,
71             "Expression failed to return safe type"
72         );
73 
74         try{
75             // use auto to avoid checking assignment.
76             auto result = v1 << t2;
77             std::cout << make_result_display(result);
78             if(expected_result == 'x'){
79                 std::cout
80                     << " ! = "<< av1 << " << " << av2
81                     << " failed to detect error in left shift"
82                     << std::hex << result << "(" << std::dec << result << ")"
83                     << std::endl;
84                 v1 << t2;
85                 return false;
86             }
87             std::cout << std::endl;
88         }
89         catch(const std::exception & e){
90             if(expected_result == '.'){
91                 std::cout
92                     << " == "<< av1 << " << " << av2
93                     << "erroneously detected error in left shift "
94                     << ' ' << e.what()
95                     << std::endl;
96                 try{
97                     v1 << t2;
98                 }
99                 catch(const std::exception &){}
100                 return false;
101             }
102             std::cout << std::endl;
103         }
104     }
105     {
106         safe_t<T1> t1 = v1;
107         safe_t<T2> t2 = v2;
108         using result_type = decltype(t1 << t2);
109         std::cout << "safe<" << av1 << "> << " << "safe<" << av2 << "> -> ";
110         static_assert(
111             boost::safe_numerics::is_safe<result_type>::value,
112             "Expression failed to return safe type"
113         );
114 
115         try{
116             // use auto to avoid checking assignment.
117             auto result = t1 << t2;
118             std::cout << make_result_display(result);
119             if(expected_result == 'x'){
120                 std::cout
121                     << " ! = "<< av1 << " << " << av2
122                     << " failed to detect error in left shift"
123                     << std::endl;
124                 t1 << t2;
125                 return false;
126             }
127             std::cout << std::endl;
128         }
129         catch(const std::exception & e){
130             if(expected_result == '.'){
131                 std::cout
132                     << " == "<< av1 << " << " << av2
133                     << " erroneously detected error in left shift"
134                     << ' ' << e.what()
135                     << std::endl;
136                 try{
137                     t1 << t2;
138                 }
139                 catch(const std::exception &){}
140                 return false;
141             }
142             std::cout << std::endl;
143         }
144     }
145     return true; // correct result
146 }
147 
148 #endif // BOOST_TEST_DIVIDE
149