Chris@16: // Boost.Geometry Index Chris@16: // Chris@101: // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. Chris@16: // Chris@16: // Use, modification and distribution is subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_GEOMETRY_INDEX_DETAIL_SERIALIZATION_HPP Chris@16: #define BOOST_GEOMETRY_INDEX_DETAIL_SERIALIZATION_HPP Chris@16: Chris@16: //#include Chris@16: #include Chris@16: #include Chris@16: //#include Chris@16: Chris@16: // TODO Chris@16: // how about using the unsigned type capable of storing Max in compile-time versions? Chris@16: Chris@16: // TODO Chris@16: // - add wrappers for Point and Box and implement serialize for those wrappers instead of Chris@16: // raw geometries Chris@16: // PROBLEM: after implementing this, how Values would be set? Chris@16: // - store the name of the parameters to know how to load and detect errors Chris@16: // - in the header, once store info about the Indexable and Bounds types (geometry type, point CS, Dim, etc.) Chris@16: // each geometry save without this info Chris@16: Chris@16: // TODO - move to index/detail/serialization.hpp Chris@16: namespace boost { namespace geometry { namespace index { namespace detail { Chris@16: Chris@16: // TODO - use boost::move? Chris@16: template Chris@16: class serialization_storage Chris@16: { Chris@16: public: Chris@16: template Chris@16: serialization_storage(Archive & ar, unsigned int version) Chris@16: { Chris@16: boost::serialization::load_construct_data_adl(ar, this->address(), version); Chris@16: } Chris@16: ~serialization_storage() Chris@16: { Chris@16: this->address()->~T(); Chris@16: } Chris@16: T * address() Chris@16: { Chris@16: return static_cast(m_storage.address()); Chris@16: } Chris@16: private: Chris@16: boost::aligned_storage::value> m_storage; Chris@16: }; Chris@16: Chris@16: // TODO - save and load item_version? see: collections_load_imp and collections_save_imp Chris@16: // this should be done once for the whole container Chris@16: // versions of all used types should be stored Chris@16: Chris@16: template inline Chris@16: T serialization_load(const char * name, Archive & ar) Chris@16: { Chris@16: namespace bs = boost::serialization; Chris@16: serialization_storage storage(ar, bs::version::value); // load_construct_data Chris@16: ar >> boost::serialization::make_nvp(name, *storage.address()); // serialize Chris@16: //ar >> *storage.address(); // serialize Chris@16: return *storage.address(); Chris@16: } Chris@16: Chris@16: template inline Chris@16: void serialization_save(T const& t, const char * name, Archive & ar) Chris@16: { Chris@16: namespace bs = boost::serialization; Chris@16: bs::save_construct_data_adl(ar, boost::addressof(t), bs::version::value); // save_construct_data Chris@16: ar << boost::serialization::make_nvp(name, t); // serialize Chris@16: //ar << t; // serialize Chris@16: } Chris@16: Chris@16: }}}} Chris@16: Chris@16: // TODO - move to index/serialization/rtree.hpp Chris@16: namespace boost { namespace serialization { Chris@16: Chris@16: // boost::geometry::index::linear Chris@16: Chris@16: template Chris@16: void save_construct_data(Archive & ar, const boost::geometry::index::linear * params, unsigned int ) Chris@16: { Chris@16: size_t max = params->get_max_elements(), min = params->get_min_elements(); Chris@16: ar << boost::serialization::make_nvp("max", max); Chris@16: ar << boost::serialization::make_nvp("min", min); Chris@16: } Chris@16: template Chris@16: void load_construct_data(Archive & ar, boost::geometry::index::linear * params, unsigned int ) Chris@16: { Chris@16: size_t max, min; Chris@16: ar >> boost::serialization::make_nvp("max", max); Chris@16: ar >> boost::serialization::make_nvp("min", min); Chris@16: if ( max != params->get_max_elements() || min != params->get_min_elements() ) Chris@16: // TODO change exception type Chris@16: BOOST_THROW_EXCEPTION(std::runtime_error("parameters not compatible")); Chris@16: // the constructor musn't be called for this type Chris@16: //::new(params)boost::geometry::index::linear(); Chris@16: } Chris@16: template void serialize(Archive &, boost::geometry::index::linear &, unsigned int) {} Chris@16: Chris@16: // boost::geometry::index::quadratic Chris@16: Chris@16: template Chris@16: void save_construct_data(Archive & ar, const boost::geometry::index::quadratic * params, unsigned int ) Chris@16: { Chris@16: size_t max = params->get_max_elements(), min = params->get_min_elements(); Chris@16: ar << boost::serialization::make_nvp("max", max); Chris@16: ar << boost::serialization::make_nvp("min", min); Chris@16: } Chris@16: template Chris@16: void load_construct_data(Archive & ar, boost::geometry::index::quadratic * params, unsigned int ) Chris@16: { Chris@16: size_t max, min; Chris@16: ar >> boost::serialization::make_nvp("max", max); Chris@16: ar >> boost::serialization::make_nvp("min", min); Chris@16: if ( max != params->get_max_elements() || min != params->get_min_elements() ) Chris@16: // TODO change exception type Chris@16: BOOST_THROW_EXCEPTION(std::runtime_error("parameters not compatible")); Chris@16: // the constructor musn't be called for this type Chris@16: //::new(params)boost::geometry::index::quadratic(); Chris@16: } Chris@16: template void serialize(Archive &, boost::geometry::index::quadratic &, unsigned int) {} Chris@16: Chris@16: // boost::geometry::index::rstar Chris@16: Chris@16: template Chris@16: void save_construct_data(Archive & ar, const boost::geometry::index::rstar * params, unsigned int ) Chris@16: { Chris@16: size_t max = params->get_max_elements() Chris@16: , min = params->get_min_elements() Chris@16: , re = params->get_reinserted_elements() Chris@16: , oct = params->get_overlap_cost_threshold(); Chris@16: ar << boost::serialization::make_nvp("max", max); Chris@16: ar << boost::serialization::make_nvp("min", min); Chris@16: ar << boost::serialization::make_nvp("re", re); Chris@16: ar << boost::serialization::make_nvp("oct", oct); Chris@16: } Chris@16: template Chris@16: void load_construct_data(Archive & ar, boost::geometry::index::rstar * params, unsigned int ) Chris@16: { Chris@16: size_t max, min, re, oct; Chris@16: ar >> boost::serialization::make_nvp("max", max); Chris@16: ar >> boost::serialization::make_nvp("min", min); Chris@16: ar >> boost::serialization::make_nvp("re", re); Chris@16: ar >> boost::serialization::make_nvp("oct", oct); Chris@16: if ( max != params->get_max_elements() || min != params->get_min_elements() || Chris@16: re != params->get_reinserted_elements() || oct != params->get_overlap_cost_threshold() ) Chris@16: // TODO change exception type Chris@16: BOOST_THROW_EXCEPTION(std::runtime_error("parameters not compatible")); Chris@16: // the constructor musn't be called for this type Chris@16: //::new(params)boost::geometry::index::rstar(); Chris@16: } Chris@16: template Chris@16: void serialize(Archive &, boost::geometry::index::rstar &, unsigned int) {} Chris@16: Chris@16: // boost::geometry::index::dynamic_linear Chris@16: Chris@16: template Chris@16: inline void save_construct_data(Archive & ar, const boost::geometry::index::dynamic_linear * params, unsigned int ) Chris@16: { Chris@16: size_t max = params->get_max_elements(), min = params->get_min_elements(); Chris@16: ar << boost::serialization::make_nvp("max", max); Chris@16: ar << boost::serialization::make_nvp("min", min); Chris@16: } Chris@16: template Chris@16: inline void load_construct_data(Archive & ar, boost::geometry::index::dynamic_linear * params, unsigned int ) Chris@16: { Chris@16: size_t max, min; Chris@16: ar >> boost::serialization::make_nvp("max", max); Chris@16: ar >> boost::serialization::make_nvp("min", min); Chris@16: ::new(params)boost::geometry::index::dynamic_linear(max, min); Chris@16: } Chris@16: template void serialize(Archive &, boost::geometry::index::dynamic_linear &, unsigned int) {} Chris@16: Chris@16: // boost::geometry::index::dynamic_quadratic Chris@16: Chris@16: template Chris@16: inline void save_construct_data(Archive & ar, const boost::geometry::index::dynamic_quadratic * params, unsigned int ) Chris@16: { Chris@16: size_t max = params->get_max_elements(), min = params->get_min_elements(); Chris@16: ar << boost::serialization::make_nvp("max", max); Chris@16: ar << boost::serialization::make_nvp("min", min); Chris@16: } Chris@16: template Chris@16: inline void load_construct_data(Archive & ar, boost::geometry::index::dynamic_quadratic * params, unsigned int ) Chris@16: { Chris@16: size_t max, min; Chris@16: ar >> boost::serialization::make_nvp("max", max); Chris@16: ar >> boost::serialization::make_nvp("min", min); Chris@16: ::new(params)boost::geometry::index::dynamic_quadratic(max, min); Chris@16: } Chris@16: template void serialize(Archive &, boost::geometry::index::dynamic_quadratic &, unsigned int) {} Chris@16: Chris@16: // boost::geometry::index::dynamic_rstar Chris@16: Chris@16: template Chris@16: inline void save_construct_data(Archive & ar, const boost::geometry::index::dynamic_rstar * params, unsigned int ) Chris@16: { Chris@16: size_t max = params->get_max_elements() Chris@16: , min = params->get_min_elements() Chris@16: , re = params->get_reinserted_elements() Chris@16: , oct = params->get_overlap_cost_threshold(); Chris@16: ar << boost::serialization::make_nvp("max", max); Chris@16: ar << boost::serialization::make_nvp("min", min); Chris@16: ar << boost::serialization::make_nvp("re", re); Chris@16: ar << boost::serialization::make_nvp("oct", oct); Chris@16: } Chris@16: template Chris@16: inline void load_construct_data(Archive & ar, boost::geometry::index::dynamic_rstar * params, unsigned int ) Chris@16: { Chris@16: size_t max, min, re, oct; Chris@16: ar >> boost::serialization::make_nvp("max", max); Chris@16: ar >> boost::serialization::make_nvp("min", min); Chris@16: ar >> boost::serialization::make_nvp("re", re); Chris@16: ar >> boost::serialization::make_nvp("oct", oct); Chris@16: ::new(params)boost::geometry::index::dynamic_rstar(max, min, re, oct); Chris@16: } Chris@16: template void serialize(Archive &, boost::geometry::index::dynamic_rstar &, unsigned int) {} Chris@16: Chris@16: }} // boost::serialization Chris@16: Chris@16: // TODO - move to index/detail/serialization.hpp or maybe geometry/serialization.hpp Chris@16: namespace boost { namespace geometry { namespace index { namespace detail { Chris@16: Chris@101: template ::value> Chris@16: struct serialize_point Chris@16: { Chris@16: template Chris@16: static inline void save(Archive & ar, P const& p, unsigned int version) Chris@16: { Chris@16: typename coordinate_type

