• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2012 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 #include <iostream>
8 #include <boost/core/demangle.hpp>
9 
10 #include <boost/safe_numerics/checked_result.hpp>
11 #include <boost/safe_numerics/checked_result_operations.hpp>
12 #include <boost/safe_numerics/checked_integer.hpp>
13 
14 // note: T should be of tyme checked_result<R> for some integer type R
15 template<class T>
test_checked_right_shift(T v1,T v2,char expected_result)16 bool test_checked_right_shift(
17     T v1,
18     T v2,
19     char expected_result
20 ){
21     using namespace boost::safe_numerics;
22     const T result = v1 >> v2;
23     std::cout
24         << v1 << " >> " << v2 << " -> " << result
25         << std::endl;
26 
27     switch(expected_result){
28     case '.':
29         if(result.exception()){
30             std::cout
31                 << "erroneously detected error in right shift "
32                 << std::endl;
33             v1 >> v2;
34             return false;
35         }
36         return true;
37     case '-':
38         if(safe_numerics_error::negative_overflow_error == result.m_e)
39             return true;
40         break;
41     case '+':
42         if(safe_numerics_error::positive_overflow_error == result.m_e)
43             return true;
44         break;
45     case '!':
46         if(safe_numerics_error::range_error == result.m_e)
47             return true;
48         break;
49     case 'n':   // n negative_shift
50         if(safe_numerics_error::negative_shift == result.m_e)
51             return true;
52         break;
53     case 's':   // s negative_value_shift
54         if(safe_numerics_error::negative_value_shift == result.m_e)
55             return true;
56         break;
57     case 'l':   // l shift_too_large
58         if(safe_numerics_error::shift_too_large == result.m_e)
59             return true;
60         break;
61     default:
62         assert(false);
63     }
64     std::cout
65         << "failed to detect error in right shift "
66         << std::hex << result << "(" << std::dec << result << ")"
67         << " != "<< v1 << " >> " << v2
68         << std::endl;
69     v1 >> v2;
70     return false;
71 }
72 
73 #include "test_checked_right_shift.hpp"
74 
75 template<typename T, typename First, typename Second>
76 struct test_signed_pair {
operator ()test_signed_pair77     bool operator()() const {
78         std::size_t i = First();
79         std::size_t j = Second();
80         std::cout << std::dec << i << ',' << j << ','
81             << "testing " << boost::core::demangle(typeid(T).name()) << ' ';
82         return test_checked_right_shift(
83             signed_values<T>[i],
84             signed_values<T>[j],
85             signed_right_shift_results[i][j]
86         );
87     };
88 };
89 
90 template<typename T, typename First, typename Second>
91 struct test_unsigned_pair {
operator ()test_unsigned_pair92     bool operator()() const {
93         std::size_t i = First();
94         std::size_t j = Second();
95         std::cout << std::dec << i << ',' << j << ','
96             << "testing " << boost::core::demangle(typeid(T).name()) << ' ';
97         return test_checked_right_shift(
98             unsigned_values<T>[i],
99             unsigned_values<T>[j],
100             unsigned_right_shift_results[i][j]
101         );
102     };
103 };
104 
105 #include <boost/mp11/algorithm.hpp>
106 
main()107 int main(){
108     using namespace boost::mp11;
109 
110     bool rval = true;
111 
112     std::cout << "*** testing signed values\n";
113 
114     mp_for_each<
115         mp_product<
116             test_signed_pair,
117             signed_test_types,
118             signed_value_indices,
119             signed_value_indices
120         >
121     >([&](auto I){
122         rval &= I();
123     });
124 
125     std::cout << "*** testing unsigned values\n";
126 
127     mp_for_each<
128         mp_product<
129             test_unsigned_pair,
130             unsigned_test_types,
131             unsigned_value_indices, unsigned_value_indices
132         >
133     >([&](auto I){
134         rval &= I();
135     });
136 
137     std::cout << (rval ? "success!" : "failure") << std::endl;
138     return rval ? 0 : 1;
139 }
140