Merge pull request #639 from awulkiew/feature/rtree_refactor

R-tree improvements.
This commit is contained in:
Adam Wulkiewicz
2020-01-24 22:44:29 +01:00
committed by GitHub
29 changed files with 948 additions and 717 deletions

View File

@@ -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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear_tag>
template <typename MembersHolder>
struct redistribute_elements<MembersHolder, linear_tag>
{
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<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
template <typename Node>
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<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
typedef typename rtree::element_indexable_type<element_type, translator_type>::type indexable_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
typename index::detail::strategy_type<parameters_type>::type const&
strategy = index::detail::get_strategy(parameters);
@@ -414,8 +417,8 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
else
{
// calculate enlarged boxes and areas
Box enlarged_box1(box1);
Box enlarged_box2(box2);
box_type enlarged_box1(box1);
box_type enlarged_box2(box2);
index::detail::expand(enlarged_box1, indexable, strategy);
index::detail::expand(enlarged_box2, indexable, strategy);
content_type enlarged_content1 = index::detail::content(enlarged_box1);
@@ -452,7 +455,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
elements1.clear();
elements2.clear();
rtree::destroy_elements<Value, Options, Translator, Box, Allocators>::apply(elements_copy, allocators);
rtree::destroy_elements<MembersHolder>::apply(elements_copy, allocators);
//elements_copy.clear();
BOOST_RETHROW // RETHROW, BASIC

View File

@@ -31,10 +31,9 @@
#include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_static.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
@@ -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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
struct destroy_element
{
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
inline static void apply(typename internal_node::elements_type::value_type & element, Allocators & allocators)
inline static void apply(typename internal_node::elements_type::value_type & element,
allocators_type & allocators)
{
subtree_destroyer dummy(element.second, allocators);
detail::rtree::visitors::destroy<MembersHolder>::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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
struct destroy_elements
{
typedef typename MembersHolder::value_type value_type;
typedef typename MembersHolder::allocators_type allocators_type;
template <typename Range>
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 <typename It>
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<It>::value_type
value_type, typename std::iterator_traits<It>::value_type
>::value
> is_range_of_values;
@@ -145,37 +150,38 @@ struct destroy_elements
private:
template <typename It>
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_<false> const& /*is_range_of_values*/)
{
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
for ( ; first != last ; ++first )
{
subtree_destroyer dummy(first->second, allocators);
detail::rtree::visitors::destroy<MembersHolder>::apply(first->second, allocators);
first->second = 0;
}
}
template <typename It>
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_<true> const& /*is_range_of_values*/)
{}
};
// clears node, deletes all subtrees stored in node
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
/*
template <typename MembersHolder>
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<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::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<Value, Options, Box, Allocators> ilv;
rtree::visitors::is_leaf<MembersHolder> 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<Value, Options, Translator, Box, Allocators>::apply(rtree::elements(internal_node), allocators);
destroy_elements<MembersHolder>::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 <typename Container, typename Iterator>
void move_from_back(Container & container, Iterator it)

View File

@@ -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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class subtree_destroyer
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::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 @@ public:
{
if ( m_ptr && m_ptr != ptr )
{
detail::rtree::visitors::destroy<Value, Options, Translator, Box, Allocators> del_v(m_ptr, m_allocators);
detail::rtree::apply_visitor(del_v, *m_ptr);
detail::rtree::visitors::destroy<MembersHolder>::apply(m_ptr, m_allocators);
}
m_ptr = ptr;
}
@@ -69,7 +74,7 @@ public:
private:
pointer m_ptr;
Allocators & m_allocators;
allocators_type & m_allocators;
};
}} // namespace detail::rtree

View File

@@ -20,6 +20,7 @@
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/algorithms/nth_element.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
@@ -126,37 +127,45 @@ struct nth_element_and_half_boxes<Dimension, Dimension>
// L2 25 25 25 25 25 25 17 10
// L3 5x5 5x5 5x5 5x5 5x5 5x5 3x5+2 2x5
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class pack
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef typename Allocators::node_pointer node_pointer;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::size_type size_type;
typedef typename MembersHolder::node_pointer node_pointer;
typedef typename MembersHolder::size_type size_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename geometry::point_type<Box>::type point_type;
typedef typename MembersHolder::box_type box_type;
typedef typename geometry::point_type<box_type>::type point_type;
typedef typename geometry::coordinate_type<point_type>::type coordinate_type;
typedef typename detail::default_content_result<Box>::type content_type;
typedef typename Options::parameters_type parameters_type;
typedef typename detail::default_content_result<box_type>::type content_type;
typedef typename detail::strategy_type<parameters_type>::type strategy_type;
static const std::size_t dimension = geometry::dimension<point_type>::value;
typedef typename rtree::container_from_elements_type<
typename rtree::elements_type<leaf>::type,
std::size_t
size_type
>::type values_counts_container;
typedef typename rtree::elements_type<internal_node>::type internal_elements;
typedef typename internal_elements::value_type internal_element;
typedef rtree::subtree_destroyer<MembersHolder> subtree_destroyer;
public:
// Arbitrary iterators
template <typename InIt> 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<InIt>::difference_type diff_type;
@@ -170,7 +179,7 @@ public:
values_count = static_cast<size_type>(diff);
entries.reserve(values_count);
expandable_box<Box, strategy_type> hint_box(detail::get_strategy(parameters));
expandable_box<box_type, strategy_type> hint_box(detail::get_strategy(parameters));
for ( ; first != last ; ++first )
{
// NOTE: support for iterators not returning true references adapted
@@ -178,7 +187,7 @@ public:
// An alternative would be to dereference the iterator and translate
// in one expression each time the indexable was needed.
typename std::iterator_traits<InIt>::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 @@ private:
struct subtree_elements_counts
{
subtree_elements_counts(std::size_t ma, std::size_t mi) : maxc(ma), minc(mi) {}
std::size_t maxc;
std::size_t minc;
subtree_elements_counts(size_type ma, size_type mi) : maxc(ma), minc(mi) {}
size_type maxc;
size_type minc;
};
template <typename EIt> 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::size_t>(std::distance(first, last)) == values_count,
BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<size_type>(std::distance(first, last)) == values_count,
"unexpected parameters");
if ( subtree_counts.maxc <= 1 )
@@ -270,7 +284,7 @@ private:
// if !root check m_parameters.get_min_elements() <= count
// create new leaf node
node_pointer n = rtree::create_node<Allocators, leaf>::apply(allocators); // MAY THROW (A)
node_pointer n = rtree::create_node<allocators_type, leaf>::apply(allocators); // MAY THROW (A)
subtree_destroyer auto_remover(n, allocators);
leaf & l = rtree::get<leaf>(*n);
@@ -279,8 +293,8 @@ private:
// calculate values box and copy values
// initialize the box explicitly to avoid GCC-4.4 uninitialized variable warnings with O2
expandable_box<Box, strategy_type> elements_box(translator(*(first->second)),
detail::get_strategy(parameters));
expandable_box<box_type, strategy_type> 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 @@ private:
if ( BOOST_GEOMETRY_CONDITION((
! index::detail::is_bounding_geometry
<
typename indexable_type<Translator>::type
typename indexable_type<translator_type>::type
>::value )) )
{
elements_box.expand_by_epsilon();
@@ -318,15 +332,15 @@ private:
next_subtree_counts.minc /= parameters.get_max_elements();
// create new internal node
node_pointer n = rtree::create_node<Allocators, internal_node>::apply(allocators); // MAY THROW (A)
node_pointer n = rtree::create_node<allocators_type, internal_node>::apply(allocators); // MAY THROW (A)
subtree_destroyer auto_remover(n, allocators);
internal_node & in = rtree::get<internal_node>(*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<Box, strategy_type> elements_box(detail::get_strategy(parameters));
expandable_box<box_type, strategy_type> 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 @@ private:
}
template <typename EIt, typename ExpandableBox> 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::size_t>(std::distance(first, last)) == values_count,
BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<size_type>(std::distance(first, last)) == values_count,
"unexpected parameters");
BOOST_GEOMETRY_INDEX_ASSERT(subtree_counts.minc <= values_count,
@@ -369,13 +387,13 @@ private:
return;
}
std::size_t median_count = calculate_median_count(values_count, subtree_counts);
size_type median_count = calculate_median_count(values_count, subtree_counts);
EIt median = first + median_count;
coordinate_type greatest_length;
std::size_t greatest_dim_index = 0;
pack_utils::biggest_edge<dimension>::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 @@ private:
}
inline static
subtree_elements_counts calculate_subtree_elements_counts(std::size_t elements_count, parameters_type const& parameters, size_type & leafs_level)
subtree_elements_counts calculate_subtree_elements_counts(size_type elements_count, parameters_type const& parameters, size_type & leafs_level)
{
boost::ignore_unused(parameters);
subtree_elements_counts res(1, 1);
leafs_level = 0;
std::size_t smax = parameters.get_max_elements();
size_type smax = parameters.get_max_elements();
for ( ; smax < elements_count ; smax *= parameters.get_max_elements(), ++leafs_level )
res.maxc = smax;
@@ -407,15 +425,15 @@ private:
}
inline static
std::size_t calculate_nodes_count(std::size_t count,
subtree_elements_counts const& subtree_counts)
size_type calculate_nodes_count(size_type count,
subtree_elements_counts const& subtree_counts)
{
std::size_t n = count / subtree_counts.maxc;
std::size_t r = count % subtree_counts.maxc;
size_type n = count / subtree_counts.maxc;
size_type r = count % subtree_counts.maxc;
if ( 0 < r && r < subtree_counts.minc )
{
std::size_t count_minus_min = count - subtree_counts.minc;
size_type count_minus_min = count - subtree_counts.minc;
n = count_minus_min / subtree_counts.maxc;
r = count_minus_min % subtree_counts.maxc;
++n;
@@ -428,14 +446,14 @@ private:
}
inline static
std::size_t calculate_median_count(std::size_t count,
subtree_elements_counts const& subtree_counts)
size_type calculate_median_count(size_type count,
subtree_elements_counts const& subtree_counts)
{
// e.g. for max = 5, min = 2, count = 52, subtree_max = 25, subtree_min = 10
std::size_t n = count / subtree_counts.maxc; // e.g. 52 / 25 = 2
std::size_t r = count % subtree_counts.maxc; // e.g. 52 % 25 = 2
std::size_t median_count = (n / 2) * subtree_counts.maxc; // e.g. 2 / 2 * 25 = 25
size_type n = count / subtree_counts.maxc; // e.g. 52 / 25 = 2
size_type r = count % subtree_counts.maxc; // e.g. 52 % 25 = 2
size_type median_count = (n / 2) * subtree_counts.maxc; // e.g. 2 / 2 * 25 = 25
if ( 0 != r ) // e.g. 0 != 2
{
@@ -446,7 +464,7 @@ private:
}
else // r < subtree_counts.second // e.g. 2 < 10 == true
{
std::size_t count_minus_min = count - subtree_counts.minc; // e.g. 52 - 10 = 42
size_type count_minus_min = count - subtree_counts.minc; // e.g. 52 - 10 = 42
n = count_minus_min / subtree_counts.maxc; // e.g. 42 / 25 = 1
r = count_minus_min % subtree_counts.maxc; // e.g. 42 % 25 = 17
if ( r == 0 ) // e.g. false

View File

@@ -92,29 +92,32 @@ inline void pick_seeds(Elements const& elements,
} // namespace quadratic
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadratic_tag>
template <typename MembersHolder>
struct redistribute_elements<MembersHolder, quadratic_tag>
{
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<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::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<Box>::type content_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
template <typename Node>
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<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename rtree::element_indexable_type<element_type, translator_type>::type indexable_type;
elements_type & elements1 = rtree::elements(n);
elements_type & elements2 = rtree::elements(second_node);
@@ -131,7 +134,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
// calculate initial seeds
size_t seed1 = 0;
size_t seed2 = 0;
quadratic::pick_seeds<Box>(elements_copy, parameters, translator, seed1, seed2);
quadratic::pick_seeds<box_type>(elements_copy, parameters, translator, seed1, seed2);
// prepare nodes' elements containers
elements1.clear();
@@ -249,7 +252,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
elements1.clear();
elements2.clear();
rtree::destroy_elements<Value, Options, Translator, Box, Allocators>::apply(elements_backup, allocators);
rtree::destroy_elements<MembersHolder>::apply(elements_backup, allocators);
//elements_backup.clear();
BOOST_RETHROW // RETHROW, BASIC
@@ -261,14 +264,14 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
template <typename It>
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<parameters_type>::type const& strategy,
content_type & out_content_increase1, content_type & out_content_increase2)
{
typedef typename boost::iterator_value<It>::type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename rtree::element_indexable_type<element_type, translator_type>::type indexable_type;
content_type greatest_content_incrase_diff = 0;
It out_it = first;
@@ -281,8 +284,8 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
indexable_type const& indexable = rtree::element_indexable(*el_it, translator);
// calculate enlarged boxes and areas
Box enlarged_box1(box1);
Box enlarged_box2(box2);
box_type enlarged_box1(box1);
box_type enlarged_box2(box2);
index::detail::expand(enlarged_box1, indexable, strategy);
index::detail::expand(enlarged_box2, indexable, strategy);
content_type enlarged_content1 = index::detail::content(enlarged_box1);

View File

@@ -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)
@@ -58,28 +62,31 @@ struct end_query_iterator
}
};
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates>
template <typename MembersHolder, typename Predicates>
class spatial_query_iterator
{
typedef typename Options::parameters_type parameters_type;
typedef visitors::spatial_query_incremental<Value, Options, Translator, Box, Allocators, Predicates> 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<MembersHolder, Predicates> visitor_type;
typedef typename visitor_type::node_pointer node_pointer;
public:
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
typedef typename MembersHolder::value_type value_type;
typedef typename allocators_type::const_reference reference;
typedef typename allocators_type::difference_type difference_type;
typedef typename allocators_type::const_pointer pointer;
inline spatial_query_iterator()
{}
inline spatial_query_iterator(parameters_type const& par, Translator const& t, Predicates const& p)
inline spatial_query_iterator(parameters_type const& par, translator_type const& t, Predicates const& p)
: m_visitor(par, t, p)
{}
inline spatial_query_iterator(node_pointer root, parameters_type const& par, Translator const& t, Predicates const& p)
inline spatial_query_iterator(node_pointer root, parameters_type const& par, translator_type const& t, Predicates const& p)
: m_visitor(par, t, p)
{
m_visitor.initialize(root);
@@ -113,12 +120,12 @@ public:
return l.m_visitor == r.m_visitor;
}
friend bool operator==(spatial_query_iterator const& l, end_query_iterator<Value, Allocators> const& /*r*/)
friend bool operator==(spatial_query_iterator const& l, end_query_iterator<value_type, allocators_type> const& /*r*/)
{
return l.m_visitor.is_end();
}
friend bool operator==(end_query_iterator<Value, Allocators> const& /*l*/, spatial_query_iterator const& r)
friend bool operator==(end_query_iterator<value_type, allocators_type> const& /*l*/, spatial_query_iterator const& r)
{
return r.m_visitor.is_end();
}
@@ -127,28 +134,31 @@ private:
visitor_type m_visitor;
};
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates, unsigned NearestPredicateIndex>
template <typename MembersHolder, typename Predicates, unsigned NearestPredicateIndex>
class distance_query_iterator
{
typedef typename Options::parameters_type parameters_type;
typedef visitors::distance_query_incremental<Value, Options, Translator, Box, Allocators, Predicates, NearestPredicateIndex> 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<MembersHolder, Predicates, NearestPredicateIndex> visitor_type;
typedef typename visitor_type::node_pointer node_pointer;
public:
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
typedef typename MembersHolder::value_type value_type;
typedef typename allocators_type::const_reference reference;
typedef typename allocators_type::difference_type difference_type;
typedef typename allocators_type::const_pointer pointer;
inline distance_query_iterator()
{}
inline distance_query_iterator(parameters_type const& par, Translator const& t, Predicates const& p)
inline distance_query_iterator(parameters_type const& par, translator_type const& t, Predicates const& p)
: m_visitor(par, t, p)
{}
inline distance_query_iterator(node_pointer root, parameters_type const& par, Translator const& t, Predicates const& p)
inline distance_query_iterator(node_pointer root, parameters_type const& par, translator_type const& t, Predicates const& p)
: m_visitor(par, t, p)
{
m_visitor.initialize(root);
@@ -182,12 +192,12 @@ public:
return l.m_visitor == r.m_visitor;
}
friend bool operator==(distance_query_iterator const& l, end_query_iterator<Value, Allocators> const& /*r*/)
friend bool operator==(distance_query_iterator const& l, end_query_iterator<value_type, allocators_type> const& /*r*/)
{
return l.m_visitor.is_end();
}
friend bool operator==(end_query_iterator<Value, Allocators> const& /*l*/, distance_query_iterator const& r)
friend bool operator==(end_query_iterator<value_type, allocators_type> const& /*l*/, distance_query_iterator const& r)
{
return r.m_visitor.is_end();
}

View File

@@ -33,19 +33,20 @@ namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
template <typename Value, typename Options, typename Box, typename Allocators>
class choose_next_node<Value, Options, Box, Allocators, choose_by_overlap_diff_tag>
template <typename MembersHolder>
class choose_next_node<MembersHolder, choose_by_overlap_diff_tag>
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::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<internal_node>::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<Box>::type content_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
public:
template <typename Indexable>
@@ -109,7 +110,7 @@ private:
child_type const& ch_i = children[i];
// expanded child node's box
Box box_exp(ch_i.first);
box_type box_exp(ch_i.first);
index::detail::expand(box_exp, indexable, strategy);
// areas difference
@@ -183,7 +184,7 @@ private:
child_type const& ch_i = children[i];
Box box_exp(ch_i.first);
box_type box_exp(ch_i.first);
// calculate expanded box of child node ch_i
index::detail::expand(box_exp, indexable, strategy);
@@ -238,7 +239,7 @@ private:
child_type const& ch_i = children[i];
// expanded child node's box
Box box_exp(ch_i.first);
box_type box_exp(ch_i.first);
index::detail::expand(box_exp, indexable, strategy);
// areas difference

View File

@@ -56,15 +56,18 @@ struct comparable_distance_point_point<Point1, Point2, default_strategy>
}
};
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class remove_elements_to_reinsert
{
public:
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
//typedef typename Allocators::internal_node_pointer internal_node_pointer;
typedef internal_node * internal_node_pointer;
@@ -75,12 +78,12 @@ public:
internal_node_pointer parent,
size_t current_child_index,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators)
translator_type const& translator,
allocators_type & allocators)
{
typedef typename rtree::elements_type<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename geometry::point_type<Box>::type point_type;
typedef typename geometry::point_type<box_type>::type point_type;
typedef typename index::detail::strategy_type<parameters_type>::type strategy_type;
// TODO: awulkiew - change second point_type to the point type of the Indexable?
typedef rstar::comparable_distance_point_point
@@ -159,7 +162,7 @@ public:
for ( typename sorted_elements_type::iterator it = sorted_elements.begin() ;
it != sorted_elements.end() ; ++it )
{
destroy_element<Value, Options, Translator, Box, Allocators>::apply(it->second, allocators);
destroy_element<MembersHolder>::apply(it->second, allocators);
}
BOOST_RETHROW // RETHROW
@@ -187,48 +190,69 @@ private:
}
};
template <size_t InsertIndex, typename Element, typename Value, typename Options, typename Box, typename Allocators>
template
<
size_t InsertIndex,
typename Element,
typename MembersHolder,
bool IsValue = boost::is_same<Element, typename MembersHolder::value_type>::value
>
struct level_insert_elements_type
{
typedef typename rtree::elements_type<
typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type
typename rtree::internal_node<
typename MembersHolder::value_type,
typename MembersHolder::parameters_type,
typename MembersHolder::box_type,
typename MembersHolder::allocators_type,
typename MembersHolder::node_tag
>::type
>::type type;
};
template <typename Value, typename Options, typename Box, typename Allocators>
struct level_insert_elements_type<0, Value, Value, Options, Box, Allocators>
template <typename Value, typename MembersHolder>
struct level_insert_elements_type<0, Value, MembersHolder, true>
{
typedef typename rtree::elements_type<
typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type
typename rtree::leaf<
typename MembersHolder::value_type,
typename MembersHolder::parameters_type,
typename MembersHolder::box_type,
typename MembersHolder::allocators_type,
typename MembersHolder::node_tag
>::type
>::type type;
};
template <size_t InsertIndex, typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <size_t InsertIndex, typename Element, typename MembersHolder>
struct level_insert_base
: public detail::insert<Element, Value, Options, Translator, Box, Allocators>
: public detail::insert<Element, MembersHolder>
{
typedef detail::insert<Element, Value, Options, Translator, Box, Allocators> base;
typedef detail::insert<Element, MembersHolder> base;
typedef typename base::node node;
typedef typename base::internal_node internal_node;
typedef typename base::leaf leaf;
typedef typename level_insert_elements_type<InsertIndex, Element, Value, Options, Box, Allocators>::type elements_type;
typedef typename level_insert_elements_type<InsertIndex, Element, MembersHolder>::type elements_type;
typedef typename index::detail::rtree::container_from_elements_type<
elements_type,
typename elements_type::value_type
>::type result_elements_type;
typedef typename 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<Value, Options, Translator, Box, Allocators>::apply(
rstar::remove_elements_to_reinsert<MembersHolder>::apply(
result_elements, n,
base::m_traverse_data.parent, base::m_traverse_data.current_child_index,
base::m_parameters, base::m_translator, base::m_allocators); // MAY THROW, BASIC (V, E: alloc, copy)
@@ -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<Box>(rtree::elements(n).begin(), rtree::elements(n).end(),
base::m_translator,
index::detail::get_strategy(base::m_parameters));
elements_box<box_type>(rtree::elements(n).begin(), rtree::elements(n).end(),
base::m_translator,
index::detail::get_strategy(base::m_parameters));
}
inline void recalculate_aabb(leaf const& n) const
{
base::m_traverse_data.current_element().first =
values_box<Box>(rtree::elements(n).begin(), rtree::elements(n).end(),
base::m_translator,
index::detail::get_strategy(base::m_parameters));
values_box<box_type>(rtree::elements(n).begin(), rtree::elements(n).end(),
base::m_translator,
index::detail::get_strategy(base::m_parameters));
}
size_type result_relative_level;
result_elements_type result_elements;
};
template <size_t InsertIndex, typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template
<
size_t InsertIndex,
typename Element,
typename MembersHolder,
bool IsValue = boost::is_same<Element, typename MembersHolder::value_type>::value
>
struct level_insert
: public level_insert_base<InsertIndex, Element, Value, Options, Translator, Box, Allocators>
: public level_insert_base<InsertIndex, Element, MembersHolder>
{
typedef level_insert_base<InsertIndex, Element, Value, Options, Translator, Box, Allocators> base;
typedef level_insert_base<InsertIndex, Element, MembersHolder> base;
typedef typename base::node node;
typedef typename base::internal_node internal_node;
typedef typename base::leaf leaf;
typedef typename 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<Value, Options, Translator, Box, Allocators> del_v(base::m_element.second, base::m_allocators);
rtree::apply_visitor(del_v, *base::m_element.second);
rtree::visitors::destroy<MembersHolder>::apply(base::m_element.second, base::m_allocators);
BOOST_RETHROW // RETHROW
}
@@ -390,26 +421,29 @@ struct level_insert
}
};
template <size_t InsertIndex, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct level_insert<InsertIndex, Value, Value, Options, Translator, Box, Allocators>
: public level_insert_base<InsertIndex, Value, Value, Options, Translator, Box, Allocators>
template <size_t InsertIndex, typename Value, typename MembersHolder>
struct level_insert<InsertIndex, Value, MembersHolder, true>
: public level_insert_base<InsertIndex, typename MembersHolder::value_type, MembersHolder>
{
typedef level_insert_base<InsertIndex, Value, Value, Options, Translator, Box, Allocators> base;
typedef level_insert_base<InsertIndex, typename MembersHolder::value_type, MembersHolder> base;
typedef typename base::node node;
typedef typename base::internal_node internal_node;
typedef typename base::leaf leaf;
typedef typename 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<InsertIndex, Value, Value, Options, Translator, Box, Allocat
}
};
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct level_insert<0, Value, Value, Options, Translator, Box, Allocators>
: public level_insert_base<0, Value, Value, Options, Translator, Box, Allocators>
template <typename Value, typename MembersHolder>
struct level_insert<0, Value, MembersHolder, true>
: public level_insert_base<0, typename MembersHolder::value_type, MembersHolder>
{
typedef level_insert_base<0, 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 <typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class insert<Element, Value, Options, Translator, Box, Allocators, insert_reinsert_tag>
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, false>::type
template <typename Element, typename MembersHolder>
class insert<Element, MembersHolder, insert_reinsert_tag>
: 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<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::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 @@ public:
// Distinguish between situation when reinserts are required and use adequate visitor, otherwise use default one
if ( m_parameters.get_reinserted_elements() > 0 )
{
rstar::level_insert<0, Element, Value, Options, Translator, Box, Allocators> lins_v(
rstar::level_insert<0, Element, MembersHolder> lins_v(
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
rtree::apply_visitor(lins_v, *m_root); // MAY THROW (V, E: alloc, copy, N: alloc)
@@ -551,7 +590,7 @@ public:
}
else
{
visitors::insert<Element, Value, Options, Translator, Box, Allocators, insert_default_tag> ins_v(
visitors::insert<Element, MembersHolder, insert_default_tag> ins_v(
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
rtree::apply_visitor(ins_v, *m_root);
@@ -566,7 +605,7 @@ public:
// Distinguish between situation when reinserts are required and use adequate visitor, otherwise use default one
if ( m_parameters.get_reinserted_elements() > 0 )
{
rstar::level_insert<0, Element, Value, Options, Translator, Box, Allocators> lins_v(
rstar::level_insert<0, Element, MembersHolder> lins_v(
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
rtree::apply_visitor(lins_v, *m_root); // MAY THROW (V, E: alloc, copy, N: alloc)
@@ -576,7 +615,7 @@ public:
}
else
{
visitors::insert<Element, Value, Options, Translator, Box, Allocators, insert_default_tag> ins_v(
visitors::insert<Element, MembersHolder, insert_default_tag> ins_v(
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
rtree::apply_visitor(ins_v, *m_root);
@@ -593,7 +632,7 @@ private:
typename Elements::reverse_iterator it = elements.rbegin();
for ( ; it != elements.rend() ; ++it)
{
rstar::level_insert<1, element_type, Value, Options, Translator, Box, Allocators> lins_v(
rstar::level_insert<1, element_type, MembersHolder> lins_v(
m_root, m_leafs_level, *it, m_parameters, m_translator, m_allocators, relative_level);
BOOST_TRY
@@ -604,7 +643,7 @@ private:
{
++it;
for ( ; it != elements.rend() ; ++it)
rtree::destroy_element<Value, Options, Translator, Box, Allocators>::apply(*it, m_allocators);
rtree::destroy_element<MembersHolder>::apply(*it, m_allocators);
BOOST_RETHROW // RETHROW
}
BOOST_CATCH_END
@@ -624,11 +663,11 @@ private:
Element const& m_element;
parameters_type const& m_parameters;
Translator const& m_translator;
translator_type const& m_translator;
size_type m_relative_level;
Allocators & m_allocators;
allocators_type & m_allocators;
};
}}} // namespace detail::rtree::visitors

View File

@@ -397,29 +397,32 @@ struct nth_element<Corner, Dimension, Dimension>
} // namespace rstar
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_tag>
template <typename MembersHolder>
struct redistribute_elements<MembersHolder, rstar_tag>
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::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<Box>::value;
static const size_t dimension = geometry::dimension<box_type>::value;
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
typedef typename index::detail::default_margin_result<box_type>::type margin_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
template <typename Node>
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<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
@@ -446,7 +449,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
// and again, the same below calling partial_sort/nth_element
// It would be even possible to not re-sort/find nth_element if the axis/corner
// was found for the last sorting - last combination of axis/corner
rstar::choose_split_axis_and_index<Box, dimension>
rstar::choose_split_axis_and_index<box_type, dimension>
::apply(elements_copy,
split_axis, split_corner, split_index,
smallest_sum_of_margins, smallest_overlap, smallest_content,
@@ -479,10 +482,10 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
elements2.assign(elements_copy.begin() + split_index, elements_copy.end()); // MAY THROW, BASIC
// calculate boxes
box1 = rtree::elements_box<Box>(elements1.begin(), elements1.end(),
translator, strategy);
box2 = rtree::elements_box<Box>(elements2.begin(), elements2.end(),
translator, strategy);
box1 = rtree::elements_box<box_type>(elements1.begin(), elements1.end(),
translator, strategy);
box2 = rtree::elements_box<box_type>(elements2.begin(), elements2.end(),
translator, strategy);
}
BOOST_CATCH(...)
{
@@ -490,7 +493,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
elements1.clear();
elements2.clear();
rtree::destroy_elements<Value, Options, Translator, Box, Allocators>::apply(elements_backup, allocators);
rtree::destroy_elements<MembersHolder>::apply(elements_backup, allocators);
//elements_backup.clear();
BOOST_RETHROW // RETHROW, BASIC

View File

@@ -22,17 +22,19 @@ namespace boost { namespace geometry { namespace index { namespace detail { name
namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class are_boxes_ok
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::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<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
public:
are_boxes_ok(parameters_type const& parameters, Translator const& tr, bool exact_match)
are_boxes_ok(parameters_type const& parameters, translator_type const& tr, bool exact_match)
: result(false), m_parameters(parameters), m_tr(tr), m_is_root(true), m_exact_match(exact_match)
{}
@@ -47,7 +49,7 @@ public:
return;
}
Box box_bckup = m_box;
box_type box_bckup = m_box;
bool is_root_bckup = m_is_root;
m_is_root = false;
@@ -66,8 +68,8 @@ public:
m_box = box_bckup;
m_is_root = is_root_bckup;
Box box_exp = rtree::elements_box<Box>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
box_type box_exp = rtree::elements_box<box_type>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
if ( m_exact_match )
result = m_is_root || geometry::equals(box_exp, m_box);
@@ -89,8 +91,8 @@ public:
return;
}
Box box_exp = rtree::values_box<Box>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
box_type box_exp = rtree::values_box<box_type>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
if ( m_exact_match )
result = geometry::equals(box_exp, m_box);
@@ -105,8 +107,8 @@ public:
private:
parameters_type const& m_parameters;
Translator const& m_tr;
Box m_box;
translator_type const& m_tr;
box_type m_box;
bool m_is_root;
bool m_exact_match;
};
@@ -120,11 +122,7 @@ bool are_boxes_ok(Rtree const& tree, bool exact_match = true)
RTV rtv(tree);
visitors::are_boxes_ok<
typename RTV::value_type,
typename RTV::options_type,
typename RTV::translator_type,
typename RTV::box_type,
typename RTV::allocators_type
typename RTV::members_holder
> v(tree.parameters(), rtv.translator(), exact_match);
rtv.apply_visitor(v);

View File

@@ -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 <typename Value, typename Options, typename Box, typename Allocators>
template <typename MembersHolder>
class are_counts_ok
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::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 @@ public:
elements_type const& elements = rtree::elements(n);
// root internal node shouldn't contain 0 elements
if ( elements.empty()
if ( (elements.empty() && m_check_min)
|| !check_count(elements) )
{
result = false;
@@ -62,7 +70,7 @@ public:
elements_type const& elements = rtree::elements(n);
// empty leaf in non-root node
if ( ( m_current_level > 0 && elements.empty() )
if ( (m_current_level > 0 && elements.empty() && m_check_min)
|| !check_count(elements) )
{
result = false;
@@ -78,27 +86,25 @@ private:
// root may contain count < min but should never contain count > max
return elements.size() <= m_parameters.get_max_elements()
&& ( elements.size() >= m_parameters.get_min_elements()
|| m_current_level == 0 );
|| m_current_level == 0 || !m_check_min );
}
size_t m_current_level;
parameters_type const& m_parameters;
bool m_check_min;
};
} // namespace visitors
template <typename Rtree> inline
bool are_counts_ok(Rtree const& tree)
bool are_counts_ok(Rtree const& tree, bool check_min = true)
{
typedef utilities::view<Rtree> 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);

View File

@@ -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 <typename Value, typename Options, typename Box, typename Allocators>
template <typename MembersHolder>
class are_levels_ok
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::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);

View File

@@ -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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct gl_draw : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
template <typename MembersHolder>
struct gl_draw
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::translator_type translator_type;
inline gl_draw(Translator const& t,
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
inline gl_draw(translator_type const& t,
size_t level_first = 0,
size_t level_last = (std::numeric_limits<size_t>::max)(),
typename coordinate_type<Box>::type z_coord_level_multiplier = 1
typename coordinate_type<box_type>::type z_coord_level_multiplier = 1
)
: tr(t)
, level_f(level_first)
@@ -197,10 +205,10 @@ struct gl_draw : public rtree::visitor<Value, typename Options::parameters_type,
}
}
Translator const& tr;
translator_type const& tr;
size_t level_f;
size_t level_l;
typename coordinate_type<Box>::type z_mul;
typename coordinate_type<box_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);

View File

@@ -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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct print : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
template <typename MembersHolder>
struct print
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::translator_type translator_type;
inline print(std::ostream & o, Translator const& t)
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
inline print(std::ostream & o, translator_type const& t)
: os(o), tr(t), level(0)
{}
@@ -189,7 +196,7 @@ struct print : public rtree::visitor<Value, typename Options::parameters_type, B
}
std::ostream & os;
Translator const& tr;
translator_type const& tr;
size_t level;
};
@@ -203,11 +210,7 @@ void print(std::ostream & os, Rtree const& tree)
RTV rtv(tree);
visitors::print<
typename RTV::value_type,
typename RTV::options_type,
typename RTV::translator_type,
typename RTV::box_type,
typename RTV::allocators_type
typename RTV::members_holder
> print_v(os, rtv.translator());
rtv.apply_visitor(print_v);
}

View File

@@ -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 <typename Value, typename Options, typename Box, typename Allocators>
struct statistics : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
template <typename MembersHolder>
struct statistics
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::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);

View File

@@ -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 <typename Rtree>
class view
{
public:
typedef typename Rtree::members_holder members_holder;
typedef typename Rtree::size_type size_type;
typedef typename Rtree::translator_type translator_type;

View File

@@ -19,17 +19,21 @@ namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class children_box
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::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<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
public:
inline children_box(Box & result, parameters_type const& parameters, Translator const& tr)
inline children_box(box_type & result,
parameters_type const& parameters,
translator_type const& tr)
: m_result(result), m_parameters(parameters), m_tr(tr)
{}
@@ -38,8 +42,8 @@ public:
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n);
m_result = rtree::elements_box<Box>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
m_result = rtree::elements_box<box_type>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
}
inline void operator()(leaf const& n)
@@ -47,14 +51,14 @@ public:
typedef typename rtree::elements_type<leaf>::type elements_type;
elements_type const& elements = rtree::elements(n);
m_result = rtree::values_box<Box>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
m_result = rtree::values_box<box_type>(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

View File

@@ -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 <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class copy
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, false>::type
: public MembersHolder::visitor
{
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef rtree::subtree_destroyer<MembersHolder> subtree_destroyer;
typedef typename allocators_type::node_pointer node_pointer;
public:
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
explicit inline copy(Allocators & allocators)
explicit inline copy(allocators_type & allocators)
: result(0)
, m_allocators(allocators)
{}
inline void operator()(internal_node & n)
{
node_pointer raw_new_node = rtree::create_node<Allocators, internal_node>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
node_pointer raw_new_node = rtree::create_node<allocators_type, internal_node>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
subtree_destroyer new_node(raw_new_node, m_allocators);
typedef typename rtree::elements_type<internal_node>::type elements_type;
@@ -61,7 +69,7 @@ public:
inline void operator()(leaf & l)
{
node_pointer raw_new_node = rtree::create_node<Allocators, leaf>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
node_pointer raw_new_node = rtree::create_node<allocators_type, leaf>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
subtree_destroyer new_node(raw_new_node, m_allocators);
typedef typename rtree::elements_type<leaf>::type elements_type;
@@ -82,7 +90,7 @@ public:
node_pointer result;
private:
Allocators & m_allocators;
allocators_type & m_allocators;
};
}}} // namespace detail::rtree::visitors

View File

@@ -49,19 +49,21 @@ struct count_helper<Value, Value>
}
};
template <typename ValueOrIndexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename ValueOrIndexable, typename MembersHolder>
struct count
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::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<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef count_helper<ValueOrIndexable, Value> count_help;
typedef count_helper<ValueOrIndexable, value_type> 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

View File

@@ -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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class destroy
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, false>::type
: public MembersHolder::visitor
{
public:
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::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 @@ public:
it->second = 0;
}
rtree::destroy_node<Allocators, internal_node>::apply(m_allocators, node_to_destroy);
rtree::destroy_node<allocators_type, internal_node>::apply(m_allocators, node_to_destroy);
}
inline void operator()(leaf & l)
@@ -56,12 +61,18 @@ public:
boost::ignore_unused(l);
BOOST_GEOMETRY_INDEX_ASSERT(&l == &rtree::get<leaf>(*m_current_node), "invalid pointers");
rtree::destroy_node<Allocators, leaf>::apply(m_allocators, m_current_node);
rtree::destroy_node<allocators_type, leaf>::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

View File

@@ -93,39 +93,41 @@ private:
std::vector< std::pair<distance_type, Value> > 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<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::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<parameters_type>::type strategy_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef index::detail::predicates_element<DistancePredicateIndex, Predicates> nearest_predicate_access;
typedef typename nearest_predicate_access::type nearest_predicate_type;
typedef typename indexable_type<Translator>::type indexable_type;
typedef typename indexable_type<translator_type>::type indexable_type;
typedef index::detail::calculate_distance<nearest_predicate_type, indexable_type, strategy_type, value_tag> calculate_value_distance;
typedef index::detail::calculate_distance<nearest_predicate_type, Box, strategy_type, bounds_tag> calculate_node_distance;
typedef index::detail::calculate_distance<nearest_predicate_type, box_type, strategy_type, bounds_tag> 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<Predicates>::value;
inline distance_query(parameters_type const& parameters, Translator const& translator, Predicates const& pred, OutIter out_it)
inline distance_query(parameters_type const& parameters, translator_type const& translator, Predicates const& pred, OutIter out_it)
: m_parameters(parameters), m_translator(translator)
, m_pred(pred)
, m_result(nearest_predicate_access::get(m_pred).count, out_it)
@@ -139,7 +141,7 @@ public:
// array of active nodes
typedef typename index::detail::rtree::container_from_elements_type<
elements_type,
std::pair<node_distance_type, typename Allocators::node_pointer>
std::pair<node_distance_type, typename allocators_type::node_pointer>
>::type active_branch_list_type;
active_branch_list_type active_branch_list;
@@ -261,15 +263,15 @@ public:
private:
static inline bool abl_less(
std::pair<node_distance_type, typename Allocators::node_pointer> const& p1,
std::pair<node_distance_type, typename Allocators::node_pointer> const& p2)
std::pair<node_distance_type, typename allocators_type::node_pointer> const& p1,
std::pair<node_distance_type, typename allocators_type::node_pointer> const& p2)
{
return p1.first < p2.first;
}
//static inline bool abl_greater(
// std::pair<node_distance_type, typename Allocators::node_pointer> const& p1,
// std::pair<node_distance_type, typename Allocators::node_pointer> const& p2)
// std::pair<node_distance_type, typename allocators_type::node_pointer> const& p1,
// std::pair<node_distance_type, typename allocators_type::node_pointer> const& p2)
//{
// return p1.first > p2.first;
//}
@@ -286,46 +288,47 @@ private:
}
parameters_type const& m_parameters;
Translator const& m_translator;
translator_type const& m_translator;
Predicates m_pred;
distance_query_result<Value, Translator, value_distance_type, OutIter> m_result;
distance_query_result<value_type, translator_type, value_distance_type, OutIter> 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<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::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<parameters_type>::type strategy_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef index::detail::predicates_element<DistancePredicateIndex, Predicates> nearest_predicate_access;
typedef typename nearest_predicate_access::type nearest_predicate_type;
typedef typename indexable_type<Translator>::type indexable_type;
typedef typename indexable_type<translator_type>::type indexable_type;
typedef index::detail::calculate_distance<nearest_predicate_type, indexable_type, strategy_type, value_tag> calculate_value_distance;
typedef index::detail::calculate_distance<nearest_predicate_type, Box, strategy_type, bounds_tag> calculate_node_distance;
typedef index::detail::calculate_distance<nearest_predicate_type, box_type, strategy_type, bounds_tag> 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<Predicates>::value;
@@ -362,7 +365,7 @@ public:
// , m_strategy_type()
{}
inline distance_query_incremental(parameters_type const& params, Translator const& translator, Predicates const& pred)
inline distance_query_incremental(parameters_type const& params, translator_type const& translator, Predicates const& pred)
: m_translator(::boost::addressof(translator))
, m_pred(pred)
, current_neighbor((std::numeric_limits<size_type>::max)())
@@ -552,14 +555,14 @@ public:
}
private:
static inline bool abl_less(std::pair<node_distance_type, typename Allocators::node_pointer> const& p1,
std::pair<node_distance_type, typename Allocators::node_pointer> const& p2)
static inline bool abl_less(std::pair<node_distance_type, node_pointer> const& p1,
std::pair<node_distance_type, node_pointer> const& p2)
{
return p1.first < p2.first;
}
static inline bool neighbors_less(std::pair<value_distance_type, const Value *> const& p1,
std::pair<value_distance_type, const Value *> const& p2)
static inline bool neighbors_less(std::pair<value_distance_type, const value_type *> const& p1,
std::pair<value_distance_type, const value_type *> const& p2)
{
return p1.first < p2.first;
}
@@ -597,12 +600,12 @@ private:
return nearest_predicate_access::get(m_pred);
}
const Translator * m_translator;
const translator_type * m_translator;
Predicates m_pred;
internal_stack_type internal_stack;
std::vector< std::pair<value_distance_type, const Value *> > neighbors;
std::vector< std::pair<value_distance_type, const value_type *> > neighbors;
size_type current_neighbor;
node_distance_type next_closest_node_distance;

