From 477627d16a3ea8907ee8ba3ee781a8924248efdc Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 1 Nov 2019 00:54:10 +0100 Subject: [PATCH 1/5] [rtree] Extract members_holder and pass it into visitors instead of multiple types. --- .../rtree/linear/redistribute_elements.hpp | 33 +- .../geometry/index/detail/rtree/node/node.hpp | 60 ++-- .../detail/rtree/node/subtree_destroyer.hpp | 18 +- .../index/detail/rtree/pack_create.hpp | 113 ++++--- .../rtree/quadratic/redistribute_elements.hpp | 41 +-- .../index/detail/rtree/query_iterators.hpp | 54 ++-- .../detail/rtree/rstar/choose_next_node.hpp | 23 +- .../index/detail/rtree/rstar/insert.hpp | 196 +++++++----- .../rtree/rstar/redistribute_elements.hpp | 41 +-- .../detail/rtree/utilities/are_boxes_ok.hpp | 34 +- .../detail/rtree/utilities/are_counts_ok.hpp | 20 +- .../detail/rtree/utilities/are_levels_ok.hpp | 17 +- .../index/detail/rtree/utilities/gl_draw.hpp | 30 +- .../index/detail/rtree/utilities/print.hpp | 25 +- .../detail/rtree/utilities/statistics.hpp | 18 +- .../index/detail/rtree/utilities/view.hpp | 6 + .../detail/rtree/visitors/children_box.hpp | 28 +- .../index/detail/rtree/visitors/copy.hpp | 32 +- .../index/detail/rtree/visitors/count.hpp | 22 +- .../index/detail/rtree/visitors/destroy.hpp | 25 +- .../detail/rtree/visitors/distance_query.hpp | 89 +++--- .../index/detail/rtree/visitors/insert.hpp | 172 +++++----- .../index/detail/rtree/visitors/is_leaf.hpp | 13 +- .../index/detail/rtree/visitors/remove.hpp | 70 ++--- .../detail/rtree/visitors/spatial_query.hpp | 49 +-- .../geometry/index/detail/serialization.hpp | 32 +- include/boost/geometry/index/rtree.hpp | 293 ++++++++++-------- 27 files changed, 880 insertions(+), 674 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp index a0635acab..88fb3358c 100644 --- a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp @@ -322,28 +322,31 @@ inline void pick_seeds(Elements const& elements, // from void split_node(node_pointer const& n, node_pointer& n1, node_pointer& n2) const -template -struct redistribute_elements +template +struct redistribute_elements { - typedef typename Options::parameters_type parameters_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 rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; template static inline void apply(Node & n, Node & second_node, - Box & box1, - Box & box2, + box_type & box1, + box_type & box2, parameters_type const& parameters, - Translator const& translator, - Allocators & allocators) + translator_type const& translator, + allocators_type & allocators) { typedef typename rtree::elements_type::type elements_type; typedef typename elements_type::value_type element_type; - typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename index::detail::default_content_result::type content_type; + typedef typename rtree::element_indexable_type::type indexable_type; + typedef typename index::detail::default_content_result::type content_type; typename index::detail::strategy_type::type const& strategy = index::detail::get_strategy(parameters); @@ -414,8 +417,8 @@ struct redistribute_elements::apply(elements_copy, allocators); + rtree::destroy_elements::apply(elements_copy, allocators); //elements_copy.clear(); BOOST_RETHROW // RETHROW, BASIC diff --git a/include/boost/geometry/index/detail/rtree/node/node.hpp b/include/boost/geometry/index/detail/rtree/node/node.hpp index 51ba2c7e7..e4db82d2c 100644 --- a/include/boost/geometry/index/detail/rtree/node/node.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node.hpp @@ -102,41 +102,46 @@ inline Box values_box(FwdIter first, FwdIter last, Translator const& tr, } // destroys subtree if the element is internal node's element -template +template struct destroy_element { - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::allocators_type allocators_type; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef rtree::subtree_destroyer subtree_destroyer; - - inline static void apply(typename internal_node::elements_type::value_type & element, Allocators & allocators) + inline static void apply(typename internal_node::elements_type::value_type & element, + allocators_type & allocators) { - subtree_destroyer dummy(element.second, allocators); + rtree::subtree_destroyer dummy(element.second, allocators); element.second = 0; } - inline static void apply(typename leaf::elements_type::value_type &, Allocators &) {} + inline static void apply(typename leaf::elements_type::value_type &, + allocators_type &) + {} }; // destroys stored subtrees if internal node's elements are passed -template +template struct destroy_elements { + typedef typename MembersHolder::value_type value_type; + typedef typename MembersHolder::allocators_type allocators_type; + template - inline static void apply(Range & elements, Allocators & allocators) + inline static void apply(Range & elements, allocators_type & allocators) { apply(boost::begin(elements), boost::end(elements), allocators); } template - inline static void apply(It first, It last, Allocators & allocators) + inline static void apply(It first, It last, allocators_type & allocators) { typedef boost::mpl::bool_< boost::is_same< - Value, typename std::iterator_traits::value_type + value_type, typename std::iterator_traits::value_type >::value > is_range_of_values; @@ -145,37 +150,36 @@ struct destroy_elements private: template - inline static void apply_dispatch(It first, It last, Allocators & allocators, + inline static void apply_dispatch(It first, It last, allocators_type & allocators, boost::mpl::bool_ const& /*is_range_of_values*/) { - typedef rtree::subtree_destroyer subtree_destroyer; - for ( ; first != last ; ++first ) { - subtree_destroyer dummy(first->second, allocators); + rtree::subtree_destroyer dummy(first->second, allocators); first->second = 0; } } template - inline static void apply_dispatch(It /*first*/, It /*last*/, Allocators & /*allocators*/, + inline static void apply_dispatch(It /*first*/, It /*last*/, allocators_type & /*allocators*/, boost::mpl::bool_ const& /*is_range_of_values*/) {} }; // clears node, deletes all subtrees stored in node -template +template struct clear_node { - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::allocators_type allocators_type; - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - inline static void apply(node & node, Allocators & allocators) + inline static void apply(node & node, allocators_type & allocators) { - rtree::visitors::is_leaf ilv; + rtree::visitors::is_leaf ilv; rtree::apply_visitor(ilv, node); if ( ilv.result ) { @@ -187,13 +191,13 @@ struct clear_node } } - inline static void apply(internal_node & internal_node, Allocators & allocators) + inline static void apply(internal_node & internal_node, allocators_type & allocators) { - destroy_elements::apply(rtree::elements(internal_node), allocators); + destroy_elements::apply(rtree::elements(internal_node), allocators); rtree::elements(internal_node).clear(); } - inline static void apply(leaf & leaf, Allocators &) + inline static void apply(leaf & leaf, allocators_type &) { rtree::elements(leaf).clear(); } diff --git a/include/boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp b/include/boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp index 3376068ee..ca65bad32 100644 --- a/include/boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp +++ b/include/boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2019. +// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// 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) @@ -17,17 +21,19 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { -template +template class subtree_destroyer { - typedef typename rtree::node::type node; - typedef typename Allocators::node_pointer pointer; + typedef typename MembersHolder::node node; + + typedef typename MembersHolder::allocators_type allocators_type; + typedef typename MembersHolder::node_pointer pointer; subtree_destroyer(subtree_destroyer const&); subtree_destroyer & operator=(subtree_destroyer const&); public: - subtree_destroyer(pointer ptr, Allocators & allocators) + subtree_destroyer(pointer ptr, allocators_type & allocators) : m_ptr(ptr) , m_allocators(allocators) {} @@ -41,7 +47,7 @@ public: { if ( m_ptr && m_ptr != ptr ) { - detail::rtree::visitors::destroy del_v(m_ptr, m_allocators); + detail::rtree::visitors::destroy del_v(m_ptr, m_allocators); detail::rtree::apply_visitor(del_v, *m_ptr); } m_ptr = ptr; @@ -69,7 +75,7 @@ public: private: pointer m_ptr; - Allocators & m_allocators; + allocators_type & m_allocators; }; }} // namespace detail::rtree diff --git a/include/boost/geometry/index/detail/rtree/pack_create.hpp b/include/boost/geometry/index/detail/rtree/pack_create.hpp index f8565bfb3..7280c3000 100644 --- a/include/boost/geometry/index/detail/rtree/pack_create.hpp +++ b/include/boost/geometry/index/detail/rtree/pack_create.hpp @@ -126,37 +126,45 @@ struct nth_element_and_half_boxes // L2 25 25 25 25 25 25 17 10 // L3 5x5 5x5 5x5 5x5 5x5 5x5 3x5+2 2x5 -template +template class pack { - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef typename Allocators::node_pointer node_pointer; - typedef rtree::subtree_destroyer subtree_destroyer; - typedef typename Allocators::size_type size_type; + typedef typename MembersHolder::node_pointer node_pointer; + typedef typename MembersHolder::size_type size_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::allocators_type allocators_type; - typedef typename geometry::point_type::type point_type; + typedef typename MembersHolder::box_type box_type; + typedef typename geometry::point_type::type point_type; typedef typename geometry::coordinate_type::type coordinate_type; - typedef typename detail::default_content_result::type content_type; - typedef typename Options::parameters_type parameters_type; + typedef typename detail::default_content_result::type content_type; typedef typename detail::strategy_type::type strategy_type; static const std::size_t dimension = geometry::dimension::value; typedef typename rtree::container_from_elements_type< typename rtree::elements_type::type, - std::size_t + size_type >::type values_counts_container; typedef typename rtree::elements_type::type internal_elements; typedef typename internal_elements::value_type internal_element; + typedef rtree::subtree_destroyer subtree_destroyer; + public: // Arbitrary iterators template inline static - node_pointer apply(InIt first, InIt last, size_type & values_count, size_type & leafs_level, - parameters_type const& parameters, Translator const& translator, Allocators & allocators) + node_pointer apply(InIt first, InIt last, + size_type & values_count, + size_type & leafs_level, + parameters_type const& parameters, + translator_type const& translator, + allocators_type & allocators) { typedef typename std::iterator_traits::difference_type diff_type; @@ -170,7 +178,7 @@ public: values_count = static_cast(diff); entries.reserve(values_count); - expandable_box hint_box(detail::get_strategy(parameters)); + expandable_box hint_box(detail::get_strategy(parameters)); for ( ; first != last ; ++first ) { // NOTE: support for iterators not returning true references adapted @@ -178,7 +186,7 @@ public: // An alternative would be to dereference the iterator and translate // in one expression each time the indexable was needed. typename std::iterator_traits::reference in_ref = *first; - typename Translator::result_type indexable = translator(in_ref); + typename translator_type::result_type indexable = translator(in_ref); // NOTE: added for consistency with insert() // CONSIDER: alternative - ignore invalid indexable or throw an exception @@ -250,16 +258,21 @@ private: struct subtree_elements_counts { - subtree_elements_counts(std::size_t ma, std::size_t mi) : maxc(ma), minc(mi) {} - std::size_t maxc; - std::size_t minc; + subtree_elements_counts(size_type ma, size_type mi) : maxc(ma), minc(mi) {} + size_type maxc; + size_type minc; }; template inline static - internal_element per_level(EIt first, EIt last, Box const& hint_box, std::size_t values_count, subtree_elements_counts const& subtree_counts, - parameters_type const& parameters, Translator const& translator, Allocators & allocators) + internal_element per_level(EIt first, EIt last, + box_type const& hint_box, + size_type values_count, + subtree_elements_counts const& subtree_counts, + parameters_type const& parameters, + translator_type const& translator, + allocators_type & allocators) { - BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast(std::distance(first, last)) == values_count, + BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast(std::distance(first, last)) == values_count, "unexpected parameters"); if ( subtree_counts.maxc <= 1 ) @@ -270,7 +283,7 @@ private: // if !root check m_parameters.get_min_elements() <= count // create new leaf node - node_pointer n = rtree::create_node::apply(allocators); // MAY THROW (A) + node_pointer n = rtree::create_node::apply(allocators); // MAY THROW (A) subtree_destroyer auto_remover(n, allocators); leaf & l = rtree::get(*n); @@ -279,8 +292,8 @@ private: // calculate values box and copy values // initialize the box explicitly to avoid GCC-4.4 uninitialized variable warnings with O2 - expandable_box elements_box(translator(*(first->second)), - detail::get_strategy(parameters)); + expandable_box elements_box(translator(*(first->second)), + detail::get_strategy(parameters)); rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C) for ( ++first ; first != last ; ++first ) { @@ -301,7 +314,7 @@ private: if ( BOOST_GEOMETRY_CONDITION(( ! index::detail::is_bounding_geometry < - typename indexable_type::type + typename indexable_type::type >::value )) ) { elements_box.expand_by_epsilon(); @@ -318,15 +331,15 @@ private: next_subtree_counts.minc /= parameters.get_max_elements(); // create new internal node - node_pointer n = rtree::create_node::apply(allocators); // MAY THROW (A) + node_pointer n = rtree::create_node::apply(allocators); // MAY THROW (A) subtree_destroyer auto_remover(n, allocators); internal_node & in = rtree::get(*n); // reserve space for values - std::size_t nodes_count = calculate_nodes_count(values_count, subtree_counts); + size_type nodes_count = calculate_nodes_count(values_count, subtree_counts); rtree::elements(in).reserve(nodes_count); // MAY THROW (A) // calculate values box and copy values - expandable_box elements_box(detail::get_strategy(parameters)); + expandable_box elements_box(detail::get_strategy(parameters)); per_level_packets(first, last, hint_box, values_count, subtree_counts, next_subtree_counts, rtree::elements(in), elements_box, @@ -337,14 +350,18 @@ private: } template inline static - void per_level_packets(EIt first, EIt last, Box const& hint_box, - std::size_t values_count, + void per_level_packets(EIt first, EIt last, + box_type const& hint_box, + size_type values_count, subtree_elements_counts const& subtree_counts, subtree_elements_counts const& next_subtree_counts, - internal_elements & elements, ExpandableBox & elements_box, - parameters_type const& parameters, Translator const& translator, Allocators & allocators) + internal_elements & elements, + ExpandableBox & elements_box, + parameters_type const& parameters, + translator_type const& translator, + allocators_type & allocators) { - BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast(std::distance(first, last)) == values_count, + BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast(std::distance(first, last)) == values_count, "unexpected parameters"); BOOST_GEOMETRY_INDEX_ASSERT(subtree_counts.minc <= values_count, @@ -369,13 +386,13 @@ private: return; } - std::size_t median_count = calculate_median_count(values_count, subtree_counts); + size_type median_count = calculate_median_count(values_count, subtree_counts); EIt median = first + median_count; coordinate_type greatest_length; std::size_t greatest_dim_index = 0; pack_utils::biggest_edge::apply(hint_box, greatest_length, greatest_dim_index); - Box left, right; + box_type left, right; pack_utils::nth_element_and_half_boxes<0, dimension> ::apply(first, median, last, hint_box, left, right, greatest_dim_index); @@ -390,14 +407,14 @@ private: } inline static - subtree_elements_counts calculate_subtree_elements_counts(std::size_t elements_count, parameters_type const& parameters, size_type & leafs_level) + subtree_elements_counts calculate_subtree_elements_counts(size_type elements_count, parameters_type const& parameters, size_type & leafs_level) { boost::ignore_unused(parameters); subtree_elements_counts res(1, 1); leafs_level = 0; - std::size_t smax = parameters.get_max_elements(); + size_type smax = parameters.get_max_elements(); for ( ; smax < elements_count ; smax *= parameters.get_max_elements(), ++leafs_level ) res.maxc = smax; @@ -407,15 +424,15 @@ private: } inline static - std::size_t calculate_nodes_count(std::size_t count, - subtree_elements_counts const& subtree_counts) + size_type calculate_nodes_count(size_type count, + subtree_elements_counts const& subtree_counts) { - std::size_t n = count / subtree_counts.maxc; - std::size_t r = count % subtree_counts.maxc; + size_type n = count / subtree_counts.maxc; + size_type r = count % subtree_counts.maxc; if ( 0 < r && r < subtree_counts.minc ) { - std::size_t count_minus_min = count - subtree_counts.minc; + size_type count_minus_min = count - subtree_counts.minc; n = count_minus_min / subtree_counts.maxc; r = count_minus_min % subtree_counts.maxc; ++n; @@ -428,14 +445,14 @@ private: } inline static - std::size_t calculate_median_count(std::size_t count, - subtree_elements_counts const& subtree_counts) + size_type calculate_median_count(size_type count, + subtree_elements_counts const& subtree_counts) { // e.g. for max = 5, min = 2, count = 52, subtree_max = 25, subtree_min = 10 - std::size_t n = count / subtree_counts.maxc; // e.g. 52 / 25 = 2 - std::size_t r = count % subtree_counts.maxc; // e.g. 52 % 25 = 2 - std::size_t median_count = (n / 2) * subtree_counts.maxc; // e.g. 2 / 2 * 25 = 25 + size_type n = count / subtree_counts.maxc; // e.g. 52 / 25 = 2 + size_type r = count % subtree_counts.maxc; // e.g. 52 % 25 = 2 + size_type median_count = (n / 2) * subtree_counts.maxc; // e.g. 2 / 2 * 25 = 25 if ( 0 != r ) // e.g. 0 != 2 { @@ -446,7 +463,7 @@ private: } else // r < subtree_counts.second // e.g. 2 < 10 == true { - std::size_t count_minus_min = count - subtree_counts.minc; // e.g. 52 - 10 = 42 + size_type count_minus_min = count - subtree_counts.minc; // e.g. 52 - 10 = 42 n = count_minus_min / subtree_counts.maxc; // e.g. 42 / 25 = 1 r = count_minus_min % subtree_counts.maxc; // e.g. 42 % 25 = 17 if ( r == 0 ) // e.g. false diff --git a/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp index 3fd51d56f..05e71fb0e 100644 --- a/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp @@ -92,29 +92,32 @@ inline void pick_seeds(Elements const& elements, } // namespace quadratic -template -struct redistribute_elements +template +struct redistribute_elements { - typedef typename Options::parameters_type parameters_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 rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef typename index::detail::default_content_result::type content_type; + typedef typename index::detail::default_content_result::type content_type; template static inline void apply(Node & n, Node & second_node, - Box & box1, - Box & box2, + box_type & box1, + box_type & box2, parameters_type const& parameters, - Translator const& translator, - Allocators & allocators) + translator_type const& translator, + allocators_type & allocators) { typedef typename rtree::elements_type::type elements_type; typedef typename elements_type::value_type element_type; - typedef typename rtree::element_indexable_type::type indexable_type; + typedef typename rtree::element_indexable_type::type indexable_type; elements_type & elements1 = rtree::elements(n); elements_type & elements2 = rtree::elements(second_node); @@ -131,7 +134,7 @@ struct redistribute_elements(elements_copy, parameters, translator, seed1, seed2); + quadratic::pick_seeds(elements_copy, parameters, translator, seed1, seed2); // prepare nodes' elements containers elements1.clear(); @@ -249,7 +252,7 @@ struct redistribute_elements::apply(elements_backup, allocators); + rtree::destroy_elements::apply(elements_backup, allocators); //elements_backup.clear(); BOOST_RETHROW // RETHROW, BASIC @@ -261,14 +264,14 @@ struct redistribute_elements static inline It pick_next(It first, It last, - Box const& box1, Box const& box2, + box_type const& box1, box_type const& box2, content_type const& content1, content_type const& content2, - Translator const& translator, + translator_type const& translator, typename index::detail::strategy_type::type const& strategy, content_type & out_content_increase1, content_type & out_content_increase2) { typedef typename boost::iterator_value::type element_type; - typedef typename rtree::element_indexable_type::type indexable_type; + typedef typename rtree::element_indexable_type::type indexable_type; content_type greatest_content_incrase_diff = 0; It out_it = first; @@ -281,8 +284,8 @@ struct redistribute_elements +template class spatial_query_iterator { - typedef typename Options::parameters_type parameters_type; - typedef visitors::spatial_query_incremental visitor_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::allocators_type allocators_type; + + typedef visitors::spatial_query_incremental visitor_type; typedef typename visitor_type::node_pointer node_pointer; public: typedef std::forward_iterator_tag iterator_category; - typedef Value value_type; - typedef typename Allocators::const_reference reference; - typedef typename Allocators::difference_type difference_type; - typedef typename Allocators::const_pointer pointer; + typedef typename MembersHolder::value_type value_type; + typedef typename allocators_type::const_reference reference; + typedef typename allocators_type::difference_type difference_type; + typedef typename allocators_type::const_pointer pointer; inline spatial_query_iterator() {} - inline spatial_query_iterator(parameters_type const& par, Translator const& t, Predicates const& p) + inline spatial_query_iterator(parameters_type const& par, translator_type const& t, Predicates const& p) : m_visitor(par, t, p) {} - inline spatial_query_iterator(node_pointer root, parameters_type const& par, Translator const& t, Predicates const& p) + inline spatial_query_iterator(node_pointer root, parameters_type const& par, translator_type const& t, Predicates const& p) : m_visitor(par, t, p) { m_visitor.initialize(root); @@ -113,12 +120,12 @@ public: return l.m_visitor == r.m_visitor; } - friend bool operator==(spatial_query_iterator const& l, end_query_iterator const& /*r*/) + friend bool operator==(spatial_query_iterator const& l, end_query_iterator const& /*r*/) { return l.m_visitor.is_end(); } - friend bool operator==(end_query_iterator const& /*l*/, spatial_query_iterator const& r) + friend bool operator==(end_query_iterator const& /*l*/, spatial_query_iterator const& r) { return r.m_visitor.is_end(); } @@ -127,28 +134,31 @@ private: visitor_type m_visitor; }; -template +template class distance_query_iterator { - typedef typename Options::parameters_type parameters_type; - typedef visitors::distance_query_incremental visitor_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::allocators_type allocators_type; + + typedef visitors::distance_query_incremental visitor_type; typedef typename visitor_type::node_pointer node_pointer; public: typedef std::forward_iterator_tag iterator_category; - typedef Value value_type; - typedef typename Allocators::const_reference reference; - typedef typename Allocators::difference_type difference_type; - typedef typename Allocators::const_pointer pointer; + typedef typename MembersHolder::value_type value_type; + typedef typename allocators_type::const_reference reference; + typedef typename allocators_type::difference_type difference_type; + typedef typename allocators_type::const_pointer pointer; inline distance_query_iterator() {} - inline distance_query_iterator(parameters_type const& par, Translator const& t, Predicates const& p) + inline distance_query_iterator(parameters_type const& par, translator_type const& t, Predicates const& p) : m_visitor(par, t, p) {} - inline distance_query_iterator(node_pointer root, parameters_type const& par, Translator const& t, Predicates const& p) + inline distance_query_iterator(node_pointer root, parameters_type const& par, translator_type const& t, Predicates const& p) : m_visitor(par, t, p) { m_visitor.initialize(root); @@ -182,12 +192,12 @@ public: return l.m_visitor == r.m_visitor; } - friend bool operator==(distance_query_iterator const& l, end_query_iterator const& /*r*/) + friend bool operator==(distance_query_iterator const& l, end_query_iterator const& /*r*/) { return l.m_visitor.is_end(); } - friend bool operator==(end_query_iterator const& /*l*/, distance_query_iterator const& r) + friend bool operator==(end_query_iterator const& /*l*/, distance_query_iterator const& r) { return r.m_visitor.is_end(); } diff --git a/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp b/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp index 209f6ebb2..7ba5f0f99 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp @@ -33,19 +33,20 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { -template -class choose_next_node +template +class choose_next_node { - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::box_type box_type; + typedef typename MembersHolder::parameters_type parameters_type; + + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; typedef typename rtree::elements_type::type children_type; typedef typename children_type::value_type child_type; - typedef typename Options::parameters_type parameters_type; - - typedef typename index::detail::default_content_result::type content_type; + typedef typename index::detail::default_content_result::type content_type; public: template @@ -109,7 +110,7 @@ private: child_type const& ch_i = children[i]; // expanded child node's box - Box box_exp(ch_i.first); + box_type box_exp(ch_i.first); index::detail::expand(box_exp, indexable, strategy); // areas difference @@ -183,7 +184,7 @@ private: child_type const& ch_i = children[i]; - Box box_exp(ch_i.first); + box_type box_exp(ch_i.first); // calculate expanded box of child node ch_i index::detail::expand(box_exp, indexable, strategy); @@ -238,7 +239,7 @@ private: child_type const& ch_i = children[i]; // expanded child node's box - Box box_exp(ch_i.first); + box_type box_exp(ch_i.first); index::detail::expand(box_exp, indexable, strategy); // areas difference diff --git a/include/boost/geometry/index/detail/rtree/rstar/insert.hpp b/include/boost/geometry/index/detail/rtree/rstar/insert.hpp index 73a5ccefc..8a9cb7166 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/insert.hpp @@ -56,15 +56,18 @@ struct comparable_distance_point_point } }; -template +template class remove_elements_to_reinsert { public: - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + 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 Options::parameters_type parameters_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; @@ -75,12 +78,12 @@ public: internal_node_pointer parent, size_t current_child_index, parameters_type const& parameters, - Translator const& translator, - Allocators & allocators) + translator_type const& translator, + allocators_type & allocators) { typedef typename rtree::elements_type::type elements_type; typedef typename elements_type::value_type element_type; - typedef typename geometry::point_type::type point_type; + typedef typename geometry::point_type::type point_type; typedef typename index::detail::strategy_type::type strategy_type; // TODO: awulkiew - change second point_type to the point type of the Indexable? typedef rstar::comparable_distance_point_point @@ -159,7 +162,7 @@ public: for ( typename sorted_elements_type::iterator it = sorted_elements.begin() ; it != sorted_elements.end() ; ++it ) { - destroy_element::apply(it->second, allocators); + destroy_element::apply(it->second, allocators); } BOOST_RETHROW // RETHROW @@ -187,48 +190,69 @@ private: } }; -template +template +< + size_t InsertIndex, + typename Element, + typename MembersHolder, + bool IsValue = boost::is_same::value +> struct level_insert_elements_type { typedef typename rtree::elements_type< - typename rtree::internal_node::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 -struct level_insert_elements_type<0, Value, Value, Options, Box, Allocators> +template +struct level_insert_elements_type<0, Value, MembersHolder, true> { typedef typename rtree::elements_type< - typename rtree::leaf::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 +template struct level_insert_base - : public detail::insert + : public detail::insert { - typedef detail::insert base; + typedef detail::insert base; typedef typename base::node node; typedef typename base::internal_node internal_node; typedef typename base::leaf leaf; - typedef typename level_insert_elements_type::type elements_type; + typedef typename level_insert_elements_type::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 Options::parameters_type parameters_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::node_pointer node_pointer; - typedef typename Allocators::size_type size_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 const& translator, - Allocators & allocators, + 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) @@ -249,7 +273,7 @@ struct level_insert_base { // NOTE: exception-safety // After an exception result_elements may contain garbage, don't use it - rstar::remove_elements_to_reinsert::apply( + rstar::remove_elements_to_reinsert::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) @@ -287,43 +311,51 @@ struct level_insert_base inline void recalculate_aabb(Node const& n) const { base::m_traverse_data.current_element().first = - elements_box(rtree::elements(n).begin(), rtree::elements(n).end(), - base::m_translator, - index::detail::get_strategy(base::m_parameters)); + elements_box(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(rtree::elements(n).begin(), rtree::elements(n).end(), - base::m_translator, - index::detail::get_strategy(base::m_parameters)); + values_box(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 +template +< + size_t InsertIndex, + typename Element, + typename MembersHolder, + bool IsValue = boost::is_same::value +> struct level_insert - : public level_insert_base + : public level_insert_base { - typedef level_insert_base base; + typedef level_insert_base base; typedef typename base::node node; typedef typename base::internal_node internal_node; typedef typename base::leaf leaf; - typedef typename Options::parameters_type parameters_type; + typedef typename base::parameters_type parameters_type; + typedef typename base::translator_type translator_type; + typedef typename base::allocators_type allocators_type; - typedef typename Allocators::node_pointer node_pointer; - typedef typename Allocators::size_type size_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 const& translator, - Allocators & allocators, + translator_type const& translator, + allocators_type & allocators, size_type relative_level) : base(root, leafs_level, element, parameters, translator, allocators, relative_level) {} @@ -362,7 +394,7 @@ struct level_insert // NOTE: exception-safety // if the insert fails above, the element won't be stored in the tree, so delete it - rtree::visitors::destroy del_v(base::m_element.second, base::m_allocators); + rtree::visitors::destroy del_v(base::m_element.second, base::m_allocators); rtree::apply_visitor(del_v, *base::m_element.second); BOOST_RETHROW // RETHROW @@ -390,26 +422,29 @@ struct level_insert } }; -template -struct level_insert - : public level_insert_base +template +struct level_insert + : public level_insert_base { - typedef level_insert_base base; + typedef level_insert_base base; typedef typename base::node node; typedef typename base::internal_node internal_node; typedef typename base::leaf leaf; - typedef typename Options::parameters_type parameters_type; + 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 Allocators::node_pointer node_pointer; - typedef typename Allocators::size_type size_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 const& v, + value_type const& v, parameters_type const& parameters, - Translator const& translator, - Allocators & allocators, + translator_type const& translator, + allocators_type & allocators, size_type relative_level) : base(root, leafs_level, v, parameters, translator, allocators, relative_level) {} @@ -446,26 +481,29 @@ struct level_insert -struct level_insert<0, Value, Value, Options, Translator, Box, Allocators> - : public level_insert_base<0, Value, Value, Options, Translator, Box, Allocators> +template +struct level_insert<0, Value, MembersHolder, true> + : public level_insert_base<0, typename MembersHolder::value_type, MembersHolder> { - typedef level_insert_base<0, Value, Value, Options, Translator, Box, Allocators> base; + 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 Options::parameters_type parameters_type; + 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 Allocators::node_pointer node_pointer; - typedef typename Allocators::size_type size_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 const& v, + value_type const& v, parameters_type const& parameters, - Translator const& translator, - Allocators & allocators, + translator_type const& translator, + allocators_type & allocators, size_type relative_level) : base(root, leafs_level, v, parameters, translator, allocators, relative_level) {} @@ -505,26 +543,28 @@ struct level_insert<0, Value, Value, Options, Translator, Box, Allocators> // 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 -class insert - : public rtree::visitor::type +template +class insert + : public MembersHolder::visitor { - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::allocators_type allocators_type; - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef typename Allocators::node_pointer node_pointer; - typedef typename Allocators::size_type size_type; + 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 const& translator, - Allocators & allocators, + 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) @@ -539,7 +579,7 @@ public: // 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, Value, Options, Translator, Box, Allocators> lins_v( + 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) @@ -551,7 +591,7 @@ public: } else { - visitors::insert ins_v( + visitors::insert 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); @@ -566,7 +606,7 @@ public: // 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, Value, Options, Translator, Box, Allocators> lins_v( + 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) @@ -576,7 +616,7 @@ public: } else { - visitors::insert ins_v( + visitors::insert 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); @@ -593,7 +633,7 @@ private: typename Elements::reverse_iterator it = elements.rbegin(); for ( ; it != elements.rend() ; ++it) { - rstar::level_insert<1, element_type, Value, Options, Translator, Box, Allocators> lins_v( + 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 @@ -604,7 +644,7 @@ private: { ++it; for ( ; it != elements.rend() ; ++it) - rtree::destroy_element::apply(*it, m_allocators); + rtree::destroy_element::apply(*it, m_allocators); BOOST_RETHROW // RETHROW } BOOST_CATCH_END @@ -624,11 +664,11 @@ private: Element const& m_element; parameters_type const& m_parameters; - Translator const& m_translator; + translator_type const& m_translator; size_type m_relative_level; - Allocators & m_allocators; + allocators_type & m_allocators; }; }}} // namespace detail::rtree::visitors diff --git a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp index 0b19a9e9b..f8093e2f2 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp @@ -397,29 +397,32 @@ struct nth_element } // namespace rstar -template -struct redistribute_elements +template +struct redistribute_elements { - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + 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 Options::parameters_type parameters_type; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - static const size_t dimension = geometry::dimension::value; + static const size_t dimension = geometry::dimension::value; - typedef typename index::detail::default_margin_result::type margin_type; - typedef typename index::detail::default_content_result::type content_type; + typedef typename index::detail::default_margin_result::type margin_type; + typedef typename index::detail::default_content_result::type content_type; template static inline void apply( Node & n, Node & second_node, - Box & box1, - Box & box2, + box_type & box1, + box_type & box2, parameters_type const& parameters, - Translator const& translator, - Allocators & allocators) + translator_type const& translator, + allocators_type & allocators) { typedef typename rtree::elements_type::type elements_type; typedef typename elements_type::value_type element_type; @@ -446,7 +449,7 @@ struct redistribute_elements + rstar::choose_split_axis_and_index ::apply(elements_copy, split_axis, split_corner, split_index, smallest_sum_of_margins, smallest_overlap, smallest_content, @@ -479,10 +482,10 @@ struct redistribute_elements(elements1.begin(), elements1.end(), - translator, strategy); - box2 = rtree::elements_box(elements2.begin(), elements2.end(), - translator, strategy); + box1 = rtree::elements_box(elements1.begin(), elements1.end(), + translator, strategy); + box2 = rtree::elements_box(elements2.begin(), elements2.end(), + translator, strategy); } BOOST_CATCH(...) { @@ -490,7 +493,7 @@ struct redistribute_elements::apply(elements_backup, allocators); + rtree::destroy_elements::apply(elements_backup, allocators); //elements_backup.clear(); BOOST_RETHROW // RETHROW, BASIC diff --git a/include/boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp b/include/boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp index b5fe5a0e2..64c4d7470 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp @@ -22,17 +22,19 @@ namespace boost { namespace geometry { namespace index { namespace detail { name namespace visitors { -template +template class are_boxes_ok - : public rtree::visitor::type + : public MembersHolder::visitor_const { - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::box_type box_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; public: - are_boxes_ok(parameters_type const& parameters, Translator const& tr, bool exact_match) + are_boxes_ok(parameters_type const& parameters, translator_type const& tr, bool exact_match) : result(false), m_parameters(parameters), m_tr(tr), m_is_root(true), m_exact_match(exact_match) {} @@ -47,7 +49,7 @@ public: return; } - Box box_bckup = m_box; + box_type box_bckup = m_box; bool is_root_bckup = m_is_root; m_is_root = false; @@ -66,8 +68,8 @@ public: m_box = box_bckup; m_is_root = is_root_bckup; - Box box_exp = rtree::elements_box(elements.begin(), elements.end(), m_tr, - index::detail::get_strategy(m_parameters)); + box_type box_exp = rtree::elements_box(elements.begin(), elements.end(), m_tr, + index::detail::get_strategy(m_parameters)); if ( m_exact_match ) result = m_is_root || geometry::equals(box_exp, m_box); @@ -89,8 +91,8 @@ public: return; } - Box box_exp = rtree::values_box(elements.begin(), elements.end(), m_tr, - index::detail::get_strategy(m_parameters)); + box_type box_exp = rtree::values_box(elements.begin(), elements.end(), m_tr, + index::detail::get_strategy(m_parameters)); if ( m_exact_match ) result = geometry::equals(box_exp, m_box); @@ -105,8 +107,8 @@ public: private: parameters_type const& m_parameters; - Translator const& m_tr; - Box m_box; + translator_type const& m_tr; + box_type m_box; bool m_is_root; bool m_exact_match; }; @@ -120,11 +122,7 @@ bool are_boxes_ok(Rtree const& tree, bool exact_match = true) RTV rtv(tree); visitors::are_boxes_ok< - typename RTV::value_type, - typename RTV::options_type, - typename RTV::translator_type, - typename RTV::box_type, - typename RTV::allocators_type + typename RTV::members_holder > v(tree.parameters(), rtv.translator(), exact_match); rtv.apply_visitor(v); diff --git a/include/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp b/include/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp index 10a1bec6a..3e7ff6ed3 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2019. +// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// 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) @@ -17,13 +21,14 @@ namespace boost { namespace geometry { namespace index { namespace detail { name namespace visitors { -template +template class are_counts_ok - : public rtree::visitor::type + : public MembersHolder::visitor_const { - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::parameters_type parameters_type; + + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; public: inline are_counts_ok(parameters_type const& parameters) @@ -94,10 +99,7 @@ bool are_counts_ok(Rtree const& tree) RTV rtv(tree); visitors::are_counts_ok< - typename RTV::value_type, - typename RTV::options_type, - typename RTV::box_type, - typename RTV::allocators_type + typename RTV::members_holder > v(tree.parameters()); rtv.apply_visitor(v); diff --git a/include/boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp b/include/boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp index 4860dbcb9..a76cf38bf 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2019. +// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// 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) @@ -17,12 +21,12 @@ namespace boost { namespace geometry { namespace index { namespace detail { name namespace visitors { -template +template class are_levels_ok - : public rtree::visitor::type + : public MembersHolder::visitor_const { - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; public: inline are_levels_ok() @@ -93,10 +97,7 @@ bool are_levels_ok(Rtree const& tree) RTV rtv(tree); visitors::are_levels_ok< - typename RTV::value_type, - typename RTV::options_type, - typename RTV::box_type, - typename RTV::allocators_type + typename RTV::members_holder > v; rtv.apply_visitor(v); diff --git a/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp b/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp index 84201b6af..25c08dba0 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2019. +// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// 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) @@ -114,16 +118,20 @@ namespace rtree { namespace utilities { namespace visitors { -template -struct gl_draw : public rtree::visitor::type +template +struct gl_draw + : public MembersHolder::visitor_const { - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::box_type box_type; + typedef typename MembersHolder::translator_type translator_type; - inline gl_draw(Translator const& t, + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; + + inline gl_draw(translator_type const& t, size_t level_first = 0, size_t level_last = (std::numeric_limits::max)(), - typename coordinate_type::type z_coord_level_multiplier = 1 + typename coordinate_type::type z_coord_level_multiplier = 1 ) : tr(t) , level_f(level_first) @@ -197,10 +205,10 @@ struct gl_draw : public rtree::visitor::type z_mul; + typename coordinate_type::type z_mul; size_t level; }; @@ -226,11 +234,7 @@ void gl_draw(Rtree const& tree, } visitors::gl_draw< - typename RTV::value_type, - typename RTV::options_type, - typename RTV::translator_type, - typename RTV::box_type, - typename RTV::allocators_type + typename RTV::members_holder > gl_draw_v(rtv.translator(), level_first, level_last, z_coord_level_multiplier); rtv.apply_visitor(gl_draw_v); diff --git a/include/boost/geometry/index/detail/rtree/utilities/print.hpp b/include/boost/geometry/index/detail/rtree/utilities/print.hpp index 4c42659c6..d512add24 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/print.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/print.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2019. +// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// 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) @@ -129,13 +133,16 @@ namespace rtree { namespace utilities { namespace visitors { -template -struct print : public rtree::visitor::type +template +struct print + : public MembersHolder::visitor_const { - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::translator_type translator_type; - inline print(std::ostream & o, Translator const& t) + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; + + inline print(std::ostream & o, translator_type const& t) : os(o), tr(t), level(0) {} @@ -189,7 +196,7 @@ struct print : public rtree::visitor print_v(os, rtv.translator()); rtv.apply_visitor(print_v); } diff --git a/include/boost/geometry/index/detail/rtree/utilities/statistics.hpp b/include/boost/geometry/index/detail/rtree/utilities/statistics.hpp index bbaed8100..169253510 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/statistics.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/statistics.hpp @@ -5,6 +5,10 @@ // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2013 Mateusz Loskot, London, UK. // +// This file was modified by Oracle on 2019. +// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// 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) @@ -19,11 +23,12 @@ namespace boost { namespace geometry { namespace index { namespace detail { name namespace visitors { -template -struct statistics : public rtree::visitor::type +template +struct statistics + : public MembersHolder::visitor_const { - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; inline statistics() : level(0) @@ -89,10 +94,7 @@ statistics(Rtree const& tree) RTV rtv(tree); visitors::statistics< - typename RTV::value_type, - typename RTV::options_type, - typename RTV::box_type, - typename RTV::allocators_type + typename RTV::members_holder > stats_v; rtv.apply_visitor(stats_v); diff --git a/include/boost/geometry/index/detail/rtree/utilities/view.hpp b/include/boost/geometry/index/detail/rtree/utilities/view.hpp index 6dbbd07bf..edaa045ac 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/view.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/view.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2019. +// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// 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) @@ -19,6 +23,8 @@ template class view { public: + typedef typename Rtree::members_holder members_holder; + typedef typename Rtree::size_type size_type; typedef typename Rtree::translator_type translator_type; diff --git a/include/boost/geometry/index/detail/rtree/visitors/children_box.hpp b/include/boost/geometry/index/detail/rtree/visitors/children_box.hpp index 0d26a79c3..1dde1408c 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/children_box.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/children_box.hpp @@ -19,17 +19,21 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { -template +template class children_box - : public rtree::visitor::type + : public MembersHolder::visitor_const { - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::box_type box_type; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; public: - inline children_box(Box & result, parameters_type const& parameters, Translator const& tr) + inline children_box(box_type & result, + parameters_type const& parameters, + translator_type const& tr) : m_result(result), m_parameters(parameters), m_tr(tr) {} @@ -38,8 +42,8 @@ public: typedef typename rtree::elements_type::type elements_type; elements_type const& elements = rtree::elements(n); - m_result = rtree::elements_box(elements.begin(), elements.end(), m_tr, - index::detail::get_strategy(m_parameters)); + m_result = rtree::elements_box(elements.begin(), elements.end(), m_tr, + index::detail::get_strategy(m_parameters)); } inline void operator()(leaf const& n) @@ -47,14 +51,14 @@ public: typedef typename rtree::elements_type::type elements_type; elements_type const& elements = rtree::elements(n); - m_result = rtree::values_box(elements.begin(), elements.end(), m_tr, - index::detail::get_strategy(m_parameters)); + m_result = rtree::values_box(elements.begin(), elements.end(), m_tr, + index::detail::get_strategy(m_parameters)); } private: - Box & m_result; + box_type & m_result; parameters_type const& m_parameters; - Translator const& m_tr; + translator_type const& m_tr; }; }}} // namespace detail::rtree::visitors diff --git a/include/boost/geometry/index/detail/rtree/visitors/copy.hpp b/include/boost/geometry/index/detail/rtree/visitors/copy.hpp index 86ffc99ca..1c3229b07 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/copy.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/copy.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2019. +// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// 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) @@ -15,26 +19,28 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { -template +template class copy - : public rtree::visitor::type + : public MembersHolder::visitor { + 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 rtree::subtree_destroyer subtree_destroyer; + typedef typename allocators_type::node_pointer node_pointer; + public: - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; - - typedef rtree::subtree_destroyer subtree_destroyer; - typedef typename Allocators::node_pointer node_pointer; - - explicit inline copy(Allocators & allocators) + explicit inline copy(allocators_type & allocators) : result(0) , m_allocators(allocators) {} inline void operator()(internal_node & n) { - node_pointer raw_new_node = rtree::create_node::apply(m_allocators); // MAY THROW, STRONG (N: alloc) + node_pointer raw_new_node = rtree::create_node::apply(m_allocators); // MAY THROW, STRONG (N: alloc) subtree_destroyer new_node(raw_new_node, m_allocators); typedef typename rtree::elements_type::type elements_type; @@ -61,7 +67,7 @@ public: inline void operator()(leaf & l) { - node_pointer raw_new_node = rtree::create_node::apply(m_allocators); // MAY THROW, STRONG (N: alloc) + node_pointer raw_new_node = rtree::create_node::apply(m_allocators); // MAY THROW, STRONG (N: alloc) subtree_destroyer new_node(raw_new_node, m_allocators); typedef typename rtree::elements_type::type elements_type; @@ -82,7 +88,7 @@ public: node_pointer result; private: - Allocators & m_allocators; + allocators_type & m_allocators; }; }}} // namespace detail::rtree::visitors diff --git a/include/boost/geometry/index/detail/rtree/visitors/count.hpp b/include/boost/geometry/index/detail/rtree/visitors/count.hpp index 2cdbd8c0e..c166fe3e3 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/count.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/count.hpp @@ -49,19 +49,21 @@ struct count_helper } }; -template +template struct count - : public rtree::visitor::type + : public MembersHolder::visitor_const { - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::value_type value_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef count_helper count_help; + typedef count_helper count_help; - inline count(ValueOrIndexable const& vori, parameters_type const& parameters, Translator const& t) + inline count(ValueOrIndexable const& vori, parameters_type const& parameters, translator_type const& t) : value_or_indexable(vori), m_parameters(parameters), tr(t), found_count(0) {} @@ -103,8 +105,8 @@ struct count ValueOrIndexable const& value_or_indexable; parameters_type const& m_parameters; - Translator const& tr; - typename Allocators::size_type found_count; + translator_type const& tr; + typename MembersHolder::size_type found_count; }; }}} // namespace detail::rtree::visitors diff --git a/include/boost/geometry/index/detail/rtree/visitors/destroy.hpp b/include/boost/geometry/index/detail/rtree/visitors/destroy.hpp index b4a800eac..fd4315d42 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/destroy.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/destroy.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2019. +// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// 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) @@ -15,18 +19,19 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { -template +template class destroy - : public rtree::visitor::type + : public MembersHolder::visitor { public: - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef typename Allocators::node_pointer node_pointer; + typedef typename MembersHolder::allocators_type allocators_type; + typedef typename MembersHolder::node_pointer node_pointer; - inline destroy(node_pointer root_node, Allocators & allocators) + inline destroy(node_pointer root_node, allocators_type & allocators) : m_current_node(root_node) , m_allocators(allocators) {} @@ -48,7 +53,7 @@ public: it->second = 0; } - rtree::destroy_node::apply(m_allocators, node_to_destroy); + rtree::destroy_node::apply(m_allocators, node_to_destroy); } inline void operator()(leaf & l) @@ -56,12 +61,12 @@ public: boost::ignore_unused(l); BOOST_GEOMETRY_INDEX_ASSERT(&l == &rtree::get(*m_current_node), "invalid pointers"); - rtree::destroy_node::apply(m_allocators, m_current_node); + rtree::destroy_node::apply(m_allocators, m_current_node); } private: node_pointer m_current_node; - Allocators & m_allocators; + allocators_type & m_allocators; }; }}} // namespace detail::rtree::visitors diff --git a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp index 20a954dc4..edf47f90b 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/distance_query.hpp @@ -93,39 +93,41 @@ private: std::vector< std::pair > m_neighbors; }; -template < - typename Value, - typename Options, - typename Translator, - typename Box, - typename Allocators, +template +< + typename MembersHolder, typename Predicates, unsigned DistancePredicateIndex, typename OutIter > class distance_query - : public rtree::visitor::type + : public MembersHolder::visitor_const { public: - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::value_type value_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 index::detail::strategy_type::type strategy_type; - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; typedef index::detail::predicates_element nearest_predicate_access; typedef typename nearest_predicate_access::type nearest_predicate_type; - typedef typename indexable_type::type indexable_type; + typedef typename indexable_type::type indexable_type; typedef index::detail::calculate_distance calculate_value_distance; - typedef index::detail::calculate_distance calculate_node_distance; + typedef index::detail::calculate_distance calculate_node_distance; typedef typename calculate_value_distance::result_type value_distance_type; typedef typename calculate_node_distance::result_type node_distance_type; static const unsigned predicates_len = index::detail::predicates_length::value; - inline distance_query(parameters_type const& parameters, Translator const& translator, Predicates const& pred, OutIter out_it) + inline distance_query(parameters_type const& parameters, translator_type const& translator, Predicates const& pred, OutIter out_it) : m_parameters(parameters), m_translator(translator) , m_pred(pred) , m_result(nearest_predicate_access::get(m_pred).count, out_it) @@ -139,7 +141,7 @@ public: // array of active nodes typedef typename index::detail::rtree::container_from_elements_type< elements_type, - std::pair + std::pair >::type active_branch_list_type; active_branch_list_type active_branch_list; @@ -261,15 +263,15 @@ public: private: static inline bool abl_less( - std::pair const& p1, - std::pair const& p2) + std::pair const& p1, + std::pair const& p2) { return p1.first < p2.first; } //static inline bool abl_greater( - // std::pair const& p1, - // std::pair const& p2) + // std::pair const& p1, + // std::pair const& p2) //{ // return p1.first > p2.first; //} @@ -286,46 +288,47 @@ private: } parameters_type const& m_parameters; - Translator const& m_translator; + translator_type const& m_translator; Predicates m_pred; - distance_query_result m_result; + distance_query_result m_result; strategy_type m_strategy; }; template < - typename Value, - typename Options, - typename Translator, - typename Box, - typename Allocators, + typename MembersHolder, typename Predicates, unsigned DistancePredicateIndex > class distance_query_incremental - : public rtree::visitor::type + : public MembersHolder::visitor_const { public: - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::value_type value_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 index::detail::strategy_type::type strategy_type; - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; typedef index::detail::predicates_element nearest_predicate_access; typedef typename nearest_predicate_access::type nearest_predicate_type; - typedef typename indexable_type::type indexable_type; + typedef typename indexable_type::type indexable_type; typedef index::detail::calculate_distance calculate_value_distance; - typedef index::detail::calculate_distance calculate_node_distance; + typedef index::detail::calculate_distance calculate_node_distance; typedef typename calculate_value_distance::result_type value_distance_type; typedef typename calculate_node_distance::result_type node_distance_type; - typedef typename Allocators::size_type size_type; - typedef typename Allocators::const_reference const_reference; - typedef typename Allocators::node_pointer node_pointer; + typedef typename allocators_type::size_type size_type; + typedef typename allocators_type::const_reference const_reference; + typedef typename allocators_type::node_pointer node_pointer; static const unsigned predicates_len = index::detail::predicates_length::value; @@ -362,7 +365,7 @@ public: // , m_strategy_type() {} - inline distance_query_incremental(parameters_type const& params, Translator const& translator, Predicates const& pred) + inline distance_query_incremental(parameters_type const& params, translator_type const& translator, Predicates const& pred) : m_translator(::boost::addressof(translator)) , m_pred(pred) , current_neighbor((std::numeric_limits::max)()) @@ -552,14 +555,14 @@ public: } private: - static inline bool abl_less(std::pair const& p1, - std::pair const& p2) + static inline bool abl_less(std::pair const& p1, + std::pair const& p2) { return p1.first < p2.first; } - static inline bool neighbors_less(std::pair const& p1, - std::pair const& p2) + static inline bool neighbors_less(std::pair const& p1, + std::pair const& p2) { return p1.first < p2.first; } @@ -597,12 +600,12 @@ private: return nearest_predicate_access::get(m_pred); } - const Translator * m_translator; + const translator_type * m_translator; Predicates m_pred; internal_stack_type internal_stack; - std::vector< std::pair > neighbors; + std::vector< std::pair > neighbors; size_type current_neighbor; node_distance_type next_closest_node_distance; diff --git a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp index 3c9501f37..1e9823782 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp @@ -28,22 +28,27 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { // Default choose_next_node -template +template +< + typename MembersHolder, + typename ChooseNextNodeTag = typename MembersHolder::options_type::choose_next_node_tag +> class choose_next_node; -template -class choose_next_node +template +class choose_next_node { public: - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::box_type box_type; + typedef typename MembersHolder::parameters_type parameters_type; - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; typedef typename rtree::elements_type::type children_type; - typedef typename index::detail::default_content_result::type content_type; + typedef typename index::detail::default_content_result::type content_type; template static inline size_t apply(internal_node & n, @@ -69,7 +74,7 @@ public: child_type const& ch_i = children[i]; // expanded child node's box - Box box_exp(ch_i.first); + box_type box_exp(ch_i.first); index::detail::expand(box_exp, indexable, index::detail::get_strategy(parameters)); @@ -94,7 +99,11 @@ public: // ----------------------------------------------------------------------- // // Not implemented here -template +template +< + typename MembersHolder, + typename RedistributeTag = typename MembersHolder::options_type::redistribute_tag +> struct redistribute_elements { BOOST_MPL_ASSERT_MSG( @@ -106,7 +115,11 @@ struct redistribute_elements // ----------------------------------------------------------------------- // // Split algorithm -template +template +< + typename MembersHolder, + typename SplitTag = typename MembersHolder::options_type::split_tag +> class split { BOOST_MPL_ASSERT_MSG( @@ -116,17 +129,20 @@ class split }; // Default split algorithm -template -class split +template +class split { protected: - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::box_type box_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::allocators_type allocators_type; - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef rtree::subtree_destroyer subtree_destroyer; + typedef rtree::subtree_destroyer subtree_destroyer; public: typedef index::detail::varray< @@ -137,15 +153,15 @@ public: template static inline void apply(nodes_container_type & additional_nodes, Node & n, - Box & n_box, + box_type & n_box, parameters_type const& parameters, - Translator const& translator, - Allocators & allocators) + translator_type const& translator, + allocators_type & allocators) { // TODO - consider creating nodes always with sufficient memory allocated // create additional node, use auto destroyer for automatic destruction on exception - subtree_destroyer second_node(rtree::create_node::apply(allocators), allocators); // MAY THROW, STRONG (N: alloc) + subtree_destroyer second_node(rtree::create_node::apply(allocators), allocators); // MAY THROW, STRONG (N: alloc) // create reference to the newly created node Node & n2 = rtree::get(*second_node); @@ -159,15 +175,9 @@ public: // it will be possible to throw from boost::move() in the case of e.g. static size nodes. // redistribute elements - Box box2; - redistribute_elements< - Value, - Options, - Translator, - Box, - Allocators, - typename Options::redistribute_tag - >::apply(n, n2, n_box, box2, parameters, translator, allocators); // MAY THROW (V, E: alloc, copy, copy) + box_type box2; + redistribute_elements + ::apply(n, n2, n_box, box2, parameters, translator, allocators); // MAY THROW (V, E: alloc, copy, copy) // check numbers of elements BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n).size() && @@ -232,30 +242,34 @@ struct insert_traverse_data }; // Default insert visitor -template +template class insert - : public rtree::visitor::type + : MembersHolder::visitor { protected: - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::box_type box_type; + typedef typename MembersHolder::value_type value_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::allocators_type allocators_type; - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef rtree::subtree_destroyer subtree_destroyer; - typedef typename Allocators::node_pointer node_pointer; - typedef typename Allocators::size_type size_type; + typedef rtree::subtree_destroyer subtree_destroyer; + typedef typename allocators_type::node_pointer node_pointer; + typedef typename allocators_type::size_type size_type; - //typedef typename Allocators::internal_node_pointer internal_node_pointer; + //typedef typename allocators_type::internal_node_pointer internal_node_pointer; typedef internal_node * internal_node_pointer; inline insert(node_pointer & root, size_type & leafs_level, Element const& element, parameters_type const& parameters, - Translator const& translator, - Allocators & allocators, + translator_type const& translator, + allocators_type & allocators, size_type relative_level = 0 ) : m_element(element) @@ -289,10 +303,10 @@ protected: // It's because Points and Segments are compared WRT machine epsilon // This ensures that leafs bounds correspond to the stored elements if (BOOST_GEOMETRY_CONDITION(( - boost::is_same::value + boost::is_same::value && ! index::detail::is_bounding_geometry < - typename indexable_type::type + typename indexable_type::type >::value )) ) { geometry::detail::expand_by_epsilon(m_element_bounds); @@ -304,8 +318,10 @@ protected: inline void traverse(Visitor & visitor, internal_node & n) { // choose next node - size_t choosen_node_index = rtree::choose_next_node:: - apply(n, rtree::element_indexable(m_element, m_translator), m_parameters, m_leafs_level - m_traverse_data.current_level); + size_t choosen_node_index = rtree::choose_next_node + ::apply(n, rtree::element_indexable(m_element, m_translator), + m_parameters, + m_leafs_level - m_traverse_data.current_level); // expand the node to contain value index::detail::expand( @@ -357,10 +373,10 @@ protected: template inline void split(Node & n) const { - typedef rtree::split split_algo; + typedef rtree::split split_algo; typename split_algo::nodes_container_type additional_nodes; - Box n_box; + box_type n_box; split_algo::apply(additional_nodes, n, n_box, m_parameters, m_translator, m_allocators); // MAY THROW (V, E: alloc, copy, N:alloc) @@ -387,7 +403,7 @@ protected: boost::is_same::value && ! index::detail::is_bounding_geometry < - typename indexable_type::type + typename indexable_type::type >::value ))) { geometry::detail::expand_by_epsilon(n_box); @@ -409,7 +425,7 @@ protected: BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get(*m_root_node), "node should be the root"); // create new root and add nodes - subtree_destroyer new_root(rtree::create_node::apply(m_allocators), m_allocators); // MAY THROW, STRONG (N:alloc) + subtree_destroyer new_root(rtree::create_node::apply(m_allocators), m_allocators); // MAY THROW, STRONG (N:alloc) BOOST_TRY { @@ -436,9 +452,9 @@ protected: // TODO: awulkiew - implement dispatchable split::apply to enable additional nodes creation Element const& m_element; - Box m_element_bounds; + box_type m_element_bounds; parameters_type const& m_parameters; - Translator const& m_translator; + translator_type const& m_translator; size_type const m_relative_level; size_type const m_level; @@ -448,30 +464,39 @@ protected: // traversing input parameters insert_traverse_data m_traverse_data; - Allocators & m_allocators; + allocators_type & m_allocators; }; } // namespace detail // Insert visitor forward declaration -template +template +< + typename Element, + typename MembersHolder, + typename InsertTag = typename MembersHolder::options_type::insert_tag +> class insert; // Default insert visitor used for nodes elements // 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 -class insert - : public detail::insert +template +class insert + : public detail::insert { public: - typedef detail::insert base; + typedef detail::insert base; + + 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 node; typedef typename base::internal_node internal_node; typedef typename base::leaf leaf; - typedef typename Options::parameters_type parameters_type; typedef typename base::node_pointer node_pointer; typedef typename base::size_type size_type; @@ -479,8 +504,8 @@ public: size_type & leafs_level, Element const& element, parameters_type const& parameters, - Translator const& translator, - Allocators & allocators, + translator_type const& translator, + allocators_type & allocators, size_type relative_level = 0 ) : base(root, leafs_level, element, parameters, translator, allocators, relative_level) @@ -508,7 +533,7 @@ public: { // if the insert fails above, the element won't be stored in the tree - rtree::visitors::destroy del_v(base::m_element.second, base::m_allocators); + rtree::visitors::destroy del_v(base::m_element.second, base::m_allocators); rtree::apply_visitor(del_v, *base::m_element.second); BOOST_RETHROW // RETHROW @@ -526,26 +551,31 @@ public: }; // Default insert visitor specialized for Values elements -template -class insert - : public detail::insert +template +class insert + : public detail::insert { public: - typedef detail::insert base; + typedef detail::insert base; + + typedef typename base::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 node; typedef typename base::internal_node internal_node; typedef typename base::leaf leaf; - typedef typename Options::parameters_type parameters_type; typedef typename base::node_pointer node_pointer; typedef typename base::size_type size_type; inline insert(node_pointer & root, size_type & leafs_level, - Value const& value, + value_type const& value, parameters_type const& parameters, - Translator const& translator, - Allocators & allocators, + translator_type const& translator, + allocators_type & allocators, size_type relative_level = 0 ) : base(root, leafs_level, value, parameters, translator, allocators, relative_level) diff --git a/include/boost/geometry/index/detail/rtree/visitors/is_leaf.hpp b/include/boost/geometry/index/detail/rtree/visitors/is_leaf.hpp index dd2159c71..d4b8293ef 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/is_leaf.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/is_leaf.hpp @@ -4,6 +4,10 @@ // // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2019. +// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// 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) @@ -15,11 +19,12 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { -template -struct is_leaf : public rtree::visitor::type +template +struct is_leaf + : public MembersHolder::visitor_const { - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; is_leaf() : result(false) diff --git a/include/boost/geometry/index/detail/rtree/visitors/remove.hpp b/include/boost/geometry/index/detail/rtree/visitors/remove.hpp index 1a3ccd796..efb7c0725 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/remove.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/remove.hpp @@ -24,19 +24,23 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { // Default remove algorithm -template +template class remove - : public rtree::visitor::type + : public MembersHolder::visitor { - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::box_type box_type; + typedef typename MembersHolder::value_type value_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::allocators_type allocators_type; - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef rtree::subtree_destroyer subtree_destroyer; - typedef typename Allocators::node_pointer node_pointer; - typedef typename Allocators::size_type size_type; + typedef rtree::subtree_destroyer subtree_destroyer; + typedef typename allocators_type::node_pointer node_pointer; + typedef typename allocators_type::size_type size_type; typedef typename rtree::elements_type::type::size_type internal_size_type; @@ -46,10 +50,10 @@ class remove public: inline remove(node_pointer & root, size_type & leafs_level, - Value const& value, + value_type const& value, parameters_type const& parameters, - Translator const& translator, - Allocators & allocators) + translator_type const& translator, + allocators_type & allocators) : m_value(value) , m_parameters(parameters) , m_translator(translator) @@ -116,8 +120,8 @@ public: BOOST_GEOMETRY_INDEX_ASSERT((elements.size() < m_parameters.get_min_elements()) == m_is_underflow, "unexpected state"); rtree::elements(*m_parent)[m_current_child_index].first - = rtree::elements_box(elements.begin(), elements.end(), m_translator, - index::detail::get_strategy(m_parameters)); + = rtree::elements_box(elements.begin(), elements.end(), m_translator, + index::detail::get_strategy(m_parameters)); } // n is root node else @@ -140,7 +144,7 @@ public: m_root_node = rtree::elements(n)[0].second; --m_leafs_level; - rtree::destroy_node::apply(m_allocators, root_to_destroy); + rtree::destroy_node::apply(m_allocators, root_to_destroy); } } } @@ -175,8 +179,8 @@ public: if ( 0 != m_parent ) { rtree::elements(*m_parent)[m_current_child_index].first - = rtree::values_box(elements.begin(), elements.end(), m_translator, - index::detail::get_strategy(m_parameters)); + = rtree::values_box(elements.begin(), elements.end(), m_translator, + index::detail::get_strategy(m_parameters)); } } } @@ -188,7 +192,7 @@ public: private: - typedef std::vector< std::pair > UnderflowNodes; + typedef std::vector< std::pair > underflow_nodes; void traverse_apply_visitor(internal_node &n, internal_size_type choosen_node_index) { @@ -239,14 +243,14 @@ private: static inline bool is_leaf(node const& n) { - visitors::is_leaf ilv; + visitors::is_leaf ilv; rtree::apply_visitor(ilv, n); return ilv.result; } void reinsert_removed_nodes_elements() { - typename UnderflowNodes::reverse_iterator it = m_underflowed_nodes.rbegin(); + typename underflow_nodes::reverse_iterator it = m_underflowed_nodes.rbegin(); BOOST_TRY { @@ -262,13 +266,13 @@ private: { reinsert_node_elements(rtree::get(*it->second), it->first); // MAY THROW (V, E: alloc, copy, N: alloc) - rtree::destroy_node::apply(m_allocators, it->second); + rtree::destroy_node::apply(m_allocators, it->second); } else { reinsert_node_elements(rtree::get(*it->second), it->first); // MAY THROW (V, E: alloc, copy, N: alloc) - rtree::destroy_node::apply(m_allocators, it->second); + rtree::destroy_node::apply(m_allocators, it->second); } } @@ -300,14 +304,10 @@ private: { for ( ; it != elements.end() ; ++it ) { - visitors::insert< - typename elements_type::value_type, - Value, Options, Translator, Box, Allocators, - typename Options::insert_tag - > insert_v( - m_root_node, m_leafs_level, *it, - m_parameters, m_translator, m_allocators, - node_relative_level - 1); + visitors::insert + insert_v(m_root_node, m_leafs_level, *it, + m_parameters, m_translator, m_allocators, + node_relative_level - 1); rtree::apply_visitor(insert_v, *m_root_node); // MAY THROW (V, E: alloc, copy, N: alloc) } @@ -315,7 +315,7 @@ private: BOOST_CATCH(...) { ++it; - rtree::destroy_elements + rtree::destroy_elements ::apply(it, elements.end(), m_allocators); elements.clear(); BOOST_RETHROW // RETHROW @@ -323,16 +323,16 @@ private: BOOST_CATCH_END } - Value const& m_value; + value_type const& m_value; parameters_type const& m_parameters; - Translator const& m_translator; - Allocators & m_allocators; + translator_type const& m_translator; + allocators_type & m_allocators; node_pointer & m_root_node; size_type & m_leafs_level; bool m_is_value_removed; - UnderflowNodes m_underflowed_nodes; + underflow_nodes m_underflowed_nodes; // traversing input parameters internal_node_pointer m_parent; diff --git a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp index c94248cfd..cdef103b3 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp @@ -19,22 +19,25 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { -template +template struct spatial_query - : public rtree::visitor::type + : public MembersHolder::visitor_const { - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::allocators_type allocators_type; + typedef typename index::detail::strategy_type::type strategy_type; - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef typename Allocators::size_type size_type; + typedef typename allocators_type::size_type size_type; static const unsigned predicates_len = index::detail::predicates_length::value; - inline spatial_query(parameters_type const& par, Translator const& t, Predicates const& p, OutIter out_it) + inline spatial_query(parameters_type const& par, translator_type const& t, Predicates const& p, OutIter out_it) : tr(t), pred(p), out_iter(out_it), found_count(0), strategy(index::detail::get_strategy(par)) {} @@ -82,7 +85,7 @@ struct spatial_query } } - Translator const& tr; + translator_type const& tr; Predicates pred; @@ -92,21 +95,25 @@ struct spatial_query strategy_type strategy; }; -template +template class spatial_query_incremental - : public rtree::visitor::type + : public MembersHolder::visitor_const { - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::value_type value_type; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::allocators_type allocators_type; + typedef typename index::detail::strategy_type::type strategy_type; public: - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef typename Allocators::size_type size_type; - typedef typename Allocators::const_reference const_reference; - typedef typename Allocators::node_pointer node_pointer; + typedef typename allocators_type::size_type size_type; + typedef typename allocators_type::const_reference const_reference; + typedef typename allocators_type::node_pointer node_pointer; typedef typename rtree::elements_type::type::const_iterator internal_iterator; typedef typename rtree::elements_type::type leaf_elements; @@ -122,7 +129,7 @@ public: // , m_strategy() {} - inline spatial_query_incremental(parameters_type const& params, Translator const& t, Predicates const& p) + inline spatial_query_incremental(parameters_type const& params, translator_type const& t, Predicates const& p) : m_translator(::boost::addressof(t)) , m_pred(p) , m_values(NULL) @@ -172,7 +179,7 @@ public: if ( m_current != m_values->end() ) { // return if next value is found - Value const& v = *m_current; + value_type const& v = *m_current; if (index::detail::predicates_check < index::detail::value_tag, 0, predicates_len @@ -230,7 +237,7 @@ public: private: - const Translator * m_translator; + const translator_type * m_translator; Predicates m_pred; diff --git a/include/boost/geometry/index/detail/serialization.hpp b/include/boost/geometry/index/detail/serialization.hpp index 550a37565..14961d7f4 100644 --- a/include/boost/geometry/index/detail/serialization.hpp +++ b/include/boost/geometry/index/detail/serialization.hpp @@ -343,22 +343,29 @@ private: // TODO - move to index/detail/rtree/load.hpp namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { -template +template class load { - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::translator_type translator_type; + typedef typename MembersHolder::allocators_type allocators_type; - typedef typename Options::parameters_type parameters_type; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - typedef typename Allocators::node_pointer node_pointer; - typedef rtree::subtree_destroyer subtree_destroyer; - typedef typename Allocators::size_type size_type; + typedef typename allocators_type::node_pointer node_pointer; + typedef typename allocators_type::size_type size_type; + + typedef rtree::subtree_destroyer subtree_destroyer; public: template inline static - 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) + node_pointer apply(Archive & ar, unsigned int version, size_type leafs_level, + size_type & values_count, + parameters_type const& parameters, + translator_type const& translator, + allocators_type & allocators) { values_count = 0; return raw_apply(ar, version, leafs_level, values_count, parameters, translator, allocators); @@ -366,7 +373,12 @@ public: private: template inline static - 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) + node_pointer raw_apply(Archive & ar, unsigned int version, size_type leafs_level, + size_type & values_count, + parameters_type const& parameters, + translator_type const& translator, + allocators_type & allocators, + size_type current_level = 0) { //BOOST_GEOMETRY_INDEX_ASSERT(current_level <= leafs_level, "invalid parameter"); diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index ab770fd6a..c445abd36 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -98,6 +98,123 @@ namespace boost { namespace geometry { namespace index { + +namespace detail { namespace rtree { + +template +< + typename Value, + typename Bounds, + typename Parameters, + typename IndexableGetter, + typename EqualTo, + typename Allocator +> +struct members_holder + : public detail::translator + , public Parameters + , public detail::rtree::allocators + < + Allocator, + Value, + Parameters, + Bounds, + typename detail::rtree::options_type::type::node_tag + > +{ + typedef Value value_type; + typedef Bounds bounds_type; + typedef Parameters parameters_type; + //typedef IndexableGetter indexable_getter; + //typedef EqualTo value_equal; + //typedef Allocator allocator_type; + + typedef Bounds box_type; + typedef detail::translator translator_type; + typedef typename detail::rtree::options_type::type options_type; + typedef typename options_type::node_tag node_tag; + typedef detail::rtree::allocators + < + Allocator, Value, Parameters, Bounds, node_tag + > allocators_type; + + typedef typename detail::rtree::node + < + value_type, parameters_type, bounds_type, allocators_type, node_tag + >::type node; + typedef typename detail::rtree::internal_node + < + value_type, parameters_type, bounds_type, allocators_type, node_tag + >::type internal_node; + typedef typename detail::rtree::leaf + < + value_type, parameters_type, bounds_type, allocators_type, node_tag + >::type leaf; + + // TODO: only one visitor type is needed + typedef typename detail::rtree::visitor + < + value_type, parameters_type, bounds_type, allocators_type, node_tag, false + >::type visitor; + typedef typename detail::rtree::visitor + < + value_type, parameters_type, bounds_type, allocators_type, node_tag, true + >::type visitor_const; + + typedef typename allocators_type::node_pointer node_pointer; + + typedef ::boost::container::allocator_traits allocator_traits_type; + typedef typename allocators_type::size_type size_type; + +private: + members_holder(members_holder const&); + members_holder & operator=(members_holder const&); + +public: + template + members_holder(IndGet const& ind_get, + ValEq const& val_eq, + Parameters const& parameters, + BOOST_FWD_REF(Alloc) alloc) + : translator_type(ind_get, val_eq) + , Parameters(parameters) + , allocators_type(boost::forward(alloc)) + , values_count(0) + , leafs_level(0) + , root(0) + {} + + template + members_holder(IndGet const& ind_get, + ValEq const& val_eq, + Parameters const& parameters) + : translator_type(ind_get, val_eq) + , Parameters(parameters) + , allocators_type() + , values_count(0) + , leafs_level(0) + , root(0) + {} + + translator_type const& translator() const { return *this; } + + IndexableGetter const& indexable_getter() const { return *this; } + IndexableGetter & indexable_getter() { return *this; } + EqualTo const& equal_to() const { return *this; } + EqualTo & equal_to() { return *this; } + Parameters const& parameters() const { return *this; } + Parameters & parameters() { return *this; } + allocators_type const& allocators() const { return *this; } + allocators_type & allocators() { return *this; } + + size_type values_count; + size_type leafs_level; + node_pointer root; +}; + +}} // namespace detail::rtree + + /*! \brief The R-tree spatial index. @@ -190,51 +307,27 @@ public: private: - typedef detail::translator translator_type; - typedef bounds_type box_type; - typedef typename detail::rtree::options_type::type options_type; - typedef typename options_type::node_tag node_tag; - typedef detail::rtree::allocators - < - allocator_type, - value_type, - typename options_type::parameters_type, - box_type, - node_tag - > allocators_type; - typedef typename detail::rtree::node + typedef detail::rtree::members_holder < value_type, - typename options_type::parameters_type, - box_type, - allocators_type, - node_tag - >::type node; - typedef typename detail::rtree::internal_node - < - value_type, - typename options_type::parameters_type, - box_type, - allocators_type, - node_tag - >::type internal_node; - typedef typename detail::rtree::leaf - < - value_type, - typename options_type::parameters_type, - box_type, - allocators_type, - node_tag - >::type leaf; + bounds_type, + parameters_type, + indexable_getter, + value_equal, + allocator_type + > members_holder; - typedef typename allocators_type::node_pointer node_pointer; - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef detail::rtree::subtree_destroyer - < - value_type, options_type, translator_type, box_type, allocators_type - > subtree_destroyer; + typedef typename members_holder::translator_type translator_type; + typedef typename members_holder::options_type options_type; + typedef typename members_holder::allocators_type allocators_type; + typedef typename members_holder::node node; + typedef typename members_holder::internal_node internal_node; + typedef typename members_holder::leaf leaf; + + typedef typename members_holder::node_pointer node_pointer; + typedef typename members_holder::allocator_traits_type allocator_traits_type; friend class detail::rtree::utilities::view; #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL @@ -330,10 +423,11 @@ public: allocator_type const& allocator = allocator_type()) : m_members(getter, equal, parameters, allocator) { - typedef detail::rtree::pack pack; + typedef detail::rtree::pack pack; size_type vc = 0, ll = 0; m_members.root = pack::apply(first, last, vc, ll, - m_members.parameters(), m_members.translator(), m_members.allocators()); + m_members.parameters(), m_members.translator(), + m_members.allocators()); m_members.values_count = vc; m_members.leafs_level = ll; } @@ -362,10 +456,11 @@ public: allocator_type const& allocator = allocator_type()) : m_members(getter, equal, parameters, allocator) { - typedef detail::rtree::pack pack; + typedef detail::rtree::pack pack; size_type vc = 0, ll = 0; m_members.root = pack::apply(::boost::begin(rng), ::boost::end(rng), vc, ll, - m_members.parameters(), m_members.translator(), m_members.allocators()); + m_members.parameters(), m_members.translator(), + m_members.allocators()); m_members.values_count = vc; m_members.leafs_level = ll; } @@ -1023,9 +1118,9 @@ private: template typename boost::mpl::if_c< detail::predicates_count_distance::value == 0, - detail::rtree::iterators::spatial_query_iterator, + detail::rtree::iterators::spatial_query_iterator, detail::rtree::iterators::distance_query_iterator< - value_type, options_type, translator_type, box_type, allocators_type, Predicates, + members_holder, Predicates, detail::predicates_find_distance::value > >::type @@ -1036,9 +1131,9 @@ private: typedef typename boost::mpl::if_c< detail::predicates_count_distance::value == 0, - detail::rtree::iterators::spatial_query_iterator, + detail::rtree::iterators::spatial_query_iterator, detail::rtree::iterators::distance_query_iterator< - value_type, options_type, translator_type, box_type, allocators_type, Predicates, + members_holder, Predicates, detail::predicates_find_distance::value > >::type iterator_type; @@ -1084,9 +1179,9 @@ private: template typename boost::mpl::if_c< detail::predicates_count_distance::value == 0, - detail::rtree::iterators::spatial_query_iterator, + detail::rtree::iterators::spatial_query_iterator, detail::rtree::iterators::distance_query_iterator< - value_type, options_type, translator_type, box_type, allocators_type, Predicates, + members_holder, Predicates, detail::predicates_find_distance::value > >::type @@ -1097,9 +1192,9 @@ private: typedef typename boost::mpl::if_c< detail::predicates_count_distance::value == 0, - detail::rtree::iterators::spatial_query_iterator, + detail::rtree::iterators::spatial_query_iterator, detail::rtree::iterators::distance_query_iterator< - value_type, options_type, translator_type, box_type, allocators_type, Predicates, + members_holder, Predicates, detail::predicates_find_distance::value > >::type iterator_type; @@ -1305,7 +1400,7 @@ public: { detail::rtree::visitors::children_box < - value_type, options_type, translator_type, box_type, allocators_type + members_holder > box_v(result, m_members.parameters(), m_members.translator()); detail::rtree::apply_visitor(box_v, *m_members.root); } @@ -1468,12 +1563,9 @@ private: // CONSIDER: alternative - ignore invalid indexable or throw an exception BOOST_GEOMETRY_INDEX_ASSERT(detail::is_valid(m_members.translator()(value)), "Indexable is invalid"); - detail::rtree::visitors::insert< - value_type, - value_type, options_type, translator_type, box_type, allocators_type, - typename options_type::insert_tag - > insert_v(m_members.root, m_members.leafs_level, value, - m_members.parameters(), m_members.translator(), m_members.allocators()); + detail::rtree::visitors::insert + insert_v(m_members.root, m_members.leafs_level, value, + m_members.parameters(), m_members.translator(), m_members.allocators()); detail::rtree::apply_visitor(insert_v, *m_members.root); @@ -1499,10 +1591,9 @@ private: // TODO: awulkiew - assert for correct value (indexable) ? BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist"); - detail::rtree::visitors::remove< - value_type, options_type, translator_type, box_type, allocators_type - > remove_v(m_members.root, m_members.leafs_level, value, - m_members.parameters(), m_members.translator(), m_members.allocators()); + detail::rtree::visitors::remove + remove_v(m_members.root, m_members.leafs_level, value, + m_members.parameters(), m_members.translator(), m_members.allocators()); detail::rtree::apply_visitor(remove_v, *m_members.root); @@ -1547,7 +1638,7 @@ private: { if ( t.m_members.root ) { - detail::rtree::visitors::destroy + detail::rtree::visitors::destroy del_v(t.m_members.root, t.m_members.allocators()); detail::rtree::apply_visitor(del_v, *t.m_members.root); @@ -1570,8 +1661,7 @@ private: */ inline void raw_copy(rtree const& src, rtree & dst, bool copy_tr_and_params) const { - detail::rtree::visitors::copy - copy_v(dst.m_members.allocators()); + detail::rtree::visitors::copy copy_v(dst.m_members.allocators()); if ( src.m_members.root ) detail::rtree::apply_visitor(copy_v, *src.m_members.root); // MAY THROW (V, E: alloc, copy, N: alloc) @@ -1586,7 +1676,7 @@ private: // TODO use subtree_destroyer if ( dst.m_members.root ) { - detail::rtree::visitors::destroy + detail::rtree::visitors::destroy del_v(dst.m_members.root, dst.m_members.allocators()); detail::rtree::apply_visitor(del_v, *dst.m_members.root); dst.m_members.root = 0; @@ -1680,10 +1770,8 @@ private: template size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_ const& /*is_distance_predicate*/) const { - detail::rtree::visitors::spatial_query - < - value_type, options_type, translator_type, box_type, allocators_type, Predicates, OutIter - >find_v(m_members.parameters(), m_members.translator(), predicates, out_it); + detail::rtree::visitors::spatial_query + find_v(m_members.parameters(), m_members.translator(), predicates, out_it); detail::rtree::apply_visitor(find_v, *m_members.root); @@ -1703,11 +1791,7 @@ private: static const unsigned distance_predicate_index = detail::predicates_find_distance::value; detail::rtree::visitors::distance_query< - value_type, - options_type, - translator_type, - box_type, - allocators_type, + members_holder, Predicates, distance_predicate_index, OutIter @@ -1732,11 +1816,7 @@ private: detail::rtree::visitors::count < ValueOrIndexable, - value_type, - options_type, - translator_type, - box_type, - allocators_type + members_holder > count_v(vori, m_members.parameters(), m_members.translator()); detail::rtree::apply_visitor(count_v, *m_members.root); @@ -1744,57 +1824,6 @@ private: return count_v.found_count; } - struct members_holder - : public translator_type - , public Parameters - , public allocators_type - { - private: - members_holder(members_holder const&); - members_holder & operator=(members_holder const&); - - public: - template - members_holder(IndGet const& ind_get, - ValEq const& val_eq, - Parameters const& parameters, - BOOST_FWD_REF(Alloc) alloc) - : translator_type(ind_get, val_eq) - , Parameters(parameters) - , allocators_type(boost::forward(alloc)) - , values_count(0) - , leafs_level(0) - , root(0) - {} - - template - members_holder(IndGet const& ind_get, - ValEq const& val_eq, - Parameters const& parameters) - : translator_type(ind_get, val_eq) - , Parameters(parameters) - , allocators_type() - , values_count(0) - , leafs_level(0) - , root(0) - {} - - translator_type const& translator() const { return *this; } - - IndexableGetter const& indexable_getter() const { return *this; } - IndexableGetter & indexable_getter() { return *this; } - EqualTo const& equal_to() const { return *this; } - EqualTo & equal_to() { return *this; } - Parameters const& parameters() const { return *this; } - Parameters & parameters() { return *this; } - allocators_type const& allocators() const { return *this; } - allocators_type & allocators() { return *this; } - - size_type values_count; - size_type leafs_level; - node_pointer root; - }; - members_holder m_members; }; From b0e3bd8541fe10b8bee4e63680fbc2fa5f373164 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 4 Nov 2019 23:49:20 +0100 Subject: [PATCH 2/5] [rtree] Simplify node destruction calls. --- .../boost/geometry/index/detail/rtree/node/node.hpp | 11 +++++++---- .../index/detail/rtree/node/subtree_destroyer.hpp | 3 +-- .../boost/geometry/index/detail/rtree/pack_create.hpp | 1 + .../geometry/index/detail/rtree/rstar/insert.hpp | 3 +-- .../geometry/index/detail/rtree/visitors/copy.hpp | 2 ++ .../geometry/index/detail/rtree/visitors/destroy.hpp | 10 ++++++++-- .../geometry/index/detail/rtree/visitors/insert.hpp | 5 +++-- .../geometry/index/detail/rtree/visitors/remove.hpp | 6 +++--- include/boost/geometry/index/rtree.hpp | 7 +++---- 9 files changed, 29 insertions(+), 19 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/node/node.hpp b/include/boost/geometry/index/detail/rtree/node/node.hpp index e4db82d2c..ad3e24c15 100644 --- a/include/boost/geometry/index/detail/rtree/node/node.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node.hpp @@ -31,10 +31,9 @@ #include #include -#include - #include +#include #include #include @@ -114,7 +113,8 @@ struct destroy_element inline static void apply(typename internal_node::elements_type::value_type & element, allocators_type & allocators) { - rtree::subtree_destroyer dummy(element.second, allocators); + detail::rtree::visitors::destroy::apply(element.second, allocators); + element.second = 0; } @@ -155,7 +155,8 @@ private: { for ( ; first != last ; ++first ) { - rtree::subtree_destroyer dummy(first->second, allocators); + detail::rtree::visitors::destroy::apply(first->second, allocators); + first->second = 0; } } @@ -167,6 +168,7 @@ private: }; // clears node, deletes all subtrees stored in node +/* template struct clear_node { @@ -202,6 +204,7 @@ struct clear_node rtree::elements(leaf).clear(); } }; +*/ template void move_from_back(Container & container, Iterator it) diff --git a/include/boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp b/include/boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp index ca65bad32..838d757ab 100644 --- a/include/boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp +++ b/include/boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp @@ -47,8 +47,7 @@ public: { if ( m_ptr && m_ptr != ptr ) { - detail::rtree::visitors::destroy del_v(m_ptr, m_allocators); - detail::rtree::apply_visitor(del_v, *m_ptr); + detail::rtree::visitors::destroy::apply(m_ptr, m_allocators); } m_ptr = ptr; } diff --git a/include/boost/geometry/index/detail/rtree/pack_create.hpp b/include/boost/geometry/index/detail/rtree/pack_create.hpp index 7280c3000..52a3846fb 100644 --- a/include/boost/geometry/index/detail/rtree/pack_create.hpp +++ b/include/boost/geometry/index/detail/rtree/pack_create.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include diff --git a/include/boost/geometry/index/detail/rtree/rstar/insert.hpp b/include/boost/geometry/index/detail/rtree/rstar/insert.hpp index 8a9cb7166..e11636f0f 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/insert.hpp @@ -394,8 +394,7 @@ struct level_insert // NOTE: exception-safety // if the insert fails above, the element won't be stored in the tree, so delete it - rtree::visitors::destroy del_v(base::m_element.second, base::m_allocators); - rtree::apply_visitor(del_v, *base::m_element.second); + rtree::visitors::destroy::apply(base::m_element.second, base::m_allocators); BOOST_RETHROW // RETHROW } diff --git a/include/boost/geometry/index/detail/rtree/visitors/copy.hpp b/include/boost/geometry/index/detail/rtree/visitors/copy.hpp index 1c3229b07..1dee43d63 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/copy.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/copy.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COPY_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COPY_HPP +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { diff --git a/include/boost/geometry/index/detail/rtree/visitors/destroy.hpp b/include/boost/geometry/index/detail/rtree/visitors/destroy.hpp index fd4315d42..4afb867cd 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/destroy.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/destroy.hpp @@ -31,8 +31,8 @@ public: typedef typename MembersHolder::allocators_type allocators_type; typedef typename MembersHolder::node_pointer node_pointer; - inline destroy(node_pointer root_node, allocators_type & allocators) - : m_current_node(root_node) + inline destroy(node_pointer node, allocators_type & allocators) + : m_current_node(node) , m_allocators(allocators) {} @@ -64,6 +64,12 @@ public: rtree::destroy_node::apply(m_allocators, m_current_node); } + static inline void apply(node_pointer node, allocators_type & allocators) + { + destroy v(node, allocators); + rtree::apply_visitor(v, *node); + } + private: node_pointer m_current_node; allocators_type & m_allocators; diff --git a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp index 1e9823782..490f66feb 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp @@ -23,6 +23,8 @@ #include #include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { @@ -533,8 +535,7 @@ public: { // if the insert fails above, the element won't be stored in the tree - rtree::visitors::destroy del_v(base::m_element.second, base::m_allocators); - rtree::apply_visitor(del_v, *base::m_element.second); + rtree::visitors::destroy::apply(base::m_element.second, base::m_allocators); BOOST_RETHROW // RETHROW } diff --git a/include/boost/geometry/index/detail/rtree/visitors/remove.hpp b/include/boost/geometry/index/detail/rtree/visitors/remove.hpp index efb7c0725..59f486163 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/remove.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/remove.hpp @@ -15,6 +15,7 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_REMOVE_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_REMOVE_HPP +#include #include #include @@ -283,7 +284,7 @@ private: // destroy current and remaining nodes for ( ; it != m_underflowed_nodes.rend() ; ++it ) { - subtree_destroyer dummy(it->second, m_allocators); + rtree::visitors::destroy::apply(it->second, m_allocators); } //m_underflowed_nodes.clear(); @@ -315,8 +316,7 @@ private: BOOST_CATCH(...) { ++it; - rtree::destroy_elements - ::apply(it, elements.end(), m_allocators); + rtree::destroy_elements::apply(it, elements.end(), m_allocators); elements.clear(); BOOST_RETHROW // RETHROW } diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index c445abd36..dcc647d2c 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -1639,8 +1639,7 @@ private: if ( t.m_members.root ) { detail::rtree::visitors::destroy - del_v(t.m_members.root, t.m_members.allocators()); - detail::rtree::apply_visitor(del_v, *t.m_members.root); + ::apply(t.m_members.root, t.m_members.allocators()); t.m_members.root = 0; } @@ -1677,8 +1676,8 @@ private: if ( dst.m_members.root ) { detail::rtree::visitors::destroy - del_v(dst.m_members.root, dst.m_members.allocators()); - detail::rtree::apply_visitor(del_v, *dst.m_members.root); + ::apply(dst.m_members.root, dst.m_members.allocators()); + dst.m_members.root = 0; } From 859ddb7a1ea24e849aa1075acd22f2dc62879ad6 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 7 Nov 2019 22:40:51 +0100 Subject: [PATCH 3/5] [index] Make members_holder a member type of the rtree. --- include/boost/geometry/index/rtree.hpp | 227 +++++++++++-------------- 1 file changed, 101 insertions(+), 126 deletions(-) diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index dcc647d2c..edf694743 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -98,123 +98,6 @@ namespace boost { namespace geometry { namespace index { - -namespace detail { namespace rtree { - -template -< - typename Value, - typename Bounds, - typename Parameters, - typename IndexableGetter, - typename EqualTo, - typename Allocator -> -struct members_holder - : public detail::translator - , public Parameters - , public detail::rtree::allocators - < - Allocator, - Value, - Parameters, - Bounds, - typename detail::rtree::options_type::type::node_tag - > -{ - typedef Value value_type; - typedef Bounds bounds_type; - typedef Parameters parameters_type; - //typedef IndexableGetter indexable_getter; - //typedef EqualTo value_equal; - //typedef Allocator allocator_type; - - typedef Bounds box_type; - typedef detail::translator translator_type; - typedef typename detail::rtree::options_type::type options_type; - typedef typename options_type::node_tag node_tag; - typedef detail::rtree::allocators - < - Allocator, Value, Parameters, Bounds, node_tag - > allocators_type; - - typedef typename detail::rtree::node - < - value_type, parameters_type, bounds_type, allocators_type, node_tag - >::type node; - typedef typename detail::rtree::internal_node - < - value_type, parameters_type, bounds_type, allocators_type, node_tag - >::type internal_node; - typedef typename detail::rtree::leaf - < - value_type, parameters_type, bounds_type, allocators_type, node_tag - >::type leaf; - - // TODO: only one visitor type is needed - typedef typename detail::rtree::visitor - < - value_type, parameters_type, bounds_type, allocators_type, node_tag, false - >::type visitor; - typedef typename detail::rtree::visitor - < - value_type, parameters_type, bounds_type, allocators_type, node_tag, true - >::type visitor_const; - - typedef typename allocators_type::node_pointer node_pointer; - - typedef ::boost::container::allocator_traits allocator_traits_type; - typedef typename allocators_type::size_type size_type; - -private: - members_holder(members_holder const&); - members_holder & operator=(members_holder const&); - -public: - template - members_holder(IndGet const& ind_get, - ValEq const& val_eq, - Parameters const& parameters, - BOOST_FWD_REF(Alloc) alloc) - : translator_type(ind_get, val_eq) - , Parameters(parameters) - , allocators_type(boost::forward(alloc)) - , values_count(0) - , leafs_level(0) - , root(0) - {} - - template - members_holder(IndGet const& ind_get, - ValEq const& val_eq, - Parameters const& parameters) - : translator_type(ind_get, val_eq) - , Parameters(parameters) - , allocators_type() - , values_count(0) - , leafs_level(0) - , root(0) - {} - - translator_type const& translator() const { return *this; } - - IndexableGetter const& indexable_getter() const { return *this; } - IndexableGetter & indexable_getter() { return *this; } - EqualTo const& equal_to() const { return *this; } - EqualTo & equal_to() { return *this; } - Parameters const& parameters() const { return *this; } - Parameters & parameters() { return *this; } - allocators_type const& allocators() const { return *this; } - allocators_type & allocators() { return *this; } - - size_type values_count; - size_type leafs_level; - node_pointer root; -}; - -}} // namespace detail::rtree - - /*! \brief The R-tree spatial index. @@ -309,15 +192,107 @@ private: typedef bounds_type box_type; - typedef detail::rtree::members_holder - < - value_type, - bounds_type, - parameters_type, - indexable_getter, - value_equal, - allocator_type - > members_holder; + struct members_holder + : public detail::translator + , public Parameters + , public detail::rtree::allocators + < + Allocator, + Value, + Parameters, + bounds_type, + typename detail::rtree::options_type::type::node_tag + > + { + typedef Value value_type; + typedef typename rtree::bounds_type bounds_type; + typedef Parameters parameters_type; + //typedef IndexableGetter indexable_getter; + //typedef EqualTo value_equal; + //typedef Allocator allocator_type; + + typedef bounds_type box_type; + typedef detail::translator translator_type; + typedef typename detail::rtree::options_type::type options_type; + typedef typename options_type::node_tag node_tag; + typedef detail::rtree::allocators + < + Allocator, Value, Parameters, bounds_type, node_tag + > allocators_type; + + typedef typename detail::rtree::node + < + value_type, parameters_type, bounds_type, allocators_type, node_tag + >::type node; + typedef typename detail::rtree::internal_node + < + value_type, parameters_type, bounds_type, allocators_type, node_tag + >::type internal_node; + typedef typename detail::rtree::leaf + < + value_type, parameters_type, bounds_type, allocators_type, node_tag + >::type leaf; + + // TODO: only one visitor type is needed + typedef typename detail::rtree::visitor + < + value_type, parameters_type, bounds_type, allocators_type, node_tag, false + >::type visitor; + typedef typename detail::rtree::visitor + < + value_type, parameters_type, bounds_type, allocators_type, node_tag, true + >::type visitor_const; + + typedef typename allocators_type::node_pointer node_pointer; + + typedef ::boost::container::allocator_traits allocator_traits_type; + typedef typename allocators_type::size_type size_type; + + private: + members_holder(members_holder const&); + members_holder & operator=(members_holder const&); + + public: + template + members_holder(IndGet const& ind_get, + ValEq const& val_eq, + Parameters const& parameters, + BOOST_FWD_REF(Alloc) alloc) + : translator_type(ind_get, val_eq) + , Parameters(parameters) + , allocators_type(boost::forward(alloc)) + , values_count(0) + , leafs_level(0) + , root(0) + {} + + template + members_holder(IndGet const& ind_get, + ValEq const& val_eq, + Parameters const& parameters) + : translator_type(ind_get, val_eq) + , Parameters(parameters) + , allocators_type() + , values_count(0) + , leafs_level(0) + , root(0) + {} + + translator_type const& translator() const { return *this; } + + IndexableGetter const& indexable_getter() const { return *this; } + IndexableGetter & indexable_getter() { return *this; } + EqualTo const& equal_to() const { return *this; } + EqualTo & equal_to() { return *this; } + Parameters const& parameters() const { return *this; } + Parameters & parameters() { return *this; } + allocators_type const& allocators() const { return *this; } + allocators_type & allocators() { return *this; } + + size_type values_count; + size_type leafs_level; + node_pointer root; + }; typedef typename members_holder::translator_type translator_type; typedef typename members_holder::options_type options_type; From ed0869c589be37b1157b1e55b0c4a01f1a5cbed3 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 12 Nov 2019 18:02:48 +0100 Subject: [PATCH 4/5] [index] Improve rtree state after exception is thrown in insert(). If exception is thrown in split prevent keeping more elements in a node that it is allowed. So even if a user calls insert() again there won't be a problem with pushing elements out of bounds in the same node which is already overflowed. --- .../index/detail/rtree/visitors/insert.hpp | 71 ++++++++++++------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp index 490f66feb..2d324cb7f 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp @@ -139,12 +139,13 @@ protected: typedef typename MembersHolder::box_type box_type; typedef typename MembersHolder::translator_type translator_type; typedef typename MembersHolder::allocators_type allocators_type; + typedef typename MembersHolder::size_type size_type; typedef typename MembersHolder::node node; typedef typename MembersHolder::internal_node internal_node; typedef typename MembersHolder::leaf leaf; - typedef rtree::subtree_destroyer subtree_destroyer; + typedef typename MembersHolder::node_pointer node_pointer; public: typedef index::detail::varray< @@ -163,37 +164,55 @@ public: // TODO - consider creating nodes always with sufficient memory allocated // create additional node, use auto destroyer for automatic destruction on exception - subtree_destroyer second_node(rtree::create_node::apply(allocators), allocators); // MAY THROW, STRONG (N: alloc) + node_pointer n2_ptr = rtree::create_node::apply(allocators); // MAY THROW, STRONG (N: alloc) // create reference to the newly created node - Node & n2 = rtree::get(*second_node); + Node & n2 = rtree::get(*n2_ptr); - // NOTE: thread-safety - // After throwing an exception by redistribute_elements the original node may be not changed or - // both nodes may be empty. In both cases the tree won't be valid r-tree. - // The alternative is to create 2 (or more) additional nodes here and store backup info - // in the original node, then, if exception was thrown, the node would always have more than max - // elements. - // The alternative is to use moving semantics in the implementations of redistribute_elements, - // it will be possible to throw from boost::move() in the case of e.g. static size nodes. + BOOST_TRY + { + // NOTE: thread-safety + // After throwing an exception by redistribute_elements the original node may be not changed or + // both nodes may be empty. In both cases the tree won't be valid r-tree. + // The alternative is to create 2 (or more) additional nodes here and store backup info + // in the original node, then, if exception was thrown, the node would always have more than max + // elements. + // The alternative is to use moving semantics in the implementations of redistribute_elements, + // it will be possible to throw from boost::move() in the case of e.g. static size nodes. - // redistribute elements - box_type box2; - redistribute_elements - ::apply(n, n2, n_box, box2, parameters, translator, allocators); // MAY THROW (V, E: alloc, copy, copy) + // redistribute elements + box_type box2; + redistribute_elements + ::apply(n, n2, n_box, box2, parameters, translator, allocators); // MAY THROW (V, E: alloc, copy, copy) - // check numbers of elements - BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n).size() && - rtree::elements(n).size() <= parameters.get_max_elements(), - "unexpected number of elements"); - BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n2).size() && - rtree::elements(n2).size() <= parameters.get_max_elements(), - "unexpected number of elements"); + // check numbers of elements + BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n).size() && + rtree::elements(n).size() <= parameters.get_max_elements(), + "unexpected number of elements"); + BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n2).size() && + rtree::elements(n2).size() <= parameters.get_max_elements(), + "unexpected number of elements"); - // return the list of newly created nodes (this algorithm returns one) - additional_nodes.push_back(rtree::make_ptr_pair(box2, second_node.get())); // MAY THROW, STRONG (alloc, copy) + // return the list of newly created nodes (this algorithm returns one) + additional_nodes.push_back(rtree::make_ptr_pair(box2, n2_ptr)); // MAY THROW, STRONG (alloc, copy) + } + BOOST_CATCH(...) + { + // NOTE: This code is here to prevent leaving the rtree in a state + // after an exception is thrown in which pushing new element could + // result in assert or putting it outside the memory of node elements. + typename rtree::elements_type::type & elements = rtree::elements(n); + size_type const max_size = parameters.get_max_elements(); + if (elements.size() > max_size) + { + rtree::destroy_element::apply(elements[max_size], allocators); + elements.pop_back(); + } - // release the ptr - second_node.release(); + rtree::visitors::destroy::apply(n2_ptr, allocators); + + BOOST_RETHROW + } + BOOST_CATCH_END } }; From 940d01e4f52575f3c806b3677b84911d37273c0d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 12 Nov 2019 18:07:32 +0100 Subject: [PATCH 5/5] [test][index] Check elements counts after an exception is thrown. --- .../detail/rtree/utilities/are_counts_ok.hpp | 18 +++++++++++------- .../test/rtree/exceptions/test_exceptions.hpp | 16 ++++++++++++++++ index/test/rtree/test_rtree.hpp | 3 ++- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp b/include/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp index 3e7ff6ed3..5c8fc9ef2 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp @@ -31,8 +31,11 @@ class are_counts_ok typedef typename MembersHolder::leaf leaf; public: - inline are_counts_ok(parameters_type const& parameters) - : result(true), m_current_level(0), m_parameters(parameters) + inline are_counts_ok(parameters_type const& parameters, bool check_min = true) + : result(true) + , m_current_level(0) + , m_parameters(parameters) + , m_check_min(check_min) {} inline void operator()(internal_node const& n) @@ -41,7 +44,7 @@ public: elements_type const& elements = rtree::elements(n); // root internal node shouldn't contain 0 elements - if ( elements.empty() + if ( (elements.empty() && m_check_min) || !check_count(elements) ) { result = false; @@ -67,7 +70,7 @@ public: elements_type const& elements = rtree::elements(n); // empty leaf in non-root node - if ( ( m_current_level > 0 && elements.empty() ) + if ( (m_current_level > 0 && elements.empty() && m_check_min) || !check_count(elements) ) { result = false; @@ -83,24 +86,25 @@ private: // root may contain count < min but should never contain count > max return elements.size() <= m_parameters.get_max_elements() && ( elements.size() >= m_parameters.get_min_elements() - || m_current_level == 0 ); + || m_current_level == 0 || !m_check_min ); } size_t m_current_level; parameters_type const& m_parameters; + bool m_check_min; }; } // namespace visitors template inline -bool are_counts_ok(Rtree const& tree) +bool are_counts_ok(Rtree const& tree, bool check_min = true) { typedef utilities::view RTV; RTV rtv(tree); visitors::are_counts_ok< typename RTV::members_holder - > v(tree.parameters()); + > v(tree.parameters(), check_min); rtv.apply_visitor(v); diff --git a/index/test/rtree/exceptions/test_exceptions.hpp b/index/test/rtree/exceptions/test_exceptions.hpp index 25f9fb844..df85e217c 100644 --- a/index/test/rtree/exceptions/test_exceptions.hpp +++ b/index/test/rtree/exceptions/test_exceptions.hpp @@ -5,6 +5,10 @@ // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // +// This file was modified by Oracle on 2019. +// Modifications copyright (c) 2019 Oracle and/or its affiliates. +// 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) @@ -45,6 +49,8 @@ void test_rtree_value_exceptions(Parameters const& parameters = Parameters()) throwing_value::set_max_calls(i); BOOST_CHECK_THROW( tree.insert(input.begin(), input.end()), throwing_value_copy_exception ); + + BOOST_CHECK(bgi::detail::rtree::utilities::are_counts_ok(tree, false)); } for ( size_t i = 0 ; i < 20 ; i += 1 ) @@ -68,6 +74,8 @@ void test_rtree_value_exceptions(Parameters const& parameters = Parameters()) throwing_value::set_max_calls(i); BOOST_CHECK_THROW( tree.remove(input.begin(), input.end()), throwing_value_copy_exception ); + + BOOST_CHECK(bgi::detail::rtree::utilities::are_counts_ok(tree, false)); } for ( size_t i = 0 ; i < 20 ; i += 2 ) @@ -99,6 +107,8 @@ void test_rtree_value_exceptions(Parameters const& parameters = Parameters()) throwing_value::set_max_calls(i); BOOST_CHECK_THROW(tree2 = tree, throwing_value_copy_exception ); + + BOOST_CHECK(tree2.empty()); } } @@ -128,6 +138,8 @@ void test_rtree_elements_exceptions(Parameters const& parameters = Parameters()) throwing_varray_settings::set_max_calls(i); BOOST_CHECK_THROW( tree.insert(input.begin(), input.end()), throwing_varray_exception ); + + BOOST_CHECK(bgi::detail::rtree::utilities::are_counts_ok(tree, false)); } for ( size_t i = 0 ; i < 100 ; i += 2 ) @@ -156,6 +168,8 @@ void test_rtree_elements_exceptions(Parameters const& parameters = Parameters()) throwing_varray_settings::set_max_calls(i); BOOST_CHECK_THROW( tree.remove(input.begin(), input.end()), throwing_varray_exception ); + + BOOST_CHECK(bgi::detail::rtree::utilities::are_counts_ok(tree, false)); } for ( size_t i = 0 ; i < 50 ; i += 2 ) @@ -187,6 +201,8 @@ void test_rtree_elements_exceptions(Parameters const& parameters = Parameters()) throwing_varray_settings::set_max_calls(i); BOOST_CHECK_THROW(tree2 = tree, throwing_varray_exception ); + + BOOST_CHECK(tree2.empty()); } } diff --git a/index/test/rtree/test_rtree.hpp b/index/test/rtree/test_rtree.hpp index f937e768a..89aaf02dd 100644 --- a/index/test/rtree/test_rtree.hpp +++ b/index/test/rtree/test_rtree.hpp @@ -26,8 +26,9 @@ #include #include -#include #include +#include +#include //#include //#include