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