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 a0635acab1..88fb3358c8 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 51ba2c7e74..ad3e24c159 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 @@ -102,41 +101,47 @@ 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 rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; + typedef typename MembersHolder::parameters_type parameters_type; + typedef typename MembersHolder::allocators_type allocators_type; - typedef rtree::subtree_destroyer subtree_destroyer; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - 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); + detail::rtree::visitors::destroy::apply(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,38 @@ 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); + detail::rtree::visitors::destroy::apply(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,17 +193,18 @@ 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(); } }; +*/ 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 3376068eed..838d757ab4 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,8 +47,7 @@ class subtree_destroyer { 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; } @@ -69,7 +74,7 @@ class subtree_destroyer 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 f8565bfb3e..52a3846fb5 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 @@ -126,37 +127,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 Allocators::node_pointer node_pointer; - typedef rtree::subtree_destroyer subtree_destroyer; - typedef typename Allocators::size_type size_type; - - typedef typename geometry::point_type::type point_type; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; + + 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 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 +179,7 @@ class pack 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 +187,7 @@ class pack // 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 +259,21 @@ class pack 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 +284,7 @@ class pack // 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 +293,8 @@ class pack // 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 +315,7 @@ class pack 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 +332,15 @@ class pack 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 +351,18 @@ class pack } 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 +387,13 @@ class pack 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 +408,14 @@ class pack } 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 +425,15 @@ class pack } 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 +446,14 @@ class pack } 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 +464,7 @@ class pack } 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 3fd51d56ff..05e71fb0e7 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 @@ class spatial_query_iterator 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 @@ class spatial_query_iterator 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 @@ class distance_query_iterator 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 209f6ebb20..7ba5f0f996 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 @@ class choose_next_node } }; -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 @@ class remove_elements_to_reinsert 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 @@ class remove_elements_to_reinsert 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 @@ class remove_elements_to_reinsert } }; -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,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 } @@ -390,26 +421,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 +480,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 +542,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 +578,7 @@ class insert 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 +590,7 @@ class 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 +605,7 @@ class insert 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 +615,7 @@ class 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 +632,7 @@ class insert 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 +643,7 @@ class insert::apply(*it, m_allocators); + rtree::destroy_element::apply(*it, m_allocators); BOOST_RETHROW // RETHROW } BOOST_CATCH_END @@ -624,11 +663,11 @@ class insert } // 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 b5fe5a0e28..64c4d7470d 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 @@ class are_boxes_ok 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 @@ class are_boxes_ok 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 @@ class are_boxes_ok 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 @@ class are_boxes_ok 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 10a1bec6ad..5c8fc9ef26 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,17 +21,21 @@ 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) - : 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) @@ -36,7 +44,7 @@ class are_counts_ok 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; @@ -62,7 +70,7 @@ class are_counts_ok 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; @@ -78,27 +86,25 @@ class are_counts_ok // 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::value_type, - typename RTV::options_type, - typename RTV::box_type, - typename RTV::allocators_type - > v(tree.parameters()); + typename RTV::members_holder + > v(tree.parameters(), check_min); 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 4860dbcb9b..a76cf38bf6 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 84201b6afe..25c08dba09 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; + + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - inline gl_draw(Translator const& t, + 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 4c42659c64..d512add243 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; + + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - inline print(std::ostream & o, Translator const& t) + 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 bbaed8100e..1692535103 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 6dbbd07bfe..edaa045ac3 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 0d26a79c3e..1dde1408c9 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 @@ class children_box 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 @@ class children_box 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 86ffc99caf..1dee43d63f 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) @@ -11,30 +15,34 @@ #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 { -template +template class copy - : 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::allocators_type allocators_type; - typedef rtree::subtree_destroyer subtree_destroyer; - typedef typename Allocators::node_pointer node_pointer; + typedef typename MembersHolder::node node; + typedef typename MembersHolder::internal_node internal_node; + typedef typename MembersHolder::leaf leaf; - explicit inline copy(Allocators & allocators) + typedef rtree::subtree_destroyer subtree_destroyer; + typedef typename allocators_type::node_pointer node_pointer; + +public: + 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 +69,7 @@ class copy 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 +90,7 @@ class copy 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 2cdbd8c0ed..c166fe3e36 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 b4a800eac2..4afb867cdf 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,19 +19,20 @@ 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) - : m_current_node(root_node) + inline destroy(node_pointer node, allocators_type & allocators) + : m_current_node(node) , m_allocators(allocators) {} @@ -48,7 +53,7 @@ class destroy 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,18 @@ class destroy 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); + } + + 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 & 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 20a954dc4e..edf47f90bd 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 @@ class distance_query_result 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 @@ class distance_query // 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 @@ class distance_query 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 @@ class distance_query } 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 @@ class distance_query_incremental // , 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 @@ class distance_query_incremental } 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 @@ class distance_query_incremental 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 3c9501f370..2d324cb7f4 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp @@ -23,27 +23,34 @@ #include #include +#include + 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 +76,7 @@ class choose_next_node +template +< + typename MembersHolder, + typename RedistributeTag = typename MembersHolder::options_type::redistribute_tag +> struct redistribute_elements { BOOST_MPL_ASSERT_MSG( @@ -106,7 +117,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 +131,21 @@ 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 MembersHolder::size_type size_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 MembersHolder::node_pointer node_pointer; public: typedef index::detail::varray< @@ -137,51 +156,63 @@ class split 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) + 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); - - // 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 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) - - // 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) - - // release the ptr - second_node.release(); + Node & n2 = rtree::get(*n2_ptr); + + 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) + + // 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, 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(); + } + + rtree::visitors::destroy::apply(n2_ptr, allocators); + + BOOST_RETHROW + } + BOOST_CATCH_END } }; @@ -232,30 +263,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 +324,10 @@ class insert // 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 +339,10 @@ class insert 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 +394,10 @@ class insert 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 +424,7 @@ class insert 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 +446,7 @@ class insert 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 +473,9 @@ class insert // 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 +485,39 @@ class insert // 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 +525,8 @@ class insert 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 } @@ -526,26 +571,31 @@ class insert -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 dd2159c71e..d4b8293efb 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 1a3ccd7965..59f486163d 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 @@ -24,19 +25,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 +51,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 +121,8 @@ class remove 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 +145,7 @@ class remove 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 +180,8 @@ class remove 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 +193,7 @@ class remove 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 +244,14 @@ class remove 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 +267,13 @@ class remove { 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); } } @@ -279,7 +284,7 @@ class remove // 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(); @@ -300,14 +305,10 @@ class remove { 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,24 +316,23 @@ class remove 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 } 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 c94248cfd0..cdef103b35 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 @@ class spatial_query_incremental // , 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 @@ class spatial_query_incremental 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 @@ class spatial_query_incremental 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 550a37565b..14961d7f49 100644 --- a/include/boost/geometry/index/detail/serialization.hpp +++ b/include/boost/geometry/index/detail/serialization.hpp @@ -343,22 +343,29 @@ class save // 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_type::node_pointer node_pointer; + typedef typename allocators_type::size_type size_type; - typedef typename Allocators::node_pointer node_pointer; - typedef rtree::subtree_destroyer subtree_destroyer; - typedef typename Allocators::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 @@ class load 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 ab770fd6ae..edf6947433 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -190,51 +190,119 @@ class rtree 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 - < - 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; - - 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; + + 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; + 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 +398,11 @@ class rtree 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 +431,11 @@ class rtree 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 +1093,9 @@ class rtree 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 +1106,9 @@ class rtree 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 +1154,9 @@ class rtree 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 +1167,9 @@ class rtree 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 +1375,7 @@ class rtree { 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 +1538,9 @@ class rtree // 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 +1566,9 @@ class rtree // 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,9 +1613,8 @@ class rtree { 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); + detail::rtree::visitors::destroy + ::apply(t.m_members.root, t.m_members.allocators()); t.m_members.root = 0; } @@ -1570,8 +1635,7 @@ class rtree */ 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,9 +1650,9 @@ class rtree // TODO use subtree_destroyer 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); + detail::rtree::visitors::destroy + ::apply(dst.m_members.root, dst.m_members.allocators()); + dst.m_members.root = 0; } @@ -1680,10 +1744,8 @@ class rtree 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 +1765,7 @@ class rtree 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 +1790,7 @@ class rtree 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 +1798,6 @@ class rtree 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; }; diff --git a/index/test/rtree/exceptions/test_exceptions.hpp b/index/test/rtree/exceptions/test_exceptions.hpp index 25f9fb8440..df85e217c7 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 f937e768a9..89aaf02dd4 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