From 3142975b72b8d0bd08e3051c98b019359b9d0e59 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 12 Mar 2014 12:39:20 +0100 Subject: [PATCH] [relate] supported ORed run-time masks --- .../detail/relate/boundary_checker.hpp | 1 + .../algorithms/detail/relate/relate.hpp | 14 ++ .../algorithms/detail/relate/result.hpp | 128 +++++++++++++++--- .../boost/geometry/index/detail/tuples.hpp | 13 +- include/boost/geometry/index/predicates.hpp | 11 +- test/algorithms/relate.cpp | 18 +++ 6 files changed, 156 insertions(+), 29 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/relate/boundary_checker.hpp b/include/boost/geometry/algorithms/detail/relate/boundary_checker.hpp index deabf3d2d..da0705214 100644 --- a/include/boost/geometry/algorithms/detail/relate/boundary_checker.hpp +++ b/include/boost/geometry/algorithms/detail/relate/boundary_checker.hpp @@ -41,6 +41,7 @@ public: template bool is_endpoint_boundary(point_type const& pt) const { + boost::ignore_unused_variable_warning(pt); #ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER // may give false positives for INT BOOST_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any) diff --git a/include/boost/geometry/algorithms/detail/relate/relate.hpp b/include/boost/geometry/algorithms/detail/relate/relate.hpp index 831858ae1..8219059f4 100644 --- a/include/boost/geometry/algorithms/detail/relate/relate.hpp +++ b/include/boost/geometry/algorithms/detail/relate/relate.hpp @@ -167,6 +167,20 @@ struct result_handler_type > type; }; +template +struct result_handler_type > +{ + typedef mask_handler + < + boost::tuples::cons, + interruption_enabled + < + Geometry1, + Geometry2 + >::value + > type; +}; + template #include +// TEMP - move this header to geometry/detail +#include + namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DETAIL @@ -82,7 +85,7 @@ private: template inline void set_dispatch(integral_constant) { - BOOST_STATIC_ASSERT('0' <= V && V <= '9' || V == 'T' || V == 'F'); + BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F'); m_array[F1 * Width + F2] = V; } template @@ -106,21 +109,25 @@ private: // TODO add EnableDimensions parameter? -struct matrix9 -{ - static const std::size_t width = 3; // TEMP -}; +struct matrix9 {}; +//struct matrix4 {}; -//struct matrix4 -//{ -// static const std::size_t width = 2; -//}; +template +struct matrix_width + : not_implemented +{}; + +template <> +struct matrix_width +{ + static const std::size_t value = 3; +}; template class matrix_handler - : private matrix + : private matrix::value> { - typedef matrix base_t; + typedef matrix::value> base_t; public: typedef std::string result_type; @@ -216,8 +223,8 @@ struct interrupt_dispatch_tuple { typedef typename boost::tuples::element::type mask_type; mask_type const& mask = boost::get(masks); - return interrupt_dispatch::apply(mask) - && interrupt_dispatch_tuple::apply(masks); + return interrupt_dispatch::template apply(mask) + && interrupt_dispatch_tuple::template apply(masks); } }; @@ -244,6 +251,18 @@ struct interrupt_dispatch, } }; +template +struct interrupt_dispatch, true> +{ + typedef boost::tuples::cons mask_type; + + template + static inline bool apply(mask_type const& mask) + { + return interrupt_dispatch_tuple::template apply(mask); + } +}; + template inline bool interrupt(Mask const& mask) { @@ -327,17 +346,62 @@ struct check_dispatch< boost::tuple > } }; +template +struct check_dispatch< boost::tuples::cons > +{ + typedef boost::tuples::cons mask_type; + + template + static inline bool apply(mask_type const& mask, Matrix const& matrix) + { + return check_dispatch_tuple::template apply(mask, matrix); + } +}; + template inline bool check(Mask const& mask, Matrix const& matrix) { return check_dispatch::apply(mask, matrix); } +template <> +struct matrix_width +{ + static const std::size_t value = 3; +}; + +template ::value> +struct matrix_width_tuple +{ + static const std::size_t + current = matrix_width::type>::value; + static const std::size_t + next = matrix_width_tuple::value; + + static const std::size_t + value = current > next ? current : next; +}; + +template +struct matrix_width_tuple +{ + static const std::size_t value = 0; +}; + +template +struct matrix_width< boost::tuples::cons > +{ + static const std::size_t + value = matrix_width_tuple< boost::tuples::cons >::value; +}; + template class mask_handler - : private matrix + : private matrix::value> { - typedef matrix base_t; + typedef matrix::value> base_t; public: typedef bool result_type; @@ -345,8 +409,8 @@ public: bool interrupt; inline mask_handler(Mask const& m) - : m_mask(m) - , interrupt(false) + : interrupt(false) + , m_mask(m) {} result_type result() const @@ -665,6 +729,36 @@ private: {} }; +// OPERATORS + +template inline +boost::tuples::cons< + Mask1, + boost::tuples::cons +> +operator||(Mask1 const& m1, Mask2 const& m2) +{ + namespace bt = boost::tuples; + + return + bt::cons< Mask1, bt::cons > + ( m1, bt::cons(m2, bt::null_type()) ); +} + +template inline +typename index::detail::tuples::push_back< + boost::tuples::cons, Mask +>::type +operator||(boost::tuples::cons const& t, Mask const& m) +{ + namespace bt = boost::tuples; + + return + index::detail::tuples::push_back< + bt::cons, Mask + >::apply(t, m); +} + // PREDEFINED MASKS // TODO: diff --git a/include/boost/geometry/index/detail/tuples.hpp b/include/boost/geometry/index/detail/tuples.hpp index 28e347bed..e7f6d2235 100644 --- a/include/boost/geometry/index/detail/tuples.hpp +++ b/include/boost/geometry/index/detail/tuples.hpp @@ -164,13 +164,16 @@ struct add_unique >::type type; }; -template -struct push_back_impl +template ::value> +struct push_back { typedef boost::tuples::cons< typename boost::tuples::element::type, - typename push_back_impl::type + typename push_back::type > type; static type apply(Tuple const& tup, T const& t) @@ -178,13 +181,13 @@ struct push_back_impl return type( boost::get(tup), - push_back_impl::apply(tup, t) + push_back::apply(tup, t) ); } }; template -struct push_back_impl +struct push_back { typedef boost::tuples::cons type; diff --git a/include/boost/geometry/index/predicates.hpp b/include/boost/geometry/index/predicates.hpp index ad6a537f0..e03c9ce5a 100644 --- a/include/boost/geometry/index/predicates.hpp +++ b/include/boost/geometry/index/predicates.hpp @@ -362,11 +362,8 @@ operator&&(Pred1 const& p1, Pred2 const& p2) } template inline -typename tuples::push_back_impl< - boost::tuples::cons, - Pred, - 0, - boost::tuples::length >::value +typename tuples::push_back< + boost::tuples::cons, Pred >::type operator&&(boost::tuples::cons const& t, Pred const& p) { @@ -374,8 +371,8 @@ operator&&(boost::tuples::cons const& t, Pred const& p) namespace bt = boost::tuples; return - tuples::push_back_impl< - bt::cons, Pred, 0, bt::length< bt::cons >::value + tuples::push_back< + bt::cons, Pred >::apply(t, p); } diff --git a/test/algorithms/relate.cpp b/test/algorithms/relate.cpp index 0f3084fa0..4bf9ddd52 100644 --- a/test/algorithms/relate.cpp +++ b/test/algorithms/relate.cpp @@ -322,6 +322,24 @@ void test_linestring_linestring() //test_geometry("LINESTRING(0 0,5 0)", "LINESTRING(1 0,1 0,1 0)", "0F1FF0FF2"); // Point/Point //test_geometry("LINESTRING(0 0)", "LINESTRING(0 0)", "0FFFFFFF2"); + + // OTHER MASKS + { + namespace bgdr = bg::detail::relate; + ls ls1, ls2, ls3; + bg::read_wkt("LINESTRING(0 0,2 0)", ls1); + bg::read_wkt("LINESTRING(2 0,4 0)", ls2); + bg::read_wkt("LINESTRING(1 0,1 1)", ls3); + BOOST_CHECK(bgdr::relate(ls1, ls2, bgdr::mask9("FT*******") + || bgdr::mask9("F**T*****") + || bgdr::mask9("F***T****"))); + BOOST_CHECK(bgdr::relate(ls1, ls3, bgdr::mask9("FT*******") + || bgdr::mask9("F**T*****") + || bgdr::mask9("F***T****"))); + BOOST_CHECK(bgdr::relate(ls3, ls1, bgdr::mask9("FT*******") + || bgdr::mask9("F**T*****") + || bgdr::mask9("F***T****"))); + } } template