node.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // Boost.Geometry Index
  2. //
  3. // R-tree nodes
  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_NODE_NODE_HPP
  11. #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP
  12. #include <boost/container/vector.hpp>
  13. #include <boost/geometry/index/detail/varray.hpp>
  14. #include <boost/geometry/index/detail/rtree/node/concept.hpp>
  15. #include <boost/geometry/index/detail/rtree/node/pairs.hpp>
  16. #include <boost/geometry/index/detail/rtree/node/auto_deallocator.hpp>
  17. #include <boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp>
  18. #include <boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp>
  19. #include <boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp>
  20. #include <boost/geometry/index/detail/rtree/node/static_visitor.hpp>
  21. #include <boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp>
  22. #include <boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp>
  23. #include <boost/geometry/index/detail/rtree/node/node_auto_ptr.hpp>
  24. #include <boost/geometry/algorithms/expand.hpp>
  25. #include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
  26. #include <boost/geometry/index/detail/algorithms/bounds.hpp>
  27. namespace boost { namespace geometry { namespace index {
  28. namespace detail { namespace rtree {
  29. // elements box
  30. template <typename Box, typename FwdIter, typename Translator>
  31. inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
  32. {
  33. Box result;
  34. if ( first == last )
  35. {
  36. geometry::assign_inverse(result);
  37. return result;
  38. }
  39. detail::bounds(element_indexable(*first, tr), result);
  40. ++first;
  41. for ( ; first != last ; ++first )
  42. geometry::expand(result, element_indexable(*first, tr));
  43. return result;
  44. }
  45. // destroys subtree if the element is internal node's element
  46. template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
  47. struct destroy_element
  48. {
  49. typedef typename Options::parameters_type parameters_type;
  50. typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
  51. typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
  52. typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
  53. inline static void apply(typename internal_node::elements_type::value_type & element, Allocators & allocators)
  54. {
  55. node_auto_ptr dummy(element.second, allocators);
  56. element.second = 0;
  57. }
  58. inline static void apply(typename leaf::elements_type::value_type &, Allocators &) {}
  59. };
  60. // destroys stored subtrees if internal node's elements are passed
  61. template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
  62. struct destroy_elements
  63. {
  64. typedef typename Options::parameters_type parameters_type;
  65. typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
  66. typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
  67. typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
  68. inline static void apply(typename internal_node::elements_type & elements, Allocators & allocators)
  69. {
  70. for ( size_t i = 0 ; i < elements.size() ; ++i )
  71. {
  72. node_auto_ptr dummy(elements[i].second, allocators);
  73. elements[i].second = 0;
  74. }
  75. }
  76. inline static void apply(typename leaf::elements_type &, Allocators &)
  77. {}
  78. inline static void apply(typename internal_node::elements_type::iterator first,
  79. typename internal_node::elements_type::iterator last,
  80. Allocators & allocators)
  81. {
  82. for ( ; first != last ; ++first )
  83. {
  84. node_auto_ptr dummy(first->second, allocators);
  85. first->second = 0;
  86. }
  87. }
  88. inline static void apply(typename leaf::elements_type::iterator /*first*/,
  89. typename leaf::elements_type::iterator /*last*/,
  90. Allocators & /*allocators*/)
  91. {}
  92. };
  93. // clears node, deletes all subtrees stored in node
  94. template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
  95. struct clear_node
  96. {
  97. typedef typename Options::parameters_type parameters_type;
  98. typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
  99. typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
  100. typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
  101. inline static void apply(node & node, Allocators & allocators)
  102. {
  103. rtree::visitors::is_leaf<Value, Options, Box, Allocators> ilv;
  104. rtree::apply_visitor(ilv, node);
  105. if ( ilv.result )
  106. {
  107. apply(rtree::get<leaf>(node), allocators);
  108. }
  109. else
  110. {
  111. apply(rtree::get<internal_node>(node), allocators);
  112. }
  113. }
  114. inline static void apply(internal_node & internal_node, Allocators & allocators)
  115. {
  116. destroy_elements<Value, Options, Translator, Box, Allocators>::apply(rtree::elements(internal_node), allocators);
  117. rtree::elements(internal_node).clear();
  118. }
  119. inline static void apply(leaf & leaf, Allocators &)
  120. {
  121. rtree::elements(leaf).clear();
  122. }
  123. };
  124. template <typename Container, typename Iterator>
  125. void move_from_back(Container & container, Iterator it)
  126. {
  127. BOOST_GEOMETRY_INDEX_ASSERT(!container.empty(), "cannot copy from empty container");
  128. Iterator back_it = container.end();
  129. --back_it;
  130. if ( it != back_it )
  131. {
  132. *it = boost::move(*back_it); // MAY THROW (copy)
  133. }
  134. }
  135. }} // namespace detail::rtree
  136. }}} // namespace boost::geometry::index
  137. #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP