mirror of https://github.com/CGAL/cgal
Revert back to wrapping result_type to distinguish FT-necessary operator()s
This commit is contained in:
parent
9d40a225ff
commit
2c23a6d5c5
|
|
@ -445,20 +445,16 @@ namespace CartesianKernelFunctors {
|
||||||
return cmp_dist_to_pointC2(p.x(), p.y(), q.x(), q.y(), r.x(), r.y());
|
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 <class T1, class T2, class T3>
|
template <class T1, class T2, class T3>
|
||||||
result_type
|
Needs_FT<result_type>
|
||||||
operator()(const T1& p, const T2& q, const T3& r, FT_necessary = {}) const
|
operator()(const T1& p, const T2& q, const T3& r) const
|
||||||
{
|
{
|
||||||
return CGAL::compare(squared_distance(p, q), squared_distance(p, r));
|
return CGAL::compare(squared_distance(p, q), squared_distance(p, r));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
template <class T1, class T2, class T3, class T4>
|
||||||
std::enable_if_t<!std::is_same<T4, FT_necessary>::value, result_type>
|
Needs_FT<result_type>
|
||||||
operator()(const T1& p, const T2& q, const T3& r, const T4& s, FT_necessary = {}) const
|
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));
|
return CGAL::compare(squared_distance(p, q), squared_distance(r, s));
|
||||||
}
|
}
|
||||||
|
|
@ -596,15 +592,15 @@ namespace CartesianKernelFunctors {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T1, class T2, class T3>
|
template <class T1, class T2, class T3>
|
||||||
result_type
|
Needs_FT<result_type>
|
||||||
operator()(const T1& p, const T2& q, const T3& r, FT_necessary = {}) const
|
operator()(const T1& p, const T2& q, const T3& r) const
|
||||||
{
|
{
|
||||||
return CGAL::compare(squared_distance(p, q), squared_distance(p, r));
|
return CGAL::compare(squared_distance(p, q), squared_distance(p, r));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
template <class T1, class T2, class T3, class T4>
|
||||||
std::enable_if_t<!std::is_same<T4, FT_necessary>::value, result_type>
|
Needs_FT<result_type>
|
||||||
operator()(const T1& p, const T2& q, const T3& r, const T4& s, FT_necessary = {}) const
|
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));
|
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
|
operator()(const Circle_3 &a, const Point_3 &p) const
|
||||||
{ return a.rep().has_on(p); }
|
{ return a.rep().has_on(p); }
|
||||||
|
|
||||||
result_type
|
Needs_FT<result_type>
|
||||||
operator()(const Sphere_3 &a, const Circle_3 &p, FT_necessary = {}) const
|
operator()(const Sphere_3 &a, const Circle_3 &p) const
|
||||||
{ return a.rep().has_on(p); }
|
{ return a.rep().has_on(p); }
|
||||||
|
|
||||||
result_type
|
result_type
|
||||||
|
|
|
||||||
|
|
@ -86,15 +86,8 @@ public:
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
result_type
|
result_type
|
||||||
operator()(const Args&... args) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <typename... Args>
|
|
||||||
typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_predicate<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const Args&... args) const
|
operator()(const Args&... args) const
|
||||||
{
|
{
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
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
|
// Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG
|
||||||
{
|
{
|
||||||
|
|
@ -111,7 +104,8 @@ Filtered_predicate<EP,AP,C2E,C2A,Protection>::
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
||||||
CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST);
|
CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST);
|
||||||
return ep(c2e(args)...);
|
return ep(c2e(args)...);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <class EP_RT, class EP_FT, class AP, class C2E_RT, class C2E_FT, class C2A, bool Protection = true>
|
template <class EP_RT, class EP_FT, class AP, class C2E_RT, class C2E_FT, class C2A, bool Protection = true>
|
||||||
class Filtered_predicate_RT_FT
|
class Filtered_predicate_RT_FT
|
||||||
|
|
@ -123,27 +117,17 @@ class Filtered_predicate_RT_FT
|
||||||
EP_FT ep_ft;
|
EP_FT ep_ft;
|
||||||
AP ap;
|
AP ap;
|
||||||
|
|
||||||
using Ares = typename AP::result_type;
|
using Ares = typename Remove_needs_FT<typename AP::result_type>::Type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using result_type = typename EP_FT::result_type;
|
using result_type = typename Remove_needs_FT<typename EP_FT::result_type>::Type;
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
struct Call_operator_needs_FT
|
struct Call_operator_needs_FT
|
||||||
{
|
{
|
||||||
// This type traits class checks if the call operator can be called with
|
using Actual_approx_res = decltype(ap(c2a(std::declval<const Args&>())...));
|
||||||
// `(const Args&..., FT_necessary())`.
|
using Approx_res = std::remove_cv_t<std::remove_reference_t<Actual_approx_res> >;
|
||||||
using ArrayOfOne = char[1];
|
enum { value = std::is_same<Approx_res, Needs_FT<Ares> >::value };
|
||||||
using ArrayOfTwo = char[2];
|
|
||||||
|
|
||||||
static ArrayOfOne& test(...);
|
|
||||||
|
|
||||||
template <typename... Args2>
|
|
||||||
static auto test(const Args2 &...args)
|
|
||||||
-> decltype(ap(c2a(args)..., FT_necessary()),
|
|
||||||
std::declval<ArrayOfTwo &>());
|
|
||||||
|
|
||||||
enum { value = sizeof(test(std::declval<const Args&>()...)) == sizeof(ArrayOfTwo) };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ## Important note
|
// ## Important note
|
||||||
|
|
@ -154,9 +138,7 @@ public:
|
||||||
// or `has_needs_FT<typename R::Compare_distance_3>` in
|
// or `has_needs_FT<typename R::Compare_distance_3>` in
|
||||||
// the file `Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h`.
|
// the file `Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h`.
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
constexpr bool needs_FT(const Args&...) const {
|
bool needs_FT(const Args&...) const { return Call_operator_needs_FT<Args...>::value; }
|
||||||
return Call_operator_needs_FT<Args...>::value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
result_type
|
result_type
|
||||||
|
|
|
||||||
|
|
@ -737,12 +737,12 @@ namespace CommonKernelFunctors {
|
||||||
|
|
||||||
typedef Comparison_result result_type;
|
typedef Comparison_result result_type;
|
||||||
|
|
||||||
result_type operator()(const Weighted_point_3 & p,
|
Needs_FT<result_type>
|
||||||
const Weighted_point_3 & q,
|
operator()(const Weighted_point_3 & p,
|
||||||
const Weighted_point_3 & r,
|
const Weighted_point_3 & q,
|
||||||
const Weighted_point_3 & s,
|
const Weighted_point_3 & r,
|
||||||
const FT& w,
|
const Weighted_point_3 & s,
|
||||||
FT_necessary = {}) const
|
const FT& w) const
|
||||||
{
|
{
|
||||||
return CGAL::compare(squared_radius_orthogonal_sphereC3(
|
return CGAL::compare(squared_radius_orthogonal_sphereC3(
|
||||||
p.x(),p.y(),p.z(),p.weight(),
|
p.x(),p.y(),p.z(),p.weight(),
|
||||||
|
|
@ -752,11 +752,11 @@ namespace CommonKernelFunctors {
|
||||||
w);
|
w);
|
||||||
}
|
}
|
||||||
|
|
||||||
result_type operator()(const Weighted_point_3 & p,
|
Needs_FT<result_type>
|
||||||
const Weighted_point_3 & q,
|
operator()(const Weighted_point_3 & p,
|
||||||
const Weighted_point_3 & r,
|
const Weighted_point_3 & q,
|
||||||
const FT& w,
|
const Weighted_point_3 & r,
|
||||||
FT_necessary = {}) const
|
const FT& w) const
|
||||||
{
|
{
|
||||||
return CGAL::compare(squared_radius_smallest_orthogonal_sphereC3(
|
return CGAL::compare(squared_radius_smallest_orthogonal_sphereC3(
|
||||||
p.x(),p.y(),p.z(),p.weight(),
|
p.x(),p.y(),p.z(),p.weight(),
|
||||||
|
|
@ -765,10 +765,10 @@ namespace CommonKernelFunctors {
|
||||||
w);
|
w);
|
||||||
}
|
}
|
||||||
|
|
||||||
result_type operator()(const Weighted_point_3 & p,
|
Needs_FT<result_type>
|
||||||
const Weighted_point_3 & q,
|
operator()(const Weighted_point_3 & p,
|
||||||
const FT& w,
|
const Weighted_point_3 & q,
|
||||||
FT_necessary = {}) const
|
const FT& w) const
|
||||||
{
|
{
|
||||||
return CGAL::compare(squared_radius_smallest_orthogonal_sphereC3(
|
return CGAL::compare(squared_radius_smallest_orthogonal_sphereC3(
|
||||||
p.x(),p.y(),p.z(),p.weight(),
|
p.x(),p.y(),p.z(),p.weight(),
|
||||||
|
|
@ -821,15 +821,15 @@ namespace CommonKernelFunctors {
|
||||||
typedef typename K::Comparison_result result_type;
|
typedef typename K::Comparison_result result_type;
|
||||||
|
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
result_type
|
Needs_FT<result_type>
|
||||||
operator()(const T1& p, const T2& q, const FT& d2, FT_necessary = {}) const
|
operator()(const T1& p, const T2& q, const FT& d2) const
|
||||||
{
|
{
|
||||||
return CGAL::compare(internal::squared_distance(p, q, K()), d2);
|
return CGAL::compare(internal::squared_distance(p, q, K()), d2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
template <class T1, class T2, class T3, class T4>
|
||||||
std::enable_if_t<!std::is_same<T4, FT_necessary>::value, result_type>
|
Needs_FT<result_type>
|
||||||
operator()(const T1& p, const T2& q, const T3& r, const T4& s, FT_necessary = {}) const
|
operator()(const T1& p, const T2& q, const T3& r, const T4& s) const
|
||||||
{
|
{
|
||||||
return CGAL::compare(internal::squared_distance(p, q, K()),
|
return CGAL::compare(internal::squared_distance(p, q, K()),
|
||||||
internal::squared_distance(r, s, K()));
|
internal::squared_distance(r, s, K()));
|
||||||
|
|
@ -844,15 +844,15 @@ namespace CommonKernelFunctors {
|
||||||
typedef typename K::Comparison_result result_type;
|
typedef typename K::Comparison_result result_type;
|
||||||
|
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
result_type
|
Needs_FT<result_type>
|
||||||
operator()(const T1& p, const T2& q, const FT& d2, FT_necessary = {}) const
|
operator()(const T1& p, const T2& q, const FT& d2) const
|
||||||
{
|
{
|
||||||
return CGAL::compare(internal::squared_distance(p, q, K()), d2);
|
return CGAL::compare(internal::squared_distance(p, q, K()), d2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
template <class T1, class T2, class T3, class T4>
|
||||||
std::enable_if_t<!std::is_same<T4, FT_necessary>::value, result_type>
|
Needs_FT<result_type>
|
||||||
operator()(const T1& p, const T2& q, const T3& r, const T4& s, FT_necessary = {}) const
|
operator()(const T1& p, const T2& q, const T3& r, const T4& s) const
|
||||||
{
|
{
|
||||||
return CGAL::compare(internal::squared_distance(p, q, K()),
|
return CGAL::compare(internal::squared_distance(p, q, K()),
|
||||||
internal::squared_distance(r, s, K()));
|
internal::squared_distance(r, s, K()));
|
||||||
|
|
@ -3024,10 +3024,11 @@ namespace CommonKernelFunctors {
|
||||||
public:
|
public:
|
||||||
typedef typename K::Boolean result_type;
|
typedef typename K::Boolean result_type;
|
||||||
|
|
||||||
|
// Needs FT because Line/Line (and variations) and Circle_2/X compute intersections
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
result_type
|
Needs_FT<result_type>
|
||||||
operator()(const T1& t1, const T2& t2, FT_necessary = {}) const
|
operator()(const T1& t1, const T2& t2) const
|
||||||
{ return Intersections::internal::do_intersect(t1, t2, K()); }
|
{ return { Intersections::internal::do_intersect(t1, t2, K())}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename K>
|
template <typename K>
|
||||||
|
|
@ -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.
|
// 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,
|
Needs_FT<result_type>
|
||||||
const Point_3& a, const Point_3& b,
|
operator()(const Sphere_3& s1, const Sphere_3& s2,
|
||||||
FT_necessary = {}) const
|
const Point_3& a, const Point_3& b) const
|
||||||
{
|
{
|
||||||
typedef typename K::Circle_3 Circle_3;
|
typedef typename K::Circle_3 Circle_3;
|
||||||
typedef typename K::Point_3 Point_3;
|
typedef typename K::Point_3 Point_3;
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
// Author(s) : Sylvain Pion
|
// Author(s) : Sylvain Pion
|
||||||
|
|
||||||
// This defines removes the operator/ from CGAL::Mpzf to check that functors not using
|
// 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
|
#define CGAL_NO_MPZF_DIVISION_OPERATOR 1
|
||||||
|
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Cartesian.h>
|
||||||
|
|
|
||||||
|
|
@ -81,9 +81,27 @@ Assert_compile_time_tag( const Tag&, const Derived& b)
|
||||||
x.match_compile_time_tag(b);
|
x.match_compile_time_tag(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for kernel predicates, to indicate a FT providing a division operator is required
|
// To distinguish between kernel predicates for which a division-less FT is sufficient
|
||||||
struct FT_necessary {};
|
template <typename T>
|
||||||
|
struct Needs_FT
|
||||||
|
{
|
||||||
|
T value;
|
||||||
|
Needs_FT(T v) : value(v) {}
|
||||||
|
operator T() const { return value; }
|
||||||
|
};
|
||||||
|
|
||||||
} //namespace CGAL
|
template <typename T>
|
||||||
|
struct Remove_needs_FT
|
||||||
|
{
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Remove_needs_FT<Needs_FT<T> >
|
||||||
|
{
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
#endif // CGAL_TAGS_H
|
#endif // CGAL_TAGS_H
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue