]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/safe_numerics/test/test_interval.cpp
1 // Copyright (c) 2012 Robert Ramey
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)
12 #include <boost/core/demangle.hpp>
13 #include <boost/safe_numerics/checked_result.hpp>
14 #include <boost/safe_numerics/checked_result_operations.hpp>
15 #include <boost/safe_numerics/interval.hpp>
18 using fptr
= T (*)(const T
&, const T
&);
20 using fptr_interval
= fptr
<boost::safe_numerics::interval
<T
>>;
25 const fptr_interval
<T
> m_finterval
;
26 const char * m_symbol
;
27 const bool skip_zeros
;
34 bool test_type_operator(
38 using namespace boost::safe_numerics
;
40 // for each pair of values p1, p2 (100)
41 for(const T
& l1
: value
)
42 for(const T
& u1
: value
){
43 if(l1
> u1
) continue; // skip reverse range
44 const interval
<T
> p1(l1
, u1
);
45 for(const T
& l2
: value
)
46 for(const T
& u2
: value
){
47 if(l2
> u2
) continue; // skip reverse range
48 const interval
<T
> p2(l2
, u2
);
50 // maybe skip intervals which include zero
52 if(l2
== safe_numerics_error::range_error
53 || l2
== safe_numerics_error::domain_error
54 || u2
== safe_numerics_error::range_error
55 || u2
== safe_numerics_error::domain_error
61 // create a new interval from the operation
62 const interval
<T
> result_interval
= opi
.m_finterval(p1
, p2
);
64 << p1
<< opi
.m_symbol
<< p2
<< " -> " << result_interval
<< std::endl
;
66 // if resulting interval is null
67 if(result_interval
.u
< result_interval
.l
)
70 // for each pair test values
71 for(const T r1
: value
)
72 for(const T r2
: value
){
73 // calculate result of operation
74 const T result
= opi
.m_f(r1
, r2
);
75 if(result
!= safe_numerics_error::range_error
76 && result
!= safe_numerics_error::domain_error
){
77 // note usage of tribool logic here !!!
78 // includes returns indeterminate the conditional
79 // returns false in both cases and this is what we want.
80 // This is very subtle, don't skim over this.
81 // if both r1 and r2 are within they're respective bounds
82 if(p1
.includes(r1
) && p2
.includes(r2
)
83 && ! result_interval
.includes(result
)){
94 // note: need to explicitly specify number of elements to avoid msvc failure
96 const boost::safe_numerics::checked_result
<T
> value
[8] = {
97 boost::safe_numerics::safe_numerics_error::negative_overflow_error
,
98 std::numeric_limits
<T
>::lowest(),
102 std::numeric_limits
<T
>::max(),
103 boost::safe_numerics::safe_numerics_error::positive_overflow_error
,
104 boost::safe_numerics::safe_numerics_error::domain_error
107 // note: need to explicitly specify number of elements to avoid msvc failure
109 const boost::safe_numerics::checked_result
<T
> unsigned_value
[6] = {
110 boost::safe_numerics::safe_numerics_error::negative_overflow_error
,
113 std::numeric_limits
<T
>::max(),
114 boost::safe_numerics::safe_numerics_error::positive_overflow_error
,
115 boost::safe_numerics::safe_numerics_error::domain_error
118 // invoke for each type
120 unsigned int m_error_count
;
125 bool operator()(const T
&){
126 using namespace boost::safe_numerics
;
129 << boost::core::demangle(typeid(T
).name())
132 using R
= checked_result
<T
>;
133 // pointers to operands for types T
134 static const std::array
<op
<R
>, 5> op_table
{{
135 {operator+, operator+, "+", false},
136 {operator-, operator-, "-", false},
137 {operator*, operator*, "*", false},
138 {operator<<, operator<<, "<<", false},
139 {operator>>, operator>>, ">>", false},
142 //for(unsigned int i = 0; i < sizeof(op_table)/sizeof(op) / sizeof(fptr<R>); ++i){
143 for(const op
<R
> & o
: op_table
){
144 if(std::is_signed
<T
>::value
){
145 if(! test_type_operator(value
<T
>, o
)){
151 if(! test_type_operator(unsigned_value
<T
>, o
)){
161 #include <boost/mp11/list.hpp>
162 #include <boost/mp11/algorithm.hpp>
164 int main(int, char *[]){
165 using namespace boost::mp11
;
166 // list of signed types
167 using signed_types
= mp_list
<std::int8_t, std::int16_t, std::int32_t, std::int64_t>;
168 // list of unsigned types
169 using unsigned_types
= mp_list
<std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t>;
172 mp_for_each
<unsigned_types
>(t
);
173 mp_for_each
<signed_types
>(t
);
175 std::cout
<< (t
.m_error_count
== 0 ? "success!" : "failure") << std::endl
;
176 return t
.m_error_count
;