diff --git a/NewKernel_d/include/CGAL/Filtered_predicate.h b/NewKernel_d/include/CGAL/Filtered_predicate.h new file mode 100644 index 00000000000..c4608c2d3cf --- /dev/null +++ b/NewKernel_d/include/CGAL/Filtered_predicate.h @@ -0,0 +1,420 @@ +// Copyright (c) 2001-2005 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sylvain Pion + +#ifndef CGAL_FILTERED_PREDICATE_H +#define CGAL_FILTERED_PREDICATE_H + +#include +#include +#include +#include +#include + +namespace CGAL { + +// This template class is a wrapper that implements the filtering for any +// predicate (dynamic filters with IA). + +// TODO : +// - each predicate in the default kernel should define a tag that says if it +// wants to be filtered or not (=> all homogeneous predicate define this +// tag). We could even test-suite that automatically. It makes a strong +// new requirement on the kernel though... +// Could be done with a traits mechanism ? +// A default template could use the current IA, but other tags or whatever +// could specify no filtering at all, or static filtering... +// - same thing for constructions => virtual operator() ? +// - similarly, constructions should have a tag saying if they can throw or +// not, or we let all this up to the compiler optimizer to figure out ? +// - Some caching could be done at the Point_2 level. + + +template +class Filtered_predicate +{ +//TODO: pack (at least use a tuple) +//FIXME: is it better to store those, or just store enough to recreate them +//(i.e. possibly references to the kernels)? + EP ep; + AP ap; + C2E c2e; + C2A c2a; + + typedef typename AP::result_type Ares; + +public: + + typedef AP Approximate_predicate; + typedef EP Exact_predicate; + typedef C2E To_exact_converter; + typedef C2A To_approximate_converter; + + typedef typename EP::result_type result_type; + // AP::result_type must be convertible to EP::result_type. + + Filtered_predicate() + {} + + template + Filtered_predicate(const K& k) + : ep(k.exact_kernel()), ap(k.approximate_kernel()), c2e(k,k.exact_kernel()), c2a(k,k.approximate_kernel()) + {} + + template + Filtered_predicate(const K& k,const EK& ek,const AK& ak) + : ep(ek), ap(ak), c2e(k,ek), c2a(k,ak) + {} + + +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + template + result_type + operator()(const Args&... args) const; +#else + + template + result_type + operator()(const A1 &a1) const; + + template + result_type + operator()(const A1 &a1, const A2 &a2) const; + + template + result_type + operator()(const A1 &a1, const A2 &a2, const A3 &a3) const; + + template + result_type + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const; + + template + result_type + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5) const; + + template + result_type + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5, const A6 &a6) const; + + template + result_type + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5, const A6 &a6, const A7 &a7) const; + + template + result_type + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8) const; + + template + result_type + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, + const A9 &a9) const; + + template + result_type + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, + const A9 &a9, const A10 &a10) const; + + // Idem for more than 10 arguments. Do it on demand. + +#endif +}; + +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + +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 + { + Protect_FPU_rounding p; + try + { + Ares res = ap(c2a(args)...); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(args)...); +} + +#else + +template + template +typename Filtered_predicate::result_type +Filtered_predicate:: + operator()(const A1 &a1) const +{ + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + { + Protect_FPU_rounding p; + try + { + + Ares res = ap(c2a(a1)); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(a1)); +} + +template + template +typename Filtered_predicate::result_type +Filtered_predicate:: + operator()(const A1 &a1, const A2 &a2) const +{ + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + { + Protect_FPU_rounding p; + try + { + Ares res = ap(c2a(a1), c2a(a2)); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(a1), c2e(a2)); +} + +template + template +typename Filtered_predicate::result_type +Filtered_predicate:: + operator()(const A1 &a1, const A2 &a2, const A3 &a3) const +{ + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + { + Protect_FPU_rounding p; + try + { + Ares res = ap(c2a(a1), c2a(a2), c2a(a3)); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(a1), c2e(a2), c2e(a3)); +} + +template + template +typename Filtered_predicate::result_type +Filtered_predicate:: + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const +{ + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + { + Protect_FPU_rounding p; + try + { + Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4)); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4)); +} + +template + template +typename Filtered_predicate::result_type +Filtered_predicate:: + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5) const +{ + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + { + Protect_FPU_rounding p; + try + { + Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5)); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5)); +} + +template + template +typename Filtered_predicate::result_type +Filtered_predicate:: + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5, const A6 &a6) const +{ + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + { + Protect_FPU_rounding p; + try + { + Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6)); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6)); +} + +template + template +typename Filtered_predicate::result_type +Filtered_predicate:: + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5, const A6 &a6, const A7 &a7) const +{ + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + { + Protect_FPU_rounding p; + try + { + Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6), + c2a(a7)); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7)); +} + +template + template +typename Filtered_predicate::result_type +Filtered_predicate:: + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8) const +{ + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + { + Protect_FPU_rounding p; + try + { + Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6), + c2a(a7), c2a(a8)); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7), + c2e(a8)); +} + +template + template +typename Filtered_predicate::result_type +Filtered_predicate:: + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, + const A9 &a9) const +{ + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + { + Protect_FPU_rounding p; + try + { + Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6), + c2a(a7), c2a(a8), c2a(a9)); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7), + c2e(a8), c2e(a9)); +} + +template + template +typename Filtered_predicate::result_type +Filtered_predicate:: + operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, + const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, + const A9 &a9, const A10 &a10) const +{ + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + { + Protect_FPU_rounding p; + try + { + Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6), + c2a(a7), c2a(a8), c2a(a9), c2a(a10)); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7), + c2e(a8), c2e(a9), c2e(a10)); +} + +#endif + +} //namespace CGAL + +#endif // CGAL_FILTERED_PREDICATE_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Cartesian_filter_K.h b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_filter_K.h index c0bf7bd7b19..328106b6c9c 100644 --- a/NewKernel_d/include/CGAL/Kernel_d/Cartesian_filter_K.h +++ b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_filter_K.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace CGAL { @@ -20,7 +21,12 @@ struct Cartesian_filter_K : public Base_, typedef Base_ Kernel_base; typedef AK_ AK; typedef EK_ EK; - //TODO: C2A/C2E should be able to convert *this into this->kernel() or this->kernel2(). + typedef typename Store_kernel::reference_type AK_rt; + AK_rt approximate_kernel()const{return this->kernel();} + typedef typename Store_kernel2::reference2_type EK_rt; + EK_rt exact_kernel()const{return this->kernel2();} + + //TODO: C2A/C2E could be able to convert *this into this->kernel() or this->kernel2(). typedef CartesianD_converter C2A; typedef CartesianD_converter C2E; diff --git a/NewKernel_d/include/CGAL/Kernel_d/Lazy_cartesian.h b/NewKernel_d/include/CGAL/Kernel_d/Lazy_cartesian.h index ad6b6f14031..56b9e6d2da3 100644 --- a/NewKernel_d/include/CGAL/Kernel_d/Lazy_cartesian.h +++ b/NewKernel_d/include/CGAL/Kernel_d/Lazy_cartesian.h @@ -15,7 +15,12 @@ struct Lazy_cartesian : Dimension_base //CGAL_CONSTEXPR Lazy_cartesian(){} //CGAL_CONSTEXPR Lazy_cartesian(int d):Base_(d){} - //TODO: store an AK and an EK + //TODO: Do we want to store an AK and an EK? Or just references? + //FIXME: references would be better I guess. + AK_ ak; EK_ ek; + AK_ const& approximate_kernel()const{return ak;} + EK_ const& exact_kernel()const{return ek;} + typedef Lazy_cartesian Self; //typedef typename Default::Get::type Kernel; typedef Self Kernel; diff --git a/NewKernel_d/include/CGAL/Lazy.h b/NewKernel_d/include/CGAL/Lazy.h index 9f2b9d73a8b..2f2a490c577 100644 --- a/NewKernel_d/include/CGAL/Lazy.h +++ b/NewKernel_d/include/CGAL/Lazy.h @@ -852,6 +852,9 @@ struct Approx_converter typedef K1 Source_kernel; typedef K2 Target_kernel; //typedef Converter Number_type_converter; + Approx_converter(){} + Approx_converter(K1 const&,K2 const&){} + //TODO: check that it is normal that we never need k1 or k2 here template struct result_; template struct result_ { @@ -899,6 +902,9 @@ struct Exact_converter typedef K1 Source_kernel; typedef K2 Target_kernel; //typedef Converter Number_type_converter; + Exact_converter(){} + Exact_converter(K1 const&,K2 const&){} + //TODO: check that it is normal that we never need k1 or k2 here template struct result_; template struct result_ { @@ -1784,6 +1790,7 @@ struct Lazy_construction AC ac; EC ec; + //TODO: need a constructor to initialize ac and ec properly public: