is_empty.hpp 4.7 KB

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