Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/geometry/index/detail/serialization.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Boost.Geometry Index | |
2 // | |
3 // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. | |
4 // | |
5 // Use, modification and distribution is subject to the Boost Software License, | |
6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
7 // http://www.boost.org/LICENSE_1_0.txt) | |
8 | |
9 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_SERIALIZATION_HPP | |
10 #define BOOST_GEOMETRY_INDEX_DETAIL_SERIALIZATION_HPP | |
11 | |
12 //#include <boost/serialization/serialization.hpp> | |
13 #include <boost/serialization/split_member.hpp> | |
14 #include <boost/serialization/version.hpp> | |
15 //#include <boost/serialization/nvp.hpp> | |
16 | |
17 // TODO | |
18 // how about using the unsigned type capable of storing Max in compile-time versions? | |
19 | |
20 // TODO | |
21 // - add wrappers for Point and Box and implement serialize for those wrappers instead of | |
22 // raw geometries | |
23 // PROBLEM: after implementing this, how Values would be set? | |
24 // - store the name of the parameters to know how to load and detect errors | |
25 // - in the header, once store info about the Indexable and Bounds types (geometry type, point CS, Dim, etc.) | |
26 // each geometry save without this info | |
27 | |
28 // TODO - move to index/detail/serialization.hpp | |
29 namespace boost { namespace geometry { namespace index { namespace detail { | |
30 | |
31 // TODO - use boost::move? | |
32 template<typename T> | |
33 class serialization_storage | |
34 { | |
35 public: | |
36 template <typename Archive> | |
37 serialization_storage(Archive & ar, unsigned int version) | |
38 { | |
39 boost::serialization::load_construct_data_adl(ar, this->address(), version); | |
40 } | |
41 ~serialization_storage() | |
42 { | |
43 this->address()->~T(); | |
44 } | |
45 T * address() | |
46 { | |
47 return static_cast<T*>(m_storage.address()); | |
48 } | |
49 private: | |
50 boost::aligned_storage<sizeof(T), boost::alignment_of<T>::value> m_storage; | |
51 }; | |
52 | |
53 // TODO - save and load item_version? see: collections_load_imp and collections_save_imp | |
54 // this should be done once for the whole container | |
55 // versions of all used types should be stored | |
56 | |
57 template <typename T, typename Archive> inline | |
58 T serialization_load(const char * name, Archive & ar) | |
59 { | |
60 namespace bs = boost::serialization; | |
61 serialization_storage<T> storage(ar, bs::version<T>::value); // load_construct_data | |
62 ar >> boost::serialization::make_nvp(name, *storage.address()); // serialize | |
63 //ar >> *storage.address(); // serialize | |
64 return *storage.address(); | |
65 } | |
66 | |
67 template <typename T, typename Archive> inline | |
68 void serialization_save(T const& t, const char * name, Archive & ar) | |
69 { | |
70 namespace bs = boost::serialization; | |
71 bs::save_construct_data_adl(ar, boost::addressof(t), bs::version<T>::value); // save_construct_data | |
72 ar << boost::serialization::make_nvp(name, t); // serialize | |
73 //ar << t; // serialize | |
74 } | |
75 | |
76 }}}} | |
77 | |
78 // TODO - move to index/serialization/rtree.hpp | |
79 namespace boost { namespace serialization { | |
80 | |
81 // boost::geometry::index::linear | |
82 | |
83 template<class Archive, size_t Max, size_t Min> | |
84 void save_construct_data(Archive & ar, const boost::geometry::index::linear<Max, Min> * params, unsigned int ) | |
85 { | |
86 size_t max = params->get_max_elements(), min = params->get_min_elements(); | |
87 ar << boost::serialization::make_nvp("max", max); | |
88 ar << boost::serialization::make_nvp("min", min); | |
89 } | |
90 template<class Archive, size_t Max, size_t Min> | |
91 void load_construct_data(Archive & ar, boost::geometry::index::linear<Max, Min> * params, unsigned int ) | |
92 { | |
93 size_t max, min; | |
94 ar >> boost::serialization::make_nvp("max", max); | |
95 ar >> boost::serialization::make_nvp("min", min); | |
96 if ( max != params->get_max_elements() || min != params->get_min_elements() ) | |
97 // TODO change exception type | |
98 BOOST_THROW_EXCEPTION(std::runtime_error("parameters not compatible")); | |
99 // the constructor musn't be called for this type | |
100 //::new(params)boost::geometry::index::linear<Max, Min>(); | |
101 } | |
102 template<class Archive, size_t Max, size_t Min> void serialize(Archive &, boost::geometry::index::linear<Max, Min> &, unsigned int) {} | |
103 | |
104 // boost::geometry::index::quadratic | |
105 | |
106 template<class Archive, size_t Max, size_t Min> | |
107 void save_construct_data(Archive & ar, const boost::geometry::index::quadratic<Max, Min> * params, unsigned int ) | |
108 { | |
109 size_t max = params->get_max_elements(), min = params->get_min_elements(); | |
110 ar << boost::serialization::make_nvp("max", max); | |
111 ar << boost::serialization::make_nvp("min", min); | |
112 } | |
113 template<class Archive, size_t Max, size_t Min> | |
114 void load_construct_data(Archive & ar, boost::geometry::index::quadratic<Max, Min> * params, unsigned int ) | |
115 { | |
116 size_t max, min; | |
117 ar >> boost::serialization::make_nvp("max", max); | |
118 ar >> boost::serialization::make_nvp("min", min); | |
119 if ( max != params->get_max_elements() || min != params->get_min_elements() ) | |
120 // TODO change exception type | |
121 BOOST_THROW_EXCEPTION(std::runtime_error("parameters not compatible")); | |
122 // the constructor musn't be called for this type | |
123 //::new(params)boost::geometry::index::quadratic<Max, Min>(); | |
124 } | |
125 template<class Archive, size_t Max, size_t Min> void serialize(Archive &, boost::geometry::index::quadratic<Max, Min> &, unsigned int) {} | |
126 | |
127 // boost::geometry::index::rstar | |
128 | |
129 template<class Archive, size_t Max, size_t Min, size_t RE, size_t OCT> | |
130 void save_construct_data(Archive & ar, const boost::geometry::index::rstar<Max, Min, RE, OCT> * params, unsigned int ) | |
131 { | |
132 size_t max = params->get_max_elements() | |
133 , min = params->get_min_elements() | |
134 , re = params->get_reinserted_elements() | |
135 , oct = params->get_overlap_cost_threshold(); | |
136 ar << boost::serialization::make_nvp("max", max); | |
137 ar << boost::serialization::make_nvp("min", min); | |
138 ar << boost::serialization::make_nvp("re", re); | |
139 ar << boost::serialization::make_nvp("oct", oct); | |
140 } | |
141 template<class Archive, size_t Max, size_t Min, size_t RE, size_t OCT> | |
142 void load_construct_data(Archive & ar, boost::geometry::index::rstar<Max, Min, RE, OCT> * params, unsigned int ) | |
143 { | |
144 size_t max, min, re, oct; | |
145 ar >> boost::serialization::make_nvp("max", max); | |
146 ar >> boost::serialization::make_nvp("min", min); | |
147 ar >> boost::serialization::make_nvp("re", re); | |
148 ar >> boost::serialization::make_nvp("oct", oct); | |
149 if ( max != params->get_max_elements() || min != params->get_min_elements() || | |
150 re != params->get_reinserted_elements() || oct != params->get_overlap_cost_threshold() ) | |
151 // TODO change exception type | |
152 BOOST_THROW_EXCEPTION(std::runtime_error("parameters not compatible")); | |
153 // the constructor musn't be called for this type | |
154 //::new(params)boost::geometry::index::rstar<Max, Min, RE, OCT>(); | |
155 } | |
156 template<class Archive, size_t Max, size_t Min, size_t RE, size_t OCT> | |
157 void serialize(Archive &, boost::geometry::index::rstar<Max, Min, RE, OCT> &, unsigned int) {} | |
158 | |
159 // boost::geometry::index::dynamic_linear | |
160 | |
161 template<class Archive> | |
162 inline void save_construct_data(Archive & ar, const boost::geometry::index::dynamic_linear * params, unsigned int ) | |
163 { | |
164 size_t max = params->get_max_elements(), min = params->get_min_elements(); | |
165 ar << boost::serialization::make_nvp("max", max); | |
166 ar << boost::serialization::make_nvp("min", min); | |
167 } | |
168 template<class Archive> | |
169 inline void load_construct_data(Archive & ar, boost::geometry::index::dynamic_linear * params, unsigned int ) | |
170 { | |
171 size_t max, min; | |
172 ar >> boost::serialization::make_nvp("max", max); | |
173 ar >> boost::serialization::make_nvp("min", min); | |
174 ::new(params)boost::geometry::index::dynamic_linear(max, min); | |
175 } | |
176 template<class Archive> void serialize(Archive &, boost::geometry::index::dynamic_linear &, unsigned int) {} | |
177 | |
178 // boost::geometry::index::dynamic_quadratic | |
179 | |
180 template<class Archive> | |
181 inline void save_construct_data(Archive & ar, const boost::geometry::index::dynamic_quadratic * params, unsigned int ) | |
182 { | |
183 size_t max = params->get_max_elements(), min = params->get_min_elements(); | |
184 ar << boost::serialization::make_nvp("max", max); | |
185 ar << boost::serialization::make_nvp("min", min); | |
186 } | |
187 template<class Archive> | |
188 inline void load_construct_data(Archive & ar, boost::geometry::index::dynamic_quadratic * params, unsigned int ) | |
189 { | |
190 size_t max, min; | |
191 ar >> boost::serialization::make_nvp("max", max); | |
192 ar >> boost::serialization::make_nvp("min", min); | |
193 ::new(params)boost::geometry::index::dynamic_quadratic(max, min); | |
194 } | |
195 template<class Archive> void serialize(Archive &, boost::geometry::index::dynamic_quadratic &, unsigned int) {} | |
196 | |
197 // boost::geometry::index::dynamic_rstar | |
198 | |
199 template<class Archive> | |
200 inline void save_construct_data(Archive & ar, const boost::geometry::index::dynamic_rstar * params, unsigned int ) | |
201 { | |
202 size_t max = params->get_max_elements() | |
203 , min = params->get_min_elements() | |
204 , re = params->get_reinserted_elements() | |
205 , oct = params->get_overlap_cost_threshold(); | |
206 ar << boost::serialization::make_nvp("max", max); | |
207 ar << boost::serialization::make_nvp("min", min); | |
208 ar << boost::serialization::make_nvp("re", re); | |
209 ar << boost::serialization::make_nvp("oct", oct); | |
210 } | |
211 template<class Archive> | |
212 inline void load_construct_data(Archive & ar, boost::geometry::index::dynamic_rstar * params, unsigned int ) | |
213 { | |
214 size_t max, min, re, oct; | |
215 ar >> boost::serialization::make_nvp("max", max); | |
216 ar >> boost::serialization::make_nvp("min", min); | |
217 ar >> boost::serialization::make_nvp("re", re); | |
218 ar >> boost::serialization::make_nvp("oct", oct); | |
219 ::new(params)boost::geometry::index::dynamic_rstar(max, min, re, oct); | |
220 } | |
221 template<class Archive> void serialize(Archive &, boost::geometry::index::dynamic_rstar &, unsigned int) {} | |
222 | |
223 }} // boost::serialization | |
224 | |
225 // TODO - move to index/detail/serialization.hpp or maybe geometry/serialization.hpp | |
226 namespace boost { namespace geometry { namespace index { namespace detail { | |
227 | |
228 template <typename P, size_t I = 0, size_t D = traits::dimension<P>::value> | |
229 struct serialize_point | |
230 { | |
231 template <typename Archive> | |
232 static inline void save(Archive & ar, P const& p, unsigned int version) | |
233 { | |
234 typename coordinate_type<P>::type c = get<I>(p); | |
235 ar << boost::serialization::make_nvp("c", c); | |
236 serialize_point<P, I+1, D>::save(ar, p, version); | |
237 } | |
238 | |
239 template <typename Archive> | |
240 static inline void load(Archive & ar, P & p, unsigned int version) | |
241 { | |
242 typename traits::coordinate_type<P>::type c; | |
243 ar >> boost::serialization::make_nvp("c", c); | |
244 set<I>(p, c); | |
245 serialize_point<P, I+1, D>::load(ar, p, version); | |
246 } | |
247 }; | |
248 | |
249 template <typename P, size_t D> | |
250 struct serialize_point<P, D, D> | |
251 { | |
252 template <typename Archive> static inline void save(Archive &, P const&, unsigned int) {} | |
253 template <typename Archive> static inline void load(Archive &, P &, unsigned int) {} | |
254 }; | |
255 | |
256 }}}} | |
257 | |
258 // TODO - move to index/detail/serialization.hpp or maybe geometry/serialization.hpp | |
259 namespace boost { namespace serialization { | |
260 | |
261 template<class Archive, typename T, size_t D, typename C> | |
262 void save(Archive & ar, boost::geometry::model::point<T, D, C> const& p, unsigned int version) | |
263 { | |
264 boost::geometry::index::detail::serialize_point< boost::geometry::model::point<T, D, C> >::save(ar, p, version); | |
265 } | |
266 template<class Archive, typename T, size_t D, typename C> | |
267 void load(Archive & ar, boost::geometry::model::point<T, D, C> & p, unsigned int version) | |
268 { | |
269 boost::geometry::index::detail::serialize_point< boost::geometry::model::point<T, D, C> >::load(ar, p, version); | |
270 } | |
271 template<class Archive, typename T, size_t D, typename C> | |
272 inline void serialize(Archive & ar, boost::geometry::model::point<T, D, C> & o, const unsigned int version) { split_free(ar, o, version); } | |
273 | |
274 template<class Archive, typename P> | |
275 inline void serialize(Archive & ar, boost::geometry::model::box<P> & b, const unsigned int) | |
276 { | |
277 ar & boost::serialization::make_nvp("min", b.min_corner()); | |
278 ar & boost::serialization::make_nvp("max", b.max_corner()); | |
279 } | |
280 | |
281 }} // boost::serialization | |
282 | |
283 // TODO - move to index/detail/rtree/visitors/save.hpp | |
284 namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { | |
285 | |
286 // TODO move saving and loading of the rtree outside the rtree, this will require adding some kind of members_view | |
287 | |
288 template <typename Archive, typename Value, typename Options, typename Translator, typename Box, typename Allocators> | |
289 class save | |
290 : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type | |
291 { | |
292 public: | |
293 typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node; | |
294 typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node; | |
295 typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf; | |
296 | |
297 save(Archive & archive, unsigned int version) | |
298 : m_archive(archive), m_version(version) | |
299 {} | |
300 | |
301 inline void operator()(internal_node const& n) | |
302 { | |
303 typedef typename rtree::elements_type<internal_node>::type elements_type; | |
304 elements_type const& elements = rtree::elements(n); | |
305 | |
306 // change to elements_type::size_type or size_type? | |
307 size_t s = elements.size(); | |
308 m_archive << boost::serialization::make_nvp("s", s); | |
309 | |
310 for (typename elements_type::const_iterator it = elements.begin() ; it != elements.end() ; ++it) | |
311 { | |
312 serialization_save(it->first, "b", m_archive); | |
313 | |
314 rtree::apply_visitor(*this, *it->second); | |
315 } | |
316 } | |
317 | |
318 inline void operator()(leaf const& l) | |
319 { | |
320 typedef typename rtree::elements_type<leaf>::type elements_type; | |
321 typedef typename elements_type::size_type elements_size; | |
322 elements_type const& elements = rtree::elements(l); | |
323 | |
324 // change to elements_type::size_type or size_type? | |
325 size_t s = elements.size(); | |
326 m_archive << boost::serialization::make_nvp("s", s); | |
327 | |
328 for (typename elements_type::const_iterator it = elements.begin() ; it != elements.end() ; ++it) | |
329 { | |
330 serialization_save(*it, "v", m_archive); | |
331 } | |
332 } | |
333 | |
334 private: | |
335 Archive & m_archive; | |
336 unsigned int m_version; | |
337 }; | |
338 | |
339 }}}}}} // boost::geometry::index::detail::rtree::visitors | |
340 | |
341 // TODO - move to index/detail/rtree/load.hpp | |
342 namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { | |
343 | |
344 template <typename Value, typename Options, typename Translator, typename Box, typename Allocators> | |
345 class load | |
346 { | |
347 typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node; | |
348 typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node; | |
349 typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf; | |
350 | |
351 typedef typename Options::parameters_type parameters_type; | |
352 | |
353 typedef typename Allocators::node_pointer node_pointer; | |
354 typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr; | |
355 typedef typename Allocators::size_type size_type; | |
356 | |
357 public: | |
358 template <typename Archive> inline static | |
359 node_pointer apply(Archive & ar, unsigned int version, size_type leafs_level, size_type & values_count, parameters_type const& parameters, Translator const& translator, Allocators & allocators) | |
360 { | |
361 values_count = 0; | |
362 return raw_apply(ar, version, leafs_level, values_count, parameters, translator, allocators); | |
363 } | |
364 | |
365 private: | |
366 template <typename Archive> inline static | |
367 node_pointer raw_apply(Archive & ar, unsigned int version, size_type leafs_level, size_type & values_count, parameters_type const& parameters, Translator const& translator, Allocators & allocators, size_type current_level = 0) | |
368 { | |
369 //BOOST_GEOMETRY_INDEX_ASSERT(current_level <= leafs_level, "invalid parameter"); | |
370 | |
371 // change to elements_type::size_type or size_type? | |
372 size_t elements_count; | |
373 ar >> boost::serialization::make_nvp("s", elements_count); | |
374 | |
375 if ( elements_count < parameters.get_min_elements() || parameters.get_max_elements() < elements_count ) | |
376 BOOST_THROW_EXCEPTION(std::runtime_error("rtree loading error")); | |
377 | |
378 if ( current_level < leafs_level ) | |
379 { | |
380 node_pointer n = rtree::create_node<Allocators, internal_node>::apply(allocators); // MAY THROW (A) | |
381 node_auto_ptr auto_remover(n, allocators); | |
382 internal_node & in = rtree::get<internal_node>(*n); | |
383 | |
384 typedef typename rtree::elements_type<internal_node>::type elements_type; | |
385 typedef typename elements_type::value_type element_type; | |
386 typedef typename elements_type::size_type elements_size; | |
387 elements_type & elements = rtree::elements(in); | |
388 | |
389 elements.reserve(elements_count); // MAY THROW (A) | |
390 | |
391 for ( size_t i = 0 ; i < elements_count ; ++i ) | |
392 { | |
393 typedef typename elements_type::value_type::first_type box_type; | |
394 box_type b = serialization_load<box_type>("b", ar); | |
395 node_pointer n = raw_apply(ar, version, leafs_level, values_count, parameters, translator, allocators, current_level+1); // recursive call | |
396 elements.push_back(element_type(b, n)); | |
397 } | |
398 | |
399 auto_remover.release(); | |
400 return n; | |
401 } | |
402 else | |
403 { | |
404 BOOST_GEOMETRY_INDEX_ASSERT(current_level == leafs_level, "unexpected value"); | |
405 | |
406 node_pointer n = rtree::create_node<Allocators, leaf>::apply(allocators); // MAY THROW (A) | |
407 node_auto_ptr auto_remover(n, allocators); | |
408 leaf & l = rtree::get<leaf>(*n); | |
409 | |
410 typedef typename rtree::elements_type<leaf>::type elements_type; | |
411 typedef typename elements_type::value_type element_type; | |
412 elements_type & elements = rtree::elements(l); | |
413 | |
414 values_count += elements_count; | |
415 | |
416 elements.reserve(elements_count); // MAY THROW (A) | |
417 | |
418 for ( size_t i = 0 ; i < elements_count ; ++i ) | |
419 { | |
420 element_type el = serialization_load<element_type>("v", ar); // MAY THROW (C) | |
421 elements.push_back(el); // MAY THROW (C) | |
422 } | |
423 | |
424 auto_remover.release(); | |
425 return n; | |
426 } | |
427 } | |
428 }; | |
429 | |
430 }}}}} // boost::geometry::index::detail::rtree | |
431 | |
432 // TODO - move to index/detail/rtree/private_view.hpp | |
433 namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { | |
434 | |
435 template <typename Rtree> | |
436 class const_private_view | |
437 { | |
438 public: | |
439 typedef typename Rtree::size_type size_type; | |
440 | |
441 typedef typename Rtree::translator_type translator_type; | |
442 typedef typename Rtree::value_type value_type; | |
443 typedef typename Rtree::options_type options_type; | |
444 typedef typename Rtree::box_type box_type; | |
445 typedef typename Rtree::allocators_type allocators_type; | |
446 | |
447 const_private_view(Rtree const& rt) : m_rtree(rt) {} | |
448 | |
449 typedef typename Rtree::members_holder members_holder; | |
450 | |
451 members_holder const& members() const { return m_rtree.m_members; } | |
452 | |
453 private: | |
454 const_private_view(const_private_view const&); | |
455 const_private_view & operator=(const_private_view const&); | |
456 | |
457 Rtree const& m_rtree; | |
458 }; | |
459 | |
460 template <typename Rtree> | |
461 class private_view | |
462 { | |
463 public: | |
464 typedef typename Rtree::size_type size_type; | |
465 | |
466 typedef typename Rtree::translator_type translator_type; | |
467 typedef typename Rtree::value_type value_type; | |
468 typedef typename Rtree::options_type options_type; | |
469 typedef typename Rtree::box_type box_type; | |
470 typedef typename Rtree::allocators_type allocators_type; | |
471 | |
472 private_view(Rtree & rt) : m_rtree(rt) {} | |
473 | |
474 typedef typename Rtree::members_holder members_holder; | |
475 | |
476 members_holder & members() { return m_rtree.m_members; } | |
477 members_holder const& members() const { return m_rtree.m_members; } | |
478 | |
479 private: | |
480 private_view(private_view const&); | |
481 private_view & operator=(private_view const&); | |
482 | |
483 Rtree & m_rtree; | |
484 }; | |
485 | |
486 }}}}} // namespace boost::geometry::index::detail::rtree | |
487 | |
488 // TODO - move to index/serialization/rtree.hpp | |
489 namespace boost { namespace serialization { | |
490 | |
491 template<class Archive, typename V, typename P, typename I, typename E, typename A> | |
492 void save(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> const& rt, unsigned int version) | |
493 { | |
494 namespace detail = boost::geometry::index::detail; | |
495 | |
496 typedef boost::geometry::index::rtree<V, P, I, E, A> rtree; | |
497 typedef detail::rtree::const_private_view<rtree> view; | |
498 typedef typename view::translator_type translator_type; | |
499 typedef typename view::value_type value_type; | |
500 typedef typename view::options_type options_type; | |
501 typedef typename view::box_type box_type; | |
502 typedef typename view::allocators_type allocators_type; | |
503 | |
504 view tree(rt); | |
505 | |
506 detail::serialization_save(tree.members().parameters(), "parameters", ar); | |
507 | |
508 ar << boost::serialization::make_nvp("values_count", tree.members().values_count); | |
509 ar << boost::serialization::make_nvp("leafs_level", tree.members().leafs_level); | |
510 | |
511 if ( tree.members().values_count ) | |
512 { | |
513 BOOST_GEOMETRY_INDEX_ASSERT(tree.members().root, "root shouldn't be null_ptr"); | |
514 | |
515 detail::rtree::visitors::save<Archive, value_type, options_type, translator_type, box_type, allocators_type> save_v(ar, version); | |
516 detail::rtree::apply_visitor(save_v, *tree.members().root); | |
517 } | |
518 } | |
519 | |
520 template<class Archive, typename V, typename P, typename I, typename E, typename A> | |
521 void load(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsigned int version) | |
522 { | |
523 namespace detail = boost::geometry::index::detail; | |
524 | |
525 typedef boost::geometry::index::rtree<V, P, I, E, A> rtree; | |
526 typedef detail::rtree::private_view<rtree> view; | |
527 typedef typename view::size_type size_type; | |
528 typedef typename view::translator_type translator_type; | |
529 typedef typename view::value_type value_type; | |
530 typedef typename view::options_type options_type; | |
531 typedef typename view::box_type box_type; | |
532 typedef typename view::allocators_type allocators_type; | |
533 | |
534 typedef typename options_type::parameters_type parameters_type; | |
535 typedef typename allocators_type::node_pointer node_pointer; | |
536 typedef detail::rtree::node_auto_ptr<value_type, options_type, translator_type, box_type, allocators_type> node_auto_ptr; | |
537 | |
538 view tree(rt); | |
539 | |
540 parameters_type params = detail::serialization_load<parameters_type>("parameters", ar); | |
541 | |
542 size_type values_count, leafs_level; | |
543 ar >> boost::serialization::make_nvp("values_count", values_count); | |
544 ar >> boost::serialization::make_nvp("leafs_level", leafs_level); | |
545 | |
546 node_pointer n(0); | |
547 if ( 0 < values_count ) | |
548 { | |
549 size_type loaded_values_count = 0; | |
550 n = detail::rtree::load<value_type, options_type, translator_type, box_type, allocators_type> | |
551 ::apply(ar, version, leafs_level, loaded_values_count, params, tree.members().translator(), tree.members().allocators()); // MAY THROW | |
552 | |
553 node_auto_ptr remover(n, tree.members().allocators()); | |
554 if ( loaded_values_count != values_count ) | |
555 BOOST_THROW_EXCEPTION(std::runtime_error("unexpected number of values")); // TODO change exception type | |
556 remover.release(); | |
557 } | |
558 | |
559 tree.members().parameters() = params; | |
560 tree.members().values_count = values_count; | |
561 tree.members().leafs_level = leafs_level; | |
562 | |
563 node_auto_ptr remover(tree.members().root, tree.members().allocators()); | |
564 tree.members().root = n; | |
565 } | |
566 | |
567 template<class Archive, typename V, typename P, typename I, typename E, typename A> inline | |
568 void serialize(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsigned int version) | |
569 { | |
570 split_free(ar, rt, version); | |
571 } | |
572 | |
573 template<class Archive, typename V, typename P, typename I, typename E, typename A> inline | |
574 void serialize(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> const& rt, unsigned int version) | |
575 { | |
576 split_free(ar, rt, version); | |
577 } | |
578 | |
579 }} // boost::serialization | |
580 | |
581 #endif // BOOST_GEOMETRY_INDEX_DETAIL_SERIALIZATION_HPP |