is_empty.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2015-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_IS_EMPTY_HPP
  9. #define BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
  10. #include <boost/range/begin.hpp>
  11. #include <boost/range/empty.hpp>
  12. #include <boost/range/end.hpp>
  13. #include <boost/geometry/algorithms/not_implemented.hpp>
  14. #include <boost/geometry/algorithms/detail/visit.hpp>
  15. #include <boost/geometry/core/exterior_ring.hpp>
  16. #include <boost/geometry/core/interior_rings.hpp>
  17. #include <boost/geometry/core/tag.hpp>
  18. #include <boost/geometry/core/tags.hpp>
  19. #include <boost/geometry/core/visit.hpp>
  20. #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
  21. #include <boost/geometry/geometries/concepts/check.hpp>
  22. #include <boost/geometry/util/type_traits_std.hpp>
  23. namespace boost { namespace geometry
  24. {
  25. #ifndef DOXYGEN_NO_DETAIL
  26. namespace detail { namespace is_empty
  27. {
  28. struct always_not_empty
  29. {
  30. template <typename Geometry>
  31. static inline bool apply(Geometry const&)
  32. {
  33. return false;
  34. }
  35. };
  36. struct range_is_empty
  37. {
  38. template <typename Range>
  39. static inline bool apply(Range const& range)
  40. {
  41. return boost::empty(range);
  42. }
  43. };
  44. class polygon_is_empty
  45. {
  46. template <typename InteriorRings>
  47. static inline bool check_interior_rings(InteriorRings const& interior_rings)
  48. {
  49. return std::all_of(boost::begin(interior_rings), boost::end(interior_rings),
  50. []( auto const& range ){ return boost::empty(range); });
  51. }
  52. public:
  53. template <typename Polygon>
  54. static inline bool apply(Polygon const& polygon)
  55. {
  56. return boost::empty(exterior_ring(polygon))
  57. && check_interior_rings(interior_rings(polygon));
  58. }
  59. };
  60. template <typename Policy = range_is_empty>
  61. struct multi_is_empty
  62. {
  63. template <typename MultiGeometry>
  64. static inline bool apply(MultiGeometry const& multigeometry)
  65. {
  66. return std::all_of(boost::begin(multigeometry),
  67. boost::end(multigeometry),
  68. []( auto const& range ){ return Policy::apply(range); });
  69. }
  70. };
  71. }} // namespace detail::is_empty
  72. #endif // DOXYGEN_NO_DETAIL
  73. #ifndef DOXYGEN_NO_DISPATCH
  74. namespace dispatch
  75. {
  76. template <typename Geometry, typename Tag = typename tag<Geometry>::type>
  77. struct is_empty : not_implemented<Tag>
  78. {};
  79. template <typename Geometry>
  80. struct is_empty<Geometry, point_tag>
  81. : detail::is_empty::always_not_empty
  82. {};
  83. template <typename Geometry>
  84. struct is_empty<Geometry, box_tag>
  85. : detail::is_empty::always_not_empty
  86. {};
  87. template <typename Geometry>
  88. struct is_empty<Geometry, segment_tag>
  89. : detail::is_empty::always_not_empty
  90. {};
  91. template <typename Geometry>
  92. struct is_empty<Geometry, linestring_tag>
  93. : detail::is_empty::range_is_empty
  94. {};
  95. template <typename Geometry>
  96. struct is_empty<Geometry, ring_tag>
  97. : detail::is_empty::range_is_empty
  98. {};
  99. template <typename Geometry>
  100. struct is_empty<Geometry, polygon_tag>
  101. : detail::is_empty::polygon_is_empty
  102. {};
  103. template <typename Geometry>
  104. struct is_empty<Geometry, multi_point_tag>
  105. : detail::is_empty::range_is_empty
  106. {};
  107. template <typename Geometry>
  108. struct is_empty<Geometry, multi_linestring_tag>
  109. : detail::is_empty::multi_is_empty<>
  110. {};
  111. template <typename Geometry>
  112. struct is_empty<Geometry, multi_polygon_tag>
  113. : detail::is_empty::multi_is_empty<detail::is_empty::polygon_is_empty>
  114. {};
  115. } // namespace dispatch
  116. #endif // DOXYGEN_NO_DISPATCH
  117. namespace resolve_dynamic
  118. {
  119. template <typename Geometry, typename Tag = typename tag<Geometry>::type>
  120. struct is_empty
  121. {
  122. static inline bool apply(Geometry const& geometry)
  123. {
  124. concepts::check<Geometry const>();
  125. return dispatch::is_empty<Geometry>::apply(geometry);
  126. }
  127. };
  128. template <typename Geometry>
  129. struct is_empty<Geometry, dynamic_geometry_tag>
  130. {
  131. static inline bool apply(Geometry const& geometry)
  132. {
  133. bool result = true;
  134. traits::visit<Geometry>::apply([&](auto const& g)
  135. {
  136. result = is_empty<util::remove_cref_t<decltype(g)>>::apply(g);
  137. }, geometry);
  138. return result;
  139. }
  140. };
  141. template <typename Geometry>
  142. struct is_empty<Geometry, geometry_collection_tag>
  143. {
  144. static inline bool apply(Geometry const& geometry)
  145. {
  146. bool result = true;
  147. detail::visit_breadth_first([&](auto const& g)
  148. {
  149. result = is_empty<util::remove_cref_t<decltype(g)>>::apply(g);
  150. return result;
  151. }, geometry);
  152. return result;
  153. }
  154. };
  155. } // namespace resolve_dynamic
  156. /*!
  157. \brief \brief_check{is the empty set}
  158. \ingroup is_empty
  159. \tparam Geometry \tparam_geometry
  160. \param geometry \param_geometry
  161. \return \return_check{is the empty set}
  162. \qbk{[include reference/algorithms/is_empty.qbk]}
  163. */
  164. template <typename Geometry>
  165. inline bool is_empty(Geometry const& geometry)
  166. {
  167. return resolve_dynamic::is_empty<Geometry>::apply(geometry);
  168. }
  169. }} // namespace boost::geometry
  170. #endif // BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP