// Copyright (c) 2011 GeometryFactory (France). All rights reserved. // All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL: https://github.com/CGAL/cgal/blob/v5.1/Intersections_2/include/CGAL/Intersection_traits.h $ // $Id: Intersection_traits.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Philipp Möller #ifndef CGAL_INTERSECTION_TRAITS_H #define CGAL_INTERSECTION_TRAITS_H #include #include #include #include #include #include #include #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; \ }; #define CGAL_INTERSECTION_FUNCTION(A, B, DIM) \ template \ inline \ typename cpp11::result_of::type \ intersection(const A& a, const B& b) { \ return BOOST_PP_CAT(K().intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \ } \ template \ inline \ typename cpp11::result_of::type \ intersection(const B& a, const A& b) { \ return BOOST_PP_CAT(K().intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \ } #define CGAL_INTERSECTION_FUNCTION_SELF(A, DIM) \ template \ inline \ typename cpp11::result_of::type \ intersection(const A & a, const A & b) { \ return BOOST_PP_CAT(K().intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \ } #define CGAL_DO_INTERSECT_FUNCTION(A, B, DIM) \ template \ inline bool \ do_intersect(const A& a, const B& b) { \ return BOOST_PP_CAT(K().do_intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \ } \ template \ inline bool \ do_intersect(const B& a, const A& b) { \ return BOOST_PP_CAT(K().do_intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \ } #define CGAL_DO_INTERSECT_FUNCTION_SELF(A, DIM) \ template \ inline bool \ do_intersect(const A & a, const A & b) { \ return BOOST_PP_CAT(K().do_intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \ } namespace CGAL { // only declarationn template struct Intersection_traits { // This defaults to Object, if we use VERSION < 2 and do nothing // otherwise. }; // Alias that gets the Kernel automatically and does some error checking. // Including corresponding specialization for Bbox, as it has no Kernel. template class IT : public Intersection_traits< typename Kernel_traits::Kernel, A, B > { typedef typename Kernel_traits::Kernel A_Kernel; typedef typename Kernel_traits::Kernel B_Kernel; // CGAL_static_assertion_msg( (boost::is_same< A_Kernel, B_Kernel>::value), // "IT instantiated with objects from two different Kernels"); }; class Bbox_2; class Bbox_3; template class IT : public Intersection_traits< typename Kernel_traits::Kernel, CGAL::Bbox_2, B > { }; template class IT : public Intersection_traits< typename Kernel_traits::Kernel, CGAL::Bbox_3, B > { }; namespace Intersections { 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. template inline typename cpp11::result_of::type intersection_return(T&& t) { return typename cpp11::result_of::type(std::forward(t)); } template inline typename cpp11::result_of::type intersection_return() { return typename cpp11::result_of::type(); } // 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 cpp11::result_of::Kernel::Intersect_2(A, B)>::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 cpp11::result_of::Kernel::Intersect_3(A, B)>::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 Intersection_traits< 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); } } // namespace internal } // namespace Intersections // See overloads in the respective header files // template // inline // typename Intersection_traits< typename Kernel_traits::Kernel, A, B>::result_type >::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 */