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