::type c = get(p); Chris@16: ar << boost::serialization::make_nvp("c", c); Chris@16: serialize_point::save(ar, p, version); Chris@16: } Chris@16: Chris@16: template Chris@16: static inline void load(Archive & ar, P & p, unsigned int version) Chris@16: { Chris@101: typename geometry::coordinate_type

::type c; Chris@16: ar >> boost::serialization::make_nvp("c", c); Chris@16: set(p, c); Chris@16: serialize_point::load(ar, p, version); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct serialize_point Chris@16: { Chris@16: template static inline void save(Archive &, P const&, unsigned int) {} Chris@16: template static inline void load(Archive &, P &, unsigned int) {} Chris@16: }; Chris@16: Chris@16: }}}} Chris@16: Chris@16: // TODO - move to index/detail/serialization.hpp or maybe geometry/serialization.hpp Chris@16: namespace boost { namespace serialization { Chris@16: Chris@16: template Chris@16: void save(Archive & ar, boost::geometry::model::point const& p, unsigned int version) Chris@16: { Chris@16: boost::geometry::index::detail::serialize_point< boost::geometry::model::point >::save(ar, p, version); Chris@16: } Chris@16: template Chris@16: void load(Archive & ar, boost::geometry::model::point & p, unsigned int version) Chris@16: { Chris@16: boost::geometry::index::detail::serialize_point< boost::geometry::model::point >::load(ar, p, version); Chris@16: } Chris@16: template Chris@16: inline void serialize(Archive & ar, boost::geometry::model::point & o, const unsigned int version) { split_free(ar, o, version); } Chris@16: Chris@16: template Chris@16: inline void serialize(Archive & ar, boost::geometry::model::box

