• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BOOST_TEST_DIVIDE_HPP
2 #define BOOST_TEST_DIVIDE_HPP
3 
4 //  Copyright (c) 2015 Robert Ramey
5 //
6 // Distributed under the Boost Software License, Version 1.0. (See
7 // accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 
10 #include <iostream>
11 #include <boost/core/demangle.hpp>
12 
13 #include <boost/safe_numerics/safe_integer.hpp>
14 #include <boost/safe_numerics/range_value.hpp>
15 
16 template<class T1, class T2>
test_divide(T1 v1,T2 v2,const char * av1,const char * av2,char expected_result)17 bool test_divide(
18     T1 v1,
19     T2 v2,
20     const char *av1,
21     const char *av2,
22     char expected_result
23 ){
24     {
25         safe_t<T1> t1 = v1;
26         using result_type = decltype(t1 / v2);
27         std::cout
28             << "safe<" << av1 << "> / " << av2 << " -> "
29             << boost::core::demangle(typeid(result_type).name()) << '\n';
30         static_assert(
31             boost::safe_numerics::is_safe<safe_t<T1> >::value,
32             "safe_t not safe!"
33         );
34         static_assert(
35             boost::safe_numerics::is_safe<result_type>::value,
36             "Expression failed to return safe type"
37         );
38 
39         try{
40             // use auto to avoid checking assignment.
41             auto result = t1 / v2;
42             std::cout << make_result_display(result);
43             if(expected_result == 'x'){
44                 std::cout << " *** failed to detect error in division" << std::endl;
45                 t1 / v2;
46                 return false;
47             }
48             std::cout << std::endl;
49         }
50         catch(const std::exception &){
51             if(expected_result == '.'){
52                 std::cout << " *** erroneously detected error in division" << std::endl;
53                 try{
54                     t1 / v2;
55                 }
56                 catch(const std::exception &){}
57                 return false;
58             }
59         }
60     }
61     {
62         safe_t<T2> t2 = v2;
63         using result_type = decltype(v1 / t2);
64         std::cout
65             << "safe<" << av1 << "> / " << av2 << " -> "
66             << boost::core::demangle(typeid(result_type).name()) << '\n';
67 
68         static_assert(
69             boost::safe_numerics::is_safe<safe_t<T2> >::value,
70             "safe_t not safe!"
71         );
72         static_assert(
73             boost::safe_numerics::is_safe<result_type>::value,
74             "Expression failed to return safe type"
75         );
76         try{
77             // use auto to avoid checking assignment.
78             auto result = v1 / t2;
79             std::cout << make_result_display(result);
80             if(expected_result == 'x'){
81                 std::cout << " *** failed to detect error in division " << std::endl;
82                 v1 / t2;
83                 return false;
84             }
85             std::cout << std::endl;
86         }
87         catch(const std::exception &){
88             if(expected_result == '.'){
89                 std::cout << "*** erroneously detected error in division " << std::endl;
90                 try{
91                     v1 / t2;
92                 }
93                 catch(const std::exception &){}
94                 // assert(result == unsafe_result);
95                 return false;
96             }
97         }
98     }
99     {
100         safe_t<T1> t1 = v1;
101         safe_t<T2> t2 = v2;
102         using result_type = decltype(t1 / t2);
103         std::cout
104             << "testing  safe<" << av1 << "> / safe<" << av2 << "> -> "
105             << boost::core::demangle(typeid(result_type).name()) << '\n';
106 
107         static_assert(
108             boost::safe_numerics::is_safe<result_type>::value,
109             "Expression failed to return safe type"
110         );
111 
112         try{
113             // use auto to avoid checking assignment.
114             auto result = t1 / t2;
115             std::cout << make_result_display(result);
116             if(expected_result == 'x'){
117                 std::cout << " *** failed to detect error in division" << std::endl;
118                 t1 / t2;
119                 return false;
120             }
121             std::cout << std::endl;
122         }
123         catch(const std::exception &){
124             if(expected_result == '.'){
125                 std::cout << " *** erroneously detected error in division \\" << std::endl;
126                 try{
127                     t1 / t2;
128                 }
129                 catch(const std::exception &){}
130                 return false;
131             }
132         }
133     }
134     return true;
135 }
136 
137 #endif // BOOST_TEST_DIVIDE
138