View File

@@ -23,27 +23,34 @@
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/algorithms/content.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
// Default choose_next_node
template <typename Value, typename Options, typename Box, typename Allocators, typename ChooseNextNodeTag>
template
<
typename MembersHolder,
typename ChooseNextNodeTag = typename MembersHolder::options_type::choose_next_node_tag
>
class choose_next_node;
template <typename Value, typename Options, typename Box, typename Allocators>
class choose_next_node<Value, Options, Box, Allocators, choose_by_content_diff_tag>
template <typename MembersHolder>
class choose_next_node<MembersHolder, choose_by_content_diff_tag>
{
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<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef typename rtree::elements_type<internal_node>::type children_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
template <typename Indexable>
static inline size_t apply(internal_node & n,
@@ -69,7 +76,7 @@ public:
child_type const& ch_i = children[i];
// expanded child node's box
Box box_exp(ch_i.first);
box_type box_exp(ch_i.first);
index::detail::expand(box_exp, indexable,
index::detail::get_strategy(parameters));
@@ -94,7 +101,11 @@ public:
// ----------------------------------------------------------------------- //
// Not implemented here
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename RedistributeTag>
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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename SplitTag>
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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class split<Value, Options, Translator, Box, Allocators, split_default_tag>
template <typename MembersHolder>
class split<MembersHolder, split_default_tag>
{
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<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename MembersHolder::node_pointer node_pointer;
public:
typedef index::detail::varray<
@@ -137,51 +156,63 @@ public:
template <typename Node>
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<Allocators, Node>::apply(allocators), allocators); // MAY THROW, STRONG (N: alloc)
node_pointer n2_ptr = rtree::create_node<allocators_type, Node>::apply(allocators); // MAY THROW, STRONG (N: alloc)
// create reference to the newly created node
Node & n2 = rtree::get<Node>(*second_node);
Node & n2 = rtree::get<Node>(*n2_ptr);
// NOTE: thread-safety
// After throwing an exception by redistribute_elements the original node may be not changed or
// both nodes may be empty. In both cases the tree won't be valid r-tree.
// The alternative is to create 2 (or more) additional nodes here and store backup info
// in the original node, then, if exception was thrown, the node would always have more than max
// elements.
// The alternative is to use moving semantics in the implementations of redistribute_elements,
// it will be possible to throw from boost::move() in the case of e.g. static size nodes.
BOOST_TRY
{
// NOTE: thread-safety
// After throwing an exception by redistribute_elements the original node may be not changed or
// both nodes may be empty. In both cases the tree won't be valid r-tree.
// The alternative is to create 2 (or more) additional nodes here and store backup info
// in the original node, then, if exception was thrown, the node would always have more than max
// elements.
// The alternative is to use moving semantics in the implementations of redistribute_elements,
// it will be possible to throw from boost::move() in the case of e.g. static size nodes.
// redistribute elements
Box 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)
// redistribute elements
box_type box2;
redistribute_elements<MembersHolder>
::apply(n, n2, n_box, box2, parameters, translator, allocators); // MAY THROW (V, E: alloc, copy, copy)
// check numbers of elements
BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n).size() &&
rtree::elements(n).size() <= parameters.get_max_elements(),
"unexpected number of elements");
BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n2).size() &&
rtree::elements(n2).size() <= parameters.get_max_elements(),
"unexpected number of elements");
// check numbers of elements
BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n).size() &&
rtree::elements(n).size() <= parameters.get_max_elements(),
"unexpected number of elements");
BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n2).size() &&
rtree::elements(n2).size() <= parameters.get_max_elements(),
"unexpected number of elements");
// return the list of newly created nodes (this algorithm returns one)
additional_nodes.push_back(rtree::make_ptr_pair(box2, second_node.get())); // MAY THROW, STRONG (alloc, copy)
// return the list of newly created nodes (this algorithm returns one)
additional_nodes.push_back(rtree::make_ptr_pair(box2, n2_ptr)); // MAY THROW, STRONG (alloc, copy)
}
BOOST_CATCH(...)
{
// NOTE: This code is here to prevent leaving the rtree in a state
// after an exception is thrown in which pushing new element could
// result in assert or putting it outside the memory of node elements.
typename rtree::elements_type<Node>::type & elements = rtree::elements(n);
size_type const max_size = parameters.get_max_elements();
if (elements.size() > max_size)
{
rtree::destroy_element<MembersHolder>::apply(elements[max_size], allocators);
elements.pop_back();
}
// release the ptr
second_node.release();
rtree::visitors::destroy<MembersHolder>::apply(n2_ptr, allocators);
BOOST_RETHROW
}
BOOST_CATCH_END
}
};
@@ -232,30 +263,34 @@ struct insert_traverse_data
};
// Default insert visitor
template <typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename Element, typename MembersHolder>
class insert
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, false>::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<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
typedef rtree::subtree_destroyer<MembersHolder> 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 @@ protected:
// It's because Points and Segments are compared WRT machine epsilon
// This ensures that leafs bounds correspond to the stored elements
if (BOOST_GEOMETRY_CONDITION((
boost::is_same<Element, Value>::value
boost::is_same<Element, value_type>::value
&& ! index::detail::is_bounding_geometry
<
typename indexable_type<Translator>::type
typename indexable_type<translator_type>::type
>::value )) )
{
geometry::detail::expand_by_epsilon(m_element_bounds);
@@ -304,8 +339,10 @@ protected:
inline void traverse(Visitor & visitor, internal_node & n)
{
// choose next node
size_t choosen_node_index = rtree::choose_next_node<Value, Options, Box, Allocators, typename Options::choose_next_node_tag>::
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<MembersHolder>
::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 @@ protected:
template <typename Node>
inline void split(Node & n) const
{
typedef rtree::split<Value, Options, Translator, Box, Allocators, typename Options::split_tag> split_algo;
typedef rtree::split<MembersHolder> 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 @@ protected:
boost::is_same<Node, leaf>::value
&& ! index::detail::is_bounding_geometry
<
typename indexable_type<Translator>::type
typename indexable_type<translator_type>::type
>::value )))
{
geometry::detail::expand_by_epsilon(n_box);
@@ -409,7 +446,7 @@ protected:
BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get<Node>(*m_root_node), "node should be the root");
// create new root and add nodes
subtree_destroyer new_root(rtree::create_node<Allocators, internal_node>::apply(m_allocators), m_allocators); // MAY THROW, STRONG (N:alloc)
subtree_destroyer new_root(rtree::create_node<allocators_type, internal_node>::apply(m_allocators), m_allocators); // MAY THROW, STRONG (N:alloc)
BOOST_TRY
{
@@ -436,9 +473,9 @@ protected:
// TODO: awulkiew - implement dispatchable split::apply to enable additional nodes creation
Element const& m_element;
Box m_element_bounds;
box_type m_element_bounds;
parameters_type const& m_parameters;
Translator const& m_translator;
translator_type const& m_translator;
size_type const m_relative_level;
size_type const m_level;
@@ -448,30 +485,39 @@ protected:
// traversing input parameters
insert_traverse_data<internal_node, internal_node_pointer, size_type> m_traverse_data;
Allocators & m_allocators;
allocators_type & m_allocators;
};
} // namespace detail
// Insert visitor forward declaration
template <typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename InsertTag>
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 <typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class insert<Element, Value, Options, Translator, Box, Allocators, insert_default_tag>
: public detail::insert<Element, Value, Options, Translator, Box, Allocators>
template <typename Element, typename MembersHolder>
class insert<Element, MembersHolder, insert_default_tag>
: public detail::insert<Element, MembersHolder>
{
public:
typedef detail::insert<Element, Value, Options, Translator, Box, Allocators> base;
typedef detail::insert<Element, MembersHolder> 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 @@ public:
size_type & leafs_level,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
translator_type const& translator,
allocators_type & allocators,
size_type relative_level = 0
)
: base(root, leafs_level, element, parameters, translator, allocators, relative_level)
@@ -508,8 +554,7 @@ public:
{
// if the insert fails above, the element won't be stored in the tree
rtree::visitors::destroy<Value, Options, Translator, Box, Allocators> del_v(base::m_element.second, base::m_allocators);
rtree::apply_visitor(del_v, *base::m_element.second);
rtree::visitors::destroy<MembersHolder>::apply(base::m_element.second, base::m_allocators);
BOOST_RETHROW // RETHROW
}
@@ -526,26 +571,31 @@ public:
};
// Default insert visitor specialized for Values elements
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class insert<Value, Value, Options, Translator, Box, Allocators, insert_default_tag>
: public detail::insert<Value, Value, Options, Translator, Box, Allocators>
template <typename MembersHolder>
class insert<typename MembersHolder::value_type, MembersHolder, insert_default_tag>
: public detail::insert<typename MembersHolder::value_type, MembersHolder>
{
public:
typedef detail::insert<Value, Value, Options, Translator, Box, Allocators> base;
typedef detail::insert<typename MembersHolder::value_type, MembersHolder> 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)

