num_distinct_consecutive_points.hpp 2.4 KB

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