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