1 // Copyright (c) 2018 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(const T & v1,const T & v2,char expected_result)16 constexpr bool test_checked_right_shift(
17 const T & v1,
18 const T & v2,
19 char expected_result
20 ){
21 using namespace boost::safe_numerics;
22 const T result = v1 >> v2;
23
24 switch(expected_result){
25 case '.':
26 if(result.exception()){
27 return false;
28 }
29 return true;
30 case '-':
31 if(safe_numerics_error::negative_overflow_error == result.m_e)
32 return true;
33 break;
34 case '+':
35 if(safe_numerics_error::positive_overflow_error == result.m_e)
36 return true;
37 break;
38 case '!':
39 if(safe_numerics_error::range_error == result.m_e)
40 return true;
41 break;
42 case 'n': // n negative_shift
43 if(safe_numerics_error::negative_shift == result.m_e)
44 return true;
45 break;
46 case 's': // s negative_value_shift
47 if(safe_numerics_error::negative_value_shift == result.m_e)
48 return true;
49 break;
50 case 'l': // l shift_too_large
51 if(safe_numerics_error::shift_too_large == result.m_e)
52 return true;
53 break;
54 default:
55 assert(false);
56 }
57 return false;
58 }
59
60 #include "test_checked_right_shift.hpp"
61
62 template<typename T, typename First, typename Second>
63 struct test_signed_pair {
64 static const std::size_t i = First();
65 static const std::size_t j = Second();
66 // note: is constexpr really required here? compilers disagree!
67 constexpr static const bool value = test_checked_right_shift(
68 signed_values<T>[i],
69 signed_values<T>[j],
70 signed_right_shift_results[i][j]
71 );
72 };
73
74 template<typename T, typename First, typename Second>
75 struct test_unsigned_pair {
76 static const std::size_t i = First();
77 static const std::size_t j = Second();
78 // note: is constexpr really required here? compilers disagree!
79 constexpr static const bool value = test_checked_right_shift(
80 unsigned_values<T>[i],
81 unsigned_values<T>[j],
82 unsigned_right_shift_results[i][j]
83 );
84 };
85
86 #include <boost/mp11/algorithm.hpp>
87
main()88 int main(){
89 using namespace boost::mp11;
90
91 static_assert(
92 mp_all_of<
93 mp_product<
94 test_signed_pair,
95 signed_test_types,
96 signed_value_indices, signed_value_indices
97 >,
98 mp_to_bool
99 >(),
100 "all values for all signed types correctly right_shifted"
101 );
102
103 static_assert(
104 mp_all_of<
105 mp_product<
106 test_unsigned_pair,
107 unsigned_test_types,
108 unsigned_value_indices, unsigned_value_indices
109 >,
110 mp_to_bool
111 >(),
112 "all values for all unsigned types correctly right_shifted"
113 );
114 return 0;
115 }
116