24 #ifndef PPL_Boundary_defs_hh
25 #define PPL_Boundary_defs_hh 1
31 namespace Boundary_NS {
65 template <
typename T,
typename Info>
68 PPL_ASSERT(Info::store_special);
69 info.set_boundary_property(type,
SPECIAL);
73 template <
typename T,
typename Info>
76 return !Info::may_contain_infinity;
79 template <
typename T,
typename Info>
82 if (Info::store_open) {
83 return info.get_boundary_property(type,
OPEN);
86 return !Info::store_special && !Info::may_contain_infinity
91 template <
typename T,
typename Info>
94 if (Info::store_open) {
95 return info.get_boundary_property(type,
OPEN);
98 return !Info::may_contain_infinity
103 template <
typename T,
typename Info>
107 || std::numeric_limits<T>::is_bounded
108 || std::numeric_limits<T>::has_infinity,
109 "unbounded is not representable");
111 if (Info::store_special) {
114 else if (type ==
LOWER) {
121 info.set_boundary_property(type,
OPEN);
126 template <
typename T,
typename Info>
130 PPL_ASSERT(type ==
LOWER);
133 PPL_ASSERT(Info::may_contain_infinity);
136 if (Info::store_special) {
137 PPL_ASSERT(type ==
LOWER);
145 info.set_boundary_property(type,
OPEN);
150 template <
typename T,
typename Info>
154 PPL_ASSERT(type ==
UPPER);
157 PPL_ASSERT(Info::may_contain_infinity);
160 if (Info::store_special) {
161 PPL_ASSERT(type ==
UPPER);
169 info.set_boundary_property(type,
OPEN);
174 template <
typename T,
typename Info>
177 PPL_ASSERT(open || Info::may_contain_infinity);
179 if (Info::store_special) {
182 else if (type ==
LOWER) {
190 info.set_boundary_property(type,
OPEN);
195 template <
typename T,
typename Info>
198 if (Info::store_special && type ==
LOWER) {
199 return info.get_boundary_property(type,
SPECIAL);
201 else if (std::numeric_limits<T>::has_infinity) {
204 else if (std::numeric_limits<T>::is_bounded) {
205 return x == std::numeric_limits<T>::min();
212 template <
typename T,
typename Info>
215 if (Info::store_special && type ==
UPPER) {
216 return info.get_boundary_property(type,
SPECIAL);
218 else if (std::numeric_limits<T>::has_infinity) {
221 else if (std::numeric_limits<T>::is_bounded) {
222 return x == std::numeric_limits<T>::max();
229 template <
typename T,
typename Info>
232 if (!std::numeric_limits<T>::has_infinity) {
243 template <
typename T,
typename Info>
246 if (Info::store_special) {
247 return info.get_boundary_property(type,
SPECIAL);
254 template <
typename T,
typename Info>
257 if (!Info::may_contain_infinity) {
260 else if (type ==
LOWER) {
268 template <
typename T,
typename Info>
272 if (Info::store_special) {
273 return info.get_boundary_property(type,
SPECIAL);
284 template <
typename T,
typename Info>
288 if (Info::store_special) {
289 return info.get_boundary_property(type,
SPECIAL);
300 template <
typename T,
typename Info>
306 template <
typename T,
typename Info>
310 return (type ==
LOWER) ? -1 : 1;
313 return (type ==
UPPER) ? -1 : 1;
320 template <
typename T,
typename Info>
323 return Info::may_contain_infinity
324 && !info.get_boundary_property(type,
OPEN)
328 template <
typename Info>
331 return !Info::may_contain_infinity
332 || info.get_boundary_property(type,
OPEN);
335 template <
typename T,
typename Info>
338 if (info.get_boundary_property(type,
SPECIAL)) {
339 return (type ==
LOWER) ? -1 : 1;
348 template <
typename T,
typename Info>
351 int sign =
sgn_b(type, x, info);
352 if (x == 0 && info.get_boundary_property(type,
OPEN)) {
353 return (type ==
LOWER) ? -1 : 1;
360 template <
typename T1,
typename Info1,
typename T2,
typename Info2>
364 if (type1 == type2) {
366 !=
is_open(type2, x2, info2)) {
370 else if (
is_open(type1, x1, info1)
371 ||
is_open(type2, x2, info2)) {
385 return equal(x1, x2);
389 template <
typename T1,
typename Info1,
typename T2,
typename Info2>
393 if (
is_open(type1, x1, info1)) {
396 || !
is_open(type2, x2, info2))) {
400 else if (type2 ==
LOWER
401 &&
is_open(type2, x2, info2)) {
412 return less_or_equal(x1, x2);
424 return less_than(x1, x2);
428 template <
typename T1,
typename Info1,
typename T2,
typename Info2>
432 return lt(type2, x2, info2, type1, x1, info1);
435 template <
typename T1,
typename Info1,
typename T2,
typename Info2>
439 return !
gt(type1, x1, info1, type2, x2, info2);
442 template <
typename T1,
typename Info1,
typename T2,
typename Info2>
446 return !
lt(type1, x1, info1, type2, x2, info2);
449 template <
typename T,
typename Info>
460 if (!Info::store_special) {
464 info.set_boundary_property(type,
OPEN);
473 info.set_boundary_property(type,
OPEN);
487 if (!Info::store_special) {
491 info.set_boundary_property(type,
OPEN);
500 info.set_boundary_property(type,
OPEN);
510 template <
typename To,
typename To_Info,
typename T,
typename Info>
514 PPL_ASSERT(to_type != type);
516 if (info.get_boundary_property(type,
SPECIAL)) {
526 bool check = (To_Info::check_inexact || (!should_shrink && To_Info::store_open));
531 template <
typename To,
typename To_Info,
typename T,
typename Info>
535 bool should_shrink =
false) {
536 PPL_ASSERT(to_type == type);
537 if (info.get_boundary_property(type,
SPECIAL)) {
543 = (To_Info::check_inexact || (!should_shrink && To_Info::store_open));
548 template <
typename To,
typename To_Info,
typename T,
typename Info>
552 if (
lt(type, x, info, to_type, to, to_info)) {
553 to_info.clear_boundary_properties(to_type);
554 return assign(to_type, to, to_info, type, x, info);
559 template <
typename To,
typename To_Info,
typename T1,
typename Info1,
typename T2,
typename Info2>
564 if (
lt(type1, x1, info1, type2, x2, info2)) {
565 return assign(to_type, to, to_info, type1, x1, info1);
568 return assign(to_type, to, to_info, type2, x2, info2);
572 template <
typename To,
typename To_Info,
typename T,
typename Info>
576 if (
gt(type, x, info, to_type, to, to_info)) {
577 to_info.clear_boundary_properties(to_type);
578 return assign(to_type, to, to_info, type, x, info);
583 template <
typename To,
typename To_Info,
typename T1,
typename Info1,
typename T2,
typename Info2>
588 if (
gt(type1, x1, info1, type2, x2, info2)) {
589 return assign(to_type, to, to_info, type1, x1, info1);
592 return assign(to_type, to, to_info, type2, x2, info2);
596 template <
typename To,
typename To_Info,
typename T,
typename Info>
600 PPL_ASSERT(to_type != type);
602 if (info.get_boundary_property(type,
SPECIAL)) {
607 bool check = (To_Info::check_inexact || (!should_shrink && To_Info::store_open));
612 template <
typename To,
typename To_Info,
typename T1,
typename Info1,
typename T2,
typename Info2>
617 PPL_ASSERT(type1 == type2);
631 bool check = (To_Info::check_inexact || (!should_shrink && To_Info::store_open));
637 template <
typename To,
typename To_Info,
typename T1,
typename Info1,
typename T2,
typename Info2>
642 PPL_ASSERT(type1 != type2);
656 bool check = (To_Info::check_inexact || (!should_shrink && To_Info::store_open));
662 template <
typename To,
typename To_Info,
typename T1,
typename Info1,
typename T2,
typename Info2>
680 bool check = (To_Info::check_inexact || (!should_shrink && To_Info::store_open));
687 template <
typename To,
typename To_Info>
690 bool check = (To_Info::check_inexact || (!should_shrink && To_Info::store_open));
695 template <
typename To,
typename To_Info,
typename T1,
typename Info1,
typename T2,
typename Info2>
698 Boundary_Type type1,
const T1& x1,
const Info1& info1,
int x1s,
699 Boundary_Type type2,
const T2& x2,
const Info2& info2,
int x2s) {
708 should_shrink = info2.get_boundary_property(type2,
OPEN);
712 should_shrink = (info1.get_boundary_property(type1,
OPEN)
713 && (x2s != 0 || info2.get_boundary_property(type2,
OPEN)));
715 return set_zero(to_type, to, to_info, should_shrink);
718 template <
typename To,
typename To_Info,
typename T1,
typename Info1,
typename T2,
typename Info2>
730 return set_zero(to_type, to, to_info, should_shrink);
734 bool check = (To_Info::check_inexact || (!should_shrink && To_Info::store_open));
742 template <
typename To,
typename To_Info,
typename T1,
typename Info1,
typename T2,
typename Info2>
745 Boundary_Type type1,
const T1& x1,
const Info1& info1,
int x1s,
746 Boundary_Type type2,
const T2& x2,
const Info2& info2,
int x2s) {
758 bool should_shrink = info1.get_boundary_property(type1,
OPEN)
760 return set_zero(to_type, to, to_info, should_shrink);
764 template <
typename To,
typename To_Info,
typename T,
typename Info>
769 PPL_ASSERT(to_type == type);
776 bool check = (To_Info::check_inexact || (!should_shrink && To_Info::store_open));
781 template <
typename To,
typename To_Info,
typename T,
typename Info>
786 PPL_ASSERT(to_type == type);
793 bool check = (To_Info::check_inexact || (!should_shrink && To_Info::store_open));
802 #endif // !defined(PPL_Boundary_defs_hh)
Enable_If< Is_Native_Or_Checked< To >::value &&Is_Special< From >::value, Result >::type assign_r(To &to, const From &, Rounding_Dir dir)
bool normal_is_boundary_infinity(Boundary_Type type, const T &x, const Info &)
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type is_minus_infinity(const T &x)
The computed result is exact.
bool normal_is_reverse_infinity(Boundary_Type type, const T &x, const Info &)
Result div_assign_z(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type1, const T1 &x1, const Info1 &info1, int x1s, Boundary_Type type2, const T2 &x2, const Info2 &info2, int x2s)
Result set_minus_infinity(Boundary_Type type, T &x, Info &info, bool open=false)
static const Value default_value
Rounding_Dir
Rounding directions for arithmetic computations.
Result set_plus_infinity(Boundary_Type type, T &x, Info &info, bool open=false)
A positive integer overflow occurred (rounding up).
bool lt(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
int infinity_sign(Boundary_Type type, const T &x, const Info &info)
Result
Possible outcomes of a checked arithmetic computation.
From bool Type Type Rounding_Dir To
Result special_set_boundary_infinity(Boundary_Type type, T &, Info &info)
bool gt(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
bool is_reverse_infinity(Boundary_Type type, const T &x, const Info &info)
Rounding_Dir round_dir_check(Boundary_Type t, bool check=false)
bool is_domain_inf(Boundary_Type type, const T &x, const Info &info)
Result_Relation result_relation(Result r)
Result set_zero(Boundary_Type to_type, To &to, To_Info &to_info, bool should_shrink)
bool is_minus_infinity(Boundary_Type type, const T &x, const Info &info)
static const Property OPEN(Property::OPEN_)
The computed result is inexact and rounded down.
static const Property SPECIAL(Property::SPECIAL_)
Result assign(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type, const T &x, const Info &info, bool should_shrink=false)
Result neg_assign(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type, const T &x, const Info &info)
#define PPL_COMPILE_TIME_CHECK(e, msg)
Produces a compilation error if the compile-time constant e does not evaluate to true ...
bool is_open(Boundary_Type type, const T &x, const Info &info)
Result div_assign(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
Negative infinity result.
Equal. This need to be accompanied by a value.
static const Value unsupported_value
bool is_plus_infinity(Boundary_Type type, const T &x, const Info &info)
bool eq(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
Result result_relation_class(Result r)
Result sub_assign(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type is_plus_infinity(const T &x)
Result mul_assign_z(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type1, const T1 &x1, const Info1 &info1, int x1s, Boundary_Type type2, const T2 &x2, const Info2 &info2, int x2s)
bool ge(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
bool boundary_infinity_is_open(Boundary_Type type, const Info &info)
bool normal_is_open(Boundary_Type type, const T &x, const Info &info)
Result set_unbounded(Boundary_Type type, T &x, Info &info)
The computed result may be inexact and rounded up.
Result umod_2exp_assign(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type, const T &x, const Info &info, unsigned int exp)
Result complement(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type, const T &x, const Info &info)
Result mul_assign(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
Plus_Infinity PLUS_INFINITY
The entire library is confined to this namespace.
Minus_Infinity MINUS_INFINITY
Result add_assign(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
The computed result may be inexact and rounded down.
int sgn_b(Boundary_Type type, const T &x, const Info &info)
Result smod_2exp_assign(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type, const T &x, const Info &info, unsigned int exp)
int sgn(Boundary_Type type, const T &x, const Info &info)
Positive infinity result.
A negative integer overflow occurred (rounding down).
Result min_assign(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type, const T &x, const Info &info)
Result adjust_boundary(Boundary_Type type, T &x, Info &info, bool open, Result r)
bool special_is_open(Boundary_Type, const T &, const Info &)
bool result_representable(Result r)
The computed result is inexact and rounded up.
Result max_assign(Boundary_Type to_type, To &to, To_Info &to_info, Boundary_Type type, const T &x, const Info &info)
bool is_boundary_infinity_closed(Boundary_Type type, const T &x, const Info &info)
bool le(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
bool is_domain_sup(Boundary_Type type, const T &x, const Info &info)
bool is_boundary_infinity(Boundary_Type type, const T &x, const Info &info)
Result set_boundary_infinity(Boundary_Type type, T &x, Info &info, bool open=false)