View File

@@ -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 <typename Value, typename Options, typename Box, typename Allocators>
struct is_leaf : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
template <typename MembersHolder>
struct is_leaf
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
is_leaf()
: result(false)

View File

@@ -15,6 +15,7 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_REMOVE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_REMOVE_HPP
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
#include <boost/geometry/algorithms/detail/covered_by/interface.hpp>
@@ -24,19 +25,23 @@ namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
// Default remove algorithm
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class remove
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, false>::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<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
typedef rtree::subtree_destroyer<MembersHolder> subtree_destroyer;
typedef typename allocators_type::node_pointer node_pointer;
typedef typename allocators_type::size_type size_type;
typedef typename rtree::elements_type<internal_node>::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 @@ public:
BOOST_GEOMETRY_INDEX_ASSERT((elements.size() < m_parameters.get_min_elements()) == m_is_underflow, "unexpected state");
rtree::elements(*m_parent)[m_current_child_index].first
= rtree::elements_box<Box>(elements.begin(), elements.end(), m_translator,
index::detail::get_strategy(m_parameters));
= rtree::elements_box<box_type>(elements.begin(), elements.end(), m_translator,
index::detail::get_strategy(m_parameters));
}
// n is root node
else
@@ -140,7 +145,7 @@ public:
m_root_node = rtree::elements(n)[0].second;
--m_leafs_level;
rtree::destroy_node<Allocators, internal_node>::apply(m_allocators, root_to_destroy);
rtree::destroy_node<allocators_type, internal_node>::apply(m_allocators, root_to_destroy);
}
}
}
@@ -175,8 +180,8 @@ public:
if ( 0 != m_parent )
{
rtree::elements(*m_parent)[m_current_child_index].first
= rtree::values_box<Box>(elements.begin(), elements.end(), m_translator,
index::detail::get_strategy(m_parameters));
= rtree::values_box<box_type>(elements.begin(), elements.end(), m_translator,
index::detail::get_strategy(m_parameters));
}
}
}
@@ -188,7 +193,7 @@ public:
private:
typedef std::vector< std::pair<size_type, node_pointer> > UnderflowNodes;
typedef std::vector< std::pair<size_type, node_pointer> > underflow_nodes;
void traverse_apply_visitor(internal_node &n, internal_size_type choosen_node_index)
{
@@ -239,14 +244,14 @@ private:
static inline bool is_leaf(node const& n)
{
visitors::is_leaf<Value, Options, Box, Allocators> ilv;
visitors::is_leaf<MembersHolder> 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 @@ private:
{
reinsert_node_elements(rtree::get<leaf>(*it->second), it->first); // MAY THROW (V, E: alloc, copy, N: alloc)
rtree::destroy_node<Allocators, leaf>::apply(m_allocators, it->second);
rtree::destroy_node<allocators_type, leaf>::apply(m_allocators, it->second);
}
else
{
reinsert_node_elements(rtree::get<internal_node>(*it->second), it->first); // MAY THROW (V, E: alloc, copy, N: alloc)
rtree::destroy_node<Allocators, internal_node>::apply(m_allocators, it->second);
rtree::destroy_node<allocators_type, internal_node>::apply(m_allocators, it->second);
}
}
@@ -279,7 +284,7 @@ private:
// destroy current and remaining nodes
for ( ; it != m_underflowed_nodes.rend() ; ++it )
{
subtree_destroyer dummy(it->second, m_allocators);
rtree::visitors::destroy<MembersHolder>::apply(it->second, m_allocators);
}
//m_underflowed_nodes.clear();
@@ -300,14 +305,10 @@ private:
{
for ( ; it != elements.end() ; ++it )
{
visitors::insert<
typename elements_type::value_type,
Value, Options, Translator, Box, Allocators,
typename Options::insert_tag
> insert_v(
m_root_node, m_leafs_level, *it,
m_parameters, m_translator, m_allocators,
node_relative_level - 1);
visitors::insert<typename elements_type::value_type, MembersHolder>
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 @@ private:
BOOST_CATCH(...)
{
++it;
rtree::destroy_elements<Value, Options, Translator, Box, Allocators>
::apply(it, elements.end(), m_allocators);
rtree::destroy_elements<MembersHolder>::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;

View File

@@ -19,22 +19,25 @@ namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates, typename OutIter>
template <typename MembersHolder, typename Predicates, typename OutIter>
struct spatial_query
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::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<parameters_type>::type strategy_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::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<Predicates>::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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates>
template <typename MembersHolder, typename Predicates>
class spatial_query_incremental
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::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<parameters_type>::type strategy_type;
public:
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::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<internal_node>::type::const_iterator internal_iterator;
typedef typename rtree::elements_type<leaf>::type leaf_elements;
@@ -122,7 +129,7 @@ public:
// , m_strategy()
{}
inline spatial_query_incremental(parameters_type const& params, Translator const& t, Predicates const& p)
inline spatial_query_incremental(parameters_type const& params, translator_type const& t, Predicates const& p)
: m_translator(::boost::addressof(t))
, m_pred(p)
, m_values(NULL)
@@ -172,7 +179,7 @@ public:
if ( m_current != m_values->end() )
{
// return if next value is found
Value const& v = *m_current;
value_type const& v = *m_current;
if (index::detail::predicates_check
<
index::detail::value_tag, 0, predicates_len
@@ -230,7 +237,7 @@ public:
private:
const Translator * m_translator;
const translator_type * m_translator;
Predicates m_pred;

View File

@@ -343,22 +343,29 @@ private:
// TODO - move to index/detail/rtree/load.hpp
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class load
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef typename Allocators::node_pointer node_pointer;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::size_type size_type;
typedef typename allocators_type::node_pointer node_pointer;
typedef typename allocators_type::size_type size_type;
typedef rtree::subtree_destroyer<MembersHolder> subtree_destroyer;
public:
template <typename Archive> inline static
node_pointer apply(Archive & ar, unsigned int version, size_type leafs_level, size_type & values_count, parameters_type const& parameters, Translator const& translator, Allocators & allocators)
node_pointer apply(Archive & ar, unsigned int version, size_type leafs_level,
size_type & values_count,
parameters_type const& parameters,
translator_type const& translator,
allocators_type & allocators)
{
values_count = 0;
return raw_apply(ar, version, leafs_level, values_count, parameters, translator, allocators);
@@ -366,7 +373,12 @@ public:
private:
template <typename Archive> 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");

View File

@@ -190,51 +190,119 @@ public:
private:
typedef detail::translator<IndexableGetter, EqualTo> translator_type;
typedef bounds_type box_type;
typedef typename detail::rtree::options_type<Parameters>::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;
struct members_holder
: public detail::translator<IndexableGetter, EqualTo>
, public Parameters
, public detail::rtree::allocators
<
Allocator,
Value,
Parameters,
bounds_type,
typename detail::rtree::options_type<Parameters>::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 typename allocators_type::node_pointer node_pointer;
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef detail::rtree::subtree_destroyer
<
value_type, options_type, translator_type, box_type, allocators_type
> subtree_destroyer;
typedef bounds_type box_type;
typedef detail::translator<IndexableGetter, EqualTo> translator_type;
typedef typename detail::rtree::options_type<Parameters>::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> 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 <typename IndGet, typename ValEq, typename Alloc>
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>(alloc))
, values_count(0)
, leafs_level(0)
, root(0)
{}
template <typename IndGet, typename ValEq>
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<rtree>;
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -330,10 +398,11 @@ public:
allocator_type const& allocator = allocator_type())
: m_members(getter, equal, parameters, allocator)
{
typedef detail::rtree::pack<value_type, options_type, translator_type, box_type, allocators_type> pack;
typedef detail::rtree::pack<members_holder> 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 @@ public:
allocator_type const& allocator = allocator_type())
: m_members(getter, equal, parameters, allocator)
{
typedef detail::rtree::pack<value_type, options_type, translator_type, box_type, allocators_type> pack;
typedef detail::rtree::pack<members_holder> 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 @@ private:
template <typename Predicates>
typename boost::mpl::if_c<
detail::predicates_count_distance<Predicates>::value == 0,
detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
detail::rtree::iterators::spatial_query_iterator<members_holder, Predicates>,
detail::rtree::iterators::distance_query_iterator<
value_type, options_type, translator_type, box_type, allocators_type, Predicates,
members_holder, Predicates,
detail::predicates_find_distance<Predicates>::value
>
>::type
@@ -1036,9 +1106,9 @@ private:
typedef typename boost::mpl::if_c<
detail::predicates_count_distance<Predicates>::value == 0,
detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
detail::rtree::iterators::spatial_query_iterator<members_holder, Predicates>,
detail::rtree::iterators::distance_query_iterator<
value_type, options_type, translator_type, box_type, allocators_type, Predicates,
members_holder, Predicates,
detail::predicates_find_distance<Predicates>::value
>
>::type iterator_type;
@@ -1084,9 +1154,9 @@ private:
template <typename Predicates>
typename boost::mpl::if_c<
detail::predicates_count_distance<Predicates>::value == 0,
detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
detail::rtree::iterators::spatial_query_iterator<members_holder, Predicates>,
detail::rtree::iterators::distance_query_iterator<
value_type, options_type, translator_type, box_type, allocators_type, Predicates,
members_holder, Predicates,
detail::predicates_find_distance<Predicates>::value
>
>::type
@@ -1097,9 +1167,9 @@ private:
typedef typename boost::mpl::if_c<
detail::predicates_count_distance<Predicates>::value == 0,
detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
detail::rtree::iterators::spatial_query_iterator<members_holder, Predicates>,
detail::rtree::iterators::distance_query_iterator<
value_type, options_type, translator_type, box_type, allocators_type, Predicates,
members_holder, Predicates,
detail::predicates_find_distance<Predicates>::value
>
>::type iterator_type;
@@ -1305,7 +1375,7 @@ public:
{
detail::rtree::visitors::children_box
<
value_type, options_type, translator_type, box_type, allocators_type
members_holder
> box_v(result, m_members.parameters(), m_members.translator());
detail::rtree::apply_visitor(box_v, *m_members.root);
}
@@ -1468,12 +1538,9 @@ private:
// CONSIDER: alternative - ignore invalid indexable or throw an exception
BOOST_GEOMETRY_INDEX_ASSERT(detail::is_valid(m_members.translator()(value)), "Indexable is invalid");
detail::rtree::visitors::insert<
value_type,
value_type, options_type, translator_type, box_type, allocators_type,
typename options_type::insert_tag
> insert_v(m_members.root, m_members.leafs_level, value,
m_members.parameters(), m_members.translator(), m_members.allocators());
detail::rtree::visitors::insert<value_type, members_holder>
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 @@ private:
// TODO: awulkiew - assert for correct value (indexable) ?
BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
detail::rtree::visitors::remove<
value_type, options_type, translator_type, box_type, allocators_type
> remove_v(m_members.root, m_members.leafs_level, value,
m_members.parameters(), m_members.translator(), m_members.allocators());
detail::rtree::visitors::remove<members_holder>
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 @@ private:
{
if ( t.m_members.root )
{
detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
del_v(t.m_members.root, t.m_members.allocators());
detail::rtree::apply_visitor(del_v, *t.m_members.root);
detail::rtree::visitors::destroy<members_holder>
::apply(t.m_members.root, t.m_members.allocators());
t.m_members.root = 0;
}
@@ -1570,8 +1635,7 @@ private:
*/
inline void raw_copy(rtree const& src, rtree & dst, bool copy_tr_and_params) const
{
detail::rtree::visitors::copy<value_type, options_type, translator_type, box_type, allocators_type>
copy_v(dst.m_members.allocators());
detail::rtree::visitors::copy<members_holder> 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 @@ private:
// TODO use subtree_destroyer
if ( dst.m_members.root )
{
detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
del_v(dst.m_members.root, dst.m_members.allocators());
detail::rtree::apply_visitor(del_v, *dst.m_members.root);
detail::rtree::visitors::destroy<members_holder>
::apply(dst.m_members.root, dst.m_members.allocators());
dst.m_members.root = 0;
}
@@ -1680,10 +1744,8 @@ private:
template <typename Predicates, typename OutIter>
size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<false> 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<members_holder, Predicates, OutIter>
find_v(m_members.parameters(), m_members.translator(), predicates, out_it);
detail::rtree::apply_visitor(find_v, *m_members.root);
@@ -1703,11 +1765,7 @@ private:
static const unsigned distance_predicate_index = detail::predicates_find_distance<Predicates>::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 @@ private:
detail::rtree::visitors::count
<
ValueOrIndexable,
value_type,
options_type,
translator_type,
box_type,
allocators_type
members_holder
> count_v(vori, m_members.parameters(), m_members.translator());
detail::rtree::apply_visitor(count_v, *m_members.root);
@@ -1744,57 +1798,6 @@ private:
return count_v.found_count;
}
struct members_holder
: public translator_type
, public Parameters
, public allocators_type
{
private:
members_holder(members_holder const&);
members_holder & operator=(members_holder const&);
public:
template <typename IndGet, typename ValEq, typename Alloc>
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>(alloc))
, values_count(0)
, leafs_level(0)
, root(0)
{}
template <typename IndGet, typename ValEq>
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;
};

View File

@@ -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());
}
}

View File

@@ -26,8 +26,9 @@
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp>
#include <boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp>
#include <boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp>
#include <boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp>
//#include <boost/geometry/geometries/ring.hpp>
//#include <boost/geometry/geometries/polygon.hpp>