From 106645ec2e1367d9586f4ddbab4fc081136b74c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 8 Sep 2021 16:37:07 +0200 Subject: [PATCH 1/3] make sure the rounding mode is to nearest when doing exact computations Thoses changes should have been done when the code was modified for CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG --- .../include/CGAL/Filtered_construction.h | 65 +-- Filtered_kernel/include/CGAL/Lazy.h | 389 +++++++++--------- .../CGAL/Filtered_extended_homogeneous.h | 248 +++++++---- .../include/CGAL/NewKernel_d/Lazy_cartesian.h | 15 +- .../include/CGAL/Skin_surface_base_3.h | 37 +- .../CGAL/triangulate_mixed_complex_3.h | 61 ++- .../Straight_skeleton_builder_traits_2_aux.h | 16 +- 7 files changed, 473 insertions(+), 358 deletions(-) diff --git a/Filtered_kernel/include/CGAL/Filtered_construction.h b/Filtered_kernel/include/CGAL/Filtered_construction.h index c755d3a1eab..22b509bcabd 100644 --- a/Filtered_kernel/include/CGAL/Filtered_construction.h +++ b/Filtered_kernel/include/CGAL/Filtered_construction.h @@ -44,54 +44,57 @@ public: result_type operator()(const A1 &a1) const { - // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG - Protect_FPU_rounding P1; - try { - return From_Filtered( Filter_construction(To_Filtered(a1)) ); - } - catch (Uncertain_conversion_exception&) - { - Protect_FPU_rounding P(CGAL_FE_TONEAREST); - return From_Exact( Exact_construction(To_Exact(a1)) ); + // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG + Protect_FPU_rounding P1; + try + { + return From_Filtered( Filter_construction(To_Filtered(a1)) ); + } + catch (Uncertain_conversion_exception&) + {} } + Protect_FPU_rounding P(CGAL_FE_TONEAREST); + return From_Exact( Exact_construction(To_Exact(a1)) ); } template result_type operator()(const A1 &a1, const A2 &a2) const { - Protect_FPU_rounding P1; - try { - return From_Filtered( Filter_construction(To_Filtered(a1), - To_Filtered(a2)) ); - } - catch (Uncertain_conversion_exception&) - { - Protect_FPU_rounding P(CGAL_FE_TONEAREST); - return From_Exact( Exact_construction(To_Exact(a1), - To_Exact(a2)) ); + Protect_FPU_rounding P1; + try + { + return From_Filtered( Filter_construction(To_Filtered(a1), + To_Filtered(a2)) ); + } + catch (Uncertain_conversion_exception&) + {} } + Protect_FPU_rounding P(CGAL_FE_TONEAREST); + return From_Exact( Exact_construction(To_Exact(a1), + To_Exact(a2)) ); } template result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3) const { - Protect_FPU_rounding P1; - try { - return From_Filtered( Filter_construction(To_Filtered(a1), - To_Filtered(a2), - To_Filtered(a3)) ); - } - catch (Uncertain_conversion_exception&) - { - Protect_FPU_rounding P(CGAL_FE_TONEAREST); - return From_Exact( Exact_construction(To_Exact(a1), - To_Exact(a2), - To_Exact(a3)) ); + Protect_FPU_rounding P1; + try + { + return From_Filtered( Filter_construction(To_Filtered(a1), + To_Filtered(a2), + To_Filtered(a3)) ); + } + catch (Uncertain_conversion_exception&) + {} } + Protect_FPU_rounding P(CGAL_FE_TONEAREST); + return From_Exact( Exact_construction(To_Exact(a1), + To_Exact(a2), + To_Exact(a3)) ); } }; diff --git a/Filtered_kernel/include/CGAL/Lazy.h b/Filtered_kernel/include/CGAL/Lazy.h index 4969dc77eab..4a85eafc269 100644 --- a/Filtered_kernel/include/CGAL/Lazy.h +++ b/Filtered_kernel/include/CGAL/Lazy.h @@ -794,15 +794,16 @@ struct Lazy_construction_bbox result_type operator()(const L1& l1) 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 { - return ac(CGAL::approx(l1)); - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - return ec(CGAL::exact(l1)); + { + // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG + Protect_FPU_rounding P; + try { + return ac(CGAL::approx(l1)); + } catch (Uncertain_conversion_exception&) {} } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return ec(CGAL::exact(l1)); } }; @@ -842,14 +843,15 @@ struct Lazy_construction_nt { typedef std::remove_cv_t> ET; typedef std::remove_cv_t> AT; CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - return new Lazy_rep_n, L... >(ac, ec, l...); - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - return new Lazy_rep_0 >(ec( CGAL::exact(l)... )); + { + Protect_FPU_rounding P; + try { + return new Lazy_rep_n, L... >(ac, ec, l...); + } catch (Uncertain_conversion_exception&) {} } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return new Lazy_rep_0 >(ec( CGAL::exact(l)... )); } #undef CGAL_RESULT_NT @@ -1064,17 +1066,19 @@ public: operator()(const L1& l1, const L2& l2, R1& r1) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - // we suppose that R1 is a Lazy - r1 = R1(new Lazy_rep_2_1(ac, ec, l1, l2)); - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - typename R1::ET et; - ec(CGAL::exact(l1), CGAL::exact(l2), et); - r1 = R1(new Lazy_rep_0(et)); + { + Protect_FPU_rounding P; + try { + // we suppose that R1 is a Lazy + r1 = R1(new Lazy_rep_2_1(ac, ec, l1, l2)); + return; + } catch (Uncertain_conversion_exception&) {} } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + typename R1::ET et; + ec(CGAL::exact(l1), CGAL::exact(l2), et); + r1 = R1(new Lazy_rep_0(et)); } }; @@ -1130,21 +1134,23 @@ public: typedef Lazy Handle_1; typedef Lazy Handle_2; CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - typedef Lazy, std::pair, E2A> Lazy_pair; - Lazy_pair lv(new Lazy_rep_2_2(ac, ec, l1, l2)); - // lv->approx() is a std::pair; - r1 = R1(Handle_1(new Lazy_rep_n >, First >, E2A, Lazy_pair>(First >(), First >(), lv))); - r2 = R2(Handle_2(new Lazy_rep_n >, Second >, E2A, Lazy_pair>(Second >(), Second >(), lv))); - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - typename R1::ET et1, et2; - ec(CGAL::exact(l1), CGAL::exact(l2), et1, et2); - r1 = R1(Handle_1(new Lazy_rep_0(et1))); - r2 = R2(Handle_2(new Lazy_rep_0(et2))); + { + Protect_FPU_rounding P; + try { + typedef Lazy, std::pair, E2A> Lazy_pair; + Lazy_pair lv(new Lazy_rep_2_2(ac, ec, l1, l2)); + // lv->approx() is a std::pair; + r1 = R1(Handle_1(new Lazy_rep_n >, First >, E2A, Lazy_pair>(First >(), First >(), lv))); + r2 = R2(Handle_2(new Lazy_rep_n >, Second >, E2A, Lazy_pair>(Second >(), Second >(), lv))); + return; + } catch (Uncertain_conversion_exception&) {} } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + typename R1::ET et1, et2; + ec(CGAL::exact(l1), CGAL::exact(l2), et1, et2); + r1 = R1(Handle_1(new Lazy_rep_0(et1))); + r2 = R2(Handle_2(new Lazy_rep_0(et2))); } }; @@ -1174,36 +1180,37 @@ public: operator()(const L1& l1, const L2& l2, OutputIterator it) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - Lazy_vector lv(new Lazy_rep_with_vector_2(ac, ec, l1, l2)); - // lv.approx() is a std::vector - // that is, when we get here we have constructed all approximate results - for (unsigned int i = 0; i < lv.approx().size(); i++) { -// FIXME : I'm not sure how this work... -#define CGAL_Kernel_obj(X) if (object_cast(& (lv.approx()[i]))) { \ - *it++ = make_object(typename LK::X(new Lazy_rep_n, \ - Ith, E2A, Lazy_vector> \ - (Ith(i), Ith(i), lv))); \ - continue; \ + { + Protect_FPU_rounding P; + try { + Lazy_vector lv(new Lazy_rep_with_vector_2(ac, ec, l1, l2)); + // lv.approx() is a std::vector + // that is, when we get here we have constructed all approximate results + for (unsigned int i = 0; i < lv.approx().size(); i++) { + // FIXME : I'm not sure how this work... + #define CGAL_Kernel_obj(X) if (object_cast(& (lv.approx()[i]))) { \ + *it++ = make_object(typename LK::X(new Lazy_rep_n, \ + Ith, E2A, Lazy_vector> \ + (Ith(i), Ith(i), lv))); \ + continue; \ + } + + #include + + std::cerr << "we need more casts" << std::endl; } - -#include - - std::cerr << "we need more casts" << std::endl; - } - - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - // TODO: Instead of using a vector, write an iterator adapter - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - std::vector exact_objects; - ec(CGAL::exact(l1), CGAL::exact(l2), std::back_inserter(exact_objects)); - for (std::vector::const_iterator oit = exact_objects.begin(); - oit != exact_objects.end(); - ++oit){ - *it++ = make_lazy(*oit); - } + return it; + } catch (Uncertain_conversion_exception&) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + // TODO: Instead of using a vector, write an iterator adapter + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + std::vector exact_objects; + ec(CGAL::exact(l1), CGAL::exact(l2), std::back_inserter(exact_objects)); + for (std::vector::const_iterator oit = exact_objects.begin(); + oit != exact_objects.end(); + ++oit){ + *it++ = make_lazy(*oit); } return it; } @@ -1252,32 +1259,32 @@ public: operator()(const L1& l1) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - Lazy_object lo(new Lazy_rep_n(ac, ec, l1)); + { + Protect_FPU_rounding P; + try { + Lazy_object lo(new Lazy_rep_n(ac, ec, l1)); - if(lo.approx().is_empty()) + if(lo.approx().is_empty()) + return Object(); + + #define CGAL_Kernel_obj(X) \ + if (object_cast(& (lo.approx()))) { \ + typedef Lazy_rep_n< typename AK::X, typename EK::X, Object_cast, Object_cast, E2A, Lazy_object> Lcr; \ + Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); \ + return make_object(typename LK::X(lcr)); \ + } + + #include + + std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; + std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; return Object(); - -#define CGAL_Kernel_obj(X) \ - if (object_cast(& (lo.approx()))) { \ - typedef Lazy_rep_n< typename AK::X, typename EK::X, Object_cast, Object_cast, E2A, Lazy_object> Lcr; \ - Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); \ - return make_object(typename LK::X(lcr)); \ - } - -#include - - std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; - std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; - - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - ET eto = ec(CGAL::exact(l1)); - return make_lazy(eto); + } catch (Uncertain_conversion_exception&) {} } - return Object(); + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + ET eto = ec(CGAL::exact(l1)); + return make_lazy(eto); } template @@ -1285,12 +1292,13 @@ public: operator()(const L1& l1, const L2& l2) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - Lazy_object lo(new Lazy_rep_n(ac, ec, l1, l2)); + { + Protect_FPU_rounding P; + try { + Lazy_object lo(new Lazy_rep_n(ac, ec, l1, l2)); - if(lo.approx().is_empty()) - return Object(); + if(lo.approx().is_empty()) + return Object(); #define CGAL_Kernel_obj(X) \ if (object_cast(& (lo.approx()))) { \ @@ -1301,7 +1309,7 @@ public: #include - // We now check vector + // We now check vector #define CGAL_Kernel_obj(X) \ { \ @@ -1318,20 +1326,20 @@ public: }\ } -CGAL_Kernel_obj(Point_2) -CGAL_Kernel_obj(Point_3) + CGAL_Kernel_obj(Point_2) + CGAL_Kernel_obj(Point_3) #undef CGAL_Kernel_obj - std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; - std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; + std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; + std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - ET eto = ec(CGAL::exact(l1), CGAL::exact(l2)); - return make_lazy(eto); + return Object(); + } catch (Uncertain_conversion_exception&) {} } - return Object(); + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + ET eto = ec(CGAL::exact(l1), CGAL::exact(l2)); + return make_lazy(eto); } template @@ -1339,12 +1347,13 @@ CGAL_Kernel_obj(Point_3) operator()(const L1& l1, const L2& l2, const L3& l3) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - Lazy_object lo(new Lazy_rep_n(ac, ec, l1, l2, l3)); + { + Protect_FPU_rounding P; + try { + Lazy_object lo(new Lazy_rep_n(ac, ec, l1, l2, l3)); - if(lo.approx().is_empty()) - return Object(); + if(lo.approx().is_empty()) + return Object(); #define CGAL_Kernel_obj(X) \ if (object_cast(& (lo.approx()))) { \ @@ -1355,16 +1364,15 @@ CGAL_Kernel_obj(Point_3) #include - std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; - std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; - - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - ET eto = ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); - return make_lazy(eto); + std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; + std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; + return Object(); + } catch (Uncertain_conversion_exception&) {} } - return Object(); + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + ET eto = ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); + return make_lazy(eto); } }; @@ -1512,41 +1520,41 @@ struct Lazy_construction_variant { typename Type_mapper::type)>::type ET; CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; + { + Protect_FPU_rounding P; + try { + Lazy lazy(new Lazy_rep_n(AC(), EC(), l1, l2)); - try { - Lazy lazy(new Lazy_rep_n(AC(), EC(), l1, l2)); + // the approximate result requires the trait with types from the AK + AT approx_v = lazy.approx(); + // the result we build + result_type res; - // the approximate result requires the trait with types from the AK - AT approx_v = lazy.approx(); - // the result we build - result_type res; + if(!approx_v) { + // empty + return res; + } + + // the static visitor fills the result_type with the correct unwrapped type + internal::Fill_lazy_variant_visitor_2< result_type, AK, LK, EK, Lazy > visitor(res, lazy); + boost::apply_visitor(visitor, *approx_v); - if(!approx_v) { - // empty return res; - } + } catch (Uncertain_conversion_exception&) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - // the static visitor fills the result_type with the correct unwrapped type - internal::Fill_lazy_variant_visitor_2< result_type, AK, LK, EK, Lazy > visitor(res, lazy); - boost::apply_visitor(visitor, *approx_v); + ET exact_v = EC()(CGAL::exact(l1), CGAL::exact(l2)); + result_type res; - return res; - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - - ET exact_v = EC()(CGAL::exact(l1), CGAL::exact(l2)); - result_type res; - - if(!exact_v) { - return res; - } - - internal::Fill_lazy_variant_visitor_0 visitor(res); - boost::apply_visitor(visitor, *exact_v); + if(!exact_v) { return res; } + + internal::Fill_lazy_variant_visitor_0 visitor(res); + boost::apply_visitor(visitor, *exact_v); + return res; } template @@ -1562,40 +1570,41 @@ struct Lazy_construction_variant { typename Type_mapper::type)>::type ET; CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - Lazy lazy(new Lazy_rep_n(AC(), EC(), l1, l2, l3)); + { + Protect_FPU_rounding P; + try { + Lazy lazy(new Lazy_rep_n(AC(), EC(), l1, l2, l3)); - // the approximate result requires the trait with types from the AK - AT approx_v = lazy.approx(); - // the result we build - result_type res; + // the approximate result requires the trait with types from the AK + AT approx_v = lazy.approx(); + // the result we build + result_type res; + + if(!approx_v) { + // empty + return res; + } + + // the static visitor fills the result_type with the correct unwrapped type + internal::Fill_lazy_variant_visitor_2< result_type, AK, LK, EK, Lazy > visitor(res, lazy); + boost::apply_visitor(visitor, *approx_v); - if(!approx_v) { - // empty return res; - } + } catch (Uncertain_conversion_exception&) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - // the static visitor fills the result_type with the correct unwrapped type - internal::Fill_lazy_variant_visitor_2< result_type, AK, LK, EK, Lazy > visitor(res, lazy); - boost::apply_visitor(visitor, *approx_v); + ET exact_v = EC()(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); + result_type res; - return res; - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - - ET exact_v = EC()(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); - result_type res; - - if(!exact_v) { - return res; - } - - internal::Fill_lazy_variant_visitor_0< result_type, AK, LK, EK> visitor(res); - boost::apply_visitor(visitor, *exact_v); + if(!exact_v) { return res; } + + internal::Fill_lazy_variant_visitor_0< result_type, AK, LK, EK> visitor(res); + boost::apply_visitor(visitor, *exact_v); + return res; } }; @@ -1629,14 +1638,15 @@ struct Lazy_construction { operator()( BOOST_PP_ENUM(n, CGAL_LARGS, _) ) const { \ typedef Lazy< AT, ET, E2A> Handle; \ CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); \ - Protect_FPU_rounding P; \ - try { \ - return result_type( Handle(new Lazy_rep_n(ac, ec, BOOST_PP_ENUM_PARAMS(n, l)))); \ - } catch (Uncertain_conversion_exception&) { \ - CGAL_BRANCH_PROFILER_BRANCH(tmp); \ - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); \ - return result_type( Handle(new Lazy_rep_0(ec( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ))) ); \ + { \ + Protect_FPU_rounding P; \ + try { \ + return result_type( Handle(new Lazy_rep_n(ac, ec, BOOST_PP_ENUM_PARAMS(n, l)))); \ + } catch (Uncertain_conversion_exception&) {} \ } \ + CGAL_BRANCH_PROFILER_BRANCH(tmp); \ + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); \ + return result_type( Handle(new Lazy_rep_0(ec( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ))) ); \ } // arity 1-8 @@ -1696,14 +1706,15 @@ struct result { \ typedef Lazy< AT, ET, E2A> Handle; \ typedef typename cpp11::result_of::type result_type; \ CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); \ - Protect_FPU_rounding P; \ - try { \ - return result_type( Handle(new Lazy_rep_n(ac, ec, BOOST_PP_ENUM_PARAMS(n, l)))); \ - } catch (Uncertain_conversion_exception&) { \ - CGAL_BRANCH_PROFILER_BRANCH(tmp); \ - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); \ - return result_type( Handle(new Lazy_rep_0(ec( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ))) ); \ + { \ + Protect_FPU_rounding P; \ + try { \ + return result_type( Handle(new Lazy_rep_n(ac, ec, BOOST_PP_ENUM_PARAMS(n, l)))); \ + } catch (Uncertain_conversion_exception&) {} \ } \ + CGAL_BRANCH_PROFILER_BRANCH(tmp); \ + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); \ + return result_type( Handle(new Lazy_rep_0(ec( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ))) ); \ } // arity 1-8 diff --git a/Nef_2/include/CGAL/Filtered_extended_homogeneous.h b/Nef_2/include/CGAL/Filtered_extended_homogeneous.h index 31f67e9e45d..48c23338465 100644 --- a/Nef_2/include/CGAL/Filtered_extended_homogeneous.h +++ b/Nef_2/include/CGAL/Filtered_extended_homogeneous.h @@ -390,40 +390,61 @@ int orientation(const Extended_point& p1, const Extended_point& p3) { CGAL_NEF_TRACEN("orientation "< Protection; - res = orientation_coeff2(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + bool run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(or2); + res = orientation_coeff2(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(or2); + run_exact=true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(or2); + if (run_exact) res = orientation_coeff2(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw()); - } if ( res != 0 ) return res; - try { INCTOTAL(or1); Protect_FPU_rounding Protection; - res = orientation_coeff1(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(or1); + res = orientation_coeff1(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(or1); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(or1); + if (run_exact) res = orientation_coeff1(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw()); - } if ( res != 0 ) return res; - try { INCTOTAL(or0); Protect_FPU_rounding Protection; - res = orientation_coeff0(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(or0); + res = orientation_coeff0(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(or0); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(or0); + if (run_exact) res = orientation_coeff0(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw()); - } return res; } @@ -441,20 +462,36 @@ int compare_x(const Extended_point& p1, const Extended_point& p2) { int res; - try { INCTOTAL(cmpx1); Protect_FPU_rounding Protection; - res = compare_expr(p1.mxD(),p1.hwD(),p2.mxD(),p2.hwD()); + bool run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmpx1); + res = compare_expr(p1.mxD(),p1.hwD(),p2.mxD(),p2.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmpx1); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmpx1); + if (run_exact) res = compare_expr(p1.mx(),p1.hw(),p2.mx(),p2.hw()); - } + if ( res != 0 ) return res; - try { INCTOTAL(cmpx0); Protect_FPU_rounding Protection; - res = compare_expr(p1.nxD(),p1.hwD(),p2.nxD(),p2.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { + INCTOTAL(cmpx0); + res = compare_expr(p1.nxD(),p1.hwD(),p2.nxD(),p2.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmpx0); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmpx0); + if (run_exact) res = compare_expr(p1.nx(),p1.hw(),p2.nx(),p2.hw()); - } return res; } @@ -466,20 +503,34 @@ int compare_y(const Extended_point& p1, const Extended_point& p2) { int res; - try { INCTOTAL(cmpy1); Protect_FPU_rounding Protection; - res = compare_expr(p1.myD(),p1.hwD(),p2.myD(),p2.hwD()); + bool run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmpy1); + res = compare_expr(p1.myD(),p1.hwD(),p2.myD(),p2.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmpy1); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmpy1); + if (run_exact) res = compare_expr(p1.my(),p1.hw(),p2.my(),p2.hw()); - } if ( res != 0 ) return res; - try { INCTOTAL(cmpy0); Protect_FPU_rounding Protection; - res = compare_expr(p1.nyD(),p1.hwD(),p2.nyD(),p2.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmpy0); + res = compare_expr(p1.nyD(),p1.hwD(),p2.nyD(),p2.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmpy0); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmpy0); + if (run_exact) res = compare_expr(p1.ny(),p1.hw(),p2.ny(),p2.hw()); - } return res; } @@ -608,46 +659,68 @@ int compare_pair_dist( const Extended_point& p3, const Extended_point& p4) { int res; - try { INCTOTAL(cmppd2); Protect_FPU_rounding Protection; - res = cmppd_coeff2(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + bool run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmppd2); + res = cmppd_coeff2(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmppd2); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmppd2); + if (run_exact) res = cmppd_coeff2(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } + if ( res != 0 ) return res; - try { INCTOTAL(cmppd1); Protect_FPU_rounding Protection; - res = cmppd_coeff1(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmppd1); + res = cmppd_coeff1(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmppd1); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmppd1); + if (run_exact) res = cmppd_coeff1(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } if ( res != 0 ) return res; - try { INCTOTAL(cmppd0); Protect_FPU_rounding Protection; - res = cmppd_coeff0(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmppd0); + res = cmppd_coeff0(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmppd0); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmppd0); + if (run_exact) res = cmppd_coeff0(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } return res; } @@ -873,42 +946,65 @@ int orientation(const Extended_direction& d1, Extended_point p1(d1.p1()), p2(d1.p2()), p3(d2.p1()), p4(d2.p2()); int res; - try { INCTOTAL(ord2); Protect_FPU_rounding Protection; - res = coeff2_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); - } catch (Uncertain_conversion_exception&) { INCEXCEPTION(ord2); + bool run_exact = true; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(ord2); + res = coeff2_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } catch (Uncertain_conversion_exception&) { + INCEXCEPTION(ord2); + run_exact=true; + } + } + if (run_exact) res = coeff2_dor(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } if ( res != 0 ) return res; - try { INCTOTAL(ord1); Protect_FPU_rounding Protection; - res = coeff1_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); - } catch (Uncertain_conversion_exception&) { INCEXCEPTION(ord1); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(ord1); + res = coeff1_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } catch (Uncertain_conversion_exception&) { + INCEXCEPTION(ord1); + run_exact=true; + } + } + if (run_exact) res = coeff1_dor(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } + if ( res != 0 ) return res; - try { INCTOTAL(ord0); Protect_FPU_rounding Protection; - res = coeff0_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); - } catch (Uncertain_conversion_exception&) { INCEXCEPTION(ord0); + + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(ord0); Protect_FPU_rounding Protection; + res = coeff0_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } catch (Uncertain_conversion_exception&) { + INCEXCEPTION(ord0); + run_exact = true; + } + } + if(run_exact) res = coeff0_dor(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } return res; } diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h index c7f3b3ebbdd..7e82e90a407 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h @@ -176,14 +176,15 @@ struct Lazy_construction2 { template std::enable_if_t<(sizeof...(L)>0), result_type> operator()(L const&...l) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - return new Lazy_rep_XXX(ac, ec, l...); - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - return new Lazy_rep_0(ec(CGAL::exact(l)...)); + { + Protect_FPU_rounding P; + try { + return new Lazy_rep_XXX(ac, ec, l...); + } catch (Uncertain_conversion_exception&) {} } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return new Lazy_rep_0(ec(CGAL::exact(l)...)); } // FIXME: this forces us to have default constructors for all types, try to make its instantiation lazier // Actually, that may be the clearing in update_exact(). diff --git a/Skin_surface_3/include/CGAL/Skin_surface_base_3.h b/Skin_surface_3/include/CGAL/Skin_surface_base_3.h index 108b8ff2b25..57f8d2306e1 100644 --- a/Skin_surface_3/include/CGAL/Skin_surface_base_3.h +++ b/Skin_surface_3/include/CGAL/Skin_surface_base_3.h @@ -689,33 +689,36 @@ locate_in_tmc(const Bare_point &p0, TMC_Cell_handle start) const // We temporarily put p at i's place in pts. const TMC_Point* backup = pts[i]; pts[i] = &p_inexact; + bool run_exact=false; { Protect_FPU_rounding P; try { o = TMC_Geom_traits().orientation_3_object()(*pts[0], *pts[1], *pts[2], *pts[3]); - } catch (Uncertain_conversion_exception&) { - Protect_FPU_rounding P(CGAL_FE_TONEAREST); - typedef Exact_predicates_exact_constructions_kernel EK; - Cartesian_converter converter_ek; + } catch (Uncertain_conversion_exception&) { run_exact=true; } + } + if (run_exact) + { + Protect_FPU_rounding P(CGAL_FE_TONEAREST); + typedef Exact_predicates_exact_constructions_kernel EK; + Cartesian_converter converter_ek; - Skin_surface_traits_3 exact_traits(shrink_factor()); + Skin_surface_traits_3 exact_traits(shrink_factor()); - typename EK::Point_3 e_pts[4]; + typename EK::Point_3 e_pts[4]; - // We know that the 4 vertices of c are positively oriented. - // So, in order to test if p is seen outside from one of c's facets, - // we just replace the corresponding point by p in the orientation - // test. We do this using the array below. - for (int k=0; k<4; k++) { - if (k != i) { - e_pts[k] = get_anchor_point(c->vertex(k)->info(), exact_traits); - } else { - e_pts[k] = converter_ek(p0); - } + // We know that the 4 vertices of c are positively oriented. + // So, in order to test if p is seen outside from one of c's facets, + // we just replace the corresponding point by p in the orientation + // test. We do this using the array below. + for (int k=0; k<4; k++) { + if (k != i) { + e_pts[k] = get_anchor_point(c->vertex(k)->info(), exact_traits); + } else { + e_pts[k] = converter_ek(p0); } - o = orientation(e_pts[0], e_pts[1], e_pts[2], e_pts[3]); } + o = orientation(e_pts[0], e_pts[1], e_pts[2], e_pts[3]); } if ( o != NEGATIVE ) { diff --git a/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h b/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h index 0a6451424fc..c643fe88ddd 100644 --- a/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h +++ b/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h @@ -1197,39 +1197,38 @@ Mixed_complex_triangulator_3:: orientation(Tmc_Cell_handle ch) { - Orientation o; - // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG - Protect_FPU_rounding P; - try { - Tmc_Point pts[4]; - for (int i=0; i<4; i++) - pts[i] = ch->vertex(i)->point(); + { + // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG + Protect_FPU_rounding P; + try { + Tmc_Point pts[4]; + for (int i=0; i<4; i++) + pts[i] = ch->vertex(i)->point(); - // filtered kernel - o = _tmc.geom_traits().orientation_3_object()(pts[0], pts[1], pts[2], pts[3]); - } catch (Uncertain_conversion_exception&) { - Protect_FPU_rounding P(CGAL_FE_TONEAREST); - typedef Exact_predicates_exact_constructions_kernel EK; - typedef Cartesian_converter Exact_converter; - typedef Skin_surface_traits_3 Exact_traits; - typedef Skin_surface_base_3 Exact_skin_surface; - - Exact_converter converter; - Exact_traits exact_traits(shrink); - typename Exact_skin_surface::Bare_point e_pts[4]; - - for (int k=0; k<4; k++) { - e_pts[k] = - Triangulated_mixed_complex_observer::Skin_surface:: - get_anchor_point(ch->vertex(k)->info(), exact_traits); - - // Store the more precise point - ch->vertex(k)->point() = converter(e_pts[k]); - } - o = exact_traits.orientation_3_object()(e_pts[0], e_pts[1], - e_pts[2], e_pts[3]); + // filtered kernel + return _tmc.geom_traits().orientation_3_object()(pts[0], pts[1], pts[2], pts[3]); + } catch (Uncertain_conversion_exception&) {} } - return o; + Protect_FPU_rounding P(CGAL_FE_TONEAREST); + typedef Exact_predicates_exact_constructions_kernel EK; + typedef Cartesian_converter Exact_converter; + typedef Skin_surface_traits_3 Exact_traits; + typedef Skin_surface_base_3 Exact_skin_surface; + + Exact_converter converter; + Exact_traits exact_traits(shrink); + typename Exact_skin_surface::Bare_point e_pts[4]; + + for (int k=0; k<4; k++) { + e_pts[k] = + Triangulated_mixed_complex_observer::Skin_surface:: + get_anchor_point(ch->vertex(k)->info(), exact_traits); + + // Store the more precise point + ch->vertex(k)->point() = converter(e_pts[k]); + } + return exact_traits.orientation_3_object()(e_pts[0], e_pts[1], + e_pts[2], e_pts[3]); } template P; - FC_result_type fr = Filter_construction(To_Filtered(std::forward(a))...); + try + { + FC_result_type fr = Filter_construction(To_Filtered(std::forward(a))...); - const double precision = - Lazy_exact_nt::get_relative_precision_of_to_double(); + const double precision = + Lazy_exact_nt::get_relative_precision_of_to_double(); - if ( fr && has_enough_precision(*fr, precision) ) - return From_Filtered(fr); + if ( fr && has_enough_precision(*fr, precision) ) + return From_Filtered(fr); + } + catch (Uncertain_conversion_exception&) {} } - catch (Uncertain_conversion_exception&) {} Protect_FPU_rounding P(CGAL_FE_TONEAREST); EC_result_type er = Exact_construction(To_Exact(std::forward(a))...) ; From c8624ee0b3a1e63e21f172a3a4ebc33dc408539e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 9 Sep 2021 11:01:03 +0200 Subject: [PATCH 2/3] check that the rounding mode when doing exact computation is to-nearest --- Convex_hull_3/include/CGAL/convex_hull_3.h | 2 ++ .../include/CGAL/Filtered_construction.h | 3 +++ Filtered_kernel/include/CGAL/Filtered_predicate.h | 1 + .../include/CGAL/Filtered_predicate_with_state.h | 1 + Filtered_kernel/include/CGAL/Lazy.h | 14 ++++++++++++-- Nef_2/include/CGAL/Filtered_extended_homogeneous.h | 13 +++++++++++++ .../include/CGAL/NewKernel_d/Cartesian_filter_NT.h | 1 + .../include/CGAL/NewKernel_d/Filtered_predicate2.h | 1 + .../include/CGAL/NewKernel_d/Lazy_cartesian.h | 1 + Skin_surface_3/include/CGAL/Skin_surface_base_3.h | 6 ++++-- .../include/CGAL/triangulate_mixed_complex_3.h | 1 + .../Straight_skeleton_builder_traits_2_aux.h | 1 + 12 files changed, 41 insertions(+), 4 deletions(-) diff --git a/Convex_hull_3/include/CGAL/convex_hull_3.h b/Convex_hull_3/include/CGAL/convex_hull_3.h index cf35a6d78af..ad1ac57945f 100644 --- a/Convex_hull_3/include/CGAL/convex_hull_3.h +++ b/Convex_hull_3/include/CGAL/convex_hull_3.h @@ -359,6 +359,8 @@ public: } } catch (Uncertain_conversion_exception&){} + Protector protector(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (ek_plane_ptr==nullptr) { const typename Exact_K::Point_3 ep = to_EK(p); ek_plane_ptr = new Vector_plus_point; diff --git a/Filtered_kernel/include/CGAL/Filtered_construction.h b/Filtered_kernel/include/CGAL/Filtered_construction.h index 22b509bcabd..51910605980 100644 --- a/Filtered_kernel/include/CGAL/Filtered_construction.h +++ b/Filtered_kernel/include/CGAL/Filtered_construction.h @@ -55,6 +55,7 @@ public: {} } Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return From_Exact( Exact_construction(To_Exact(a1)) ); } template @@ -72,6 +73,7 @@ public: {} } Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return From_Exact( Exact_construction(To_Exact(a1), To_Exact(a2)) ); } @@ -92,6 +94,7 @@ public: {} } Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return From_Exact( Exact_construction(To_Exact(a1), To_Exact(a2), To_Exact(a3)) ); diff --git a/Filtered_kernel/include/CGAL/Filtered_predicate.h b/Filtered_kernel/include/CGAL/Filtered_predicate.h index 63199a63a32..8fe25f2b5b6 100644 --- a/Filtered_kernel/include/CGAL/Filtered_predicate.h +++ b/Filtered_kernel/include/CGAL/Filtered_predicate.h @@ -103,6 +103,7 @@ Filtered_predicate:: } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding p(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return ep(c2e(args)...); } diff --git a/Filtered_kernel/include/CGAL/Filtered_predicate_with_state.h b/Filtered_kernel/include/CGAL/Filtered_predicate_with_state.h index 56ef70f0ef9..efcbd15f74b 100644 --- a/Filtered_kernel/include/CGAL/Filtered_predicate_with_state.h +++ b/Filtered_kernel/include/CGAL/Filtered_predicate_with_state.h @@ -74,6 +74,7 @@ Filtered_predicate_with_state:: } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding p(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if(! oep){ #if BOOST_VERSION < 105600 oep = EP(c2e(o1)); diff --git a/Filtered_kernel/include/CGAL/Lazy.h b/Filtered_kernel/include/CGAL/Lazy.h index 4a85eafc269..04bcfc034b6 100644 --- a/Filtered_kernel/include/CGAL/Lazy.h +++ b/Filtered_kernel/include/CGAL/Lazy.h @@ -803,6 +803,7 @@ struct Lazy_construction_bbox } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return ec(CGAL::exact(l1)); } }; @@ -851,6 +852,7 @@ struct Lazy_construction_nt { } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return new Lazy_rep_0 >(ec( CGAL::exact(l)... )); } @@ -1076,6 +1078,7 @@ public: } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); typename R1::ET et; ec(CGAL::exact(l1), CGAL::exact(l2), et); r1 = R1(new Lazy_rep_0(et)); @@ -1147,6 +1150,7 @@ public: } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); typename R1::ET et1, et2; ec(CGAL::exact(l1), CGAL::exact(l2), et1, et2); r1 = R1(Handle_1(new Lazy_rep_0(et1))); @@ -1205,6 +1209,7 @@ public: CGAL_BRANCH_PROFILER_BRANCH(tmp); // TODO: Instead of using a vector, write an iterator adapter Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); std::vector exact_objects; ec(CGAL::exact(l1), CGAL::exact(l2), std::back_inserter(exact_objects)); for (std::vector::const_iterator oit = exact_objects.begin(); @@ -1283,6 +1288,7 @@ public: } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); ET eto = ec(CGAL::exact(l1)); return make_lazy(eto); } @@ -1338,6 +1344,7 @@ public: } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); ET eto = ec(CGAL::exact(l1), CGAL::exact(l2)); return make_lazy(eto); } @@ -1371,6 +1378,7 @@ public: } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); ET eto = ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); return make_lazy(eto); } @@ -1544,7 +1552,7 @@ struct Lazy_construction_variant { } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); ET exact_v = EC()(CGAL::exact(l1), CGAL::exact(l2)); result_type res; @@ -1594,7 +1602,7 @@ struct Lazy_construction_variant { } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); ET exact_v = EC()(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); result_type res; @@ -1646,6 +1654,7 @@ struct Lazy_construction { } \ CGAL_BRANCH_PROFILER_BRANCH(tmp); \ Protect_FPU_rounding P2(CGAL_FE_TONEAREST); \ + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); \ return result_type( Handle(new Lazy_rep_0(ec( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ))) ); \ } @@ -1714,6 +1723,7 @@ struct result { \ } \ CGAL_BRANCH_PROFILER_BRANCH(tmp); \ Protect_FPU_rounding P2(CGAL_FE_TONEAREST); \ + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); \ return result_type( Handle(new Lazy_rep_0(ec( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ))) ); \ } diff --git a/Nef_2/include/CGAL/Filtered_extended_homogeneous.h b/Nef_2/include/CGAL/Filtered_extended_homogeneous.h index 48c23338465..32055377064 100644 --- a/Nef_2/include/CGAL/Filtered_extended_homogeneous.h +++ b/Nef_2/include/CGAL/Filtered_extended_homogeneous.h @@ -403,6 +403,7 @@ int orientation(const Extended_point& p1, run_exact=true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = orientation_coeff2(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), @@ -422,6 +423,7 @@ int orientation(const Extended_point& p1, run_exact = true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = orientation_coeff1(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), @@ -441,6 +443,7 @@ int orientation(const Extended_point& p1, run_exact = true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = orientation_coeff0(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), @@ -473,6 +476,7 @@ int compare_x(const Extended_point& p1, run_exact = true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = compare_expr(p1.mx(),p1.hw(),p2.mx(),p2.hw()); @@ -490,6 +494,7 @@ int compare_x(const Extended_point& p1, run_exact = true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = compare_expr(p1.nx(),p1.hw(),p2.nx(),p2.hw()); return res; @@ -514,6 +519,7 @@ int compare_y(const Extended_point& p1, run_exact = true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = compare_expr(p1.my(),p1.hw(),p2.my(),p2.hw()); if ( res != 0 ) return res; @@ -529,6 +535,7 @@ int compare_y(const Extended_point& p1, run_exact = true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = compare_expr(p1.ny(),p1.hw(),p2.ny(),p2.hw()); return res; @@ -673,6 +680,7 @@ int compare_pair_dist( run_exact = true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = cmppd_coeff2(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), @@ -695,6 +703,7 @@ int compare_pair_dist( run_exact = true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = cmppd_coeff1(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), @@ -716,6 +725,7 @@ int compare_pair_dist( run_exact = true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = cmppd_coeff0(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), @@ -959,6 +969,7 @@ int orientation(const Extended_direction& d1, run_exact=true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = coeff2_dor(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), @@ -979,6 +990,7 @@ int orientation(const Extended_direction& d1, run_exact=true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) res = coeff1_dor(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), @@ -1000,6 +1012,7 @@ int orientation(const Extended_direction& d1, run_exact = true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if(run_exact) res = coeff0_dor(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_NT.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_NT.h index d2fad323fe4..02dab4dbbcc 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_NT.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_NT.h @@ -48,6 +48,7 @@ struct Cartesian_filter_NT : public Base_ if(is_certain(res)) return get_certain(res); } catch (Uncertain_conversion_exception&) {} } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return p2(std::forward(u)...); } }; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h b/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h index c3d2281ad96..b7fefa139b6 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h @@ -88,6 +88,7 @@ public: } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding p(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return ep(c2e(std::forward(args))...); } }; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h index 7e82e90a407..cc96d8e5f12 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h @@ -184,6 +184,7 @@ struct Lazy_construction2 { } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return new Lazy_rep_0(ec(CGAL::exact(l)...)); } // FIXME: this forces us to have default constructors for all types, try to make its instantiation lazier diff --git a/Skin_surface_3/include/CGAL/Skin_surface_base_3.h b/Skin_surface_3/include/CGAL/Skin_surface_base_3.h index 57f8d2306e1..3c6507ca49e 100644 --- a/Skin_surface_3/include/CGAL/Skin_surface_base_3.h +++ b/Skin_surface_3/include/CGAL/Skin_surface_base_3.h @@ -313,7 +313,7 @@ sign(TMC_Vertex_handle vit) const } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P(CGAL_FE_TONEAREST); - + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); typedef Exact_predicates_exact_constructions_kernel EK; typedef Skin_surface_traits_3 Exact_skin_surface_traits; typedef Skin_surface_base_3 Exact_skin_surface_base; @@ -355,6 +355,7 @@ sign(const Bare_point &p, const Cell_info &info) const } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return construct_surface(info.first, Exact_predicates_exact_constructions_kernel()).sign(p); } @@ -630,7 +631,7 @@ compare(Cell_info &info1, const Bare_point &p1, } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P(CGAL_FE_TONEAREST); - + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return CGAL_NTS sign( construct_surface(info1.first, Exact_predicates_exact_constructions_kernel()).value(p1) - @@ -697,6 +698,7 @@ locate_in_tmc(const Bare_point &p0, TMC_Cell_handle start) const *pts[2], *pts[3]); } catch (Uncertain_conversion_exception&) { run_exact=true; } } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (run_exact) { Protect_FPU_rounding P(CGAL_FE_TONEAREST); diff --git a/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h b/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h index c643fe88ddd..92bfb84c326 100644 --- a/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h +++ b/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h @@ -1210,6 +1210,7 @@ orientation(Tmc_Cell_handle ch) } catch (Uncertain_conversion_exception&) {} } Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); typedef Exact_predicates_exact_constructions_kernel EK; typedef Cartesian_converter Exact_converter; typedef Skin_surface_traits_3 Exact_traits; diff --git a/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h b/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h index 973e7abeae8..6939ad21b72 100644 --- a/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h +++ b/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h @@ -152,6 +152,7 @@ public: } Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); EC_result_type er = Exact_construction(To_Exact(std::forward(a))...) ; return From_Exact(er); } From 2ba64da4e5a353194b2aee776e125b0fb9028e46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 9 Sep 2021 11:34:08 +0200 Subject: [PATCH 3/3] change protector scope + FPU assertion for operator not in 5.2 --- Filtered_kernel/include/CGAL/Lazy.h | 102 ++++++++++++++-------------- 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/Filtered_kernel/include/CGAL/Lazy.h b/Filtered_kernel/include/CGAL/Lazy.h index 3bb327920b1..226cd3a6585 100644 --- a/Filtered_kernel/include/CGAL/Lazy.h +++ b/Filtered_kernel/include/CGAL/Lazy.h @@ -917,35 +917,36 @@ struct Lazy_construction_optional_for_polygonal_envelope template result_type operator()(const L1& l1, const L1& l2, const L1& l3) const { - Protect_FPU_rounding P; + { + Protect_FPU_rounding P; - try { - boost::optional oap = ac(CGAL::approx(l1),CGAL::approx(l2),CGAL::approx(l3)); - if(oap == boost::none){ - return boost::none; - } - // Now we have to construct a rep for a lazy point with the three lazy planes. - typedef Lazy_rep_optional_n LazyPointRep; - CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(LazyPointRep, rep); + try { + boost::optional oap = ac(CGAL::approx(l1),CGAL::approx(l2),CGAL::approx(l3)); + if(oap == boost::none){ + return boost::none; + } + // Now we have to construct a rep for a lazy point with the three lazy planes. + typedef Lazy_rep_optional_n LazyPointRep; + CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(LazyPointRep, rep); - const typename AK::Point_3 ap = *oap; - rep = LazyPointRep(2,ap, ec, l1, l2, l3); - typename LK::Point_3 lp(&rep); - return boost::make_optional(lp); + const typename AK::Point_3 ap = *oap; + rep = LazyPointRep(2,ap, ec, l1, l2, l3); + typename LK::Point_3 lp(&rep); + return boost::make_optional(lp); - - } catch (Uncertain_conversion_exception&) { - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - boost::optional oep = ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); - if(oep == boost::none){ - return boost::none; - } - typedef Lazy_rep_0 LazyPointRep; - const typename EK::Point_3 ep = *oep; - LazyPointRep *rep = new LazyPointRep(ep); - typename LK::Point_3 lp(rep); - return boost::make_optional(lp); + } catch (Uncertain_conversion_exception&) {} } + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + boost::optional oep = ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); + if(oep == boost::none){ + return boost::none; + } + typedef Lazy_rep_0 LazyPointRep; + const typename EK::Point_3 ep = *oep; + LazyPointRep *rep = new LazyPointRep(ep); + typename LK::Point_3 lp(rep); + return boost::make_optional(lp); // AF can we get here?? return boost::none; } @@ -955,35 +956,36 @@ struct Lazy_construction_optional_for_polygonal_envelope result_type operator()(const L1& l1, const L2& l2) const { - Protect_FPU_rounding P; + { + Protect_FPU_rounding P; - try { - boost::optional oap = ac(CGAL::approx(l1),CGAL::approx(l2)); - if(oap == boost::none){ - return boost::none; - } - // Now we have to construct a rep for a lazy point with the line and the plane. - typedef Lazy_rep_optional_n LazyPointRep; + try { + boost::optional oap = ac(CGAL::approx(l1),CGAL::approx(l2)); + if(oap == boost::none){ + return boost::none; + } + // Now we have to construct a rep for a lazy point with the line and the plane. + typedef Lazy_rep_optional_n LazyPointRep; - CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(LazyPointRep, rep); - const typename AK::Point_3 ap = *oap; - rep = LazyPointRep(2, ap, ec, l1, l2); - typename LK::Point_3 lp(&rep); - return boost::make_optional(lp); + CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(LazyPointRep, rep); + const typename AK::Point_3 ap = *oap; + rep = LazyPointRep(2, ap, ec, l1, l2); + typename LK::Point_3 lp(&rep); + return boost::make_optional(lp); - - } catch (Uncertain_conversion_exception&) { - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - boost::optional oep = ec(CGAL::exact(l1), CGAL::exact(l2)); - if(oep == boost::none){ - return boost::none; - } - typedef Lazy_rep_0 LazyPointRep; - const typename EK::Point_3 ep = *oep; - LazyPointRep *rep = new LazyPointRep(ep); - typename LK::Point_3 lp(rep); - return boost::make_optional(lp); + } catch (Uncertain_conversion_exception&) {} } + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + boost::optional oep = ec(CGAL::exact(l1), CGAL::exact(l2)); + if(oep == boost::none){ + return boost::none; + } + typedef Lazy_rep_0 LazyPointRep; + const typename EK::Point_3 ep = *oep; + LazyPointRep *rep = new LazyPointRep(ep); + typename LK::Point_3 lp(rep); + return boost::make_optional(lp); // AF can we get here?? return boost::none; }