From e472d4b439210df9e040b401ee5891145276e758 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Mon, 11 Aug 2014 13:20:07 +0300 Subject: [PATCH] [algorithms][num_points] re-write the num_points code so that the add_for_open boolean argument is passed at the dispatch level as a template parameter; this enables the firther simplification of the code in detail::counting namespace --- .../geometry/algorithms/detail/counting.hpp | 21 +----- .../boost/geometry/algorithms/num_points.hpp | 66 ++++++++++++------- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/counting.hpp b/include/boost/geometry/algorithms/detail/counting.hpp index d6572aca0..dc5bb26c1 100644 --- a/include/boost/geometry/algorithms/detail/counting.hpp +++ b/include/boost/geometry/algorithms/detail/counting.hpp @@ -62,16 +62,16 @@ template struct polygon_count { template - static inline std::size_t apply(Polygon const& poly, bool add_for_open) + static inline std::size_t apply(Polygon const& poly) { - std::size_t n = RangeCount::apply(exterior_ring(poly), add_for_open); + std::size_t n = RangeCount::apply(exterior_ring(poly)); typename interior_return_type::type rings = interior_rings(poly); for (typename detail::interior_iterator::type it = boost::begin(rings); it != boost::end(rings); ++it) { - n += RangeCount::apply(*it, add_for_open); + n += RangeCount::apply(*it); } return n; @@ -95,21 +95,6 @@ struct multi_count } return n; } - - template - static inline - std::size_t apply(MultiGeometry const& geometry, bool add_for_open) - { - std::size_t n = 0; - for (typename boost::range_iterator::type - it = boost::begin(geometry); - it != boost::end(geometry); - ++it) - { - n += SingleCount::apply(*it, add_for_open); - } - return n; - } }; diff --git a/include/boost/geometry/algorithms/num_points.hpp b/include/boost/geometry/algorithms/num_points.hpp index ab2afabe0..541240c78 100644 --- a/include/boost/geometry/algorithms/num_points.hpp +++ b/include/boost/geometry/algorithms/num_points.hpp @@ -36,8 +36,8 @@ #include -#include #include +#include #include @@ -57,14 +57,26 @@ namespace detail { namespace num_points { +template struct range_count { template - static inline std::size_t apply(Range const& range, bool add_for_open) + static inline std::size_t apply(Range const& range) { - return (boost::size(range) > 0) - ? (num_segments::range_count::apply(range, add_for_open) + 1) - : 0; + std::size_t n = boost::size(range); + if ( n == 0 ) + { + return 0; + } + if (AddForOpen + && geometry::closure::value == open + && detail::disjoint::disjoint_point_point(range::front(range), + range::at(range, n - 1)) + ) + { + return n + 1; + } + return n; } }; @@ -79,6 +91,7 @@ namespace dispatch template < typename Geometry, + bool AddForOpen, typename Tag = typename tag_cast < typename tag::type, multi_tag @@ -87,41 +100,44 @@ template struct num_points: not_implemented {}; -template -struct num_points +template +struct num_points : detail::counting::other_count<1> {}; -template -struct num_points +template +struct num_points : detail::counting::other_count<(1 << geometry::dimension::value)> {}; -template -struct num_points +template +struct num_points : detail::counting::other_count<2> {}; -template -struct num_points - : detail::num_points::range_count +template +struct num_points + : detail::num_points::range_count {}; -template -struct num_points - : detail::num_points::range_count +template +struct num_points + : detail::num_points::range_count {}; -template -struct num_points - : detail::counting::polygon_count +template +struct num_points + : detail::counting::polygon_count + < + detail::num_points::range_count + > {}; -template -struct num_points +template +struct num_points : detail::counting::multi_count < - num_points::type> + num_points::type, AddForOpen> > {}; @@ -140,7 +156,9 @@ struct num_points { concept::check(); - return dispatch::num_points::apply(geometry, add_for_open); + return add_for_open + ? dispatch::num_points::apply(geometry) + : dispatch::num_points::apply(geometry); } };