• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2012 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 
9 #include <boost/core/demangle.hpp>
10 #include <boost/safe_numerics/checked_result_operations.hpp>
11 #include <boost/safe_numerics/checked_integer.hpp>
12 
13 // note: T should be of tyme checked_result<R> for some integer type R
14 template<class T>
test_checked_xor(T v1,T v2,char expected_result)15 bool test_checked_xor(
16     T v1,
17     T v2,
18     char expected_result
19 ){
20     using namespace boost::safe_numerics;
21     const T result = v1 ^ v2;
22     std::cout
23         << v1 << " ^ " << v2 << " -> " << result
24         << std::endl;
25 
26     switch(expected_result){
27     case '.':
28         if(result.exception()){
29             std::cout
30                 << "erroneously detected error in exclusive or "
31                 << std::endl;
32             v1 ^ v2;
33             return false;
34         }
35         return true;
36     case '-':
37         if(safe_numerics_error::negative_overflow_error == result.m_e)
38             return true;
39         break;
40     case '+':
41         if(safe_numerics_error::positive_overflow_error == result.m_e)
42             return true;
43         break;
44     case '!':
45         if(safe_numerics_error::range_error == result.m_e)
46             return true;
47         break;
48     }
49     std::cout
50         << "failed to detect error in exclusive or "
51         << std::hex << result << "(" << std::dec << result << ")"
52         << " != "<< v1 << " ^ " << v2
53         << std::endl;
54     v1 ^ v2;
55     return false;
56 }
57 
58 #include "test_checked_xor.hpp"
59 
60 template<typename T, typename First, typename Second>
61 struct test_signed_pair {
operator ()test_signed_pair62     bool operator()() const {
63         std::size_t i = First();
64         std::size_t j = Second();
65         std::cout << std::dec << i << ',' << j << ','
66             << "testing " << boost::core::demangle(typeid(T).name()) << ' ';
67         return test_checked_xor(
68             signed_values<T>[i],
69             signed_values<T>[j],
70             signed_xor_results[i][j]
71         );
72     };
73 };
74 
75 template<typename T, typename First, typename Second>
76 struct test_unsigned_pair {
operator ()test_unsigned_pair77     bool operator()() const {
78         std::size_t i = First();
79         std::size_t j = Second();
80         std::cout << std::dec << i << ',' << j << ','
81             << "testing " << boost::core::demangle(typeid(T).name()) << ' ';
82         return test_checked_xor(
83             unsigned_values<T>[i],
84             unsigned_values<T>[j],
85             unsigned_xor_results[i][j]
86         );
87     };
88 };
89 
90 #include "check_symmetry.hpp"
91 
92 #include <boost/mp11/algorithm.hpp>
93 
main()94 int main(){
95     static_assert(
96         check_symmetry(signed_xor_results),
97         "sanity check on test matrix - should be symmetrical"
98     );
99     static_assert(
100         check_symmetry(unsigned_xor_results),
101         "sanity check on test matrix - should be symmetrical"
102     );
103 
104     using namespace boost::mp11;
105     bool rval = true;
106 
107     std::cout << "*** testing signed values\n";
108 
109     mp_for_each<
110         mp_product<
111             test_signed_pair,
112             signed_test_types,
113             signed_value_indices,
114             signed_value_indices
115         >
116     >([&](auto I){
117         rval &= I();
118     });
119 
120     std::cout << "*** testing unsigned values\n";
121 
122     mp_for_each<
123         mp_product<
124             test_unsigned_pair,
125             unsigned_test_types,
126             unsigned_value_indices, unsigned_value_indices
127         >
128     >([&](auto I){
129         rval &= I();
130     });
131 
132     std::cout << (rval ? "success!" : "failure") << std::endl;
133     return rval ? 0 : 1;
134 }
135