From b37ea9c8b4f067c954c41a76cbda05d44c63affc Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 10 Jul 2014 11:30:47 +0300 Subject: [PATCH] [algorithms][comparable distance] implement variant support as in all other algorithms --- .../detail/comparable_distance/interface.hpp | 277 +++++++++++++++++- 1 file changed, 269 insertions(+), 8 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/comparable_distance/interface.hpp b/include/boost/geometry/algorithms/detail/comparable_distance/interface.hpp index 62a42ca05..1a57c8f4b 100644 --- a/include/boost/geometry/algorithms/detail/comparable_distance/interface.hpp +++ b/include/boost/geometry/algorithms/detail/comparable_distance/interface.hpp @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -33,6 +32,269 @@ namespace boost { namespace geometry { +namespace resolve_strategy +{ + +struct comparable_distance +{ + template + static inline + typename comparable_distance_result::type + apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + typedef typename strategy::distance::services::comparable_type + < + Strategy + >::type comparable_strategy_type; + + return dispatch::distance + < + Geometry1, Geometry2, comparable_strategy_type + >::apply(geometry1, + geometry2, + strategy::distance::services::get_comparable + < + Strategy + >::apply(strategy)); + } + + template + static inline typename comparable_distance_result + < + Geometry1, Geometry2, default_strategy + >::type + apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + default_strategy) + { + typedef typename strategy::distance::services::comparable_type + < + typename detail::distance::default_strategy + < + Geometry1, Geometry2 + >::type + >::type comparable_strategy_type; + + return dispatch::distance + < + Geometry1, Geometry2, comparable_strategy_type + >::apply(geometry1, geometry2, comparable_strategy_type()); + } +}; + +} // namespace resolve_strategy + + +namespace resolve_variant +{ + + +template +struct comparable_distance +{ + template + static inline + typename comparable_distance_result::type + apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + return resolve_strategy::comparable_distance::apply(geometry1, + geometry2, + strategy); + } +}; + + +template +struct comparable_distance + < + boost::variant, + Geometry2 + > +{ + template + struct visitor: static_visitor + < + typename comparable_distance_result + < + boost::variant, + Geometry2, + Strategy + >::type + > + { + Geometry2 const& m_geometry2; + Strategy const& m_strategy; + + visitor(Geometry2 const& geometry2, + Strategy const& strategy) + : m_geometry2(geometry2), + m_strategy(strategy) + {} + + template + typename comparable_distance_result + < + Geometry1, Geometry2, Strategy + >::type + operator()(Geometry1 const& geometry1) const + { + return comparable_distance + < + Geometry1, + Geometry2 + >::template apply + < + Strategy + >(geometry1, m_geometry2, m_strategy); + } + }; + + template + static inline typename comparable_distance_result + < + boost::variant, + Geometry2, + Strategy + >::type + apply(boost::variant const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + return apply_visitor(visitor(geometry2, strategy), geometry1); + } +}; + + +template +struct comparable_distance + < + Geometry1, + boost::variant + > +{ + template + struct visitor: static_visitor + < + typename comparable_distance_result + < + Geometry1, + boost::variant, + Strategy + >::type + > + { + Geometry1 const& m_geometry1; + Strategy const& m_strategy; + + visitor(Geometry1 const& geometry1, + Strategy const& strategy) + : m_geometry1(geometry1), + m_strategy(strategy) + {} + + template + typename comparable_distance_result + < + Geometry1, Geometry2, Strategy + >::type + operator()(Geometry2 const& geometry2) const + { + return comparable_distance + < + Geometry1, + Geometry2 + >::template apply + < + Strategy + >(m_geometry1, geometry2, m_strategy); + } + }; + + template + static inline typename comparable_distance_result + < + Geometry1, + boost::variant, + Strategy + >::type + apply(Geometry1 const& geometry1, + boost::variant const& geometry2, + Strategy const& strategy) + { + return apply_visitor(visitor(geometry1, strategy), geometry2); + } +}; + + +template +< + BOOST_VARIANT_ENUM_PARAMS(typename A), + BOOST_VARIANT_ENUM_PARAMS(typename B) +> +struct comparable_distance + < + boost::variant, + boost::variant + > +{ + template + struct visitor: static_visitor + < + typename comparable_distance_result + < + boost::variant, + boost::variant, + Strategy + >::type + > + { + Strategy const& m_strategy; + + visitor(Strategy const& strategy) + : m_strategy(strategy) + {} + + template + typename comparable_distance_result + < + Geometry1, Geometry2, Strategy + >::type + operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const + { + return comparable_distance + < + Geometry1, + Geometry2 + >::template apply + < + Strategy + >(geometry1, geometry2, m_strategy); + } + }; + + template + static inline typename comparable_distance_result + < + boost::variant, + boost::variant, + Strategy + >::type + apply(boost::variant const& geometry1, + boost::variant const& geometry2, + Strategy const& strategy) + { + return apply_visitor(visitor(strategy), geometry1, geometry2); + } +}; + +} // namespace resolve_variant + + + /*! \brief \brief_calc2{comparable distance measurement} \brief_strategy \ingroup distance @@ -59,12 +321,11 @@ comparable_distance(Geometry1 const& geometry1, Geometry2 const& geometry2, concept::check(); concept::check(); - return distance(geometry1, geometry2, - strategy::distance::services::get_comparable - < - Strategy - >::apply(strategy) - ); + return resolve_variant::comparable_distance + < + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, strategy); } @@ -92,7 +353,7 @@ comparable_distance(Geometry1 const& geometry1, Geometry2 const& geometry2) concept::check(); concept::check(); - return distance(geometry1, geometry2, default_comparable_strategy()); + return comparable_distance(geometry1, geometry2, default_strategy()); }