predicate_based_interrupt_policy.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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_POLICIES_PREDICATE_BASED_INTERRUPT_POLICY_HPP
  9. #define BOOST_GEOMETRY_ALGORITHMS_POLICIES_PREDICATE_BASED_INTERRUPT_POLICY_HPP
  10. #include <algorithm>
  11. #include <boost/range/begin.hpp>
  12. #include <boost/range/empty.hpp>
  13. #include <boost/range/end.hpp>
  14. namespace boost { namespace geometry
  15. {
  16. #ifndef DOXYGEN_NO_DETAIL
  17. namespace detail { namespace overlay
  18. {
  19. template
  20. <
  21. typename IsAcceptableTurnPredicate,
  22. bool AllowEmptyTurnRange = true // by default, allow an empty turn range
  23. >
  24. struct stateless_predicate_based_interrupt_policy
  25. {
  26. static bool const enabled = true;
  27. bool has_intersections; // set to true if there is at least one
  28. // unacceptable turn
  29. inline stateless_predicate_based_interrupt_policy()
  30. : has_intersections(false)
  31. {}
  32. template <typename Range>
  33. inline bool apply(Range const& range)
  34. {
  35. // if there is at least one unacceptable turn in the range, return true
  36. bool const has_unacceptable_turn = std::any_of(boost::begin(range), boost::end(range),
  37. [](auto const& turn) {
  38. return ! IsAcceptableTurnPredicate::apply(turn);
  39. });
  40. has_intersections = has_unacceptable_turn
  41. && !(AllowEmptyTurnRange && boost::empty(range));
  42. return has_intersections;
  43. }
  44. };
  45. template
  46. <
  47. typename IsAcceptableTurnPredicate,
  48. bool AllowEmptyTurnRange = true // by default, allow an empty turn range
  49. >
  50. struct predicate_based_interrupt_policy
  51. {
  52. static bool const enabled = true;
  53. bool has_intersections; // set to true if there is at least one
  54. // unacceptable turn
  55. IsAcceptableTurnPredicate const& m_predicate;
  56. inline
  57. predicate_based_interrupt_policy(IsAcceptableTurnPredicate const& predicate)
  58. : has_intersections(false)
  59. , m_predicate(predicate)
  60. {}
  61. template <typename Range>
  62. inline bool apply(Range const& range)
  63. {
  64. // if there is at least one unacceptable turn in the range, return true
  65. bool const has_unacceptable_turn = std::any_of(boost::begin(range),
  66. boost::end(range),
  67. [&]( auto const& turn ) {
  68. return ! m_predicate.apply(turn);
  69. });
  70. has_intersections = has_unacceptable_turn
  71. && !(AllowEmptyTurnRange && boost::empty(range));
  72. return has_intersections;
  73. }
  74. };
  75. }} // namespace detail::overlay
  76. #endif // DOXYGEN_NO_DETAIL
  77. }} // namespace boost::geometry
  78. #endif // BOOST_GEOMETRY_ALGORITHMS_POLICIES_PREDICATE_BASED_INTERRUPT_POLICY_HPP