are_levels_ok.hpp 3.1 KB

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