123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685 |
- // Boost.Geometry Index
- //
- // R-tree R*-tree insert algorithm implementation
- //
- // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
- //
- // This file was modified by Oracle on 2019-2023.
- // Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
- // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
- // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
- //
- // Use, modification and distribution is subject to the Boost Software License,
- // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_INSERT_HPP
- #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_INSERT_HPP
- #include <type_traits>
- #include <boost/core/ignore_unused.hpp>
- #include <boost/geometry/algorithms/centroid.hpp>
- #include <boost/geometry/algorithms/detail/comparable_distance/interface.hpp>
- #include <boost/geometry/index/detail/algorithms/content.hpp>
- #include <boost/geometry/index/detail/rtree/node/concept.hpp>
- #include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
- #include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
- namespace boost { namespace geometry { namespace index {
- namespace detail { namespace rtree { namespace visitors {
- namespace rstar {
- // Utility to distinguish between default and non-default index strategy
- template <typename Point1, typename Point2, typename Strategy>
- struct comparable_distance
- {
- typedef typename geometry::comparable_distance_result
- <
- Point1, Point2, Strategy
- >::type result_type;
- static inline result_type call(Point1 const& p1, Point2 const& p2, Strategy const& s)
- {
- return geometry::comparable_distance(p1, p2, s);
- }
- };
- template <typename Point1, typename Point2>
- struct comparable_distance<Point1, Point2, default_strategy>
- {
- typedef typename geometry::default_comparable_distance_result
- <
- Point1, Point2
- >::type result_type;
- static inline result_type call(Point1 const& p1, Point2 const& p2, default_strategy const& )
- {
- return geometry::comparable_distance(p1, p2);
- }
- };
- template <typename MembersHolder>
- class remove_elements_to_reinsert
- {
- public:
- typedef typename MembersHolder::box_type box_type;
- typedef typename MembersHolder::parameters_type parameters_type;
- typedef typename MembersHolder::translator_type translator_type;
- typedef typename MembersHolder::allocators_type allocators_type;
- typedef typename MembersHolder::node node;
- typedef typename MembersHolder::internal_node internal_node;
- typedef typename MembersHolder::leaf leaf;
- //typedef typename Allocators::internal_node_pointer internal_node_pointer;
- typedef internal_node * internal_node_pointer;
- template <typename ResultElements, typename Node>
- static inline void apply(ResultElements & result_elements,
- Node & n,
- internal_node_pointer parent,
- size_t current_child_index,
- parameters_type const& parameters,
- translator_type const& translator,
- allocators_type & allocators)
- {
- typedef typename rtree::elements_type<Node>::type elements_type;
- typedef typename elements_type::value_type element_type;
- typedef typename geometry::point_type<box_type>::type point_type;
- typedef typename index::detail::strategy_type<parameters_type>::type strategy_type;
- // TODO: awulkiew - change second point_type to the point type of the Indexable?
- typedef rstar::comparable_distance
- <
- point_type, point_type, strategy_type
- > comparable_distance_pp;
- typedef typename comparable_distance_pp::result_type comparable_distance_type;
- elements_type & elements = rtree::elements(n);
- const size_t elements_count = parameters.get_max_elements() + 1;
- const size_t reinserted_elements_count = (::std::min)(parameters.get_reinserted_elements(), elements_count - parameters.get_min_elements());
- BOOST_GEOMETRY_INDEX_ASSERT(parent, "node shouldn't be the root node");
- BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected elements number");
- BOOST_GEOMETRY_INDEX_ASSERT(0 < reinserted_elements_count, "wrong value of elements to reinsert");
- auto const& strategy = index::detail::get_strategy(parameters);
- // calculate current node's center
- point_type node_center;
- geometry::centroid(rtree::elements(*parent)[current_child_index].first, node_center,
- strategy);
- // fill the container of centers' distances of children from current node's center
- typedef typename index::detail::rtree::container_from_elements_type<
- elements_type,
- std::pair<comparable_distance_type, element_type>
- >::type sorted_elements_type;
- sorted_elements_type sorted_elements;
- // If constructor is used instead of resize() MS implementation leaks here
- sorted_elements.reserve(elements_count); // MAY THROW, STRONG (V, E: alloc, copy)
- for ( typename elements_type::const_iterator it = elements.begin() ;
- it != elements.end() ; ++it )
- {
- point_type element_center;
- geometry::centroid(rtree::element_indexable(*it, translator), element_center,
- strategy);
- sorted_elements.push_back(std::make_pair(
- comparable_distance_pp::call(node_center, element_center, strategy),
- *it)); // MAY THROW (V, E: copy)
- }
- // sort elements by distances from center
- std::partial_sort(
- sorted_elements.begin(),
- sorted_elements.begin() + reinserted_elements_count,
- sorted_elements.end(),
- distances_dsc<comparable_distance_type, element_type>); // MAY THROW, BASIC (V, E: copy)
- // copy elements which will be reinserted
- result_elements.clear();
- result_elements.reserve(reinserted_elements_count); // MAY THROW, STRONG (V, E: alloc, copy)
- for ( typename sorted_elements_type::const_iterator it = sorted_elements.begin() ;
- it != sorted_elements.begin() + reinserted_elements_count ; ++it )
- {
- result_elements.push_back(it->second); // MAY THROW (V, E: copy)
- }
- BOOST_TRY
- {
- // copy remaining elements to the current node
- elements.clear();
- elements.reserve(elements_count - reinserted_elements_count); // SHOULDN'T THROW (new_size <= old size)
- for ( typename sorted_elements_type::const_iterator it = sorted_elements.begin() + reinserted_elements_count;
- it != sorted_elements.end() ; ++it )
- {
- elements.push_back(it->second); // MAY THROW (V, E: copy)
- }
- }
- BOOST_CATCH(...)
- {
- elements.clear();
- for ( typename sorted_elements_type::iterator it = sorted_elements.begin() ;
- it != sorted_elements.end() ; ++it )
- {
- destroy_element<MembersHolder>::apply(it->second, allocators);
- }
- BOOST_RETHROW // RETHROW
- }
- BOOST_CATCH_END
- ::boost::ignore_unused(parameters);
- }
- private:
- template <typename Distance, typename El>
- static inline bool distances_asc(
- std::pair<Distance, El> const& d1,
- std::pair<Distance, El> const& d2)
- {
- return d1.first < d2.first;
- }
- template <typename Distance, typename El>
- static inline bool distances_dsc(
- std::pair<Distance, El> const& d1,
- std::pair<Distance, El> const& d2)
- {
- return d1.first > d2.first;
- }
- };
- template
- <
- size_t InsertIndex,
- typename Element,
- typename MembersHolder,
- bool IsValue = std::is_same<Element, typename MembersHolder::value_type>::value
- >
- struct level_insert_elements_type
- {
- typedef typename rtree::elements_type<
- typename rtree::internal_node<
- typename MembersHolder::value_type,
- typename MembersHolder::parameters_type,
- typename MembersHolder::box_type,
- typename MembersHolder::allocators_type,
- typename MembersHolder::node_tag
- >::type
- >::type type;
- };
- template <typename Value, typename MembersHolder>
- struct level_insert_elements_type<0, Value, MembersHolder, true>
- {
- typedef typename rtree::elements_type<
- typename rtree::leaf<
- typename MembersHolder::value_type,
- typename MembersHolder::parameters_type,
- typename MembersHolder::box_type,
- typename MembersHolder::allocators_type,
- typename MembersHolder::node_tag
- >::type
- >::type type;
- };
- template <size_t InsertIndex, typename Element, typename MembersHolder>
- struct level_insert_base
- : public detail::insert<Element, MembersHolder>
- {
- typedef detail::insert<Element, MembersHolder> base;
- typedef typename base::node node;
- typedef typename base::internal_node internal_node;
- typedef typename base::leaf leaf;
- typedef typename level_insert_elements_type<InsertIndex, Element, MembersHolder>::type elements_type;
- typedef typename index::detail::rtree::container_from_elements_type<
- elements_type,
- typename elements_type::value_type
- >::type result_elements_type;
- typedef typename MembersHolder::box_type box_type;
- typedef typename MembersHolder::parameters_type parameters_type;
- typedef typename MembersHolder::translator_type translator_type;
- typedef typename MembersHolder::allocators_type allocators_type;
- typedef typename allocators_type::node_pointer node_pointer;
- typedef typename allocators_type::size_type size_type;
- inline level_insert_base(node_pointer & root,
- size_type & leafs_level,
- Element const& element,
- parameters_type const& parameters,
- translator_type const& translator,
- allocators_type & allocators,
- size_type relative_level)
- : base(root, leafs_level, element, parameters, translator, allocators, relative_level)
- , result_relative_level(0)
- {}
- template <typename Node>
- inline void handle_possible_reinsert_or_split_of_root(Node &n)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(result_elements.empty(), "reinsert should be handled only once for level");
- result_relative_level = base::m_leafs_level - base::m_traverse_data.current_level;
- // overflow
- if ( base::m_parameters.get_max_elements() < rtree::elements(n).size() )
- {
- // node isn't root node
- if ( !base::m_traverse_data.current_is_root() )
- {
- // NOTE: exception-safety
- // After an exception result_elements may contain garbage, don't use it
- rstar::remove_elements_to_reinsert<MembersHolder>::apply(
- result_elements, n,
- base::m_traverse_data.parent, base::m_traverse_data.current_child_index,
- base::m_parameters, base::m_translator, base::m_allocators); // MAY THROW, BASIC (V, E: alloc, copy)
- }
- // node is root node
- else
- {
- BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get<Node>(*base::m_root_node), "node should be the root node");
- base::split(n); // MAY THROW (V, E: alloc, copy, N: alloc)
- }
- }
- }
- template <typename Node>
- inline void handle_possible_split(Node &n) const
- {
- // overflow
- if ( base::m_parameters.get_max_elements() < rtree::elements(n).size() )
- {
- base::split(n); // MAY THROW (V, E: alloc, copy, N: alloc)
- }
- }
- template <typename Node>
- inline void recalculate_aabb_if_necessary(Node const& n) const
- {
- if ( !result_elements.empty() && !base::m_traverse_data.current_is_root() )
- {
- // calulate node's new box
- recalculate_aabb(n);
- }
- }
- template <typename Node>
- inline void recalculate_aabb(Node const& n) const
- {
- base::m_traverse_data.current_element().first =
- elements_box<box_type>(rtree::elements(n).begin(), rtree::elements(n).end(),
- base::m_translator,
- index::detail::get_strategy(base::m_parameters));
- }
- inline void recalculate_aabb(leaf const& n) const
- {
- base::m_traverse_data.current_element().first =
- values_box<box_type>(rtree::elements(n).begin(), rtree::elements(n).end(),
- base::m_translator,
- index::detail::get_strategy(base::m_parameters));
- }
- size_type result_relative_level;
- result_elements_type result_elements;
- };
- template
- <
- size_t InsertIndex,
- typename Element,
- typename MembersHolder,
- bool IsValue = std::is_same<Element, typename MembersHolder::value_type>::value
- >
- struct level_insert
- : public level_insert_base<InsertIndex, Element, MembersHolder>
- {
- typedef level_insert_base<InsertIndex, Element, MembersHolder> base;
- typedef typename base::node node;
- typedef typename base::internal_node internal_node;
- typedef typename base::leaf leaf;
- typedef typename base::parameters_type parameters_type;
- typedef typename base::translator_type translator_type;
- typedef typename base::allocators_type allocators_type;
- typedef typename base::node_pointer node_pointer;
- typedef typename base::size_type size_type;
- inline level_insert(node_pointer & root,
- size_type & leafs_level,
- Element const& element,
- parameters_type const& parameters,
- translator_type const& translator,
- allocators_type & allocators,
- size_type relative_level)
- : base(root, leafs_level, element, parameters, translator, allocators, relative_level)
- {}
- inline void operator()(internal_node & n)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(base::m_traverse_data.current_level < base::m_leafs_level, "unexpected level");
- if ( base::m_traverse_data.current_level < base::m_level )
- {
- // next traversing step
- base::traverse(*this, n); // MAY THROW (E: alloc, copy, N: alloc)
- // further insert
- if ( 0 < InsertIndex )
- {
- BOOST_GEOMETRY_INDEX_ASSERT(0 < base::m_level, "illegal level value, level shouldn't be the root level for 0 < InsertIndex");
- if ( base::m_traverse_data.current_level == base::m_level - 1 )
- {
- base::handle_possible_reinsert_or_split_of_root(n); // MAY THROW (E: alloc, copy, N: alloc)
- }
- }
- }
- else
- {
- BOOST_GEOMETRY_INDEX_ASSERT(base::m_level == base::m_traverse_data.current_level, "unexpected level");
- BOOST_TRY
- {
- // push new child node
- rtree::elements(n).push_back(base::m_element); // MAY THROW, STRONG (E: alloc, copy)
- }
- BOOST_CATCH(...)
- {
- // NOTE: exception-safety
- // if the insert fails above, the element won't be stored in the tree, so delete it
- rtree::visitors::destroy<MembersHolder>::apply(base::m_element.second, base::m_allocators);
- BOOST_RETHROW // RETHROW
- }
- BOOST_CATCH_END
- // first insert
- if ( 0 == InsertIndex )
- {
- base::handle_possible_reinsert_or_split_of_root(n); // MAY THROW (E: alloc, copy, N: alloc)
- }
- // not the first insert
- else
- {
- base::handle_possible_split(n); // MAY THROW (E: alloc, N: alloc)
- }
- }
- base::recalculate_aabb_if_necessary(n);
- }
- inline void operator()(leaf &)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(false, "this visitor can't be used for a leaf");
- }
- };
- template <size_t InsertIndex, typename Value, typename MembersHolder>
- struct level_insert<InsertIndex, Value, MembersHolder, true>
- : public level_insert_base<InsertIndex, typename MembersHolder::value_type, MembersHolder>
- {
- typedef level_insert_base<InsertIndex, typename MembersHolder::value_type, MembersHolder> base;
- typedef typename base::node node;
- typedef typename base::internal_node internal_node;
- typedef typename base::leaf leaf;
- typedef typename MembersHolder::value_type value_type;
- typedef typename base::parameters_type parameters_type;
- typedef typename base::translator_type translator_type;
- typedef typename base::allocators_type allocators_type;
- typedef typename base::node_pointer node_pointer;
- typedef typename base::size_type size_type;
- inline level_insert(node_pointer & root,
- size_type & leafs_level,
- value_type const& v,
- parameters_type const& parameters,
- translator_type const& translator,
- allocators_type & allocators,
- size_type relative_level)
- : base(root, leafs_level, v, parameters, translator, allocators, relative_level)
- {}
- inline void operator()(internal_node & n)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(base::m_traverse_data.current_level < base::m_leafs_level, "unexpected level");
- BOOST_GEOMETRY_INDEX_ASSERT(base::m_traverse_data.current_level < base::m_level, "unexpected level");
- // next traversing step
- base::traverse(*this, n); // MAY THROW (V, E: alloc, copy, N: alloc)
- BOOST_GEOMETRY_INDEX_ASSERT(0 < base::m_level, "illegal level value, level shouldn't be the root level for 0 < InsertIndex");
- if ( base::m_traverse_data.current_level == base::m_level - 1 )
- {
- base::handle_possible_reinsert_or_split_of_root(n); // MAY THROW (E: alloc, copy, N: alloc)
- }
- base::recalculate_aabb_if_necessary(n);
- }
- inline void operator()(leaf & n)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(base::m_traverse_data.current_level == base::m_leafs_level,
- "unexpected level");
- BOOST_GEOMETRY_INDEX_ASSERT(base::m_level == base::m_traverse_data.current_level ||
- base::m_level == (std::numeric_limits<size_t>::max)(),
- "unexpected level");
- rtree::elements(n).push_back(base::m_element); // MAY THROW, STRONG (V: alloc, copy)
- base::handle_possible_split(n); // MAY THROW (V: alloc, copy, N: alloc)
- }
- };
- template <typename Value, typename MembersHolder>
- struct level_insert<0, Value, MembersHolder, true>
- : public level_insert_base<0, typename MembersHolder::value_type, MembersHolder>
- {
- typedef level_insert_base<0, typename MembersHolder::value_type, MembersHolder> base;
- typedef typename base::node node;
- typedef typename base::internal_node internal_node;
- typedef typename base::leaf leaf;
- typedef typename MembersHolder::value_type value_type;
- typedef typename base::parameters_type parameters_type;
- typedef typename base::translator_type translator_type;
- typedef typename base::allocators_type allocators_type;
- typedef typename base::node_pointer node_pointer;
- typedef typename base::size_type size_type;
- inline level_insert(node_pointer & root,
- size_type & leafs_level,
- value_type const& v,
- parameters_type const& parameters,
- translator_type const& translator,
- allocators_type & allocators,
- size_type relative_level)
- : base(root, leafs_level, v, parameters, translator, allocators, relative_level)
- {}
- inline void operator()(internal_node & n)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(base::m_traverse_data.current_level < base::m_leafs_level,
- "unexpected level");
- BOOST_GEOMETRY_INDEX_ASSERT(base::m_traverse_data.current_level < base::m_level,
- "unexpected level");
- // next traversing step
- base::traverse(*this, n); // MAY THROW (V: alloc, copy, N: alloc)
- base::recalculate_aabb_if_necessary(n);
- }
- inline void operator()(leaf & n)
- {
- BOOST_GEOMETRY_INDEX_ASSERT(base::m_traverse_data.current_level == base::m_leafs_level,
- "unexpected level");
- BOOST_GEOMETRY_INDEX_ASSERT(base::m_level == base::m_traverse_data.current_level ||
- base::m_level == (std::numeric_limits<size_t>::max)(),
- "unexpected level");
- rtree::elements(n).push_back(base::m_element); // MAY THROW, STRONG (V: alloc, copy)
- base::handle_possible_reinsert_or_split_of_root(n); // MAY THROW (V: alloc, copy, N: alloc)
- base::recalculate_aabb_if_necessary(n);
- }
- };
- } // namespace rstar
- // R*-tree insert visitor
- // After passing the Element to insert visitor the Element is managed by the tree
- // I.e. one should not delete the node passed to the insert visitor after exception is thrown
- // because this visitor may delete it
- template <typename Element, typename MembersHolder>
- class insert<Element, MembersHolder, insert_reinsert_tag>
- : public MembersHolder::visitor
- {
- typedef typename MembersHolder::parameters_type parameters_type;
- typedef typename MembersHolder::translator_type translator_type;
- typedef typename MembersHolder::allocators_type allocators_type;
- typedef typename MembersHolder::node node;
- typedef typename MembersHolder::internal_node internal_node;
- typedef typename MembersHolder::leaf leaf;
- typedef typename allocators_type::node_pointer node_pointer;
- typedef typename allocators_type::size_type size_type;
- public:
- inline insert(node_pointer & root,
- size_type & leafs_level,
- Element const& element,
- parameters_type const& parameters,
- translator_type const& translator,
- allocators_type & allocators,
- size_type relative_level = 0)
- : m_root(root), m_leafs_level(leafs_level), m_element(element)
- , m_parameters(parameters), m_translator(translator)
- , m_relative_level(relative_level), m_allocators(allocators)
- {}
- inline void operator()(internal_node & n)
- {
- boost::ignore_unused(n);
- BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get<internal_node>(*m_root), "current node should be the root");
- // Distinguish between situation when reinserts are required and use adequate visitor, otherwise use default one
- if ( m_parameters.get_reinserted_elements() > 0 )
- {
- rstar::level_insert<0, Element, MembersHolder> lins_v(
- m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
- rtree::apply_visitor(lins_v, *m_root); // MAY THROW (V, E: alloc, copy, N: alloc)
- if ( !lins_v.result_elements.empty() )
- {
- recursive_reinsert(lins_v.result_elements, lins_v.result_relative_level); // MAY THROW (V, E: alloc, copy, N: alloc)
- }
- }
- else
- {
- visitors::insert<Element, MembersHolder, insert_default_tag> ins_v(
- m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
- rtree::apply_visitor(ins_v, *m_root);
- }
- }
- inline void operator()(leaf & n)
- {
- boost::ignore_unused(n);
- BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get<leaf>(*m_root), "current node should be the root");
- // Distinguish between situation when reinserts are required and use adequate visitor, otherwise use default one
- if ( m_parameters.get_reinserted_elements() > 0 )
- {
- rstar::level_insert<0, Element, MembersHolder> lins_v(
- m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
- rtree::apply_visitor(lins_v, *m_root); // MAY THROW (V, E: alloc, copy, N: alloc)
- // we're in the root, so root should be split and there should be no elements to reinsert
- BOOST_GEOMETRY_INDEX_ASSERT(lins_v.result_elements.empty(), "unexpected state");
- }
- else
- {
- visitors::insert<Element, MembersHolder, insert_default_tag> ins_v(
- m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
- rtree::apply_visitor(ins_v, *m_root);
- }
- }
- private:
- template <typename Elements>
- inline void recursive_reinsert(Elements & elements, size_t relative_level)
- {
- typedef typename Elements::value_type element_type;
- // reinsert children starting from the minimum distance
- typename Elements::reverse_iterator it = elements.rbegin();
- for ( ; it != elements.rend() ; ++it)
- {
- rstar::level_insert<1, element_type, MembersHolder> lins_v(
- m_root, m_leafs_level, *it, m_parameters, m_translator, m_allocators, relative_level);
- BOOST_TRY
- {
- rtree::apply_visitor(lins_v, *m_root); // MAY THROW (V, E: alloc, copy, N: alloc)
- }
- BOOST_CATCH(...)
- {
- ++it;
- for ( ; it != elements.rend() ; ++it)
- rtree::destroy_element<MembersHolder>::apply(*it, m_allocators);
- BOOST_RETHROW // RETHROW
- }
- BOOST_CATCH_END
- BOOST_GEOMETRY_INDEX_ASSERT(relative_level + 1 == lins_v.result_relative_level, "unexpected level");
- // non-root relative level
- if ( lins_v.result_relative_level < m_leafs_level && !lins_v.result_elements.empty())
- {
- recursive_reinsert(lins_v.result_elements, lins_v.result_relative_level); // MAY THROW (V, E: alloc, copy, N: alloc)
- }
- }
- }
- node_pointer & m_root;
- size_type & m_leafs_level;
- Element const& m_element;
- parameters_type const& m_parameters;
- translator_type const& m_translator;
- size_type m_relative_level;
- allocators_type & m_allocators;
- };
- }}} // namespace detail::rtree::visitors
- }}} // namespace boost::geometry::index
- #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_INSERT_HPP
|