diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index 92aa3d6b4eb..737a52dfc14 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -445,20 +445,16 @@ namespace CartesianKernelFunctors { return cmp_dist_to_pointC2(p.x(), p.y(), q.x(), q.y(), r.x(), r.y()); } - // Slightly wkward, but not to get a false positive in the `test_RT_or_FT_predicate` - // as otherwise trying to compile P2,P2,P2,FT_necessary would match the T1,T2,T3 templated operator() - result_type operator()(const Point_2& p, const Point_2& q, const Point_2& r, FT_necessary) = delete; - template - result_type - operator()(const T1& p, const T2& q, const T3& r, FT_necessary = {}) const + Needs_FT + operator()(const T1& p, const T2& q, const T3& r) const { return CGAL::compare(squared_distance(p, q), squared_distance(p, r)); } template - std::enable_if_t::value, result_type> - operator()(const T1& p, const T2& q, const T3& r, const T4& s, FT_necessary = {}) const + Needs_FT + operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { return CGAL::compare(squared_distance(p, q), squared_distance(r, s)); } @@ -596,15 +592,15 @@ namespace CartesianKernelFunctors { } template - result_type - operator()(const T1& p, const T2& q, const T3& r, FT_necessary = {}) const + Needs_FT + operator()(const T1& p, const T2& q, const T3& r) const { return CGAL::compare(squared_distance(p, q), squared_distance(p, r)); } template - std::enable_if_t::value, result_type> - operator()(const T1& p, const T2& q, const T3& r, const T4& s, FT_necessary = {}) const + Needs_FT + operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { return CGAL::compare(squared_distance(p, q), squared_distance(r, s)); } @@ -3981,8 +3977,8 @@ namespace CartesianKernelFunctors { operator()(const Circle_3 &a, const Point_3 &p) const { return a.rep().has_on(p); } - result_type - operator()(const Sphere_3 &a, const Circle_3 &p, FT_necessary = {}) const + Needs_FT + operator()(const Sphere_3 &a, const Circle_3 &p) const { return a.rep().has_on(p); } result_type diff --git a/Filtered_kernel/include/CGAL/Filtered_predicate.h b/Filtered_kernel/include/CGAL/Filtered_predicate.h index bf3cfdcf21c..90e9a554f75 100644 --- a/Filtered_kernel/include/CGAL/Filtered_predicate.h +++ b/Filtered_kernel/include/CGAL/Filtered_predicate.h @@ -86,15 +86,8 @@ public: template result_type - operator()(const Args&... args) const; -}; - -template - template -typename Filtered_predicate::result_type -Filtered_predicate:: operator()(const Args&... args) const -{ + { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG { @@ -111,7 +104,8 @@ Filtered_predicate:: Protect_FPU_rounding p(CGAL_FE_TONEAREST); CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return ep(c2e(args)...); -} + } +}; template class Filtered_predicate_RT_FT @@ -123,27 +117,17 @@ class Filtered_predicate_RT_FT EP_FT ep_ft; AP ap; - using Ares = typename AP::result_type; + using Ares = typename Remove_needs_FT::Type; public: - using result_type = typename EP_FT::result_type; + using result_type = typename Remove_needs_FT::Type; template struct Call_operator_needs_FT { - // This type traits class checks if the call operator can be called with - // `(const Args&..., FT_necessary())`. - using ArrayOfOne = char[1]; - using ArrayOfTwo = char[2]; - - static ArrayOfOne& test(...); - - template - static auto test(const Args2 &...args) - -> decltype(ap(c2a(args)..., FT_necessary()), - std::declval()); - - enum { value = sizeof(test(std::declval()...)) == sizeof(ArrayOfTwo) }; + using Actual_approx_res = decltype(ap(c2a(std::declval())...)); + using Approx_res = std::remove_cv_t >; + enum { value = std::is_same >::value }; }; // ## Important note @@ -154,9 +138,7 @@ public: // or `has_needs_FT` in // the file `Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h`. template - constexpr bool needs_FT(const Args&...) const { - return Call_operator_needs_FT::value; - } + bool needs_FT(const Args&...) const { return Call_operator_needs_FT::value; } template result_type diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 4bcec963285..1a7065e1a59 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -737,12 +737,12 @@ namespace CommonKernelFunctors { typedef Comparison_result result_type; - result_type operator()(const Weighted_point_3 & p, - const Weighted_point_3 & q, - const Weighted_point_3 & r, - const Weighted_point_3 & s, - const FT& w, - FT_necessary = {}) const + Needs_FT + operator()(const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s, + const FT& w) const { return CGAL::compare(squared_radius_orthogonal_sphereC3( p.x(),p.y(),p.z(),p.weight(), @@ -752,11 +752,11 @@ namespace CommonKernelFunctors { w); } - result_type operator()(const Weighted_point_3 & p, - const Weighted_point_3 & q, - const Weighted_point_3 & r, - const FT& w, - FT_necessary = {}) const + Needs_FT + operator()(const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const FT& w) const { return CGAL::compare(squared_radius_smallest_orthogonal_sphereC3( p.x(),p.y(),p.z(),p.weight(), @@ -765,10 +765,10 @@ namespace CommonKernelFunctors { w); } - result_type operator()(const Weighted_point_3 & p, - const Weighted_point_3 & q, - const FT& w, - FT_necessary = {}) const + Needs_FT + operator()(const Weighted_point_3 & p, + const Weighted_point_3 & q, + const FT& w) const { return CGAL::compare(squared_radius_smallest_orthogonal_sphereC3( p.x(),p.y(),p.z(),p.weight(), @@ -821,15 +821,15 @@ namespace CommonKernelFunctors { typedef typename K::Comparison_result result_type; template - result_type - operator()(const T1& p, const T2& q, const FT& d2, FT_necessary = {}) const + Needs_FT + operator()(const T1& p, const T2& q, const FT& d2) const { return CGAL::compare(internal::squared_distance(p, q, K()), d2); } template - std::enable_if_t::value, result_type> - operator()(const T1& p, const T2& q, const T3& r, const T4& s, FT_necessary = {}) const + Needs_FT + operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { return CGAL::compare(internal::squared_distance(p, q, K()), internal::squared_distance(r, s, K())); @@ -844,15 +844,15 @@ namespace CommonKernelFunctors { typedef typename K::Comparison_result result_type; template - result_type - operator()(const T1& p, const T2& q, const FT& d2, FT_necessary = {}) const + Needs_FT + operator()(const T1& p, const T2& q, const FT& d2) const { return CGAL::compare(internal::squared_distance(p, q, K()), d2); } template - std::enable_if_t::value, result_type> - operator()(const T1& p, const T2& q, const T3& r, const T4& s, FT_necessary = {}) const + Needs_FT + operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { return CGAL::compare(internal::squared_distance(p, q, K()), internal::squared_distance(r, s, K())); @@ -3024,10 +3024,11 @@ namespace CommonKernelFunctors { public: typedef typename K::Boolean result_type; + // Needs FT because Line/Line (and variations) and Circle_2/X compute intersections template - result_type - operator()(const T1& t1, const T2& t2, FT_necessary = {}) const - { return Intersections::internal::do_intersect(t1, t2, K()); } + Needs_FT + operator()(const T1& t1, const T2& t2) const + { return { Intersections::internal::do_intersect(t1, t2, K())}; } }; template @@ -3337,9 +3338,9 @@ namespace CommonKernelFunctors { } // returns true iff the line segment ab is inside the union of the bounded sides of s1 and s2. - result_type operator()(const Sphere_3& s1, const Sphere_3& s2, - const Point_3& a, const Point_3& b, - FT_necessary = {}) const + Needs_FT + operator()(const Sphere_3& s1, const Sphere_3& s2, + const Point_3& a, const Point_3& b) const { typedef typename K::Circle_3 Circle_3; typedef typename K::Point_3 Point_3; diff --git a/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp b/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp index 6a9c564882d..3c56a17f44b 100644 --- a/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp +++ b/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp @@ -15,7 +15,7 @@ // Author(s) : Sylvain Pion // This defines removes the operator/ from CGAL::Mpzf to check that functors not using -// the tag `FT_necessary` really only need a RT (ring type) without division. +// the tag `Needs_FT<>` really only need a RT (ring type) without division. #define CGAL_NO_MPZF_DIVISION_OPERATOR 1 #include diff --git a/STL_Extension/include/CGAL/tags.h b/STL_Extension/include/CGAL/tags.h index dd13818aae9..6aa1988e1cc 100644 --- a/STL_Extension/include/CGAL/tags.h +++ b/STL_Extension/include/CGAL/tags.h @@ -81,9 +81,27 @@ Assert_compile_time_tag( const Tag&, const Derived& b) x.match_compile_time_tag(b); } -// for kernel predicates, to indicate a FT providing a division operator is required -struct FT_necessary {}; +// To distinguish between kernel predicates for which a division-less FT is sufficient +template +struct Needs_FT +{ + T value; + Needs_FT(T v) : value(v) {} + operator T() const { return value; } +}; -} //namespace CGAL +template +struct Remove_needs_FT +{ + using Type = T; +}; + +template +struct Remove_needs_FT > +{ + using Type = T; +}; + +} // namespace CGAL #endif // CGAL_TAGS_H