diff --git a/include/boost/geometry/algorithms/touches.hpp b/include/boost/geometry/algorithms/touches.hpp index 7cb551472..069e0dd45 100644 --- a/include/boost/geometry/algorithms/touches.hpp +++ b/include/boost/geometry/algorithms/touches.hpp @@ -28,8 +28,10 @@ #include #include #include - #include +#include +#include +#include namespace boost { namespace geometry { @@ -489,6 +491,96 @@ struct touches } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH + +namespace resolve_variant { + +template +struct touches +{ + static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2) + { + concept::check(); + concept::check(); + + return dispatch::touches + ::apply(geometry1, geometry2); + } +}; + +template +struct touches, Geometry2> +{ + struct visitor: boost::static_visitor + { + Geometry2 const& m_geometry2; + + visitor(Geometry2 const& geometry2): m_geometry2(geometry2) {} + + template + bool operator()(Geometry1 const& geometry1) const + { + return touches::apply(geometry1, m_geometry2); + } + }; + + static inline bool + apply(boost::variant const& geometry1, + Geometry2 const& geometry2) + { + return boost::apply_visitor(visitor(geometry2), geometry1); + } +}; + +template +struct touches > +{ + struct visitor: boost::static_visitor + { + Geometry1 const& m_geometry1; + + visitor(Geometry1 const& geometry1): m_geometry1(geometry1) {} + + template + bool operator()(Geometry2 const& geometry2) const + { + return touches::apply(m_geometry1, geometry2); + } + }; + + static inline bool + apply(Geometry1 const& geometry1, + boost::variant const& geometry2) + { + return boost::apply_visitor(visitor(geometry1), geometry2); + } +}; + +template +struct touches, + boost::variant > +{ + struct visitor: boost::static_visitor + { + template + bool operator()(Geometry1 const& geometry1, + Geometry2 const& geometry2) const + { + return touches::apply(geometry1, geometry2); + } + }; + + static inline bool + apply(boost::variant const& geometry1, + boost::variant const& geometry2) + { + return boost::apply_visitor(visitor(), geometry1, geometry2); + } +}; + +} // namespace resolve_variant + + /*! \brief \brief_check{has at least one touching point (self-tangency)} \note This function can be called for one geometry (self-tangency) and @@ -543,10 +635,7 @@ inline bool touches(Geometry const& geometry) template inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2) { - concept::check(); - concept::check(); - - return dispatch::touches::apply(geometry1, geometry2); + return resolve_variant::touches::apply(geometry1, geometry2); } diff --git a/test/algorithms/test_touches.hpp b/test/algorithms/test_touches.hpp index 5df70fbfe..97b7a4df0 100644 --- a/test/algorithms/test_touches.hpp +++ b/test/algorithms/test_touches.hpp @@ -35,16 +35,15 @@ #include +#include + template -void test_touches(std::string const& wkt1, - std::string const& wkt2, bool expected) +void check_touches(Geometry1 const& geometry1, + Geometry2 const& geometry2, + std::string const& wkt1, + std::string const& wkt2, + bool expected) { - Geometry1 geometry1; - Geometry2 geometry2; - - bg::read_wkt(wkt1, geometry1); - bg::read_wkt(wkt2, geometry2); - bool detected = bg::touches(geometry1, geometry2); BOOST_CHECK_MESSAGE(detected == expected, @@ -62,6 +61,25 @@ void test_touches(std::string const& wkt1, << " detected: " << detected); } +template +void test_touches(std::string const& wkt1, + std::string const& wkt2, bool expected) +{ + Geometry1 geometry1; + Geometry2 geometry2; + + bg::read_wkt(wkt1, geometry1); + bg::read_wkt(wkt2, geometry2); + + boost::variant v1(geometry1); + boost::variant v2(geometry2); + + check_touches(geometry1, geometry2, wkt1, wkt2, expected); + check_touches(v1, geometry2, wkt1, wkt2, expected); + check_touches(geometry1, v2, wkt1, wkt2, expected); + check_touches(v1, v2, wkt1, wkt2, expected); +} + template void test_self_touches(std::string const& wkt, bool expected)