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