]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/safe_numerics/test/test_interval.cpp
115f4abd04f96b5b8efb6c3b6ce2082744509ed2
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
)){
85 const boost::logic::tribool b1
= p1
.includes(r1
);
86 const boost::logic::tribool b2
= p2
.includes(r2
);
87 const boost::logic::tribool b3
= result_interval
.includes(result
);
88 const interval
<T
> result_intervalx
= opi
.m_finterval(p1
, p2
);
89 const T resultx
= opi
.m_f(r1
, r2
);
101 // note: need to explicitly specify number of elements to avoid msvc failure
103 const boost::safe_numerics::checked_result
<T
> value
[8] = {
104 boost::safe_numerics::safe_numerics_error::negative_overflow_error
,
105 std::numeric_limits
<T
>::lowest(),
109 std::numeric_limits
<T
>::max(),
110 boost::safe_numerics::safe_numerics_error::positive_overflow_error
,
111 boost::safe_numerics::safe_numerics_error::domain_error
114 // note: need to explicitly specify number of elements to avoid msvc failure
116 const boost::safe_numerics::checked_result
<T
> unsigned_value
[6] = {
117 boost::safe_numerics::safe_numerics_error::negative_overflow_error
,
120 std::numeric_limits
<T
>::max(),
121 boost::safe_numerics::safe_numerics_error::positive_overflow_error
,
122 boost::safe_numerics::safe_numerics_error::domain_error
125 // invoke for each type
127 unsigned int m_error_count
;
132 bool operator()(const T
&){
133 using namespace boost::safe_numerics
;
136 << boost::core::demangle(typeid(T
).name())
139 using R
= checked_result
<T
>;
140 // pointers to operands for types T
141 static const std::array
<op
<R
>, 5> op_table
{{
142 {operator+, operator+, "+", false},
143 {operator-, operator-, "-", false},
144 {operator*, operator*, "*", false},
145 {operator<<, operator<<, "<<", false},
146 {operator>>, operator>>, ">>", false},
149 //for(unsigned int i = 0; i < sizeof(op_table)/sizeof(op) / sizeof(fptr<R>); ++i){
150 for(const op
<R
> & o
: op_table
){
151 if(std::is_signed
<T
>::value
){
152 if(! test_type_operator(value
<T
>, o
)){
158 if(! test_type_operator(unsigned_value
<T
>, o
)){
168 #include <boost/mp11/list.hpp>
169 #include <boost/mp11/algorithm.hpp>
171 int main(int, char *[]){
172 using namespace boost::mp11
;
173 // list of signed types
174 using signed_types
= mp_list
<std::int8_t, std::int16_t, std::int32_t, std::int64_t>;
175 // list of unsigned types
176 using unsigned_types
= mp_list
<std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t>;
179 mp_for_each
<unsigned_types
>(t
);
180 mp_for_each
<signed_types
>(t
);
182 std::cout
<< (t
.m_error_count
== 0 ? "success!" : "failure") << std::endl
;
183 return t
.m_error_count
;