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