& b, const unsigned int) Chris@16: { Chris@16: ar & boost::serialization::make_nvp("min", b.min_corner()); Chris@16: ar & boost::serialization::make_nvp("max", b.max_corner()); Chris@16: } Chris@16: Chris@16: }} // boost::serialization Chris@16: Chris@16: // TODO - move to index/detail/rtree/visitors/save.hpp Chris@16: namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { Chris@16: Chris@16: // TODO move saving and loading of the rtree outside the rtree, this will require adding some kind of members_view Chris@16: Chris@16: template Chris@16: class save Chris@16: : public rtree::visitor::type Chris@16: { Chris@16: public: Chris@16: typedef typename rtree::node::type node; Chris@16: typedef typename rtree::internal_node::type internal_node; Chris@16: typedef typename rtree::leaf::type leaf; Chris@16: Chris@16: save(Archive & archive, unsigned int version) Chris@16: : m_archive(archive), m_version(version) Chris@16: {} Chris@16: Chris@16: inline void operator()(internal_node const& n) Chris@16: { Chris@16: typedef typename rtree::elements_type::type elements_type; Chris@16: elements_type const& elements = rtree::elements(n); Chris@16: Chris@101: // CONSIDER: change to elements_type::size_type or size_type Chris@101: // or use fixed-size type like uint32 or even uint16? Chris@16: size_t s = elements.size(); Chris@16: m_archive << boost::serialization::make_nvp("s", s); Chris@16: Chris@16: for (typename elements_type::const_iterator it = elements.begin() ; it != elements.end() ; ++it) Chris@16: { Chris@16: serialization_save(it->first, "b", m_archive); Chris@16: Chris@16: rtree::apply_visitor(*this, *it->second); Chris@16: } Chris@16: } Chris@16: Chris@16: inline void operator()(leaf const& l) Chris@16: { Chris@16: typedef typename rtree::elements_type::type elements_type; Chris@101: //typedef typename elements_type::size_type elements_size; Chris@16: elements_type const& elements = rtree::elements(l); Chris@16: Chris@101: // CONSIDER: change to elements_type::size_type or size_type Chris@101: // or use fixed-size type like uint32 or even uint16? Chris@16: size_t s = elements.size(); Chris@16: m_archive << boost::serialization::make_nvp("s", s); Chris@16: Chris@16: for (typename elements_type::const_iterator it = elements.begin() ; it != elements.end() ; ++it) Chris@16: { Chris@16: serialization_save(*it, "v", m_archive); Chris@16: } Chris@16: } Chris@16: Chris@16: private: Chris@16: Archive & m_archive; Chris@16: unsigned int m_version; Chris@16: }; Chris@16: Chris@16: }}}}}} // boost::geometry::index::detail::rtree::visitors Chris@16: Chris@16: // TODO - move to index/detail/rtree/load.hpp Chris@16: namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { Chris@16: Chris@16: template Chris@16: class load Chris@16: { Chris@16: typedef typename rtree::node::type node; Chris@16: typedef typename rtree::internal_node::type internal_node; Chris@16: typedef typename rtree::leaf::type leaf; Chris@16: Chris@16: typedef typename Options::parameters_type parameters_type; Chris@16: Chris@16: typedef typename Allocators::node_pointer node_pointer; Chris@101: typedef rtree::subtree_destroyer subtree_destroyer; Chris@16: typedef typename Allocators::size_type size_type; Chris@16: Chris@16: public: Chris@16: template inline static Chris@16: 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: { Chris@16: values_count = 0; Chris@16: return raw_apply(ar, version, leafs_level, values_count, parameters, translator, allocators); Chris@16: } Chris@16: Chris@16: private: Chris@16: template inline static Chris@16: 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: { Chris@16: //BOOST_GEOMETRY_INDEX_ASSERT(current_level <= leafs_level, "invalid parameter"); Chris@16: Chris@101: typedef typename rtree::elements_type::type elements_type; Chris@101: typedef typename elements_type::value_type element_type; Chris@101: //typedef typename elements_type::size_type elements_size; Chris@101: Chris@101: // CONSIDER: change to elements_type::size_type or size_type Chris@101: // or use fixed-size type like uint32 or even uint16? Chris@16: size_t elements_count; Chris@16: ar >> boost::serialization::make_nvp("s", elements_count); Chris@16: Chris@16: if ( elements_count < parameters.get_min_elements() || parameters.get_max_elements() < elements_count ) Chris@16: BOOST_THROW_EXCEPTION(std::runtime_error("rtree loading error")); Chris@16: Chris@16: if ( current_level < leafs_level ) Chris@16: { Chris@16: node_pointer n = rtree::create_node::apply(allocators); // MAY THROW (A) Chris@101: subtree_destroyer auto_remover(n, allocators); Chris@16: internal_node & in = rtree::get(*n); Chris@16: Chris@16: elements_type & elements = rtree::elements(in); Chris@16: Chris@16: elements.reserve(elements_count); // MAY THROW (A) Chris@16: Chris@16: for ( size_t i = 0 ; i < elements_count ; ++i ) Chris@16: { Chris@16: typedef typename elements_type::value_type::first_type box_type; Chris@16: box_type b = serialization_load("b", ar); Chris@16: node_pointer n = raw_apply(ar, version, leafs_level, values_count, parameters, translator, allocators, current_level+1); // recursive call Chris@16: elements.push_back(element_type(b, n)); Chris@16: } Chris@16: Chris@16: auto_remover.release(); Chris@16: return n; Chris@16: } Chris@16: else Chris@16: { Chris@16: BOOST_GEOMETRY_INDEX_ASSERT(current_level == leafs_level, "unexpected value"); Chris@16: Chris@16: node_pointer n = rtree::create_node::apply(allocators); // MAY THROW (A) Chris@101: subtree_destroyer auto_remover(n, allocators); Chris@16: leaf & l = rtree::get(*n); Chris@16: Chris@16: typedef typename rtree::elements_type::type elements_type; Chris@16: typedef typename elements_type::value_type element_type; Chris@16: elements_type & elements = rtree::elements(l); Chris@16: Chris@16: values_count += elements_count; Chris@16: Chris@16: elements.reserve(elements_count); // MAY THROW (A) Chris@16: Chris@16: for ( size_t i = 0 ; i < elements_count ; ++i ) Chris@16: { Chris@16: element_type el = serialization_load("v", ar); // MAY THROW (C) Chris@16: elements.push_back(el); // MAY THROW (C) Chris@16: } Chris@16: Chris@16: auto_remover.release(); Chris@16: return n; Chris@16: } Chris@16: } Chris@16: }; Chris@16: Chris@16: }}}}} // boost::geometry::index::detail::rtree Chris@16: Chris@16: // TODO - move to index/detail/rtree/private_view.hpp Chris@16: namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { Chris@16: Chris@16: template Chris@16: class const_private_view Chris@16: { Chris@16: public: Chris@16: typedef typename Rtree::size_type size_type; Chris@16: Chris@16: typedef typename Rtree::translator_type translator_type; Chris@16: typedef typename Rtree::value_type value_type; Chris@16: typedef typename Rtree::options_type options_type; Chris@16: typedef typename Rtree::box_type box_type; Chris@16: typedef typename Rtree::allocators_type allocators_type; Chris@16: Chris@16: const_private_view(Rtree const& rt) : m_rtree(rt) {} Chris@16: Chris@16: typedef typename Rtree::members_holder members_holder; Chris@16: Chris@16: members_holder const& members() const { return m_rtree.m_members; } Chris@16: Chris@16: private: Chris@16: const_private_view(const_private_view const&); Chris@16: const_private_view & operator=(const_private_view const&); Chris@16: Chris@16: Rtree const& m_rtree; Chris@16: }; Chris@16: Chris@16: template Chris@16: class private_view Chris@16: { Chris@16: public: Chris@16: typedef typename Rtree::size_type size_type; Chris@16: Chris@16: typedef typename Rtree::translator_type translator_type; Chris@16: typedef typename Rtree::value_type value_type; Chris@16: typedef typename Rtree::options_type options_type; Chris@16: typedef typename Rtree::box_type box_type; Chris@16: typedef typename Rtree::allocators_type allocators_type; Chris@16: Chris@16: private_view(Rtree & rt) : m_rtree(rt) {} Chris@16: Chris@16: typedef typename Rtree::members_holder members_holder; Chris@16: Chris@16: members_holder & members() { return m_rtree.m_members; } Chris@16: members_holder const& members() const { return m_rtree.m_members; } Chris@16: Chris@16: private: Chris@16: private_view(private_view const&); Chris@16: private_view & operator=(private_view const&); Chris@16: Chris@16: Rtree & m_rtree; Chris@16: }; Chris@16: Chris@16: }}}}} // namespace boost::geometry::index::detail::rtree Chris@16: Chris@16: // TODO - move to index/serialization/rtree.hpp Chris@16: namespace boost { namespace serialization { Chris@16: Chris@16: template Chris@16: void save(Archive & ar, boost::geometry::index::rtree const& rt, unsigned int version) Chris@16: { Chris@16: namespace detail = boost::geometry::index::detail; Chris@16: Chris@16: typedef boost::geometry::index::rtree rtree; Chris@16: typedef detail::rtree::const_private_view view; Chris@16: typedef typename view::translator_type translator_type; Chris@16: typedef typename view::value_type value_type; Chris@16: typedef typename view::options_type options_type; Chris@16: typedef typename view::box_type box_type; Chris@16: typedef typename view::allocators_type allocators_type; Chris@16: Chris@16: view tree(rt); Chris@16: Chris@16: detail::serialization_save(tree.members().parameters(), "parameters", ar); Chris@16: Chris@16: ar << boost::serialization::make_nvp("values_count", tree.members().values_count); Chris@16: ar << boost::serialization::make_nvp("leafs_level", tree.members().leafs_level); Chris@16: Chris@16: if ( tree.members().values_count ) Chris@16: { Chris@16: BOOST_GEOMETRY_INDEX_ASSERT(tree.members().root, "root shouldn't be null_ptr"); Chris@16: Chris@16: detail::rtree::visitors::save save_v(ar, version); Chris@16: detail::rtree::apply_visitor(save_v, *tree.members().root); Chris@16: } Chris@16: } Chris@16: Chris@16: template Chris@16: void load(Archive & ar, boost::geometry::index::rtree & rt, unsigned int version) Chris@16: { Chris@16: namespace detail = boost::geometry::index::detail; Chris@16: Chris@16: typedef boost::geometry::index::rtree rtree; Chris@16: typedef detail::rtree::private_view view; Chris@16: typedef typename view::size_type size_type; Chris@16: typedef typename view::translator_type translator_type; Chris@16: typedef typename view::value_type value_type; Chris@16: typedef typename view::options_type options_type; Chris@16: typedef typename view::box_type box_type; Chris@16: typedef typename view::allocators_type allocators_type; Chris@16: Chris@16: typedef typename options_type::parameters_type parameters_type; Chris@16: typedef typename allocators_type::node_pointer node_pointer; Chris@101: typedef detail::rtree::subtree_destroyer subtree_destroyer; Chris@16: Chris@16: view tree(rt); Chris@16: Chris@16: parameters_type params = detail::serialization_load("parameters", ar); Chris@16: Chris@16: size_type values_count, leafs_level; Chris@16: ar >> boost::serialization::make_nvp("values_count", values_count); Chris@16: ar >> boost::serialization::make_nvp("leafs_level", leafs_level); Chris@16: Chris@16: node_pointer n(0); Chris@16: if ( 0 < values_count ) Chris@16: { Chris@16: size_type loaded_values_count = 0; Chris@16: n = detail::rtree::load Chris@16: ::apply(ar, version, leafs_level, loaded_values_count, params, tree.members().translator(), tree.members().allocators()); // MAY THROW Chris@16: Chris@101: subtree_destroyer remover(n, tree.members().allocators()); Chris@16: if ( loaded_values_count != values_count ) Chris@16: BOOST_THROW_EXCEPTION(std::runtime_error("unexpected number of values")); // TODO change exception type Chris@16: remover.release(); Chris@16: } Chris@16: Chris@16: tree.members().parameters() = params; Chris@16: tree.members().values_count = values_count; Chris@16: tree.members().leafs_level = leafs_level; Chris@16: Chris@101: subtree_destroyer remover(tree.members().root, tree.members().allocators()); Chris@16: tree.members().root = n; Chris@16: } Chris@16: Chris@16: template inline Chris@16: void serialize(Archive & ar, boost::geometry::index::rtree & rt, unsigned int version) Chris@16: { Chris@16: split_free(ar, rt, version); Chris@16: } Chris@16: Chris@16: template inline Chris@16: void serialize(Archive & ar, boost::geometry::index::rtree const& rt, unsigned int version) Chris@16: { Chris@16: split_free(ar, rt, version); Chris@16: } Chris@16: Chris@16: }} // boost::serialization Chris@16: Chris@16: #endif // BOOST_GEOMETRY_INDEX_DETAIL_SERIALIZATION_HPP