From a214d62bd6a1d6597900c3bc05f14f872c115d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20M=C3=B6ller?= Date: Thu, 6 Dec 2012 14:32:59 +0100 Subject: [PATCH] Integrate boost::variant with Lazy kernels interaction This requires changing the way Lazy_construction_XXX wrappers are selected and some code to unpack variants. --- Filtered_kernel/include/CGAL/Lazy.h | 337 +++++++----------- Filtered_kernel/include/CGAL/Lazy_kernel.h | 232 ++++++------ .../include/CGAL/Intersection_traits.h | 12 +- .../test/Intersections_3/call_test.cpp | 10 +- .../include/CGAL/Interval_traits.h | 5 +- .../include/CGAL/Kernel/function_objects.h | 34 +- 6 files changed, 284 insertions(+), 346 deletions(-) diff --git a/Filtered_kernel/include/CGAL/Lazy.h b/Filtered_kernel/include/CGAL/Lazy.h index ded3d853474..ae5556c66bf 100644 --- a/Filtered_kernel/include/CGAL/Lazy.h +++ b/Filtered_kernel/include/CGAL/Lazy.h @@ -42,9 +42,6 @@ #include #include -#include -#include -#include #include #include @@ -53,9 +50,6 @@ #include #include -// this needs to be removed -#include - namespace CGAL { template class Lazy; @@ -971,10 +965,8 @@ struct Ith_for_intersection_with_variant { const std::vector* ptr = (boost::get >(&o)); return (*ptr)[i]; } - }; - template struct Lazy_cartesian_const_iterator_2 { @@ -1361,122 +1353,112 @@ CGAL_Kernel_obj(Point_3) }; + + +//____________________________________________________________ +// The magic functor that has Lazy as result type. +// Two versions are distinguished: one that needs to fiddle +// with result_of and another that can forward the result types. + namespace internal { - // lift boost::get into a functor with a result_type member name and - // extend it to operate on optionals +BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) - // TODO there is a mismatch between the result_type typedef and the - // actual return type of operator() +// lift boost::get into a functor with a result_type member name and +// extend it to operate on optionals + +// TODO there is a mismatch between the result_type typedef and the +// actual return type of operator() +template +struct Variant_cast { + typedef T result_type; + + template + const T& + operator()(const boost::optional< boost::variant< BOOST_VARIANT_ENUM_PARAMS(U) > >& o) const { + // can throw but should never because we always build it inside + // a static visitor with the right type + return boost::get(*o); + } + + template + T& + operator()(boost::optional< boost::variant< BOOST_VARIANT_ENUM_PARAMS(U) > >& o) const { + // can throw but should never because we always build it inside + // a static visitor with the right type, if it throws bad_get + return boost::get(*o); + } +}; + + +template +struct Fill_lazy_variant_visitor_2 : boost::static_visitor<> { + Fill_lazy_variant_visitor_2(Result& r, Origin& o) : r(&r), o(&o) {} + Result* r; + Origin* o; + template - struct Variant_cast { - typedef T result_type; + void operator()(const T&) { + // the equivalent type we are currently matching in the lazy kernel + typedef T AKT; + typedef typename Type_mapper::type EKT; + typedef typename Type_mapper::type LKT; - template - const T& - operator()(const boost::optional< boost::variant< BOOST_VARIANT_ENUM_PARAMS(U) > >& o) const { - // can throw but should never because we always build it inside - // a static visitor with the right type - return boost::get(*o); - } - - template - T& - operator()(boost::optional< boost::variant< BOOST_VARIANT_ENUM_PARAMS(U) > >& o) const { - // can throw but should never because we always build it inside - // a static visitor with the right type, if it throws bad_get - return boost::get(*o); - } - }; - - template - struct Fill_lazy_variant_visitor_2 : boost::static_visitor<> { - Fill_lazy_variant_visitor_2(Result& r, Origin& o) : r(&r), o(&o) {} - Result* r; - Origin* o; + typedef Lazy_rep_1, Variant_cast, typename LK::E2A, Origin> Lcr; + Lcr * lcr = new Lcr(Variant_cast(), Variant_cast(), *o); + + *r = LKT(lcr); + } - template - void operator()(const T&) { - // the equivalent type we are currently matching in the lazy kernel - typedef T AKT; - typedef typename Type_mapper::type EKT; - typedef typename Type_mapper::type LKT; + template + void operator()(const std::vector& t) { + typedef T AKT; + typedef typename Type_mapper::type EKT; + typedef typename Type_mapper::type LKT; - typedef Lazy_rep_1, Variant_cast, typename LK::E2A, Origin> Lcr; - Lcr * lcr = new Lcr(Variant_cast(), Variant_cast(), *o); - - *r = LKT(lcr); + std::vector V; + V.resize(t.size()); + for (unsigned int i = 0; i < t.size(); i++) { + V[i] = LKT(new Lazy_rep_1, + Ith_for_intersection, typename LK::E2A, Origin> + (Ith_for_intersection(i), Ith_for_intersection(i), *o)); } + + *r = V; + } +}; + +template +struct Fill_lazy_variant_visitor_0 : boost::static_visitor<> { + Fill_lazy_variant_visitor_0(Result& r) : r(&r) {} + Result* r; - template - void operator()(const std::vector& t) { - typedef T AKT; - typedef typename Type_mapper::type EKT; - typedef typename Type_mapper::type LKT; - - std::vector V; - V.resize(t.size()); - for (unsigned int i = 0; i < t.size(); i++) { - V[i] = LKT(new Lazy_rep_1, - Ith_for_intersection, typename LK::E2A, Origin> - (Ith_for_intersection(i), Ith_for_intersection(i), *o)); - } + template + void operator()(const T& t) { + // the equivalent type we are currently matching in the lazy kernel + typedef T EKT; + typedef typename Type_mapper::type AKT; + typedef typename Type_mapper::type LKT; - *r = V; - } - }; - - template - struct Fill_lazy_variant_visitor_0 : boost::static_visitor<> { - Fill_lazy_variant_visitor_0(Result& r) : r(&r) {} - Result* r; - - template - void operator()(const T& t) { - // the equivalent type we are currently matching in the lazy kernel - typedef T EKT; - typedef typename Type_mapper::type AKT; - typedef typename Type_mapper::type LKT; - - *r = LKT(new Lazy_rep_0(t)); - } - - template - void operator()(const std::vector& t) { - typedef T EKT; - typedef typename Type_mapper::type AKT; - typedef typename Type_mapper::type LKT; - - std::vector V; - V.resize(t.size()); - for (unsigned int i = 0; i < t.size(); i++) { - V[i] = LKT(new Lazy_rep_0(t[i])); - - // Ith_for_intersection_with_variant, - // Ith_for_intersection_with_variant, typename LK::E2A> - // (Ith_for_intersection_with_variant(i), Ith_for_intersection_with_variant(i), t[i])); - } - - *r = V; - } - }; - - // metafunction to add a result_type typedef to a Intersect functor - // as soon as the arguments are known - template - struct Add_result_type_fix { - struct Extended_F : public T { - typedef Add result_type; - }; - - typedef Extended_F type; - }; + *r = LKT(new Lazy_rep_0(t)); + } template - struct is_optional : boost::mpl::false_{}; + void operator()(const std::vector& t) { + typedef T EKT; + typedef typename Type_mapper::type AKT; + typedef typename Type_mapper::type LKT; - template - struct is_optional > : boost::mpl::true_{}; -} + std::vector V; + V.resize(t.size()); + for (unsigned int i = 0; i < t.size(); i++) { + V[i] = LKT(new Lazy_rep_0(t[i])); + } + + *r = V; + } +}; + +} // internal template struct Lazy_construction_variant { @@ -1487,68 +1469,21 @@ struct Lazy_construction_variant { typedef typename EK::FT EFT; typedef typename LK::E2A E2A; - // Forward the result meta function, without touching implementation - // details, we steal the result of the exact functor, know that it - // is a optional< variant > or variant, and transform the inner type - // list to a LK Kernel types. Partly stolen from the - // cartesian_converter and a candidate for consolidation. - template - class Result { - typedef typename EC::template Result< typename Type_mapper::type, - typename Type_mapper::type >::Type Exact_type; - public: - // This is the solution that prevents include Intersection_traits - // but is buggy right now - - // typedef typename - // boost::mpl::if_< internal::is_optional, - // boost::optional< - // typename boost::make_variant_over< - // typename internal::Transform_type_mapper< - // typename boost::mpl::remove< typename Exact_type::value_type::types, - // boost::detail::variant::void_, - // boost::mpl::back_inserter< boost::mpl::vector0<> > - // >::type - // , EK, LK >::type - // >::type - // >, - // typename boost::make_variant_over< - // typename internal::Transform_type_mapper< - // typename boost::mpl::remove< typename Exact_type::types, - // boost::detail::variant::void_, - // boost::mpl::back_inserter< boost::mpl::vector0<> > - // >::type - // , EK, LK >::type - // >::type - // >::type Type; - - // This is hack around but requires the include - typedef typename CGAL::IT::result_type Type; - typedef Type type; - }; - template - typename Result::Type + typename boost::result_of::type operator()(const L1& l1, const L2& l2) const { - - typedef typename Result< L1, L2 >::Type result_type; - typedef typename AC::template Result< typename Type_mapper::type, - typename Type_mapper::type >::Type AT; - typedef typename EC::template Result< typename Type_mapper::type, - typename Type_mapper::type >::Type ET; - - typedef typename internal::Add_result_type_fix::type AC_with_result_type; - typedef typename internal::Add_result_type_fix::type EC_with_result_type; - + typedef typename boost::result_of::type result_type; + + typedef typename boost::result_of::type, + typename Type_mapper::type)>::type AT; + typedef typename boost::result_of::type, + typename Type_mapper::type)>::type ET; + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); Protect_FPU_rounding P; try { - Lazy lazy( - new Lazy_rep_2(AC_with_result_type(), EC_with_result_type(), l1, l2) - ); + Lazy lazy(new Lazy_rep_2(AC(), EC(), l1, l2)); // the approximate result requires the trait with types from the AK AT approx_v = lazy.approx(); @@ -1576,35 +1511,26 @@ struct Lazy_construction_variant { return res; } - internal::Fill_lazy_variant_visitor_0< result_type, AK, LK, EK> visitor(res); + internal::Fill_lazy_variant_visitor_0 visitor(res); boost::apply_visitor(visitor, *exact_v); return res; } } - - // hardcoded for ternary plane intersection template - boost::optional< boost::variant< typename LK::Point_3, typename LK::Line_3, typename LK::Plane_3 > > + typename boost::result_of::type operator()(const L1& l1, const L2& l2, const L3& l3) const { - typedef boost::optional< boost::variant< typename LK::Point_3, typename LK::Line_3, typename LK::Plane_3 > > - result_type; - typedef boost::optional< boost::variant< typename AK::Point_3, typename AK::Line_3, typename AK::Plane_3 > > - AT; - typedef boost::optional< boost::variant< typename EK::Point_3, typename EK::Line_3, typename EK::Plane_3 > > - ET; - typedef typename internal::Add_result_type_fix::type AC_with_result_type; - typedef typename internal::Add_result_type_fix::type EC_with_result_type; + typedef typename boost::result_of::type result_type; + + typedef typename boost::result_of::type, + typename Type_mapper::type, + typename Type_mapper::type)>::type AT; + typedef typename boost::result_of::type, + typename Type_mapper::type, + typename Type_mapper::type)>::type ET; - - CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; try { - Lazy lazy( - new Lazy_rep_3(AC_with_result_type(), EC_with_result_type(), l1, l2, l3) - ); + Lazy lazy(new Lazy_rep_3(AC(), EC(), l1, l2, l3)); // the approximate result requires the trait with types from the AK AT approx_v = lazy.approx(); @@ -1637,17 +1563,24 @@ struct Lazy_construction_variant { return res; } } + + template + struct result { + // this does not default, if you want to make a lazy lazy-kernel, + // you are on your own + }; + + #define CGAL_RESULT(z, n, d) \ + template< typename F, BOOST_PP_ENUM_PARAMS(n, class T) > \ + struct result { \ + BOOST_PP_REPEAT(n, CGAL_TYPEMAP_AC, T) \ + typedef typename Type_mapper< \ + typename boost::result_of::type, AK, LK>::type type; \ + }; + + BOOST_PP_REPEAT_FROM_TO(1, 9, CGAL_RESULT, _) }; -//____________________________________________________________ -// The magic functor that has Lazy as result type. -// Two versions are distinguished: one that needs to fiddle -// with result_of and another that can forward the result types. - -namespace internal { - BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) -} - template::value && internal::has_result_type::value > struct Lazy_construction; @@ -1673,14 +1606,14 @@ struct Lazy_construction { AC ac; EC ec; -#define CGAL_CONSTRUCTION_OPERATOR(z, n, d ) \ +#define CGAL_CONSTRUCTION_OPERATOR(z, n, d ) \ template \ result_type \ - operator()( BOOST_PP_ENUM(n, CGAL_LARGS, _) ) const { \ - typedef Lazy< AT, ET, EFT, E2A> Handle; \ + operator()( BOOST_PP_ENUM(n, CGAL_LARGS, _) ) const { \ + typedef Lazy< AT, ET, EFT, E2A> Handle; \ CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); \ - Protect_FPU_rounding P; \ - try { \ + Protect_FPU_rounding P; \ + try { \ return result_type( Handle(new Lazy_rep_##n(ac, ec, BOOST_PP_ENUM_PARAMS(n, l)))); \ } catch (Uncertain_conversion_exception) { \ CGAL_BRANCH_PROFILER_BRANCH(tmp); \ diff --git a/Filtered_kernel/include/CGAL/Lazy_kernel.h b/Filtered_kernel/include/CGAL/Lazy_kernel.h index 0f8325cb366..0ba503bc088 100644 --- a/Filtered_kernel/include/CGAL/Lazy_kernel.h +++ b/Filtered_kernel/include/CGAL/Lazy_kernel.h @@ -32,16 +32,17 @@ #include #include +#include #include -#include -#include - +#include #include #include + namespace CGAL { namespace internal { + // SFINAE way to detect result_type typedefs. template class Has_result_type_helper @@ -68,43 +69,23 @@ struct Has_result_type Has_result_type_helper< typename boost::remove_cv::type>::value> {}; -template -struct Maybe_result_type { - // This is incredibly evil. It relies on the fact that we always - // have a type in the primary result template but it looks like the - // only way out given the current design. - typedef typename F::template result::type type; -}; - -template -struct Maybe_result_type { - typedef typename F::result_type type; -}; - -// goes through the standard process of selecting the right -// Lazy_something after the kind of the return type has been -// determined -template -struct Standard_pick { - typedef typename boost::remove_cv< typename boost::remove_reference< typename T::type >::type >::type T_; - typedef typename boost::mpl::if_< boost::is_same< T_, typename AK::FT >, - Lazy_construction_nt, - typename boost::mpl::if_< boost::is_same< T_, Object >, - Lazy_construction_object, - Lazy_construction >::type - >::type type; -}; - -// accessor for result_type, to get a nullary meta function for use in eval_if -template -struct Get_rs { +template +struct Get_result_type { typedef typename T::result_type type; }; -template -struct Get_lazy_rs : boost::mpl::eval_if< typename internal::Has_result_type< T >, - typename internal::Get_rs< T >, - typename boost::mpl::identity< T > > {}; +template +struct Lazy_result_type + : boost::mpl::eval_if< Has_result_type, + Get_result_type, + boost::mpl::identity > +{}; + +class Enum_holder { +protected: + enum { NONE, NT, VARIANT, OBJECT, BBOX }; +}; + } // internal // Exact_kernel = exact kernel that will be made lazy @@ -112,8 +93,8 @@ struct Get_lazy_rs : boost::mpl::eval_if< typename internal::Has_result_type< T // the Generic base simplies applies the generic magic functor stupidly. // then the real base fixes up a few special cases. -template < typename EK_, typename AK_, typename E2A_, typename Kernel > -class Lazy_kernel_generic_base +template < typename EK_, typename AK_, typename E2A_, typename Kernel_ > +class Lazy_kernel_generic_base : protected internal::Enum_holder // : public Filtered_kernel_base // TODO : Static_filters_base too ? Check performance { @@ -122,14 +103,14 @@ public: typedef AK_ Approximate_kernel; typedef EK_ Exact_kernel; typedef E2A_ E2A; + typedef Kernel_ Kernel; - // 3 synonyms identical to Filtered_kernel (TODO : cleanup !) + // synonym identical to Filtered_kernel typedef AK_ FK; - //typedef E2A_ C2F; + // Note: Approx_converter and Exact_converter are defined in typedef Approx_converter C2F; typedef Exact_converter C2E; - // Note: Approx_converter and Exact_converter are defined in template < typename Kernel2 > struct Base { typedef Lazy_kernel_generic_base Type; }; @@ -144,10 +125,6 @@ public: typedef typename T::Feature_dimension type; }; - // What to do with the tag ? - // Probably this should not exist, should it ? - // struct filter_tag{}; - // typedef filter_tag Kernel_tag; typedef typename Exact_kernel::Kernel_tag Kernel_tag; typedef typename Exact_kernel::Rep_tag Rep_tag; @@ -193,6 +170,93 @@ public: typedef CGAL::Aff_transformationC2 Aff_transformation_2; typedef CGAL::Aff_transformationC3 Aff_transformation_3; +private: + // We use a combination of partial and logic to extract the right + // construction. Constructions without a result_type always have to + // be done through specializations. + // + // The case distinction goes as follows: + // result_type == FT => NT + // result_type == Object => Object + // result_type == Bbox_2 || result_type == Bbox_3 => BBOX + // default => NONE + // no result_type => NONE + // + // + // we require a Dummy because we cannot have complete + // specializations inside a non-namespace scope. + // The default implementation does some default handling, + // the special cases are filtered by partial specializations. + template + struct Lazy_wrapper_traits : + boost::mpl::eval_if< internal::Has_result_type, + boost::mpl::eval_if< boost::is_same< typename boost::remove_cv< + typename boost::remove_reference< + typename internal::Lazy_result_type::type + >::type >::type, + typename Approximate_kernel::FT>, + boost::mpl::int_, + boost::mpl::eval_if< boost::is_same< typename internal::Lazy_result_type::type, + CGAL::Object >, + boost::mpl::int_, + boost::mpl::eval_if< boost::mpl::or_< + boost::is_same< typename internal::Lazy_result_type::type, CGAL::Bbox_2 >, + boost::is_same< typename internal::Lazy_result_type::type, CGAL::Bbox_3 > >, + boost::mpl::int_, + boost::mpl::int_ > > >, + boost::mpl::int_ >::type {}; + +#define CGAL_WRAPPER_TRAIT(NAME, WRAPPER) \ + template \ + struct Lazy_wrapper_traits \ + : boost::mpl::int_ {}; + + CGAL_WRAPPER_TRAIT(Intersect_2, VARIANT) + CGAL_WRAPPER_TRAIT(Intersect_3, VARIANT) + CGAL_WRAPPER_TRAIT(Compute_squared_radius_2, NT) + CGAL_WRAPPER_TRAIT(Compute_x_3, NT) + CGAL_WRAPPER_TRAIT(Compute_y_3, NT) + CGAL_WRAPPER_TRAIT(Compute_z_3, NT) + +#undef CGAL_WRAPPER_TRAIT + + template ::value> + struct Select_wrapper_impl; + + template + struct Select_wrapper_impl { + template + struct apply { typedef Lazy_construction type; }; + }; + + template + struct Select_wrapper_impl { + template + struct apply { typedef Lazy_construction_nt type; }; + }; + + template + struct Select_wrapper_impl { + template + struct apply { typedef Lazy_construction_variant type; }; + }; + + template + struct Select_wrapper_impl { + template + struct apply { typedef Lazy_construction_object type; }; + }; + + template + struct Select_wrapper_impl { + template + struct apply { typedef Lazy_construction_bbox type; }; + }; + + template + struct Select_wrapper : Select_wrapper_impl {}; + +public: // We don't touch the predicates. // FIXME TODO : better use a layer of Filtered_kernel on top of everything, @@ -201,46 +265,10 @@ public: typedef Filtered_predicate P; \ P Pf() const { return P(); } - // We change the constructions. -#ifdef CGAL_INTERSECT_WITH_ITERATORS_2 #define CGAL_Kernel_cons(C, Cf) \ - typedef typename boost::mpl::if_, \ - Lazy_intersect_with_iterators, \ - typename boost::mpl::if_, \ - Lazy_construction_bbox, \ - typename boost::mpl::if_,\ - Lazy_construction_nt,\ - typename boost::mpl::if_,\ - Lazy_construction_object,\ - Lazy_construction >::type >::type > ::type > ::type C; \ - C Cf() const { return C(); } - - CGAL_Kernel_cons(Intersect_with_iterators_2, - intersect_with_iterators_2_object) -#else - // This does the following: If the Construction has a result_type - // member, do the eval_if dance, otherwise we have (hopefully) a - // variant result_type. The inner eval_if dance is necessary to - // prevent the compiler from trying to instantiate the result_type - // if it isn't actually there. The true branch of the outer most if - // evaluates to either Lazy_construction_object, - // Lazy_construction_nt or Lazy_construction; depending on the - // result_type. -#define CGAL_Kernel_cons(C, Cf) \ - typedef typename boost::mpl::if_< internal::Has_result_type< typename Approximate_kernel::C >, \ - typename boost::mpl::if_< boost::is_same< typename internal::Get_lazy_rs< typename Approximate_kernel::C >::type , \ - typename Approximate_kernel::FT >, \ - Lazy_construction_nt< Kernel, typename Approximate_kernel::C, typename Exact_kernel::C >, \ - typename boost::mpl::if_< boost::is_same< typename internal::Get_lazy_rs< typename Approximate_kernel::C >::type, \ - typename CGAL::Object >, \ - Lazy_construction_object< Kernel,typename Approximate_kernel::C, typename Exact_kernel::C >, \ - Lazy_construction< Kernel,typename Approximate_kernel::C, typename Exact_kernel::C > >::type \ - >::type, \ - Lazy_construction_variant< Kernel, typename Approximate_kernel::C, typename Exact_kernel::C > >::type C; \ + typedef typename Select_wrapper::template apply::type C; \ C Cf() const { return C(); } -#endif //CGAL_INTERSECT_WITH_ITERATORS_2 - #include }; @@ -257,44 +285,6 @@ public: template < typename Kernel2 > struct Base { typedef Lazy_kernel_base Type; }; -#if 0 - // We change the constructions. -#ifdef CGAL_INTERSECT_WITH_ITERATORS_2 -#define CGAL_Kernel_cons(C, Cf) \ - typedef typename boost::mpl::if_, \ - Lazy_intersect_with_iterators, \ - typename boost::mpl::if_, \ - Lazy_construction_bbox, \ - typename boost::mpl::if_,\ - Lazy_construction_nt,\ - typename boost::mpl::if_,\ - Lazy_construction_object,\ - Lazy_construction >::type >::type > ::type > ::type C; \ - C Cf() const { return C(); } - - CGAL_Kernel_cons(Intersect_with_iterators_2, - intersect_with_iterators_2_object) -#else -#define CGAL_Kernel_cons(C, Cf) \ - typedef typename boost::mpl::if_, \ - Lazy_cartesian_const_iterator_2, \ - typename boost::mpl::if_, \ - Lazy_cartesian_const_iterator_3, \ - typename boost::mpl::if_, \ - Lazy_construction_bbox, \ - typename boost::mpl::if_, \ - Lazy_construction_bbox, \ - typename boost::mpl::if_,\ - Lazy_construction_nt,\ - typename boost::mpl::if_,\ - Lazy_construction_object,\ - Lazy_construction >::type >::type >::type > ::type > ::type > ::type C; \ - C Cf() const { return C(); } - -#endif //CGAL_INTERSECT_WITH_ITERATORS_2 - -#endif // 0 - typedef CommonKernelFunctors::Assign_2 Assign_2; typedef CommonKernelFunctors::Assign_3 Assign_3; typedef Lazy_construction_bbox Construct_bbox_2; diff --git a/Intersections_2/include/CGAL/Intersection_traits.h b/Intersections_2/include/CGAL/Intersection_traits.h index 74ac1a1314d..afa36131cea 100644 --- a/Intersections_2/include/CGAL/Intersection_traits.h +++ b/Intersections_2/include/CGAL/Intersection_traits.h @@ -69,21 +69,21 @@ #define CGAL_INTERSECTION_FUNCTION(A, B, DIM) \ template \ inline \ - typename BOOST_PP_CAT(K::Intersect_, DIM)::template Result::Type \ - intersection(const A& a, const B& b) { \ + typename boost::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 BOOST_PP_CAT(K::Intersect_, DIM)::template Result::Type \ - intersection(const B& a, const A& b) { \ + typename boost::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 BOOST_PP_CAT(K::Intersect_, DIM)::template Result::Type \ + typename boost::result_of::type \ intersection(const A & a, const A & b) { \ return BOOST_PP_CAT(K().intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \ } @@ -112,7 +112,7 @@ namespace CGAL { // only declarationn template struct Intersection_traits { - // This defaults to Object, if we use VERSION < 2 and to nothing + // This defaults to Object, if we use VERSION < 2 and do nothing // otherwise. #if CGAL_INTERSECTION_VERSION < 2 typedef CGAL::Object result_type; diff --git a/Intersections_3/test/Intersections_3/call_test.cpp b/Intersections_3/test/Intersections_3/call_test.cpp index 58ab4985539..3919ff815e6 100644 --- a/Intersections_3/test/Intersections_3/call_test.cpp +++ b/Intersections_3/test/Intersections_3/call_test.cpp @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -24,8 +26,12 @@ typedef CGAL::Bbox_3 Bbox_3; template void call_intersection_global(const A& a, const B& b) { - typename CGAL::IT::result_type x = CGAL::intersection(a, b); - typename CGAL::IT::result_type y = CGAL::intersection(b, a); + typename boost::result_of::type x =CGAL::intersection(a, b); + typename boost::result_of::type y =CGAL::intersection(b, a); + typename boost::result_of::type z =CGAL::intersection(b, a); + CGAL_USE(x); + CGAL_USE(y); + CGAL_USE(z); } template diff --git a/Interval_support/include/CGAL/Interval_traits.h b/Interval_support/include/CGAL/Interval_traits.h index ba54a3614b3..6c1658c70cf 100644 --- a/Interval_support/include/CGAL/Interval_traits.h +++ b/Interval_support/include/CGAL/Interval_traits.h @@ -201,9 +201,8 @@ proper_subset(Interval interval1, Interval interval2) { template inline typename Interval_traits::Intersection::result_type intersection(Interval interval1, Interval interval2, typename boost::enable_if< - boost::is_same< - typename Interval_traits::Is_interval, - Tag_true > >::type* = NULL + typename Interval_traits::Is_interval + >::type* = NULL ) { typename Interval_traits::Intersection intersection; return intersection(interval1, interval2); diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 53997dd5223..36ca4dc5167 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -2524,11 +2524,12 @@ namespace CommonKernelFunctors { class Intersect_2 { public: - template - struct Result { - typedef typename Intersection_traits::result_type Type; - // Boost MPL compatibility - typedef Type type; + template + struct result; + + template + struct result { + typedef typename Intersection_traits::result_type type; }; // Solely to make the lazy kernel work @@ -2538,7 +2539,7 @@ namespace CommonKernelFunctors { // 25 possibilities, so I keep the template. template - typename Result< T1, T2 >::Type + typename boost::result_of< Intersect_2(T1, T2) >::type operator()(const T1& t1, const T2& t2) const { return internal::intersection(t1, t2, K()); } }; @@ -2548,11 +2549,20 @@ namespace CommonKernelFunctors { { typedef typename K::Plane_3 Plane_3; public: - template - struct Result { - typedef typename Intersection_traits::result_type Type; - // Boost MPL compatibility - typedef Type type; + template + struct result; + + template + struct result { + typedef typename Intersection_traits::result_type type; + }; + + template + struct result { + typedef boost::optional< + boost::variant< typename K::Point_3, + typename K::Line_3, + typename K::Plane_3 > > type; }; // Solely to make the lazy kernel work @@ -2562,7 +2572,7 @@ namespace CommonKernelFunctors { // n possibilities, so I keep the template. template - typename Result< T1, T2 >::Type + typename boost::result_of< Intersect_3(T1, T2) >::type operator()(const T1& t1, const T2& t2) const { return internal::intersection(t1, t2, K() ); }