annotate DEPENDENCIES/generic/include/boost/geometry/index/detail/serialization.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // Boost.Geometry Index
Chris@16 2 //
Chris@101 3 // Copyright (c) 2011-2015 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@101 228 template <typename P, size_t I = 0, size_t D = geometry::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@101 242 typename geometry::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@101 306 // CONSIDER: change to elements_type::size_type or size_type
Chris@101 307 // or use fixed-size type like uint32 or even uint16?
Chris@16 308 size_t s = elements.size();
Chris@16 309 m_archive << boost::serialization::make_nvp("s", s);
Chris@16 310
Chris@16 311 for (typename elements_type::const_iterator it = elements.begin() ; it != elements.end() ; ++it)
Chris@16 312 {
Chris@16 313 serialization_save(it->first, "b", m_archive);
Chris@16 314
Chris@16 315 rtree::apply_visitor(*this, *it->second);
Chris@16 316 }
Chris@16 317 }
Chris@16 318
Chris@16 319 inline void operator()(leaf const& l)
Chris@16 320 {
Chris@16 321 typedef typename rtree::elements_type<leaf>::type elements_type;
Chris@101 322 //typedef typename elements_type::size_type elements_size;
Chris@16 323 elements_type const& elements = rtree::elements(l);
Chris@16 324
Chris@101 325 // CONSIDER: change to elements_type::size_type or size_type
Chris@101 326 // or use fixed-size type like uint32 or even uint16?
Chris@16 327 size_t s = elements.size();
Chris@16 328 m_archive << boost::serialization::make_nvp("s", s);
Chris@16 329
Chris@16 330 for (typename elements_type::const_iterator it = elements.begin() ; it != elements.end() ; ++it)
Chris@16 331 {
Chris@16 332 serialization_save(*it, "v", m_archive);
Chris@16 333 }
Chris@16 334 }
Chris@16 335
Chris@16 336 private:
Chris@16 337 Archive & m_archive;
Chris@16 338 unsigned int m_version;
Chris@16 339 };
Chris@16 340
Chris@16 341 }}}}}} // boost::geometry::index::detail::rtree::visitors
Chris@16 342
Chris@16 343 // TODO - move to index/detail/rtree/load.hpp
Chris@16 344 namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
Chris@16 345
Chris@16 346 template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
Chris@16 347 class load
Chris@16 348 {
Chris@16 349 typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
Chris@16 350 typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
Chris@16 351 typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
Chris@16 352
Chris@16 353 typedef typename Options::parameters_type parameters_type;
Chris@16 354
Chris@16 355 typedef typename Allocators::node_pointer node_pointer;
Chris@101 356 typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
Chris@16 357 typedef typename Allocators::size_type size_type;
Chris@16 358
Chris@16 359 public:
Chris@16 360 template <typename Archive> inline static
Chris@16 361 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 362 {
Chris@16 363 values_count = 0;
Chris@16 364 return raw_apply(ar, version, leafs_level, values_count, parameters, translator, allocators);
Chris@16 365 }
Chris@16 366
Chris@16 367 private:
Chris@16 368 template <typename Archive> inline static
Chris@16 369 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 370 {
Chris@16 371 //BOOST_GEOMETRY_INDEX_ASSERT(current_level <= leafs_level, "invalid parameter");
Chris@16 372
Chris@101 373 typedef typename rtree::elements_type<internal_node>::type elements_type;
Chris@101 374 typedef typename elements_type::value_type element_type;
Chris@101 375 //typedef typename elements_type::size_type elements_size;
Chris@101 376
Chris@101 377 // CONSIDER: change to elements_type::size_type or size_type
Chris@101 378 // or use fixed-size type like uint32 or even uint16?
Chris@16 379 size_t elements_count;
Chris@16 380 ar >> boost::serialization::make_nvp("s", elements_count);
Chris@16 381
Chris@16 382 if ( elements_count < parameters.get_min_elements() || parameters.get_max_elements() < elements_count )
Chris@16 383 BOOST_THROW_EXCEPTION(std::runtime_error("rtree loading error"));
Chris@16 384
Chris@16 385 if ( current_level < leafs_level )
Chris@16 386 {
Chris@16 387 node_pointer n = rtree::create_node<Allocators, internal_node>::apply(allocators); // MAY THROW (A)
Chris@101 388 subtree_destroyer auto_remover(n, allocators);
Chris@16 389 internal_node & in = rtree::get<internal_node>(*n);
Chris@16 390
Chris@16 391 elements_type & elements = rtree::elements(in);
Chris@16 392
Chris@16 393 elements.reserve(elements_count); // MAY THROW (A)
Chris@16 394
Chris@16 395 for ( size_t i = 0 ; i < elements_count ; ++i )
Chris@16 396 {
Chris@16 397 typedef typename elements_type::value_type::first_type box_type;
Chris@16 398 box_type b = serialization_load<box_type>("b", ar);
Chris@16 399 node_pointer n = raw_apply(ar, version, leafs_level, values_count, parameters, translator, allocators, current_level+1); // recursive call
Chris@16 400 elements.push_back(element_type(b, n));
Chris@16 401 }
Chris@16 402
Chris@16 403 auto_remover.release();
Chris@16 404 return n;
Chris@16 405 }
Chris@16 406 else
Chris@16 407 {
Chris@16 408 BOOST_GEOMETRY_INDEX_ASSERT(current_level == leafs_level, "unexpected value");
Chris@16 409
Chris@16 410 node_pointer n = rtree::create_node<Allocators, leaf>::apply(allocators); // MAY THROW (A)
Chris@101 411 subtree_destroyer auto_remover(n, allocators);
Chris@16 412 leaf & l = rtree::get<leaf>(*n);
Chris@16 413
Chris@16 414 typedef typename rtree::elements_type<leaf>::type elements_type;
Chris@16 415 typedef typename elements_type::value_type element_type;
Chris@16 416 elements_type & elements = rtree::elements(l);
Chris@16 417
Chris@16 418 values_count += elements_count;
Chris@16 419
Chris@16 420 elements.reserve(elements_count); // MAY THROW (A)
Chris@16 421
Chris@16 422 for ( size_t i = 0 ; i < elements_count ; ++i )
Chris@16 423 {
Chris@16 424 element_type el = serialization_load<element_type>("v", ar); // MAY THROW (C)
Chris@16 425 elements.push_back(el); // MAY THROW (C)
Chris@16 426 }
Chris@16 427
Chris@16 428 auto_remover.release();
Chris@16 429 return n;
Chris@16 430 }
Chris@16 431 }
Chris@16 432 };
Chris@16 433
Chris@16 434 }}}}} // boost::geometry::index::detail::rtree
Chris@16 435
Chris@16 436 // TODO - move to index/detail/rtree/private_view.hpp
Chris@16 437 namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
Chris@16 438
Chris@16 439 template <typename Rtree>
Chris@16 440 class const_private_view
Chris@16 441 {
Chris@16 442 public:
Chris@16 443 typedef typename Rtree::size_type size_type;
Chris@16 444
Chris@16 445 typedef typename Rtree::translator_type translator_type;
Chris@16 446 typedef typename Rtree::value_type value_type;
Chris@16 447 typedef typename Rtree::options_type options_type;
Chris@16 448 typedef typename Rtree::box_type box_type;
Chris@16 449 typedef typename Rtree::allocators_type allocators_type;
Chris@16 450
Chris@16 451 const_private_view(Rtree const& rt) : m_rtree(rt) {}
Chris@16 452
Chris@16 453 typedef typename Rtree::members_holder members_holder;
Chris@16 454
Chris@16 455 members_holder const& members() const { return m_rtree.m_members; }
Chris@16 456
Chris@16 457 private:
Chris@16 458 const_private_view(const_private_view const&);
Chris@16 459 const_private_view & operator=(const_private_view const&);
Chris@16 460
Chris@16 461 Rtree const& m_rtree;
Chris@16 462 };
Chris@16 463
Chris@16 464 template <typename Rtree>
Chris@16 465 class private_view
Chris@16 466 {
Chris@16 467 public:
Chris@16 468 typedef typename Rtree::size_type size_type;
Chris@16 469
Chris@16 470 typedef typename Rtree::translator_type translator_type;
Chris@16 471 typedef typename Rtree::value_type value_type;
Chris@16 472 typedef typename Rtree::options_type options_type;
Chris@16 473 typedef typename Rtree::box_type box_type;
Chris@16 474 typedef typename Rtree::allocators_type allocators_type;
Chris@16 475
Chris@16 476 private_view(Rtree & rt) : m_rtree(rt) {}
Chris@16 477
Chris@16 478 typedef typename Rtree::members_holder members_holder;
Chris@16 479
Chris@16 480 members_holder & members() { return m_rtree.m_members; }
Chris@16 481 members_holder const& members() const { return m_rtree.m_members; }
Chris@16 482
Chris@16 483 private:
Chris@16 484 private_view(private_view const&);
Chris@16 485 private_view & operator=(private_view const&);
Chris@16 486
Chris@16 487 Rtree & m_rtree;
Chris@16 488 };
Chris@16 489
Chris@16 490 }}}}} // namespace boost::geometry::index::detail::rtree
Chris@16 491
Chris@16 492 // TODO - move to index/serialization/rtree.hpp
Chris@16 493 namespace boost { namespace serialization {
Chris@16 494
Chris@16 495 template<class Archive, typename V, typename P, typename I, typename E, typename A>
Chris@16 496 void save(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> const& rt, unsigned int version)
Chris@16 497 {
Chris@16 498 namespace detail = boost::geometry::index::detail;
Chris@16 499
Chris@16 500 typedef boost::geometry::index::rtree<V, P, I, E, A> rtree;
Chris@16 501 typedef detail::rtree::const_private_view<rtree> view;
Chris@16 502 typedef typename view::translator_type translator_type;
Chris@16 503 typedef typename view::value_type value_type;
Chris@16 504 typedef typename view::options_type options_type;
Chris@16 505 typedef typename view::box_type box_type;
Chris@16 506 typedef typename view::allocators_type allocators_type;
Chris@16 507
Chris@16 508 view tree(rt);
Chris@16 509
Chris@16 510 detail::serialization_save(tree.members().parameters(), "parameters", ar);
Chris@16 511
Chris@16 512 ar << boost::serialization::make_nvp("values_count", tree.members().values_count);
Chris@16 513 ar << boost::serialization::make_nvp("leafs_level", tree.members().leafs_level);
Chris@16 514
Chris@16 515 if ( tree.members().values_count )
Chris@16 516 {
Chris@16 517 BOOST_GEOMETRY_INDEX_ASSERT(tree.members().root, "root shouldn't be null_ptr");
Chris@16 518
Chris@16 519 detail::rtree::visitors::save<Archive, value_type, options_type, translator_type, box_type, allocators_type> save_v(ar, version);
Chris@16 520 detail::rtree::apply_visitor(save_v, *tree.members().root);
Chris@16 521 }
Chris@16 522 }
Chris@16 523
Chris@16 524 template<class Archive, typename V, typename P, typename I, typename E, typename A>
Chris@16 525 void load(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsigned int version)
Chris@16 526 {
Chris@16 527 namespace detail = boost::geometry::index::detail;
Chris@16 528
Chris@16 529 typedef boost::geometry::index::rtree<V, P, I, E, A> rtree;
Chris@16 530 typedef detail::rtree::private_view<rtree> view;
Chris@16 531 typedef typename view::size_type size_type;
Chris@16 532 typedef typename view::translator_type translator_type;
Chris@16 533 typedef typename view::value_type value_type;
Chris@16 534 typedef typename view::options_type options_type;
Chris@16 535 typedef typename view::box_type box_type;
Chris@16 536 typedef typename view::allocators_type allocators_type;
Chris@16 537
Chris@16 538 typedef typename options_type::parameters_type parameters_type;
Chris@16 539 typedef typename allocators_type::node_pointer node_pointer;
Chris@101 540 typedef detail::rtree::subtree_destroyer<value_type, options_type, translator_type, box_type, allocators_type> subtree_destroyer;
Chris@16 541
Chris@16 542 view tree(rt);
Chris@16 543
Chris@16 544 parameters_type params = detail::serialization_load<parameters_type>("parameters", ar);
Chris@16 545
Chris@16 546 size_type values_count, leafs_level;
Chris@16 547 ar >> boost::serialization::make_nvp("values_count", values_count);
Chris@16 548 ar >> boost::serialization::make_nvp("leafs_level", leafs_level);
Chris@16 549
Chris@16 550 node_pointer n(0);
Chris@16 551 if ( 0 < values_count )
Chris@16 552 {
Chris@16 553 size_type loaded_values_count = 0;
Chris@16 554 n = detail::rtree::load<value_type, options_type, translator_type, box_type, allocators_type>
Chris@16 555 ::apply(ar, version, leafs_level, loaded_values_count, params, tree.members().translator(), tree.members().allocators()); // MAY THROW
Chris@16 556
Chris@101 557 subtree_destroyer remover(n, tree.members().allocators());
Chris@16 558 if ( loaded_values_count != values_count )
Chris@16 559 BOOST_THROW_EXCEPTION(std::runtime_error("unexpected number of values")); // TODO change exception type
Chris@16 560 remover.release();
Chris@16 561 }
Chris@16 562
Chris@16 563 tree.members().parameters() = params;
Chris@16 564 tree.members().values_count = values_count;
Chris@16 565 tree.members().leafs_level = leafs_level;
Chris@16 566
Chris@101 567 subtree_destroyer remover(tree.members().root, tree.members().allocators());
Chris@16 568 tree.members().root = n;
Chris@16 569 }
Chris@16 570
Chris@16 571 template<class Archive, typename V, typename P, typename I, typename E, typename A> inline
Chris@16 572 void serialize(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsigned int version)
Chris@16 573 {
Chris@16 574 split_free(ar, rt, version);
Chris@16 575 }
Chris@16 576
Chris@16 577 template<class Archive, typename V, typename P, typename I, typename E, typename A> inline
Chris@16 578 void serialize(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> const& rt, unsigned int version)
Chris@16 579 {
Chris@16 580 split_free(ar, rt, version);
Chris@16 581 }
Chris@16 582
Chris@16 583 }} // boost::serialization
Chris@16 584
Chris@16 585 #endif // BOOST_GEOMETRY_INDEX_DETAIL_SERIALIZATION_HPP