• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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