num_distinct_consecutive_points.hpp 2.7 KB

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