diff --git a/Cartesian_kernel/include/CGAL/predicates/kernel_ftC2.h b/Cartesian_kernel/include/CGAL/predicates/kernel_ftC2.h index c386fba7c15..eae01beefcc 100644 --- a/Cartesian_kernel/include/CGAL/predicates/kernel_ftC2.h +++ b/Cartesian_kernel/include/CGAL/predicates/kernel_ftC2.h @@ -295,16 +295,18 @@ CGAL_KERNEL_MEDIUM_INLINE typename Compare::result_type compare_slopesC2(const FT &l1a, const FT &l1b, const FT &l2a, const FT &l2b) { + typedef typename Compare::result_type result_type; + if (CGAL_NTS is_zero(l1a)) // l1 is horizontal - return CGAL_NTS is_zero(l2b) ? SMALLER + return CGAL_NTS is_zero(l2b) ? result_type(SMALLER) : CGAL_NTS sign(l2a) * CGAL_NTS sign(l2b); if (CGAL_NTS is_zero(l2a)) // l2 is horizontal - return CGAL_NTS is_zero(l1b) ? LARGER + return CGAL_NTS is_zero(l1b) ? result_type(LARGER) : - CGAL_NTS sign(l1a) * CGAL_NTS sign(l1b); if (CGAL_NTS is_zero(l1b)) return CGAL_NTS is_zero(l2b) ? EQUAL : LARGER; if (CGAL_NTS is_zero(l2b)) return SMALLER; - int l1_sign = - CGAL_NTS sign(l1a) * CGAL_NTS sign(l1b); - int l2_sign = - CGAL_NTS sign(l2a) * CGAL_NTS sign(l2b); + result_type l1_sign = - CGAL_NTS sign(l1a) * CGAL_NTS sign(l1b); + result_type l2_sign = - CGAL_NTS sign(l2a) * CGAL_NTS sign(l2b); if (l1_sign < l2_sign) return SMALLER; if (l1_sign > l2_sign) return LARGER; diff --git a/Filtered_kernel/include/CGAL/Uncertain.h b/Filtered_kernel/include/CGAL/Uncertain.h index 8fba62975d6..ab5352f0c06 100644 --- a/Filtered_kernel/include/CGAL/Uncertain.h +++ b/Filtered_kernel/include/CGAL/Uncertain.h @@ -278,6 +278,105 @@ Uncertain operator!=(const T & a, Uncertain const& b) } +// Comparison operators (useful for enums only, I guess (?) ). + +template < typename T > +inline +Uncertain operator<(Uncertain a, Uncertain b) +{ + if (a.sup() < b.inf()) + return true; + if (a.inf() >= b.sup()) + return false; + return Uncertain::indeterminate(); +} + +template < typename T > +inline +Uncertain operator<(Uncertain a, T b) +{ + if (a.sup() < b) + return true; + if (a.inf() >= b) + return false; + return Uncertain::indeterminate(); +} + +template < typename T > +inline +Uncertain operator<(T a, Uncertain b) +{ + if (a < b.inf()) + return true; + if (a >= b.sup()) + return false; + return Uncertain::indeterminate(); +} + +template < typename T > +inline +Uncertain operator>(Uncertain a, Uncertain b) +{ + return b < a; +} + +template < typename T > +inline +Uncertain operator>(Uncertain a, T b) +{ + return b < a; +} + +template < typename T > +inline +Uncertain operator>(T a, Uncertain b) +{ + return b < a; +} + +template < typename T > +inline +Uncertain operator<=(Uncertain a, Uncertain b) +{ + return !(b < a); +} + +template < typename T > +inline +Uncertain operator<=(Uncertain a, T b) +{ + return !(b < a); +} + +template < typename T > +inline +Uncertain operator<=(T a, Uncertain b) +{ + return !(b < a); +} + +template < typename T > +inline +Uncertain operator>=(Uncertain a, Uncertain b) +{ + return !(a < b); +} + +template < typename T > +inline +Uncertain operator>=(Uncertain a, T b) +{ + return !(a < b); +} + +template < typename T > +inline +Uncertain operator>=(T a, Uncertain b) +{ + return !(a < b); +} + + // Maker function (a la std::make_pair). template < typename T > @@ -296,13 +395,61 @@ const Uncertain & make_uncertain(const Uncertain &t) // opposite -template < typename T > +template < typename T > // should be constrained only for enums. inline -Uncertain opposite(const Uncertain &u) +Uncertain operator-(const Uncertain &u) { - return Uncertain(opposite(u.sup()), opposite(u.inf())); + return Uncertain(-u.sup(), -u.inf()); } +// "sign" multiplication. +// Should be constrained only for "sign" enums, useless for bool. +// Well, Uncertain<> should probably be split into Uncertain_bool (std::bool_set) and Uncertain_enum<>. +template < typename T > +Uncertain operator*(Uncertain a, Uncertain b) +{ + if (a.inf() >= 0) // e>=0 + { + // b>=0 [a.inf()*b.inf(); a.sup()*b.sup()] + // b<=0 [a.sup()*b.inf(); a.inf()*b.sup()] + // b~=0 [a.sup()*b.inf(); a.sup()*b.sup()] + T aa = a.inf(), bb = a.sup(); + if (b.inf() < 0) + { + aa = bb; + if (b.sup() < 0) + bb = a.inf(); + } + return Uncertain(aa * b.inf(), bb * b.sup()); + } + else if (a.sup()<=0) // e<=0 + { + // b>=0 [a.inf()*b.sup(); a.sup()*b.inf()] + // b<=0 [a.sup()*b.sup(); a.inf()*b.inf()] + // b~=0 [a.inf()*b.sup(); a.inf()*b.inf()] + T aa = a.sup(), bb = a.inf(); + if (b.inf() < 0) + { + aa=bb; + if (b.sup() < 0) + bb=a.sup(); + } + return Uncertain(bb * b.sup(), aa * b.inf()); + } + else // 0 \in [inf();sup()] + { + if (b.inf()>=0) // d>=0 + return Uncertain(a.inf() * b.sup(), a.sup() * b.sup()); + if (b.sup()<=0) // d<=0 + return Uncertain(a.sup() * b.inf(), a.inf() * b.inf()); + // 0 \in d + T tmp1 = a.inf() * b.sup(); + T tmp2 = a.sup() * b.inf(); + T tmp3 = a.inf() * b.inf(); + T tmp4 = a.sup() * b.sup(); + return Uncertain((std::min)(tmp1, tmp2), (std::max)(tmp3, tmp4)); + } +} // enum_cast overload