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