From cf39a595b3325faa415e112cefe0d4d23333a89f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20M=C3=B6ller?= Date: Thu, 25 Aug 2011 10:11:55 +0000 Subject: [PATCH] Modified cartesian converter to support optionals and variants --- .../include/CGAL/Cartesian_converter.h | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/Cartesian_kernel/include/CGAL/Cartesian_converter.h b/Cartesian_kernel/include/CGAL/Cartesian_converter.h index 22a6dd87318..a4b6ede567d 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian_converter.h +++ b/Cartesian_kernel/include/CGAL/Cartesian_converter.h @@ -36,7 +36,14 @@ #include #include #include +#include #include +#include +#include +#include +#include +#include +#include namespace CGAL { @@ -48,6 +55,37 @@ struct Default_converter { typedef typename K2::FT FT2; typedef ::CGAL::NT_converter Type; }; + +template +struct Transform_type_mapper { + typedef typename boost::mpl::transform< Seq, typename boost::mpl::lambda< Type_mapper< boost::mpl::_1, K1, K2 > >::type >::type type; +}; + +// Out will be a variant, source kernel and target kernel +template +struct Converting_visitor : boost::static_visitor<> { + Converting_visitor(const Conv& conv, Out& out) : conv(&conv), out(&out) {} + const Conv* conv; + Out* out; + + template + void operator()(const T& t) { + *out = conv->operator()(t); + } + + template + void operator()(const std::vector& t) { + typedef typename Type_mapper< T, typename Conv::Source_kernel, typename Conv::Target_kernel >::type value_type; + std::vector< value_type > tmp(t.size()); + + for(std::size_t i = 0; i < t.size(); ++i) { + tmp[i] = conv->operator()(t[i]); + } + + *out = tmp; + } +}; + } // namespace internal template < class K1, class K2, @@ -56,7 +94,7 @@ template < class K1, class K2, class Cartesian_converter : public Enum_converter { typedef Enum_converter Base; - + typedef Cartesian_converter Self; public: typedef K1 Source_kernel; typedef K2 Target_kernel; @@ -94,6 +132,58 @@ public: return c(a); } + // drop the boost::detail::variant::void_ generated by the macros + // from the sequence, transform with the type mapper and throw the + // new list into a variant + // visit to get the type, and copy construct inside the return type + template + boost::optional< + typename boost::make_variant_over< + typename internal::Transform_type_mapper< + typename boost::mpl::remove< boost::mpl::vector< BOOST_VARIANT_ENUM_PARAMS(U) >, + boost::detail::variant::void_ >::type + , K1, K2 >::type + >::type > + operator()(const boost::optional< boost::variant< BOOST_VARIANT_ENUM_PARAMS(U) > >& o) const { + typedef boost::optional< + typename boost::make_variant_over< + typename internal::Transform_type_mapper< + typename boost::mpl::remove< boost::mpl::vector< BOOST_VARIANT_ENUM_PARAMS(U) >, + boost::detail::variant::void_ >::type + , K1, K2 >::type + >::type > result_type; + result_type res; + if(!o) { + // empty converts to empty + return res; + } + + internal::Converting_visitor conv_visitor = internal::Converting_visitor(*this, res); + boost::apply_visitor(conv_visitor, *o); + return res; + } + + template + typename boost::make_variant_over< + typename internal::Transform_type_mapper< + typename boost::mpl::remove< boost::mpl::vector< BOOST_VARIANT_ENUM_PARAMS(U) >, + boost::detail::variant::void_ >::type + , K1, K2 >::type + >::type + operator()(const boost::variant< BOOST_VARIANT_ENUM_PARAMS(U) > & o) const { + typedef + typename boost::make_variant_over< + typename internal::Transform_type_mapper< + typename boost::mpl::remove< boost::mpl::vector< BOOST_VARIANT_ENUM_PARAMS(U) >, + boost::detail::variant::void_ >::type + , K1, K2 >::type + >::type result_type; + result_type res; + internal::Converting_visitor conv_visitor = internal::Converting_visitor(*this, res); + boost::apply_visitor(conv_visitor, o); + return res; + } + typename K2::Object_2 operator()(const typename K1::Object_2 &obj) const {