// ====================================================================== // // Copyright (c) 2001 The CGAL Consortium // // This software and related documentation is part of an INTERNAL release // of the Computational Geometry Algorithms Library (CGAL). It is not // intended for general use. // // ---------------------------------------------------------------------- // // release : // release_date : // // file : include/CGAL/Kernel_checker.h // package : // maintainer : // revision : $Id$ // revision_date : $Date$ // author(s) : // coordinator : // // ====================================================================== #ifndef CGAL_KERNEL_CHECKER_H #define CGAL_KERNEL_CHECKER_H #include #include #include #include CGAL_BEGIN_NAMESPACE // Class used by Kernel_checker. template class Special_construction { O1 o1; O2 o2; public: Special_construction(const O1 &oo1 = O1(), const O2 &oo2 = O2()) : o1(oo1), o2(oo2) {} // we have another result type now ... typedef MultiRep result_type; // the arity can stay ... typedef typename O1::Arity Arity; // -------------------------------------------------------------------------------- // attention: we have to handle MultiRep arguments in the templated // operators, but also other stuff (for instance ints in Construct_vertex) // problem: does this work on VC++ ? template const FR& get_first_rep(const MultiRep& obj) const { return obj.get_first_rep(); } template const T& get_first_rep(const T& other_obj) const { return other_obj; } template const SR& get_second_rep(const MultiRep& obj) const { return obj.get_second_rep(); } template const T& get_second_rep(const T& other_obj) const { return other_obj; } // -------------------------------------------------------------------------------- template result_type operator()(const A1 &a1) const { // construct the two representations ... typename O1::result_type res1 = o1(get_first_rep(a1)); typename O2::result_type res2 = o2(get_second_rep(a1)); // should we add some kind of check here as well ? // we use the special constructor here ... return result_type(res1, res2); } template result_type operator()(const A1 &a1, const A2 &a2) const { // construct the two representations ... typename O1::result_type res1 = o1(get_first_rep(a1), get_first_rep(a2)); typename O2::result_type res2 = o2(get_second_rep(a1), get_second_rep(a2)); // should we add some kind of check here as well ? // we use the special constructor here ... return result_type(res1, res2); } template result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3) const { // construct the two representations ... typename O1::result_type res1 = o1(get_first_rep(a1), get_first_rep(a2), get_first_rep(a3)); typename O2::result_type res2 = o2(get_second_rep(a1), get_second_rep(a2), get_second_rep(a3)); // should we add some kind of check here as well ? // we use the special constructor here ... return result_type(res1, res2); } template result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const { // construct the two representations ... typename O1::result_type res1 = o1(get_first_rep(a1), get_first_rep(a2), get_first_rep(a3), get_first_rep(a4)); typename O2::result_type res2 = o2(get_second_rep(a1), get_second_rep(a2), get_second_rep(a3), get_second_rep(a4)); // should we add some kind of check here as well ? // we use the special constructor here ... return result_type(res1, res2); } template result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) const { // construct the two representations ... typename O1::result_type res1 = o1(get_first_rep(a1), get_first_rep(a2), get_first_rep(a3), get_first_rep(a4), get_first_rep(a5)); typename O2::result_type res2 = o2(get_second_rep(a1), get_second_rep(a2), get_second_rep(a3), get_second_rep(a4), get_second_rep(a5)); // should we add some kind of check here as well ? // we use the special constructor here ... return result_type(res1, res2); } template result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6) const { // construct the two representations ... typename O1::result_type res1 = o1(get_first_rep(a1), get_first_rep(a2), get_first_rep(a3), get_first_rep(a4), get_first_rep(a5), get_first_rep(a6)); typename O2::result_type res2 = o2(get_second_rep(a1), get_second_rep(a2), get_second_rep(a3), get_second_rep(a4), get_second_rep(a5), get_second_rep(a6)); // should we add some kind of check here as well ? // we use the special constructor here ... return result_type(res1, res2); } 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 { // construct the two representations ... typename O1::result_type res1 = o1(get_first_rep(a1), get_first_rep(a2), get_first_rep(a3), get_first_rep(a4), get_first_rep(a5), get_first_rep(a6), get_first_rep(a7)); typename O2::result_type res2 = o2(get_second_rep(a1), get_second_rep(a2), get_second_rep(a3), get_second_rep(a4), get_second_rep(a5), get_second_rep(a6), get_second_rep(a7)); // should we add some kind of check here as well ? // we use the special constructor here ... return result_type(res1, res2); } 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 { // construct the two representations ... typename O1::result_type res1 = o1(get_first_rep(a1), get_first_rep(a2), get_first_rep(a3), get_first_rep(a4), get_first_rep(a5), get_first_rep(a6), get_first_rep(a7), get_first_rep(a8)); typename O2::result_type res2 = o2(get_second_rep(a1), get_second_rep(a2), get_second_rep(a3), get_second_rep(a4), get_second_rep(a5), get_second_rep(a6), get_second_rep(a7), get_second_rep(a8)); // should we add some kind of check here as well ? // we use the special constructor here ... return result_type(res1, res2); } // Same thing with more arguments... }; // Class used by Kernel_checker. template class Predicate_checker { O1 o1; O2 o2; public: Predicate_checker(const O1 &oo1 = O1(), const O2 &oo2 = O2()) : o1(oo1), o2(oo2) {} // the result type and arity of predicates can stay ... typedef typename O1::result_type result_type; typedef typename O1::Arity Arity; template result_type operator()(const A1 &a1) const { #if defined(CGAL_KCH_DEBUG) std::cout << "Predicate_checker(1):"; a1.output(std::cout); std::cout << "\n"; #endif typename O1::result_type res1 = o1(a1); typename O2::result_type res2 = o2(a1.get_second_rep()); if (res1 != res2) { std::cerr << "Kernel_checker error : " << res1 << " != " << res2 << " for the inputs : " << std::endl; std::cerr << a1 << std::endl; #ifdef __GNUG__ std::cerr << __PRETTY_FUNCTION__ << std::endl; #endif CGAL_kernel_assertion(false); } return res1; } template result_type operator()(const A1 &a1, const A2 &a2) const { #if defined(CGAL_KCH_DEBUG) std::cout << "Predicate_checker(2):"; a1.output(std::cout); a2.output(std::cout); std::cout << "\n"; #endif typename O1::result_type res1 = o1(a1, a2); typename O2::result_type res2 = o2(a1.get_second_rep(), a2.get_second_rep()); if (res1 != res2) { std::cerr << "Kernel_checker error : " << res1 << " != " << res2 << " for the inputs : " << std::endl; std::cerr << a1 << ", " << a2 << std::endl; #ifdef __GNUG__ std::cerr << __PRETTY_FUNCTION__ << std::endl; #endif CGAL_kernel_assertion(false); } return res1; } template result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3) const { #if defined(CGAL_KCH_DEBUG) std::cout << "Predicate_checker(3):"; a1.output(std::cout); a2.output(std::cout); a3.output(std::cout); std::cout << "\n"; #endif typename O1::result_type res1 = o1(a1, a2, a3); typename O2::result_type res2 = o2(a1.get_second_rep(), a2.get_second_rep(), a3.get_second_rep()); if (res1 != res2) { std::cerr << "Kernel_checker error : " << res1 << " != " << res2 << " for the inputs : " << std::endl; std::cerr << a1 << ", " << a2 << ", " << a3 << std::endl; #ifdef __GNUG__ std::cerr << __PRETTY_FUNCTION__ << std::endl; #endif CGAL_kernel_assertion(false); } return res1; } template result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const { #if defined(CGAL_KCH_DEBUG) std::cout << "Predicate_checker(4):"; a1.output(std::cout); a2.output(std::cout); a3.output(std::cout); a4.output(std::cout); #endif typename O1::result_type res1 = o1(a1, a2, a3, a4); typename O2::result_type res2 = o2(a1.get_second_rep(), a2.get_second_rep(), a3.get_second_rep(), a4.get_second_rep()); if (res1 != res2) { std::cerr << "Kernel_checker error : " << res1 << " != " << res2 << " for the inputs : " << std::endl; std::cerr << a1 << ", " << a2 << ", " << a3 << ", " << a4 << std::endl; #ifdef __GNUG__ std::cerr << __PRETTY_FUNCTION__ << std::endl; #endif CGAL_kernel_assertion(false); } return res1; } template result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) const { typename O1::result_type res1 = o1(a1, a2, a3, a4, a5); typename O2::result_type res2 = o2(a1.get_second_rep(), a2.get_second_rep(), a3.get_second_rep(), a4.get_second_rep(), a5.get_second_rep()); if (res1 != res2) { std::cerr << "Kernel_checker error : " << res1 << " != " << res2 << " for the inputs : " << std::endl; std::cerr << a1 << ", " << a2 << ", " << a3 << ", " << a4 << ", " << a5 << std::endl; #ifdef __GNUG__ std::cerr << __PRETTY_FUNCTION__ << std::endl; #endif CGAL_kernel_assertion(false); } return res1; } template result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6) const { typename O1::result_type res1 = o1(a1, a2, a3, a4, a5, a6); typename O2::result_type res2 = o2(a1.get_second_rep(), a2.get_second_rep(), a3.get_second_rep(), a4.get_second_rep(), a5.get_second_rep(), a6.get_second_rep()); if (res1 != res2) { std::cerr << "Kernel_checker error : " << res1 << " != " << res2 << " for the inputs : " << std::endl; std::cerr << a1 << ", " << a2 << ", " << a3 << ", " << a4 << ", " << a5 << std::endl; #ifdef __GNUG__ std::cerr << __PRETTY_FUNCTION__ << std::endl; #endif CGAL_kernel_assertion(false); } return res1; } // Same thing with more arguments... }; // offer the ability to use different converters for different objects ... // (might be important for some traits classes with vector type = direction type ?) template struct Default_converter_traits { typedef Converter Converter_object_2; typedef Converter Converter_object_3; typedef Converter Converter_point_2; typedef Converter Converter_vector_2; typedef Converter Converter_direction_2; typedef Converter Converter_line_2; typedef Converter Converter_ray_2; typedef Converter Converter_segment_2; typedef Converter Converter_triangle_2; typedef Converter Converter_circle_2; typedef Converter Converter_iso_rectangle_2; typedef Converter Converter_point_3; typedef Converter Converter_vector_3; typedef Converter Converter_direction_3; typedef Converter Converter_line_3; typedef Converter Converter_plane_3; typedef Converter Converter_ray_3; typedef Converter Converter_segment_3; typedef Converter Converter_triangle_3; typedef Converter Converter_tetrahedron_3; typedef Converter Converter_sphere_3; typedef Converter Converter_iso_cuboid_3; }; // For now, we inherit all geometric objects and constructions from K1, and // just overload the predicates. template class Kernel_checker : public K1 { typedef K1 Kernel1; typedef K2 Kernel2; Kernel2 k2; typedef Conv c; // the FT/RT stuff is still a problem ... // we derive it at the moment from K1 // get the conversion functors from Conv ... public: typedef typename Conv::Converter_object_2 Converter_object_2; typedef typename Conv::Converter_object_3 Converter_object_3; typedef typename Conv::Converter_point_2 Converter_point_2; typedef typename Conv::Converter_vector_2 Converter_vector_2; typedef typename Conv::Converter_direction_2 Converter_direction_2; typedef typename Conv::Converter_line_2 Converter_line_2; typedef typename Conv::Converter_ray_2 Converter_ray_2; typedef typename Conv::Converter_segment_2 Converter_segment_2; typedef typename Conv::Converter_triangle_2 Converter_triangle_2; typedef typename Conv::Converter_circle_2 Converter_circle_2; typedef typename Conv::Converter_iso_rectangle_2 Converter_iso_rectangle_2; typedef typename Conv::Converter_point_3 Converter_point_3; typedef typename Conv::Converter_vector_3 Converter_vector_3; typedef typename Conv::Converter_direction_3 Converter_direction_3; typedef typename Conv::Converter_line_3 Converter_line_3; typedef typename Conv::Converter_plane_3 Converter_plane_3; typedef typename Conv::Converter_ray_3 Converter_ray_3; typedef typename Conv::Converter_segment_3 Converter_segment_3; typedef typename Conv::Converter_triangle_3 Converter_triangle_3; typedef typename Conv::Converter_tetrahedron_3 Converter_tetrahedron_3; typedef typename Conv::Converter_sphere_3 Converter_sphere_3; typedef typename Conv::Converter_iso_cuboid_3 Converter_iso_cuboid_3; // now the typedefs; we use the MultiRep class template ... typedef CGAL::MultiRep Object_2; typedef CGAL::MultiRep Object_3; typedef CGAL::MultiRep Point_2; typedef CGAL::MultiRep Vector_2; typedef CGAL::MultiRep Direction_2; typedef CGAL::MultiRep Line_2; typedef CGAL::MultiRep Ray_2; typedef CGAL::MultiRep Segment_2; typedef CGAL::MultiRep Triangle_2; typedef CGAL::MultiRep Circle_2; typedef CGAL::MultiRep Iso_rectangle_2; typedef CGAL::MultiRep Point_3; typedef CGAL::MultiRep Vector_3; typedef CGAL::MultiRep Direction_3; typedef CGAL::MultiRep Line_3; typedef CGAL::MultiRep Plane_3; typedef CGAL::MultiRep Ray_3; typedef CGAL::MultiRep Segment_3; typedef CGAL::MultiRep Triangle_3; typedef CGAL::MultiRep Tetrahedron_3; typedef CGAL::MultiRep Sphere_3; typedef CGAL::MultiRep Iso_cuboid_3; // typedef std::pair Point_2; // ... Same thing for all objects. #define CGAL_check_pred(X, Y) \ typedef Predicate_checker X; \ X Y() const { return X(K1::Y(), k2.Y()); } #define CGAL_special_cons(X, Y) \ typedef Special_construction X; \ X Y() const { return X(K1::Y(), k2.Y()); } #define CGAL_Kernel_pred(Y,Z) CGAL_check_pred(Y, Z) #define CGAL_Kernel_cons(Y,Z) CGAL_special_cons(Y,Z) public: #include }; CGAL_END_NAMESPACE #endif // CGAL_KERNEL_CHECKER_H