// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under // the terms of the Q Public License version 1.0. // See the file LICENSE.QPL 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) : Monique Teillaud, Sylvain Pion // Andreas Fabri, Constantinos Tsirogiannis #ifndef CGAL_LAZY_CURVED_KERNEL_CONSTRUCTIONS_H #define CGAL_LAZY_CURVED_KERNEL_CONSTRUCTIONS_H #include #include //TODO : More if-else's with object cast for all the possible // types that could be returned by object-returning functions CGAL_BEGIN_NAMESPACE template Object make_lazy_CK(const Object& eto) { typedef typename LK::AK AK; typedef typename LK::EK EK; typedef typename LK::E2A E2A; const std::pair *ptr; if(( ptr = object_cast >(&eto))){ return make_object(std::make_pair(typename LK::Circular_arc_point_2( new Lazy_construct_rep_0(ptr->first)),ptr->second)); } else if(const typename EK::Circular_arc_2* ptr = object_cast(&eto)){ return make_object(typename LK::Circular_arc_2( new Lazy_construct_rep_0(*ptr))); } else if(const typename EK::Line_arc_2* ptr = object_cast(&eto)){ return make_object(typename LK::Line_arc_2( new Lazy_construct_rep_0(*ptr))); } else{ std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's" << std::endl; } return Object(); } // This is the magic functor for functors that write their result as Objects into an output iterator template struct Lazy_construct_intersections_2 { static const bool Protection = true; typedef typename LK::AK AK; typedef typename LK::EK EK; typedef typename EK::FT EFT; typedef typename LK::E2A E2A; typedef void result_type; typedef Lazy Lazy_object; typedef Lazy, std::vector, EFT, E2A> Lazy_vector; AC ac; EC ec; public: // In the example we intersect two Lazys // and write into a back_inserter(list,Lazy]) >) template OutputIterator operator()(const L1& l1, const L2& l2, OutputIterator it) const { try { CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); Protect_FPU_rounding P; Lazy_vector lv(new Lazy_construct_rep_with_vector_2(ac, ec, l1, l2)); for(unsigned int i = 0; i < lv.approx().size(); i++){ const std::pair *temp_p; if((temp_p=object_cast >(& (lv.approx()[i])))){ *it = make_object(std::make_pair(typename LK::Circular_arc_point_2( new Lazy_construct_rep_1, Ith, E2A, Lazy_vector>(Ith(i,false), Ith(i,false), lv)),temp_p->second)); ++it; } else if(object_cast(& (lv.approx()[i]))){ *it = make_object(typename LK::Circular_arc_2( new Lazy_construct_rep_1, Ith,E2A, Lazy_vector>(Ith(i), Ith(i), lv))); ++it; } else if(object_cast(& (lv.approx()[i]))){ *it = make_object(typename LK::Line_arc_2( new Lazy_construct_rep_1, Ith,E2A, Lazy_vector>(Ith(i), Ith(i), lv))); ++it; } else{ std::cout << "UNEXPECTED CONSTRUCT_INTERSECTIONS_2 PRODUCT" << std::endl; std::cout << lv.approx()[i].type().name() << std::endl; std::abort(); } } } catch (Interval_nt_advanced::unsafe_comparison) { CGAL_PROFILER(std::string("failures of : ") + std::string(CGAL_PRETTY_FUNCTION)); Protect_FPU_rounding P(CGAL_FE_TONEAREST); // TODO: Instead of using a vector, write an iterator adapter std::vector exact_objects; ec(CGAL::exact(l1), CGAL::exact(l2), std::back_inserter(exact_objects)); for (std::vector::iterator oit = exact_objects.begin(); oit != exact_objects.end(); oit++){ *it = make_lazy_CK(*oit); ++it; } } return it; } }; template struct Lazy_make_x_monotone_2 { static const bool Protection = true; typedef typename LK::AK AK; typedef typename LK::EK EK; typedef typename EK::FT EFT; typedef typename LK::E2A E2A; typedef void result_type; typedef Lazy Lazy_object; typedef Lazy, std::vector, EFT, E2A> Lazy_vector; AC ac; EC ec; public: // In the example we intersect two Lazys // and write into a back_inserter(list,Lazy]) >) template OutputIterator operator()(const L1& l1,OutputIterator it) const { try { CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); Protect_FPU_rounding P; Lazy_vector lv(new Lazy_construct_rep_with_vector_1(ac, ec, l1)); // 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++){ if(object_cast(& (lv.approx()[i]))){ *it = make_object(typename LK::Circular_arc_2( new Lazy_construct_rep_1, Ith,E2A, Lazy_vector>(Ith(i), Ith(i), lv))); ++it; } else if(object_cast(& (lv.approx()[i]))){ *it = make_object(typename LK::Line_arc_2( new Lazy_construct_rep_1, Ith,E2A, Lazy_vector>(Ith(i), Ith(i), lv))); ++it; } else{ std::cout << "UNEXPECTED MAKE_X_MONOTONE PRODUCT" << std::endl; std::abort(); } } } catch (Interval_nt_advanced::unsafe_comparison) { CGAL_PROFILER(std::string("failures of : ") + std::string(CGAL_PRETTY_FUNCTION)); Protect_FPU_rounding P(CGAL_FE_TONEAREST); // TODO: Instead of using a vector, write an iterator adapter std::vector exact_objects; ec(CGAL::exact(l1), std::back_inserter(exact_objects)); for (std::vector::iterator oit = exact_objects.begin(); oit != exact_objects.end(); oit++){ *it = make_lazy_CK(*oit); ++it; } } return it; } }; template struct Lazy_advanced_make_x_monotone_2 { static const bool Protection = true; typedef typename LK::AK AK; typedef typename LK::EK EK; typedef typename EK::FT EFT; typedef typename LK::E2A E2A; typedef void result_type; typedef Lazy Lazy_object; typedef Lazy, std::vector, EFT, E2A> Lazy_vector; AC ac; EC ec; public: // In the example we intersect two Lazys // and write into a back_inserter(list,Lazy]) >) template OutputIterator operator()(const L1& l1,OutputIterator it) const { try { CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); Protect_FPU_rounding P; Lazy_vector lv(new Lazy_construct_rep_with_vector_1(ac, ec, l1)); // 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++){ if(object_cast(& (lv.approx()[i].first))){ *it = std::make_pair(make_object(typename LK::Circular_arc_2( new Lazy_construct_rep_1, Ith,E2A, Lazy_vector>(Ith(i), Ith(i), lv))),lv.approx()[i].second); ++it; } else if(object_cast(& (lv.approx()[i].first))){ *it = std::make_pair(make_object(typename LK::Line_arc_2( new Lazy_construct_rep_1, Ith,E2A, Lazy_vector>(Ith(i), Ith(i), lv))),lv.approx()[i].second); ++it; } else{ std::cout << "UNEXPECTED ADVANCED_MAKE_X_MONOTONE PRODUCT" << std::endl; std::abort(); } } } catch (Interval_nt_advanced::unsafe_comparison) { CGAL_PROFILER(std::string("failures of : ") + std::string(CGAL_PRETTY_FUNCTION)); Protect_FPU_rounding P(CGAL_FE_TONEAREST); // TODO: Instead of using a vector, write an iterator adapter std::vector exact_objects; ec(CGAL::exact(l1), std::back_inserter(exact_objects)); for (std::vector::iterator oit = exact_objects.begin(); oit != exact_objects.end(); ++oit){ CGAL_assertion_msg(false, "Unfinished code !!!"); std::abort(); //*it = std::make_pair(make_lazy_CK((*oit).first),(*oit).second); ++it; } } return it; } }; // The following functor returns an Object with a Lazy inside // As the nested kernels return Objects of AK::Something and EK::Something // we have to unwrap them from the Object, and wrap them in a Lazy // // TODO: write operators for more than two arguments. For the current kernel we only need two for // Construct_intersections_2 and one for Make_x_monotone_2 template struct Lazy_construction_object_CK { static const bool Protection = true; typedef typename LK::AK AK; typedef typename LK::EK EK; typedef typename EK::FT EFT; typedef typename LK::E2A E2A; typedef typename AC::result_type AT; typedef typename EC::result_type ET; typedef Object result_type; typedef Lazy Lazy_object; AC ac; EC ec; public: template result_type operator()(const L1& l1) const { try { CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); Protect_FPU_rounding P; Lazy_object lo(new Lazy_construct_rep_1(ac, ec, l1)); std::pair *temp_p; if((temp_p=object_cast >(& (lo.approx())))){ typedef Lazy_construct_rep_1, Object_cast, E2A, Lazy_object> Lcr; Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); return make_object(std::make_pair(typename LK::Circular_arc_point_2(lcr),temp_p->second)); } else if(object_cast(& (lo.approx()))){ typedef Lazy_construct_rep_1, Object_cast, E2A, Lazy_object> Lcr; Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); return make_object(typename LK::Circular_arc_point_2(lcr)); } else if(object_cast(& (lo.approx()))){ typedef Lazy_construct_rep_1, Object_cast, E2A, Lazy_object> Lcr; Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); return make_object(typename LK::Circular_arc_2(lcr));} else if(object_cast(& (lo.approx()))){ typedef Lazy_construct_rep_1, Object_cast, E2A, Lazy_object> Lcr; Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); return make_object(typename LK::Line_arc_2(lcr));} else { std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's" << std::endl; } } catch (Interval_nt_advanced::unsafe_comparison) { CGAL_PROFILER(std::string("failures of : ") + std::string(CGAL_PRETTY_FUNCTION)); Protect_FPU_rounding P(CGAL_FE_TONEAREST); ET eto = ec(CGAL::exact(l1)); return make_lazy_CK(eto); } return Object(); } template result_type operator()(const L1& l1, const L2& l2) const { try { CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); Protect_FPU_rounding P; Lazy_object lo(new Lazy_construct_rep_2(ac, ec, l1, l2)); std::pair *temp_p; if((temp_p=object_cast >(& (lo.approx())))){ typedef Lazy_construct_rep_1, Object_cast, E2A, Lazy_object> Lcr; Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); return make_object(std::make_pair(typename LK::Circular_arc_point_2(lcr),temp_p->second)); } else if(object_cast(& (lo.approx()))){ typedef Lazy_construct_rep_1, Object_cast, E2A, Lazy_object> Lcr; Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); return make_object(typename LK::Circular_arc_point_2(lcr)); } else if(object_cast(& (lo.approx()))){ typedef Lazy_construct_rep_1, Object_cast, E2A, Lazy_object> Lcr; Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); return make_object(typename LK::Circular_arc_2(lcr));} else if(object_cast(& (lo.approx()))){ typedef Lazy_construct_rep_1, Object_cast, E2A, Lazy_object> Lcr; Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); return make_object(typename LK::Line_arc_2(lcr));} else { std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's" << std::endl; } } catch (Interval_nt_advanced::unsafe_comparison) { CGAL_PROFILER(std::string("failures of : ") + std::string(CGAL_PRETTY_FUNCTION)); Protect_FPU_rounding P(CGAL_FE_TONEAREST); ET eto = ec(CGAL::exact(l1), CGAL::exact(l2)); return make_lazy_CK(eto); } return Object(); } }; CGAL_END_NAMESPACE #endif // CGAL_LAZY_CURVED_KERNEL_CONSTRUCTIONS_H