// Copyright (c) 2011 GeometryFactory (France). All rights reserved. // All rights reserved. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // 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. // // 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) : Philipp Möller #ifndef CGAL_INTERSECTION_TRAITS_H #define CGAL_INTERSECTION_TRAITS_H #include #include #include #include #include #include // The macro CGAL_INTERSECTION_VERSION controls which version of the // intersection is used. // Currently two values are supported: // - 1, which means intersections with CGAL::Object // - 2, which means intersections with Intersection_traits and the // corresponding APIs in other modules // The default value is 2. #if !defined(CGAL_INTERSECTION_VERSION) #define CGAL_INTERSECTION_VERSION 2 #endif #if CGAL_INTERSECTION_VERSION < 2 #define CGAL_INTERSECTION_TRAITS_2(A, B, R1, R2) #define CGAL_INTERSECTION_TRAITS_3(A, B, R1, R2, R3) #else #define CGAL_INTERSECTION_TRAITS_2(A, B, R1, R2) \ template \ struct Intersection_traits { \ typedef typename boost::variant \ variant_type; \ typedef typename boost::optional< variant_type > result_type; \ }; #define CGAL_INTERSECTION_TRAITS_3(A, B, R1, R2, R3) \ template \ struct Intersection_traits { \ typedef typename boost::variant variant_type; \ typedef typename boost::optional< variant_type > result_type; \ }; #endif namespace CGAL { // only declarationn template struct Intersection_traits { // This defaults to Object, if we use VERSION < 2 and to nothing // otherwise. #if CGAL_INTERSECTION_VERSION < 2 typedef CGAL::Object result_type; #endif }; // alias template struct IT : public Intersection_traits {}; // The version to cover ternary intersections of the Spherical_kernel template struct Intersection_traits_spherical { typedef boost::variant< typename K::Circle_3, typename K::Plane_3, typename K::Sphere_3, std::pair< typename K::Circular_arc_point_3, unsigned > > result_type; }; template struct ITs : public Intersection_traits_spherical {}; namespace internal { // this function is used to call either make_object or a // Intersection_traits::result_type constructor to create return // values. The Object version takes some dummy template arguments // that are needed for the return of the Intersection_traits. In // theory a one parameter variant could be returned, but this // _could_ come with conversion overhead and so we rather go for // the real type. // Overloads for empty returns are also provided. #if CGAL_INTERSECTION_VERSION < 2 #if defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) template inline CGAL::Object intersection_return(const T& t) { return CGAL::make_object(t); } #else template inline CGAL::Object intersection_return(T&& t) { return CGAL::make_object(std::forward(t)); } #endif // CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE template inline CGAL::Object intersection_return() { return CGAL::Object(); } #else #if defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) template inline typename Intersection_traits::result_type intersection_return(const T& t) { return typename CGAL::Intersection_traits::result_type(t); } #else template inline typename Intersection_traits::result_type intersection_return(T&& t) { return typename CGAL::Intersection_traits::result_type(std::forward(t)); } #endif // CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE template inline typename Intersection_traits::result_type intersection_return() { return typename CGAL::Intersection_traits::result_type(); } #endif // CGAL_INTERSECTION_VERSION < 2 // Something similar to wrap around boost::get and object_cast to // prevent ifdefing too much. Another way could be to introduce an // overload of boost::get for Object. We only provide the pointer // casts here. But use references to const as parameters. This makes // it somewhat nicer. template inline const T* intersect_get(const CGAL::Object& o) { return CGAL::object_cast(&o); } template inline const T* intersect_get(const boost::optional< boost::variant >& v) { return boost::get(&*v); } template inline const T* intersect_get(const boost::variant & v) { return boost::get(&v); } template typename IT< typename CGAL::Kernel_traits::Kernel, A, B>::result_type intersection_impl(const A& a, const B& b, CGAL::Dimension_tag<2>) { typedef typename CGAL::Kernel_traits::Kernel Kernel; return Kernel().intersect_2_object()(a, b); } template typename IT< typename CGAL::Kernel_traits::Kernel, A, B>::result_type intersection_impl(const A& a, const B& b, Dimension_tag<3>) { typedef typename CGAL::Kernel_traits::Kernel Kernel; return Kernel().intersect_3_object()(a, b); } template typename IT< typename CGAL::Kernel_traits::Kernel, A, B>::result_type intersection_impl(const A& a, const B& b, Dynamic_dimension_tag) { typedef typename CGAL::Kernel_traits::Kernel Kernel; return Kernel().intersect_d_object()(a, b); } template inline bool do_intersect_impl(const A& a, const B& b, CGAL::Dimension_tag<2>) { typedef typename CGAL::Kernel_traits::Kernel Kernel; return Kernel().do_intersect_2_object()(a, b); } template inline bool do_intersect_impl(const A& a, const B& b, Dimension_tag<3>) { typedef typename CGAL::Kernel_traits::Kernel Kernel; return Kernel().do_intersect_3_object()(a, b); } template inline bool do_intersect_impl(const A& a, const B& b, Dynamic_dimension_tag) { typedef typename CGAL::Kernel_traits::Kernel Kernel; return Kernel().do_intersect_d_object()(a, b); } } // internal template inline typename IT< typename Kernel_traits::Kernel, A, B>::result_type intersection(const A& a, const B& b) { CGAL_static_assertion_msg( (boost::is_same::value), "intersection with objects of different dimensions not supported"); return internal::intersection_impl(a, b, typename A::Ambient_dimension()); } template inline bool do_intersect(const A& a, const B& b) { CGAL_static_assertion_msg((boost::is_same::value), "do_intersect with objects of different dimensions not supported"); return internal::do_intersect_impl(a, b, typename A::Ambient_dimension()); } } // CGAL #endif /* CGAL_INTERSECTION_TRAITS_H */