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