is_empty.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2015-2020, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  4. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  5. // Licensed under the Boost Software License version 1.0.
  6. // http://www.boost.org/users/license.html
  7. #ifndef BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
  8. #define BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP
  9. #include <boost/range/begin.hpp>
  10. #include <boost/range/empty.hpp>
  11. #include <boost/range/end.hpp>
  12. #include <boost/variant/apply_visitor.hpp>
  13. #include <boost/variant/static_visitor.hpp>
  14. #include <boost/variant/variant_fwd.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/algorithms/not_implemented.hpp>
  20. #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
  21. #include <boost/geometry/geometries/concepts/check.hpp>
  22. namespace boost { namespace geometry
  23. {
  24. #ifndef DOXYGEN_NO_DETAIL
  25. namespace detail { namespace is_empty
  26. {
  27. struct always_not_empty
  28. {
  29. template <typename Geometry>
  30. static inline bool apply(Geometry const&)
  31. {
  32. return false;
  33. }
  34. };
  35. struct range_is_empty
  36. {
  37. template <typename Range>
  38. static inline bool apply(Range const& range)
  39. {
  40. return boost::empty(range);
  41. }
  42. };
  43. class polygon_is_empty
  44. {
  45. template <typename InteriorRings>
  46. static inline bool check_interior_rings(InteriorRings const& interior_rings)
  47. {
  48. return check_iterator_range
  49. <
  50. range_is_empty, true // allow empty range
  51. >::apply(boost::begin(interior_rings), boost::end(interior_rings));
  52. }
  53. public:
  54. template <typename Polygon>
  55. static inline bool apply(Polygon const& polygon)
  56. {
  57. return boost::empty(exterior_ring(polygon))
  58. && check_interior_rings(interior_rings(polygon));
  59. }
  60. };
  61. template <typename Policy = range_is_empty>
  62. struct multi_is_empty
  63. {
  64. template <typename MultiGeometry>
  65. static inline bool apply(MultiGeometry const& multigeometry)
  66. {
  67. return check_iterator_range
  68. <
  69. Policy, true // allow empty range
  70. >::apply(boost::begin(multigeometry), boost::end(multigeometry));
  71. }
  72. };
  73. }} // namespace detail::is_empty
  74. #endif // DOXYGEN_NO_DETAIL
  75. #ifndef DOXYGEN_NO_DISPATCH
  76. namespace dispatch
  77. {
  78. template <typename Geometry, typename Tag = typename tag<Geometry>::type>
  79. struct is_empty : not_implemented<Tag>
  80. {};
  81. template <typename Geometry>
  82. struct is_empty<Geometry, point_tag>
  83. : detail::is_empty::always_not_empty
  84. {};
  85. template <typename Geometry>
  86. struct is_empty<Geometry, box_tag>
  87. : detail::is_empty::always_not_empty
  88. {};
  89. template <typename Geometry>
  90. struct is_empty<Geometry, segment_tag>
  91. : detail::is_empty::always_not_empty
  92. {};
  93. template <typename Geometry>
  94. struct is_empty<Geometry, linestring_tag>
  95. : detail::is_empty::range_is_empty
  96. {};
  97. template <typename Geometry>
  98. struct is_empty<Geometry, ring_tag>
  99. : detail::is_empty::range_is_empty
  100. {};
  101. template <typename Geometry>
  102. struct is_empty<Geometry, polygon_tag>
  103. : detail::is_empty::polygon_is_empty
  104. {};
  105. template <typename Geometry>
  106. struct is_empty<Geometry, multi_point_tag>
  107. : detail::is_empty::range_is_empty
  108. {};
  109. template <typename Geometry>
  110. struct is_empty<Geometry, multi_linestring_tag>
  111. : detail::is_empty::multi_is_empty<>
  112. {};
  113. template <typename Geometry>
  114. struct is_empty<Geometry, multi_polygon_tag>
  115. : detail::is_empty::multi_is_empty<detail::is_empty::polygon_is_empty>
  116. {};
  117. } // namespace dispatch
  118. #endif // DOXYGEN_NO_DISPATCH
  119. namespace resolve_variant
  120. {
  121. template <typename Geometry>
  122. struct is_empty
  123. {
  124. static inline bool apply(Geometry const& geometry)
  125. {
  126. concepts::check<Geometry const>();
  127. return dispatch::is_empty<Geometry>::apply(geometry);
  128. }
  129. };
  130. template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
  131. struct is_empty<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  132. {
  133. struct visitor : boost::static_visitor<bool>
  134. {
  135. template <typename Geometry>
  136. inline bool operator()(Geometry const& geometry) const
  137. {
  138. return is_empty<Geometry>::apply(geometry);
  139. }
  140. };
  141. static bool
  142. apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
  143. {
  144. return boost::apply_visitor(visitor(), geometry);
  145. }
  146. };
  147. } // namespace resolve_variant
  148. /*!
  149. \brief \brief_check{is the empty set}
  150. \ingroup is_empty
  151. \tparam Geometry \tparam_geometry
  152. \param geometry \param_geometry
  153. \return \return_check{is the empty set}
  154. \qbk{[include reference/algorithms/is_empty.qbk]}
  155. */
  156. template <typename Geometry>
  157. inline bool is_empty(Geometry const& geometry)
  158. {
  159. return resolve_variant::is_empty<Geometry>::apply(geometry);
  160. }
  161. }} // namespace boost::geometry
  162. #endif // BOOST_GEOMETRY_ALGORITHMS_IS_EMPTY_HPP