// Copyright (c) 2011 GeometryFactory (France). All rights reserved. // All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // 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 #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 \ decltype(auto) \ intersection(const A& a, const B& b) { \ return BOOST_PP_CAT(K().intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \ } \ template \ inline \ decltype(auto) \ intersection(const B& b, const A& a) { \ return BOOST_PP_CAT(K().intersect_, BOOST_PP_CAT(DIM, _object()(b, a))); \ } #define CGAL_INTERSECTION_FUNCTION_SELF(A, DIM) \ template \ inline \ decltype(auto) \ 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 typename K::Boolean \ do_intersect(const A& a, const B& b) { \ return BOOST_PP_CAT(K().do_intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \ } \ template \ inline typename K::Boolean \ do_intersect(const B& b, const A& a) { \ return BOOST_PP_CAT(K().do_intersect_, BOOST_PP_CAT(DIM, _object()(b, a))); \ } #define CGAL_DO_INTERSECT_FUNCTION_SELF(A, DIM) \ template \ inline typename K::Boolean \ 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. }; 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 decltype(auto) intersection_return(T&& t) { return decltype(std::declval()(std::declval(), std::declval()))(std::forward(t)); } template decltype(auto) intersection_return() { return decltype(std::declval()(std::declval(), std::declval()))(); } // 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 decltype(auto) 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 decltype(auto) 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 auto // K::Boolean 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 auto // K::Boolean 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 auto // K::Boolean 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) { // static_assert(std::is_same::value), // "intersection with objects of different dimensions not supported"; // return internal::intersection_impl(a, b, typename A::Ambient_dimension()); // } // template // inline // auto // K::Boolean // do_intersect(const A& a, const B& b) { // static_assert(std::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 */