• 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 <boost/safe_numerics/checked_result.hpp>
8 #include <boost/safe_numerics/checked_result_operations.hpp>
9 #include <boost/safe_numerics/checked_integer.hpp>
10 
11 template<class T>
test_checked_left_shift(const T & v1,const T & v2,char expected_result)12 constexpr bool test_checked_left_shift(
13     const T & v1,
14     const T & v2,
15     char expected_result
16 ){
17     using namespace boost::safe_numerics;
18     const T result = v1 << v2;
19     switch(expected_result){
20     case '.':
21         return ! result.exception();
22     case '-':
23         return safe_numerics_error::negative_overflow_error == result.m_e;
24     case '+':
25         return safe_numerics_error::positive_overflow_error == result.m_e;
26     case '!':
27         return safe_numerics_error::range_error == result.m_e;
28     case 'n':   // n negative_shift
29         return safe_numerics_error::negative_shift == result.m_e;
30     case 's':   // s negative_value_shift
31         return safe_numerics_error::negative_value_shift == result.m_e;
32     case 'l':   // l shift_too_large
33         return safe_numerics_error::shift_too_large == result.m_e;
34     default:
35         assert(false);
36     }
37     return false;
38 }
39 
40 #include "test_checked_left_shift.hpp"
41 
42 template<typename T, typename First, typename Second>
43 struct test_signed_pair {
44     static const std::size_t i = First();
45     static const std::size_t j = Second();
46     // note: is constexpr really required here?  compilers disagree!
47     constexpr static const bool value = test_checked_left_shift(
48         signed_values<T>[i],
49         signed_values<T>[j],
50         signed_left_shift_results[i][j]
51     );
52 };
53 
54 template<typename T, typename First, typename Second>
55 struct test_unsigned_pair {
56     static const std::size_t i = First();
57     static const std::size_t j = Second();
58     // note: is constexpr really required here?  compilers disagree!
59     constexpr static const bool value = test_checked_left_shift(
60         unsigned_values<T>[i],
61         unsigned_values<T>[j],
62         unsigned_left_shift_results[i][j]
63     );
64 };
65 
66 #include <boost/mp11/algorithm.hpp>
67 
main()68 int main(){
69     using namespace boost::mp11;
70 
71     static_assert(
72         mp_all_of<
73             mp_product<
74                 test_signed_pair,
75                 signed_test_types,
76                 signed_value_indices, signed_value_indices
77             >,
78             mp_to_bool
79         >(),
80         "all values for all signed types correctly shifted"
81     );
82 
83     static_assert(
84         mp_all_of<
85             mp_product<
86                 test_unsigned_pair,
87                 unsigned_test_types,
88                 unsigned_value_indices, unsigned_value_indices
89             >,
90             mp_to_bool
91         >(),
92         "all values for all unsigned types correctly shifted"
93     );
94 
95     return 0;
96 }
97