]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry Index |
2 | // | |
3 | // R-tree nodes based on static conversion, storing dynamic-size containers | |
4 | // | |
5 | // Copyright (c) 2011-2014 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 | ||
11 | #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP | |
12 | #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP | |
13 | ||
14 | namespace boost { namespace geometry { namespace index { | |
15 | ||
16 | namespace detail { namespace rtree { | |
17 | ||
18 | template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag> | |
19 | struct weak_internal_node | |
20 | : public weak_node<Value, Parameters, Box, Allocators, Tag> | |
21 | { | |
22 | typedef boost::container::vector | |
23 | < | |
24 | rtree::ptr_pair<Box, typename Allocators::node_pointer>, | |
25 | typename Allocators::internal_node_allocator_type::template rebind | |
26 | < | |
27 | rtree::ptr_pair<Box, typename Allocators::node_pointer> | |
28 | >::other | |
29 | > elements_type; | |
30 | ||
31 | template <typename Al> | |
32 | inline weak_internal_node(Al const& al) | |
33 | : elements(al) | |
34 | {} | |
35 | ||
36 | elements_type elements; | |
37 | }; | |
38 | ||
39 | template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag> | |
40 | struct weak_leaf | |
41 | : public weak_node<Value, Parameters, Box, Allocators, Tag> | |
42 | { | |
43 | typedef boost::container::vector | |
44 | < | |
45 | Value, | |
46 | typename Allocators::leaf_allocator_type::template rebind | |
47 | < | |
48 | Value | |
49 | >::other | |
50 | > elements_type; | |
51 | ||
52 | template <typename Al> | |
53 | inline weak_leaf(Al const& al) | |
54 | : elements(al) | |
55 | {} | |
56 | ||
57 | elements_type elements; | |
58 | }; | |
59 | ||
60 | // nodes traits | |
61 | ||
62 | template <typename Value, typename Parameters, typename Box, typename Allocators> | |
63 | struct node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> | |
64 | { | |
65 | typedef weak_node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> type; | |
66 | }; | |
67 | ||
68 | template <typename Value, typename Parameters, typename Box, typename Allocators> | |
69 | struct internal_node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> | |
70 | { | |
71 | typedef weak_internal_node<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> type; | |
72 | }; | |
73 | ||
74 | template <typename Value, typename Parameters, typename Box, typename Allocators> | |
75 | struct leaf<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> | |
76 | { | |
77 | typedef weak_leaf<Value, Parameters, Box, Allocators, node_weak_dynamic_tag> type; | |
78 | }; | |
79 | ||
80 | // visitor traits | |
81 | ||
82 | template <typename Value, typename Parameters, typename Box, typename Allocators, bool IsVisitableConst> | |
83 | struct visitor<Value, Parameters, Box, Allocators, node_weak_dynamic_tag, IsVisitableConst> | |
84 | { | |
85 | typedef weak_visitor<Value, Parameters, Box, Allocators, node_weak_dynamic_tag, IsVisitableConst> type; | |
86 | }; | |
87 | ||
88 | // allocators | |
89 | ||
90 | template <typename Allocator, typename Value, typename Parameters, typename Box> | |
91 | class allocators<Allocator, Value, Parameters, Box, node_weak_dynamic_tag> | |
92 | : public Allocator::template rebind< | |
93 | typename internal_node< | |
94 | Value, Parameters, Box, | |
95 | allocators<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>, | |
96 | node_weak_dynamic_tag | |
97 | >::type | |
98 | >::other | |
99 | , public Allocator::template rebind< | |
100 | typename leaf< | |
101 | Value, Parameters, Box, | |
102 | allocators<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>, | |
103 | node_weak_dynamic_tag | |
104 | >::type | |
105 | >::other | |
106 | { | |
107 | typedef typename Allocator::template rebind< | |
108 | Value | |
109 | >::other value_allocator_type; | |
110 | ||
111 | public: | |
112 | typedef Allocator allocator_type; | |
113 | ||
114 | typedef Value value_type; | |
115 | typedef typename value_allocator_type::reference reference; | |
116 | typedef typename value_allocator_type::const_reference const_reference; | |
117 | typedef typename value_allocator_type::size_type size_type; | |
118 | typedef typename value_allocator_type::difference_type difference_type; | |
119 | typedef typename value_allocator_type::pointer pointer; | |
120 | typedef typename value_allocator_type::const_pointer const_pointer; | |
121 | ||
122 | typedef typename Allocator::template rebind< | |
123 | typename node<Value, Parameters, Box, allocators, node_weak_dynamic_tag>::type | |
124 | >::other::pointer node_pointer; | |
125 | ||
126 | typedef typename Allocator::template rebind< | |
127 | typename internal_node<Value, Parameters, Box, allocators, node_weak_dynamic_tag>::type | |
128 | >::other internal_node_allocator_type; | |
129 | ||
130 | typedef typename Allocator::template rebind< | |
131 | typename leaf<Value, Parameters, Box, allocators, node_weak_dynamic_tag>::type | |
132 | >::other leaf_allocator_type; | |
133 | ||
134 | inline allocators() | |
135 | : internal_node_allocator_type() | |
136 | , leaf_allocator_type() | |
137 | {} | |
138 | ||
139 | template <typename Alloc> | |
140 | inline explicit allocators(Alloc const& alloc) | |
141 | : internal_node_allocator_type(alloc) | |
142 | , leaf_allocator_type(alloc) | |
143 | {} | |
144 | ||
145 | inline allocators(BOOST_FWD_REF(allocators) a) | |
146 | : internal_node_allocator_type(boost::move(a.internal_node_allocator())) | |
147 | , leaf_allocator_type(boost::move(a.leaf_allocator())) | |
148 | {} | |
149 | ||
150 | inline allocators & operator=(BOOST_FWD_REF(allocators) a) | |
151 | { | |
152 | internal_node_allocator() = ::boost::move(a.internal_node_allocator()); | |
153 | leaf_allocator() = ::boost::move(a.leaf_allocator()); | |
154 | return *this; | |
155 | } | |
156 | ||
157 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
158 | inline allocators & operator=(allocators const& a) | |
159 | { | |
160 | internal_node_allocator() = a.internal_node_allocator(); | |
161 | leaf_allocator() = a.leaf_allocator(); | |
162 | return *this; | |
163 | } | |
164 | #endif | |
165 | ||
166 | void swap(allocators & a) | |
167 | { | |
168 | boost::swap(internal_node_allocator(), a.internal_node_allocator()); | |
169 | boost::swap(leaf_allocator(), a.leaf_allocator()); | |
170 | } | |
171 | ||
172 | bool operator==(allocators const& a) const { return leaf_allocator() == a.leaf_allocator(); } | |
173 | template <typename Alloc> | |
174 | bool operator==(Alloc const& a) const { return leaf_allocator() == leaf_allocator_type(a); } | |
175 | ||
176 | Allocator allocator() const { return Allocator(leaf_allocator()); } | |
177 | ||
178 | internal_node_allocator_type & internal_node_allocator() { return *this; } | |
179 | internal_node_allocator_type const& internal_node_allocator() const { return *this; } | |
180 | leaf_allocator_type & leaf_allocator() { return *this; } | |
181 | leaf_allocator_type const& leaf_allocator() const { return *this; } | |
182 | }; | |
183 | ||
184 | // create_node_impl | |
185 | ||
186 | template <typename BaseNodePtr, typename Node> | |
187 | struct create_weak_node | |
188 | { | |
189 | template <typename AllocNode> | |
190 | static inline BaseNodePtr apply(AllocNode & alloc_node) | |
191 | { | |
192 | typedef boost::container::allocator_traits<AllocNode> Al; | |
193 | typedef typename Al::pointer P; | |
194 | ||
195 | P p = Al::allocate(alloc_node, 1); | |
196 | ||
197 | if ( 0 == p ) | |
198 | throw_runtime_error("boost::geometry::index::rtree node creation failed"); | |
199 | ||
200 | scoped_deallocator<AllocNode> deallocator(p, alloc_node); | |
201 | ||
202 | Al::construct(alloc_node, boost::addressof(*p), alloc_node); | |
203 | ||
204 | deallocator.release(); | |
205 | return p; | |
206 | } | |
207 | }; | |
208 | ||
209 | // destroy_node_impl | |
210 | ||
211 | template <typename Node> | |
212 | struct destroy_weak_node | |
213 | { | |
214 | template <typename AllocNode, typename BaseNodePtr> | |
215 | static inline void apply(AllocNode & alloc_node, BaseNodePtr n) | |
216 | { | |
217 | typedef boost::container::allocator_traits<AllocNode> Al; | |
218 | typedef typename Al::pointer P; | |
219 | ||
220 | P p(&static_cast<Node&>(rtree::get<Node>(*n))); | |
221 | Al::destroy(alloc_node, boost::addressof(*p)); | |
222 | Al::deallocate(alloc_node, p, 1); | |
223 | } | |
224 | }; | |
225 | ||
226 | // create_node | |
227 | ||
228 | template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag> | |
229 | struct create_node< | |
230 | Allocators, | |
231 | weak_internal_node<Value, Parameters, Box, Allocators, Tag> | |
232 | > | |
233 | { | |
234 | static inline typename Allocators::node_pointer | |
235 | apply(Allocators & allocators) | |
236 | { | |
237 | return create_weak_node< | |
238 | typename Allocators::node_pointer, | |
239 | weak_internal_node<Value, Parameters, Box, Allocators, Tag> | |
240 | >::apply(allocators.internal_node_allocator()); | |
241 | } | |
242 | }; | |
243 | ||
244 | template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag> | |
245 | struct create_node< | |
246 | Allocators, | |
247 | weak_leaf<Value, Parameters, Box, Allocators, Tag> | |
248 | > | |
249 | { | |
250 | static inline typename Allocators::node_pointer | |
251 | apply(Allocators & allocators) | |
252 | { | |
253 | return create_weak_node< | |
254 | typename Allocators::node_pointer, | |
255 | weak_leaf<Value, Parameters, Box, Allocators, Tag> | |
256 | >::apply(allocators.leaf_allocator()); | |
257 | } | |
258 | }; | |
259 | ||
260 | // destroy_node | |
261 | ||
262 | template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag> | |
263 | struct destroy_node< | |
264 | Allocators, | |
265 | weak_internal_node<Value, Parameters, Box, Allocators, Tag> | |
266 | > | |
267 | { | |
268 | static inline void apply(Allocators & allocators, typename Allocators::node_pointer n) | |
269 | { | |
270 | destroy_weak_node< | |
271 | weak_internal_node<Value, Parameters, Box, Allocators, Tag> | |
272 | >::apply(allocators.internal_node_allocator(), n); | |
273 | } | |
274 | }; | |
275 | ||
276 | template <typename Allocators, typename Value, typename Parameters, typename Box, typename Tag> | |
277 | struct destroy_node< | |
278 | Allocators, | |
279 | weak_leaf<Value, Parameters, Box, Allocators, Tag> | |
280 | > | |
281 | { | |
282 | static inline void apply(Allocators & allocators, typename Allocators::node_pointer n) | |
283 | { | |
284 | destroy_weak_node< | |
285 | weak_leaf<Value, Parameters, Box, Allocators, Tag> | |
286 | >::apply(allocators.leaf_allocator(), n); | |
287 | } | |
288 | }; | |
289 | ||
290 | }} // namespace detail::rtree | |
291 | ||
292 | }}} // namespace boost::geometry::index | |
293 | ||
294 | #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP |