Chris@16
|
1 // Boost.Geometry Index
|
Chris@16
|
2 //
|
Chris@16
|
3 // R-tree nodes
|
Chris@16
|
4 //
|
Chris@101
|
5 // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
Chris@16
|
6 //
|
Chris@16
|
7 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
9 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP
|
Chris@16
|
12 #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/container/vector.hpp>
|
Chris@16
|
15 #include <boost/geometry/index/detail/varray.hpp>
|
Chris@16
|
16
|
Chris@16
|
17 #include <boost/geometry/index/detail/rtree/node/concept.hpp>
|
Chris@16
|
18 #include <boost/geometry/index/detail/rtree/node/pairs.hpp>
|
Chris@101
|
19 #include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
|
Chris@101
|
20 #include <boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp>
|
Chris@16
|
21
|
Chris@101
|
22 //#include <boost/geometry/index/detail/rtree/node/weak_visitor.hpp>
|
Chris@101
|
23 //#include <boost/geometry/index/detail/rtree/node/weak_dynamic.hpp>
|
Chris@101
|
24 //#include <boost/geometry/index/detail/rtree/node/weak_static.hpp>
|
Chris@16
|
25
|
Chris@101
|
26 #include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
|
Chris@101
|
27 #include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp>
|
Chris@101
|
28 #include <boost/geometry/index/detail/rtree/node/variant_static.hpp>
|
Chris@16
|
29
|
Chris@101
|
30 #include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
|
Chris@16
|
31
|
Chris@16
|
32 #include <boost/geometry/algorithms/expand.hpp>
|
Chris@16
|
33
|
Chris@16
|
34 #include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
|
Chris@16
|
35
|
Chris@16
|
36 #include <boost/geometry/index/detail/algorithms/bounds.hpp>
|
Chris@16
|
37
|
Chris@16
|
38 namespace boost { namespace geometry { namespace index {
|
Chris@16
|
39
|
Chris@16
|
40 namespace detail { namespace rtree {
|
Chris@16
|
41
|
Chris@16
|
42 // elements box
|
Chris@16
|
43
|
Chris@16
|
44 template <typename Box, typename FwdIter, typename Translator>
|
Chris@16
|
45 inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
|
Chris@16
|
46 {
|
Chris@16
|
47 Box result;
|
Chris@16
|
48
|
Chris@16
|
49 if ( first == last )
|
Chris@16
|
50 {
|
Chris@16
|
51 geometry::assign_inverse(result);
|
Chris@16
|
52 return result;
|
Chris@16
|
53 }
|
Chris@16
|
54
|
Chris@16
|
55 detail::bounds(element_indexable(*first, tr), result);
|
Chris@16
|
56 ++first;
|
Chris@16
|
57
|
Chris@16
|
58 for ( ; first != last ; ++first )
|
Chris@16
|
59 geometry::expand(result, element_indexable(*first, tr));
|
Chris@16
|
60
|
Chris@16
|
61 return result;
|
Chris@16
|
62 }
|
Chris@16
|
63
|
Chris@16
|
64 // destroys subtree if the element is internal node's element
|
Chris@16
|
65 template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
Chris@16
|
66 struct destroy_element
|
Chris@16
|
67 {
|
Chris@16
|
68 typedef typename Options::parameters_type parameters_type;
|
Chris@16
|
69
|
Chris@16
|
70 typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
|
Chris@16
|
71 typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
|
Chris@16
|
72
|
Chris@101
|
73 typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
|
Chris@16
|
74
|
Chris@16
|
75 inline static void apply(typename internal_node::elements_type::value_type & element, Allocators & allocators)
|
Chris@16
|
76 {
|
Chris@101
|
77 subtree_destroyer dummy(element.second, allocators);
|
Chris@16
|
78 element.second = 0;
|
Chris@16
|
79 }
|
Chris@16
|
80
|
Chris@16
|
81 inline static void apply(typename leaf::elements_type::value_type &, Allocators &) {}
|
Chris@16
|
82 };
|
Chris@16
|
83
|
Chris@16
|
84 // destroys stored subtrees if internal node's elements are passed
|
Chris@16
|
85 template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
Chris@16
|
86 struct destroy_elements
|
Chris@16
|
87 {
|
Chris@101
|
88 template <typename Range>
|
Chris@101
|
89 inline static void apply(Range & elements, Allocators & allocators)
|
Chris@16
|
90 {
|
Chris@101
|
91 apply(boost::begin(elements), boost::end(elements), allocators);
|
Chris@16
|
92 }
|
Chris@16
|
93
|
Chris@101
|
94 template <typename It>
|
Chris@101
|
95 inline static void apply(It first, It last, Allocators & allocators)
|
Chris@101
|
96 {
|
Chris@101
|
97 typedef boost::mpl::bool_<
|
Chris@101
|
98 boost::is_same<
|
Chris@101
|
99 Value, typename std::iterator_traits<It>::value_type
|
Chris@101
|
100 >::value
|
Chris@101
|
101 > is_range_of_values;
|
Chris@16
|
102
|
Chris@101
|
103 apply_dispatch(first, last, allocators, is_range_of_values());
|
Chris@101
|
104 }
|
Chris@101
|
105
|
Chris@101
|
106 private:
|
Chris@101
|
107 template <typename It>
|
Chris@101
|
108 inline static void apply_dispatch(It first, It last, Allocators & allocators,
|
Chris@101
|
109 boost::mpl::bool_<false> const& /*is_range_of_values*/)
|
Chris@16
|
110 {
|
Chris@101
|
111 typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
|
Chris@101
|
112
|
Chris@16
|
113 for ( ; first != last ; ++first )
|
Chris@16
|
114 {
|
Chris@101
|
115 subtree_destroyer dummy(first->second, allocators);
|
Chris@16
|
116 first->second = 0;
|
Chris@16
|
117 }
|
Chris@16
|
118 }
|
Chris@16
|
119
|
Chris@101
|
120 template <typename It>
|
Chris@101
|
121 inline static void apply_dispatch(It /*first*/, It /*last*/, Allocators & /*allocators*/,
|
Chris@101
|
122 boost::mpl::bool_<true> const& /*is_range_of_values*/)
|
Chris@16
|
123 {}
|
Chris@16
|
124 };
|
Chris@16
|
125
|
Chris@16
|
126 // clears node, deletes all subtrees stored in node
|
Chris@16
|
127 template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
Chris@16
|
128 struct clear_node
|
Chris@16
|
129 {
|
Chris@16
|
130 typedef typename Options::parameters_type parameters_type;
|
Chris@16
|
131
|
Chris@16
|
132 typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
|
Chris@16
|
133 typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
|
Chris@16
|
134 typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
|
Chris@16
|
135
|
Chris@16
|
136 inline static void apply(node & node, Allocators & allocators)
|
Chris@16
|
137 {
|
Chris@16
|
138 rtree::visitors::is_leaf<Value, Options, Box, Allocators> ilv;
|
Chris@16
|
139 rtree::apply_visitor(ilv, node);
|
Chris@16
|
140 if ( ilv.result )
|
Chris@16
|
141 {
|
Chris@16
|
142 apply(rtree::get<leaf>(node), allocators);
|
Chris@16
|
143 }
|
Chris@16
|
144 else
|
Chris@16
|
145 {
|
Chris@16
|
146 apply(rtree::get<internal_node>(node), allocators);
|
Chris@16
|
147 }
|
Chris@16
|
148 }
|
Chris@16
|
149
|
Chris@16
|
150 inline static void apply(internal_node & internal_node, Allocators & allocators)
|
Chris@16
|
151 {
|
Chris@16
|
152 destroy_elements<Value, Options, Translator, Box, Allocators>::apply(rtree::elements(internal_node), allocators);
|
Chris@16
|
153 rtree::elements(internal_node).clear();
|
Chris@16
|
154 }
|
Chris@16
|
155
|
Chris@16
|
156 inline static void apply(leaf & leaf, Allocators &)
|
Chris@16
|
157 {
|
Chris@16
|
158 rtree::elements(leaf).clear();
|
Chris@16
|
159 }
|
Chris@16
|
160 };
|
Chris@16
|
161
|
Chris@16
|
162 template <typename Container, typename Iterator>
|
Chris@16
|
163 void move_from_back(Container & container, Iterator it)
|
Chris@16
|
164 {
|
Chris@16
|
165 BOOST_GEOMETRY_INDEX_ASSERT(!container.empty(), "cannot copy from empty container");
|
Chris@16
|
166 Iterator back_it = container.end();
|
Chris@16
|
167 --back_it;
|
Chris@16
|
168 if ( it != back_it )
|
Chris@16
|
169 {
|
Chris@16
|
170 *it = boost::move(*back_it); // MAY THROW (copy)
|
Chris@16
|
171 }
|
Chris@16
|
172 }
|
Chris@16
|
173
|
Chris@16
|
174 }} // namespace detail::rtree
|
Chris@16
|
175
|
Chris@16
|
176 }}} // namespace boost::geometry::index
|
Chris@16
|
177
|
Chris@16
|
178 #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP
|