• 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_subtract(T v1,T v2,char expected_result)15 bool test_checked_subtract(
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 subtraction "
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 subtraction "
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_subtract.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_subtract(
68             signed_values<T>[i],
69             signed_values<T>[j],
70             signed_subtraction_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_subtract(
83             unsigned_values<T>[i],
84             unsigned_values<T>[j],
85             unsigned_subtraction_results[i][j]
86         );
87     };
88 };
89 
90 #include <boost/mp11/algorithm.hpp>
91 
main()92 int main(){
93     using namespace boost::mp11;
94 
95     bool rval = true;
96 
97     std::cout << "*** testing signed values\n";
98 
99     mp_for_each<
100         mp_product<
101             test_signed_pair,
102             signed_test_types,
103             signed_value_indices,
104             signed_value_indices
105         >
106     >([&](auto I){
107         rval &= I();
108     });
109 
110     std::cout << "*** testing unsigned values\n";
111 
112     mp_for_each<
113         mp_product<
114             test_unsigned_pair,
115             unsigned_test_types,
116             unsigned_value_indices, unsigned_value_indices
117         >
118     >([&](auto I){
119         rval &= I();
120     });
121 
122     std::cout << (rval ? "success!" : "failure") << std::endl;
123     return rval ? 0 : 1;
124 }
125