1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2014, Oracle and/or its affiliates. 4 5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 6 7 // Licensed under the Boost Software License version 1.0. 8 // http://www.boost.org/users/license.html 9 10 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_NUM_DISTINCT_CONSECUTIVE_POINTS_HPP 11 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_NUM_DISTINCT_CONSECUTIVE_POINTS_HPP 12 13 #include <cstddef> 14 15 #include <algorithm> 16 17 #include <boost/range.hpp> 18 19 20 21 namespace boost { namespace geometry 22 { 23 24 25 #ifndef DOXYGEN_NO_DETAIL 26 namespace detail 27 { 28 29 30 // returns the number of distinct values in the range; 31 // return values are 0u through MaximumNumber, where MaximumNumber 32 // corresponds to MaximumNumber or more distinct values 33 // 34 // FUTURE: take into account topologically closed ranges; 35 // add appropriate template parameter(s) to control whether 36 // the closing point for topologically closed ranges is to be 37 // accounted for separately or not 38 template 39 < 40 typename Range, 41 std::size_t MaximumNumber, 42 bool AllowDuplicates /* true */, 43 typename NotEqualTo 44 > 45 struct num_distinct_consecutive_points 46 { applyboost::geometry::detail::num_distinct_consecutive_points47 static inline std::size_t apply(Range const& range) 48 { 49 typedef typename boost::range_iterator<Range const>::type iterator; 50 51 std::size_t const size = boost::size(range); 52 53 if ( size < 2u ) 54 { 55 return (size < MaximumNumber) ? size : MaximumNumber; 56 } 57 58 iterator current = boost::begin(range); 59 std::size_t counter(0); 60 do 61 { 62 ++counter; 63 iterator next = std::find_if(current, 64 boost::end(range), 65 NotEqualTo(*current)); 66 current = next; 67 } 68 while ( current != boost::end(range) && counter <= MaximumNumber ); 69 70 return counter; 71 } 72 }; 73 74 75 template <typename Range, std::size_t MaximumNumber, typename NotEqualTo> 76 struct num_distinct_consecutive_points<Range, MaximumNumber, false, NotEqualTo> 77 { applyboost::geometry::detail::num_distinct_consecutive_points78 static inline std::size_t apply(Range const& range) 79 { 80 std::size_t const size = boost::size(range); 81 return (size < MaximumNumber) ? size : MaximumNumber; 82 } 83 }; 84 85 86 } // namespace detail 87 #endif // DOXYGEN_NO_DETAIL 88 89 90 }} // namespace boost::geometry 91 92 93 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_NUM_DISTINCT_CONSECUTIVE_POINTS_HPP 94