are_levels_ok.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Boost.Geometry Index
  2. //
  3. // R-tree levels validating visitor implementation
  4. //
  5. // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
  6. //
  7. // This file was modified by Oracle on 2019-2023.
  8. // Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
  9. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
  10. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  11. //
  12. // Use, modification and distribution is subject to the Boost Software License,
  13. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  14. // http://www.boost.org/LICENSE_1_0.txt)
  15. #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_LEVELS_OK_HPP
  16. #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_LEVELS_OK_HPP
  17. #include <boost/geometry/index/detail/rtree/node/node.hpp>
  18. #include <boost/geometry/index/detail/rtree/utilities/view.hpp>
  19. namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
  20. namespace visitors {
  21. template <typename MembersHolder>
  22. class are_levels_ok
  23. : public MembersHolder::visitor_const
  24. {
  25. typedef typename MembersHolder::internal_node internal_node;
  26. typedef typename MembersHolder::leaf leaf;
  27. public:
  28. inline are_levels_ok()
  29. : result(true), m_leafs_level((std::numeric_limits<size_t>::max)()), m_current_level(0)
  30. {}
  31. inline void operator()(internal_node const& n)
  32. {
  33. typedef typename rtree::elements_type<internal_node>::type elements_type;
  34. elements_type const& elements = rtree::elements(n);
  35. if (elements.empty())
  36. {
  37. result = false;
  38. return;
  39. }
  40. size_t current_level_backup = m_current_level;
  41. ++m_current_level;
  42. for ( typename elements_type::const_iterator it = elements.begin();
  43. it != elements.end() ; ++it)
  44. {
  45. rtree::apply_visitor(*this, *it->second);
  46. if ( result == false )
  47. return;
  48. }
  49. m_current_level = current_level_backup;
  50. }
  51. inline void operator()(leaf const& n)
  52. {
  53. typedef typename rtree::elements_type<leaf>::type elements_type;
  54. elements_type const& elements = rtree::elements(n);
  55. // empty leaf in non-root node
  56. if (0 < m_current_level && elements.empty())
  57. {
  58. result = false;
  59. return;
  60. }
  61. if ( m_leafs_level == (std::numeric_limits<size_t>::max)() )
  62. {
  63. m_leafs_level = m_current_level;
  64. }
  65. else if ( m_leafs_level != m_current_level )
  66. {
  67. result = false;
  68. }
  69. }
  70. bool result;
  71. private:
  72. size_t m_leafs_level;
  73. size_t m_current_level;
  74. };
  75. } // namespace visitors
  76. template <typename Rtree> inline
  77. bool are_levels_ok(Rtree const& tree)
  78. {
  79. typedef utilities::view<Rtree> RTV;
  80. RTV rtv(tree);
  81. visitors::are_levels_ok<
  82. typename RTV::members_holder
  83. > v;
  84. rtv.apply_visitor(v);
  85. return v.result;
  86. }
  87. }}}}}} // namespace boost::geometry::index::detail::rtree::utilities
  88. #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_LEVELS_OK_HPP