update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 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,13 +15,13 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ADAPTORS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ADAPTORS_HPP
#include <deque>
#include <boost/static_assert.hpp>
#include <vector>
#include <boost/geometry/index/adaptors/query.hpp>
namespace boost { namespace geometry { namespace index {
// Forward declaration
template <typename Value, typename Options, typename IndexableGetter, typename EqualTo, typename Allocator>
class rtree;

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 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,6 +15,10 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
#include <iterator>
#include <boost/geometry/index/detail/rtree/visitors/iterator.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
template <typename Value, typename Allocators>
@@ -112,7 +120,7 @@ public:
{
return r.m_visitor.is_end();
}
private:
visitor_type m_visitor;
};

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 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,6 +15,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_KMEANS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_KMEANS_HPP
#include <boost/geometry/index/rtree/kmeans/split.hpp>
#include <boost/geometry/index/detail/rtree/kmeans/split.hpp>
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_KMEANS_HPP

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 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,13 +15,17 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_SPLIT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_SPLIT_HPP
#include <boost/geometry/index/rtree/node/node.hpp>
#include <boost/geometry/index/rtree/visitors/insert.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
// TODO: This should be defined in options.hpp
// For now it's defined here to satisfy Boost header policy
struct split_kmeans_tag {};
namespace kmeans {
// some details
@@ -56,25 +64,34 @@ namespace kmeans {
// 4. Pamietac o parametryzacji kontenera z nadmiarowymi elementami
// PS. Z R* reinsertami moze byc masakra
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class split<Value, Options, Translator, Box, Allocators, split_kmeans_tag>
template <typename MembersHolder>
class split<MembersHolder, split_kmeans_tag>
{
protected:
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::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 Options::parameters_type parameters_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
public:
typedef index::detail::varray
<
typename rtree::elements_type<internal_node>::type::value_type,
1
> nodes_container_type;
template <typename Node>
static inline void apply(node* & root_node,
size_t & leafs_level,
static inline void apply(nodes_container_type & additional_nodes,
Node & n,
internal_node *parent_node,
size_t current_child_index,
Translator const& tr,
Allocators & allocators)
box_type & n_box,
parameters_type const& parameters,
translator_type const& translator,
allocators_type & allocators)
{
}

View File

@@ -3,7 +3,11 @@
// R-tree linear split algorithm implementation
//
// Copyright (c) 2008 Federico J. Fernandez.
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2022 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2020.
// Modifications copyright (c) 2019-2020 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
@@ -12,9 +16,13 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_LINEAR_REDISTRIBUTE_ELEMENTS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_LINEAR_REDISTRIBUTE_ELEMENTS_HPP
#include <boost/core/ignore_unused.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <type_traits>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/algorithms/content.hpp>
#include <boost/geometry/index/detail/bounded_view.hpp>
@@ -29,13 +37,13 @@ namespace detail { namespace rtree {
namespace linear {
template <typename R, typename T>
inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_<false> const& /*is_unsigned*/)
inline R difference_dispatch(T const& from, T const& to, std::false_type /*is_unsigned*/)
{
return to - from;
}
template <typename R, typename T>
inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_<true> const& /*is_unsigned*/)
inline R difference_dispatch(T const& from, T const& to, std::true_type /*is_unsigned*/)
{
return from <= to ? R(to - from) : -R(from - to);
}
@@ -43,13 +51,11 @@ inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_<tru
template <typename R, typename T>
inline R difference(T const& from, T const& to)
{
BOOST_MPL_ASSERT_MSG(!boost::is_unsigned<R>::value, RESULT_CANT_BE_UNSIGNED, (R));
BOOST_GEOMETRY_STATIC_ASSERT((! std::is_unsigned<R>::value),
"Result can not be an unsigned type.",
R);
typedef ::boost::mpl::bool_<
boost::is_unsigned<T>::value
> is_unsigned;
return difference_dispatch<R>(from, to, is_unsigned());
return difference_dispatch<R>(from, to, std::is_unsigned<T>());
}
// TODO: awulkiew
@@ -82,15 +88,20 @@ struct find_greatest_normalized_separation
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef typename boost::mpl::if_c<
boost::is_integral<coordinate_type>::value,
double,
coordinate_type
>::type separation_type;
typedef std::conditional_t
<
std::is_integral<coordinate_type>::value,
double,
coordinate_type
> separation_type;
typedef typename geometry::point_type<indexable_type>::type point_type;
typedef geometry::model::box<point_type> bounds_type;
typedef index::detail::bounded_view<indexable_type, bounds_type> bounded_view_type;
typedef index::detail::bounded_view
<
indexable_type, bounds_type,
typename index::detail::strategy_type<Parameters>::type
> bounded_view_type;
static inline void apply(Elements const& elements,
Parameters const& parameters,
@@ -103,43 +114,52 @@ struct find_greatest_normalized_separation
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected number of elements");
BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
auto const& strategy = index::detail::get_strategy(parameters);
// find the lowest low, highest high
bounded_view_type bounded_indexable_0(rtree::element_indexable(elements[0], translator));
indexable_type const& indexable_0 = rtree::element_indexable(elements[0], translator);
bounded_view_type const bounded_indexable_0(indexable_0, strategy);
coordinate_type lowest_low = geometry::get<min_corner, DimensionIndex>(bounded_indexable_0);
coordinate_type highest_high = geometry::get<max_corner, DimensionIndex>(bounded_indexable_0);
// and the lowest high
coordinate_type lowest_high = highest_high;
size_t lowest_high_index = 0;
for ( size_t i = 1 ; i < elements_count ; ++i )
for (size_t i = 1 ; i < elements_count ; ++i)
{
bounded_view_type bounded_indexable(rtree::element_indexable(elements[i], translator));
indexable_type const& indexable_i = rtree::element_indexable(elements[i], translator);
bounded_view_type const bounded_indexable(indexable_i, strategy);
coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(bounded_indexable);
coordinate_type max_coord = geometry::get<max_corner, DimensionIndex>(bounded_indexable);
if ( max_coord < lowest_high )
if (max_coord < lowest_high)
{
lowest_high = max_coord;
lowest_high_index = i;
}
if ( min_coord < lowest_low )
if (min_coord < lowest_low)
{
lowest_low = min_coord;
}
if ( highest_high < max_coord )
if (highest_high < max_coord)
{
highest_high = max_coord;
}
}
// find the highest low
size_t highest_low_index = lowest_high_index == 0 ? 1 : 0;
bounded_view_type bounded_indexable_hl(rtree::element_indexable(elements[highest_low_index], translator));
indexable_type const& indexable_hl = rtree::element_indexable(elements[highest_low_index], translator);
bounded_view_type const bounded_indexable_hl(indexable_hl, strategy);
coordinate_type highest_low = geometry::get<min_corner, DimensionIndex>(bounded_indexable_hl);
for ( size_t i = highest_low_index ; i < elements_count ; ++i )
for (size_t i = highest_low_index ; i < elements_count ; ++i)
{
bounded_view_type bounded_indexable(rtree::element_indexable(elements[i], translator));
indexable_type const& indexable = rtree::element_indexable(elements[i], translator);
bounded_view_type const bounded_indexable(indexable, strategy);
coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(bounded_indexable);
if ( highest_low < min_coord &&
i != lowest_high_index )
if (highest_low < min_coord && i != lowest_high_index)
{
highest_low = min_coord;
highest_low_index = i;
@@ -147,12 +167,14 @@ struct find_greatest_normalized_separation
}
coordinate_type const width = highest_high - lowest_low;
// highest_low - lowest_high
separation = difference<separation_type>(lowest_high, highest_low);
// BOOST_GEOMETRY_INDEX_ASSERT(0 <= width);
if ( std::numeric_limits<coordinate_type>::epsilon() < width )
if (std::numeric_limits<coordinate_type>::epsilon() < width)
{
separation /= width;
}
seed1 = highest_low_index;
seed2 = lowest_high_index;
@@ -306,28 +328,34 @@ 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);
elements_type & elements1 = rtree::elements(n);
elements_type & elements2 = rtree::elements(second_node);
@@ -357,8 +385,10 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
elements2.push_back(elements_copy[seed2]); // MAY THROW, STRONG (alloc, copy)
// calculate boxes
detail::bounds(rtree::element_indexable(elements_copy[seed1], translator), box1);
detail::bounds(rtree::element_indexable(elements_copy[seed2], translator), box2);
detail::bounds(rtree::element_indexable(elements_copy[seed1], translator),
box1, strategy);
detail::bounds(rtree::element_indexable(elements_copy[seed2], translator),
box2, strategy);
// initialize areas
content_type content1 = index::detail::content(box1);
@@ -380,23 +410,23 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
if ( elements1.size() + remaining <= parameters.get_min_elements() )
{
elements1.push_back(elem); // MAY THROW, STRONG (copy)
geometry::expand(box1, indexable);
index::detail::expand(box1, indexable, strategy);
content1 = index::detail::content(box1);
}
else if ( elements2.size() + remaining <= parameters.get_min_elements() )
{
elements2.push_back(elem); // MAY THROW, STRONG (alloc, copy)
geometry::expand(box2, indexable);
index::detail::expand(box2, indexable, strategy);
content2 = index::detail::content(box2);
}
// choose better node and insert element
else
{
// calculate enlarged boxes and areas
Box enlarged_box1(box1);
Box enlarged_box2(box2);
geometry::expand(enlarged_box1, indexable);
geometry::expand(enlarged_box2, indexable);
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);
content_type enlarged_content2 = index::detail::content(enlarged_box2);
@@ -420,7 +450,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
content2 = enlarged_content2;
}
}
BOOST_GEOMETRY_INDEX_ASSERT(0 < remaining, "unexpected value");
--remaining;
}
@@ -431,7 +461,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

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020 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,6 +15,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_CONCEPT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_CONCEPT_HPP
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
@@ -18,64 +24,57 @@ namespace detail { namespace rtree {
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct node
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TAG_TYPE,
(node));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Tag type.",
Value, Parameters, Box, Allocators, Tag);
};
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct internal_node
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TAG_TYPE,
(internal_node));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Tag type.",
Value, Parameters, Box, Allocators, Tag);
};
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct leaf
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TAG_TYPE,
(leaf));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Tag type.",
Value, Parameters, Box, Allocators, Tag);
};
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag, bool IsVisitableConst>
struct visitor
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TAG_TYPE,
(visitor));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Tag type.",
Value, Parameters, Box, Allocators, Tag);
};
template <typename Allocator, typename Value, typename Parameters, typename Box, typename Tag>
class allocators
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TAG_TYPE,
(allocators));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Tag type.",
Allocator, Value, Parameters, Box, Tag);
};
template <typename Allocators, typename Node>
struct create_node
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_NODE_TYPE,
(create_node));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Node type.",
Allocators, Node);
};
template <typename Allocators, typename Node>
struct destroy_node
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_NODE_TYPE,
(destroy_node));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Node type.",
Allocators, Node);
};
}} // namespace detail::rtree

View File

@@ -2,7 +2,11 @@
//
// R-tree nodes
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2020.
// Modifications copyright (c) 2019-2020 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
@@ -11,7 +15,12 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP
#include <type_traits>
#include <boost/container/vector.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/index/detail/varray.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
@@ -27,10 +36,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>
@@ -42,11 +50,12 @@ namespace detail { namespace rtree {
// elements box
template <typename Box, typename FwdIter, typename Translator>
inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
template <typename Box, typename FwdIter, typename Translator, typename Strategy>
inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr,
Strategy const& strategy)
{
Box result;
// Only here to suppress 'uninitialized local variable used' warning
// until the suggestion below is not implemented
geometry::assign_inverse(result);
@@ -57,11 +66,11 @@ inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
if ( first == last )
return result;
detail::bounds(element_indexable(*first, tr), result);
detail::bounds(element_indexable(*first, tr), result, strategy);
++first;
for ( ; first != last ; ++first )
geometry::expand(result, element_indexable(*first, tr));
detail::expand(result, element_indexable(*first, tr), strategy);
return result;
}
@@ -71,15 +80,16 @@ inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
// This ensures that leafs bounds correspond to the stored elements.
// NOTE: this is done only if the Indexable is not a Box
// in the future don't do it also for NSphere
template <typename Box, typename FwdIter, typename Translator>
inline Box values_box(FwdIter first, FwdIter last, Translator const& tr)
template <typename Box, typename FwdIter, typename Translator, typename Strategy>
inline Box values_box(FwdIter first, FwdIter last, Translator const& tr,
Strategy const& strategy)
{
typedef typename std::iterator_traits<FwdIter>::value_type element_type;
BOOST_MPL_ASSERT_MSG((is_leaf_element<element_type>::value),
SHOULD_BE_CALLED_ONLY_FOR_LEAF_ELEMENTS,
(element_type));
BOOST_GEOMETRY_STATIC_ASSERT((is_leaf_element<element_type>::value),
"This function should be called only for elements of leaf nodes.",
element_type);
Box result = elements_box<Box>(first, last, tr);
Box result = elements_box<Box>(first, last, tr, strategy);
#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
if (BOOST_GEOMETRY_CONDITION((
@@ -96,80 +106,86 @@ 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
> is_range_of_values;
typedef std::is_same
<
value_type, typename std::iterator_traits<It>::value_type
> is_range_of_values;
apply_dispatch(first, last, allocators, is_range_of_values());
}
private:
template <typename It>
inline static void apply_dispatch(It first, It last, Allocators & allocators,
boost::mpl::bool_<false> const& /*is_range_of_values*/)
inline static void apply_dispatch(It first, It last, allocators_type & allocators,
std::false_type /*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*/,
boost::mpl::bool_<true> const& /*is_range_of_values*/)
inline static void apply_dispatch(It /*first*/, It /*last*/, allocators_type & /*allocators*/,
std::true_type /*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 )
{
@@ -181,17 +197,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)
@@ -201,7 +218,7 @@ void move_from_back(Container & container, Iterator it)
--back_it;
if ( it != back_it )
{
*it = boost::move(*back_it); // MAY THROW (copy)
*it = std::move(*back_it); // MAY THROW (copy)
}
}

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 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,6 +19,7 @@
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
#include <boost/geometry/index/detail/varray.hpp>
#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
#include <boost/geometry/index/detail/translator.hpp>
namespace boost { namespace geometry { namespace index {

View File

@@ -2,7 +2,7 @@
//
// Pairs intended to be used internally in nodes.
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,8 +11,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_PAIRS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_PAIRS_HPP
#include <boost/move/move.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
@@ -24,46 +22,17 @@ public:
typedef First first_type;
typedef Pointer second_type;
ptr_pair(First const& f, Pointer s) : first(f), second(s) {}
//ptr_pair(ptr_pair const& p) : first(p.first), second(p.second) {}
//ptr_pair & operator=(ptr_pair const& p) { first = p.first; second = p.second; return *this; }
first_type first;
second_type second;
};
template <typename First, typename Pointer> inline
ptr_pair<First, Pointer>
make_ptr_pair(First const& f, Pointer s)
ptr_pair<First, Pointer> make_ptr_pair(First const& f, Pointer s)
{
return ptr_pair<First, Pointer>(f, s);
}
// TODO: It this will be used, rename it to unique_ptr_pair and possibly use unique_ptr.
template <typename First, typename Pointer>
class exclusive_ptr_pair
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(exclusive_ptr_pair)
public:
typedef First first_type;
typedef Pointer second_type;
exclusive_ptr_pair(First const& f, Pointer s) : first(f), second(s) {}
// INFO - members aren't really moved!
exclusive_ptr_pair(BOOST_RV_REF(exclusive_ptr_pair) p) : first(p.first), second(p.second) { p.second = 0; }
exclusive_ptr_pair & operator=(BOOST_RV_REF(exclusive_ptr_pair) p) { first = p.first; second = p.second; p.second = 0; return *this; }
first_type first;
second_type second;
};
template <typename First, typename Pointer> inline
exclusive_ptr_pair<First, Pointer>
make_exclusive_ptr_pair(First const& f, Pointer s)
{
return exclusive_ptr_pair<First, Pointer>(f, s);
}
}} // namespace detail::rtree
}}} // namespace boost::geometry::index

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 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,6 +15,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP
#include <boost/container/allocator_traits.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {

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

@@ -2,7 +2,12 @@
//
// R-tree nodes based on Boost.Variant, storing dynamic-size containers
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021-2023.
// Modifications copyright (c) 2021-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,7 +16,16 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP
#include <boost/container/allocator_traits.hpp>
#include <boost/container/vector.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant.hpp>
#include <boost/geometry/index/detail/rtree/options.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
#include <boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp>
namespace boost { namespace geometry { namespace index {
@@ -130,7 +144,7 @@ private:
node_allocator_type // node_allocator_type for consistency with variant_leaf
>::template rebind_alloc<Value> value_allocator_type;
typedef boost::container::allocator_traits<value_allocator_type> value_allocator_traits;
public:
typedef Allocator allocator_type;
@@ -152,23 +166,21 @@ public:
: node_allocator_type(alloc)
{}
inline allocators(BOOST_FWD_REF(allocators) a)
: node_allocator_type(boost::move(a.node_allocator()))
inline allocators(allocators&& a)
: node_allocator_type(std::move(a.node_allocator()))
{}
inline allocators & operator=(BOOST_FWD_REF(allocators) a)
inline allocators & operator=(allocators&& a)
{
node_allocator() = boost::move(a.node_allocator());
node_allocator() = std::move(a.node_allocator());
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
inline allocators & operator=(allocators const& a)
{
node_allocator() = a.node_allocator();
return *this;
}
#endif
void swap(allocators & a)
{

View File

@@ -2,7 +2,11 @@
//
// R-tree nodes based on Boost.Variant, storing static-size containers
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 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
@@ -11,6 +15,9 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP
#include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp>
#include <boost/geometry/index/detail/varray.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
@@ -121,23 +128,21 @@ public:
: node_allocator_type(alloc)
{}
inline allocators(BOOST_FWD_REF(allocators) a)
: node_allocator_type(boost::move(a.node_allocator()))
inline allocators(allocators&& a)
: node_allocator_type(std::move(a.node_allocator()))
{}
inline allocators & operator=(BOOST_FWD_REF(allocators) a)
inline allocators & operator=(allocators&& a)
{
node_allocator() = boost::move(a.node_allocator());
node_allocator() = std::move(a.node_allocator());
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
inline allocators & operator=(allocators const& a)
{
node_allocator() = a.node_allocator();
return *this;
}
#endif
void swap(allocators & a)
{

View File

@@ -2,7 +2,12 @@
//
// R-tree nodes based on static conversion, storing dynamic-size containers
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021-2023.
// Modifications copyright (c) 2021-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,10 +16,26 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP
#include <boost/container/allocator_traits.hpp>
#include <boost/container/vector.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/core/swap.hpp>
#include <boost/geometry/index/detail/rtree/options.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
#include <boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp>
#include <boost/geometry/index/detail/rtree/node/weak_visitor.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
// TODO: This should be defined in options.hpp
// For now it's defined here to satisfy Boost header policy
struct node_weak_dynamic_tag {};
struct node_weak_static_tag {};
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct weak_internal_node
: public weak_node<Value, Parameters, Box, Allocators, Tag>
@@ -87,7 +108,7 @@ struct visitor<Value, Parameters, Box, Allocators, node_weak_dynamic_tag, IsVisi
template <typename Allocator, typename Value, typename Parameters, typename Box, typename Tag>
struct internal_node_alloc
{
typedef typename internal_nod
typedef typename internal_node
<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, Tag>,
@@ -116,6 +137,22 @@ struct leaf_alloc
>::template rebind_alloc<node_type> type;
};
template <typename Allocator, typename Value, typename Parameters, typename Box, typename Tag>
struct node_alloc
{
typedef typename weak_node
<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, Tag>,
Tag
>::type node_type;
typedef typename ::boost::container::allocator_traits
<
Allocator
>::template rebind_alloc<node_type> type;
};
template <typename Allocator, typename Value, typename Parameters, typename Box>
class allocators<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>
: public internal_node_alloc<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>::type
@@ -147,10 +184,10 @@ private:
leaf_allocator_type // leaf_allocator_type for consistency with weak_leaf
>::template rebind_alloc<Value> value_allocator_type;
typedef boost::container::allocator_traits<value_allocator_type> value_allocator_traits;
public:
typedef Allocator allocator_type;
typedef Value value_type;
typedef typename value_allocator_traits::reference reference;
typedef typename value_allocator_traits::const_reference const_reference;
@@ -170,26 +207,24 @@ public:
, leaf_allocator_type(alloc)
{}
inline allocators(BOOST_FWD_REF(allocators) a)
: internal_node_allocator_type(boost::move(a.internal_node_allocator()))
, leaf_allocator_type(boost::move(a.leaf_allocator()))
inline allocators(allocators&& a)
: internal_node_allocator_type(std::move(a.internal_node_allocator()))
, leaf_allocator_type(std::move(a.leaf_allocator()))
{}
inline allocators & operator=(BOOST_FWD_REF(allocators) a)
inline allocators & operator=(allocators&& a)
{
internal_node_allocator() = ::boost::move(a.internal_node_allocator());
leaf_allocator() = ::boost::move(a.leaf_allocator());
internal_node_allocator() = std::move(a.internal_node_allocator());
leaf_allocator() = std::move(a.leaf_allocator());
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
inline allocators & operator=(allocators const& a)
{
internal_node_allocator() = a.internal_node_allocator();
leaf_allocator() = a.leaf_allocator();
return *this;
}
#endif
void swap(allocators & a)
{

View File

@@ -2,7 +2,11 @@
//
// R-tree nodes based on static conversion, storing static-size containers
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 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
@@ -11,6 +15,9 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP
#include <boost/geometry/index/detail/rtree/node/weak_dynamic.hpp>
#include <boost/geometry/index/detail/varray.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
@@ -127,26 +134,24 @@ public:
, leaf_allocator_type(alloc)
{}
inline allocators(BOOST_FWD_REF(allocators) a)
: internal_node_allocator_type(boost::move(a.internal_node_allocator()))
, leaf_allocator_type(boost::move(a.leaf_allocator()))
inline allocators(allocators&& a)
: internal_node_allocator_type(std::move(a.internal_node_allocator()))
, leaf_allocator_type(std::move(a.leaf_allocator()))
{}
inline allocators & operator=(BOOST_FWD_REF(allocators) a)
inline allocators & operator=(allocators&& a)
{
internal_node_allocator() = ::boost::move(a.internal_node_allocator());
leaf_allocator() = ::boost::move(a.leaf_allocator());
internal_node_allocator() = std::move(a.internal_node_allocator());
leaf_allocator() = std::move(a.leaf_allocator());
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
inline allocators & operator=(allocators const& a)
{
internal_node_allocator() = a.internal_node_allocator();
leaf_allocator() = a.leaf_allocator();
return *this;
}
#endif
void swap(allocators & a)
{

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 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,6 +15,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP
#include <boost/geometry/index/detail/assert.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {

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)
@@ -148,6 +152,21 @@ struct options_type< index::dynamic_rstar >
> type;
};
template <typename Parameters, typename Strategy>
struct options_type< index::parameters<Parameters, Strategy> >
: options_type<Parameters>
{
typedef typename options_type<Parameters>::type opt;
typedef options<
index::parameters<Parameters, Strategy>,
typename opt::insert_tag,
typename opt::choose_next_node_tag,
typename opt::split_tag,
typename opt::redistribute_tag,
typename opt::node_tag
> type;
};
}} // namespace detail::rtree
}}} // namespace boost::geometry::index

View File

@@ -2,7 +2,13 @@
//
// R-tree initial packing
//
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2020 Caian Benedicto, Campinas, Brazil.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,11 +19,17 @@
#include <boost/core/ignore_unused.hpp>
#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/algorithms/centroid.hpp>
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/algorithms/content.hpp>
#include <boost/geometry/index/detail/algorithms/is_valid.hpp>
#include <boost/geometry/index/detail/algorithms/nth_element.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/index/parameters.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
@@ -66,23 +78,28 @@ template <std::size_t I, std::size_t Dimension>
struct nth_element_and_half_boxes
{
template <typename EIt, typename Box>
static inline void apply(EIt first, EIt median, EIt last, Box const& box, Box & left, Box & right, std::size_t dim_index)
static inline void apply(EIt first, EIt median, EIt last, Box const& box,
Box & left, Box & right, std::size_t dim_index)
{
if ( I == dim_index )
if (I == dim_index)
{
index::detail::nth_element(first, median, last, point_entries_comparer<I>());
geometry::convert(box, left);
geometry::convert(box, right);
typename coordinate_type<Box>::type edge_len
= geometry::get<max_corner, I>(box) - geometry::get<min_corner, I>(box);
typename coordinate_type<Box>::type median
= geometry::get<min_corner, I>(box) + edge_len / 2;
geometry::set<max_corner, I>(left, median);
geometry::set<min_corner, I>(right, median);
auto const mi = geometry::get<min_corner, I>(box);
auto const ma = geometry::get<max_corner, I>(box);
auto const center = mi + (ma - mi) / 2;
geometry::set<max_corner, I>(left, center);
geometry::set<min_corner, I>(right, center);
}
else
nth_element_and_half_boxes<I+1, Dimension>::apply(first, median, last, box, left, right, dim_index);
{
nth_element_and_half_boxes
<
I + 1, Dimension
>::apply(first, median, last, box, left, right, dim_index);
}
}
};
@@ -122,50 +139,78 @@ 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)
{
return apply(first, last, values_count, leafs_level, parameters, translator,
allocators, boost::container::new_allocator<void>());
}
template <typename InIt, typename TmpAlloc> inline static
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,
TmpAlloc const& temp_allocator)
{
typedef typename std::iterator_traits<InIt>::difference_type diff_type;
diff_type diff = std::distance(first, last);
if ( diff <= 0 )
return node_pointer(0);
typedef std::pair<point_type, InIt> entry_type;
std::vector<entry_type> entries;
typedef typename boost::container::allocator_traits<TmpAlloc>::
template rebind_alloc<entry_type> temp_entry_allocator_type;
temp_entry_allocator_type temp_entry_allocator(temp_allocator);
boost::container::vector<entry_type, temp_entry_allocator_type> entries(temp_entry_allocator);
values_count = static_cast<size_type>(diff);
entries.reserve(values_count);
expandable_box<Box> hint_box;
auto const& strategy = index::detail::get_strategy(parameters);
expandable_box<box_type, strategy_type> hint_box(strategy);
for ( ; first != last ; ++first )
{
// NOTE: support for iterators not returning true references adapted
@@ -173,7 +218,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
@@ -182,7 +227,7 @@ public:
hint_box.expand(indexable);
point_type pt;
geometry::centroid(indexable, pt);
geometry::centroid(indexable, pt, strategy);
entries.push_back(std::make_pair(pt, first));
}
@@ -194,19 +239,19 @@ public:
}
private:
template <typename BoxType>
template <typename BoxType, typename Strategy>
class expandable_box
{
public:
expandable_box()
: m_initialized(false)
explicit expandable_box(Strategy const& strategy)
: m_strategy(strategy), m_initialized(false)
{}
template <typename Indexable>
explicit expandable_box(Indexable const& indexable)
: m_initialized(true)
explicit expandable_box(Indexable const& indexable, Strategy const& strategy)
: m_strategy(strategy), m_initialized(true)
{
detail::bounds(indexable, m_box);
detail::bounds(indexable, m_box, m_strategy);
}
template <typename Indexable>
@@ -217,12 +262,12 @@ private:
// it's guaranteed that the Box will be initialized
// only for Points, Boxes and Segments but that's ok
// since only those Geometries can be stored
detail::bounds(indexable, m_box);
detail::bounds(indexable, m_box, m_strategy);
m_initialized = true;
}
else
{
geometry::expand(m_box, indexable);
detail::expand(m_box, indexable, m_strategy);
}
}
@@ -238,22 +283,28 @@ private:
}
private:
bool m_initialized;
BoxType m_box;
Strategy m_strategy;
bool m_initialized;
};
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 )
@@ -264,7 +315,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);
@@ -273,13 +324,14 @@ private:
// calculate values box and copy values
// initialize the box explicitly to avoid GCC-4.4 uninitialized variable warnings with O2
expandable_box<Box> elements_box(translator(*(first->second)));
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 )
{
// NOTE: push_back() must be called at the end in order to support move_iterator.
// The iterator is dereferenced 2x (no temporary reference) to support
// non-true reference types and move_iterator without boost::forward<>.
// non-true reference types and move_iterator without std::forward<>.
elements_box.expand(translator(*(first->second)));
rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C)
}
@@ -294,7 +346,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();
@@ -311,16 +363,16 @@ 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> elements_box;
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,
parameters, translator, allocators);
@@ -330,14 +382,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,
@@ -361,17 +417,17 @@ private:
elements_box.expand(el.first);
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);
per_level_packets(first, median, left,
median_count, subtree_counts, next_subtree_counts,
elements, elements_box,
@@ -383,14 +439,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;
@@ -400,15 +456,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;
@@ -421,14 +477,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
{
@@ -439,7 +495,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

@@ -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)
@@ -41,12 +45,18 @@ inline void pick_seeds(Elements const& elements,
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef Box box_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
typedef index::detail::bounded_view<indexable_type, box_type> bounded_indexable_view;
typedef typename index::detail::strategy_type<Parameters>::type strategy_type;
typedef index::detail::bounded_view
<
indexable_type, box_type, strategy_type
> bounded_indexable_view;
const size_t elements_count = parameters.get_max_elements() + 1;
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "wrong number of elements");
BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
strategy_type const& strategy = index::detail::get_strategy(parameters);
content_type greatest_free_content = 0;
seed1 = 0;
seed2 = 1;
@@ -59,15 +69,15 @@ inline void pick_seeds(Elements const& elements,
indexable_type const& ind2 = rtree::element_indexable(elements[j], tr);
box_type enlarged_box;
detail::bounds(ind1, enlarged_box);
geometry::expand(enlarged_box, ind2);
index::detail::bounds(ind1, enlarged_box, strategy);
index::detail::expand(enlarged_box, ind2, strategy);
bounded_indexable_view bounded_ind1(ind1);
bounded_indexable_view bounded_ind2(ind2);
bounded_indexable_view bounded_ind1(ind1, strategy);
bounded_indexable_view bounded_ind2(ind2, strategy);
content_type free_content = ( index::detail::content(enlarged_box)
- index::detail::content(bounded_ind1) )
- index::detail::content(bounded_ind2);
if ( greatest_free_content < free_content )
{
greatest_free_content = free_content;
@@ -82,33 +92,36 @@ 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);
BOOST_GEOMETRY_INDEX_ASSERT(elements1.size() == parameters.get_max_elements() + 1, "unexpected elements number");
// copy original elements - use in-memory storage (std::allocator)
@@ -117,11 +130,11 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
container_type;
container_type elements_copy(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy)
container_type elements_backup(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy)
// 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();
@@ -129,13 +142,18 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
BOOST_TRY
{
typename index::detail::strategy_type<parameters_type>::type const&
strategy = index::detail::get_strategy(parameters);
// add seeds
elements1.push_back(elements_copy[seed1]); // MAY THROW, STRONG (copy)
elements2.push_back(elements_copy[seed2]); // MAY THROW, STRONG (alloc, copy)
// calculate boxes
detail::bounds(rtree::element_indexable(elements_copy[seed1], translator), box1);
detail::bounds(rtree::element_indexable(elements_copy[seed2], translator), box2);
detail::bounds(rtree::element_indexable(elements_copy[seed1], translator),
box1, strategy);
detail::bounds(rtree::element_indexable(elements_copy[seed2], translator),
box2, strategy);
// remove seeds
if (seed1 < seed2)
@@ -185,7 +203,8 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
content_type content_increase1 = 0;
content_type content_increase2 = 0;
el_it = pick_next(elements_copy.rbegin(), elements_copy.rend(),
box1, box2, content1, content2, translator,
box1, box2, content1, content2,
translator, strategy,
content_increase1, content_increase2);
if ( content_increase1 < content_increase2 ||
@@ -208,13 +227,13 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
if ( insert_into_group1 )
{
elements1.push_back(elem); // MAY THROW, STRONG (copy)
geometry::expand(box1, indexable);
index::detail::expand(box1, indexable, strategy);
content1 = index::detail::content(box1);
}
else
{
elements2.push_back(elem); // MAY THROW, STRONG (alloc, copy)
geometry::expand(box2, indexable);
index::detail::expand(box2, indexable, strategy);
content2 = index::detail::content(box2);
}
@@ -233,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
@@ -245,29 +264,30 @@ 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;
out_content_increase1 = 0;
out_content_increase2 = 0;
// find element with greatest difference between increased group's boxes areas
for ( It el_it = first ; el_it != last ; ++el_it )
{
indexable_type const& indexable = rtree::element_indexable(*el_it, translator);
// calculate enlarged boxes and areas
Box enlarged_box1(box1);
Box enlarged_box2(box2);
geometry::expand(enlarged_box1, indexable);
geometry::expand(enlarged_box2, indexable);
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);
content_type enlarged_content2 = index::detail::content(enlarged_box2);

View File

@@ -2,7 +2,11 @@
//
// R-tree query iterators
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2021.
// Modifications copyright (c) 2019-2021 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
@@ -11,9 +15,11 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP
#include <boost/scoped_ptr.hpp>
#include <memory>
//#define BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/visitors/distance_query.hpp>
#include <boost/geometry/index/detail/rtree/visitors/spatial_query.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
@@ -58,45 +64,43 @@ 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 visitors::spatial_query_incremental<Value, Options, Translator, Box, Allocators, Predicates> visitor_type;
typedef typename visitor_type::node_pointer node_pointer;
typedef typename MembersHolder::allocators_type allocators_type;
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()
spatial_query_iterator() = default;
explicit spatial_query_iterator(Predicates const& pred)
: m_impl(pred)
{}
inline spatial_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
inline spatial_query_iterator(node_pointer root, Translator const& t, Predicates const& p)
: m_visitor(t, p)
spatial_query_iterator(MembersHolder const& members, Predicates const& pred)
: m_impl(members, pred)
{
m_visitor.initialize(root);
m_impl.initialize(members);
}
reference operator*() const
{
return m_visitor.dereference();
return m_impl.dereference();
}
const value_type * operator->() const
{
return boost::addressof(m_visitor.dereference());
return boost::addressof(m_impl.dereference());
}
spatial_query_iterator & operator++()
{
m_visitor.increment();
m_impl.increment();
return *this;
}
@@ -109,62 +113,60 @@ public:
friend bool operator==(spatial_query_iterator const& l, spatial_query_iterator const& r)
{
return l.m_visitor == r.m_visitor;
return l.m_impl == r.m_impl;
}
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();
return l.m_impl.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();
return r.m_impl.is_end();
}
private:
visitor_type m_visitor;
visitors::spatial_query_incremental<MembersHolder, Predicates> m_impl;
};
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates, unsigned NearestPredicateIndex>
template <typename MembersHolder, typename Predicates>
class distance_query_iterator
{
typedef visitors::distance_query_incremental<Value, Options, Translator, Box, Allocators, Predicates, NearestPredicateIndex> visitor_type;
typedef typename visitor_type::node_pointer node_pointer;
typedef typename MembersHolder::allocators_type allocators_type;
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()
distance_query_iterator() = default;
explicit distance_query_iterator(Predicates const& pred)
: m_impl(pred)
{}
inline distance_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
inline distance_query_iterator(node_pointer root, Translator const& t, Predicates const& p)
: m_visitor(t, p)
distance_query_iterator(MembersHolder const& members, Predicates const& pred)
: m_impl(members, pred)
{
m_visitor.initialize(root);
m_impl.initialize(members);
}
reference operator*() const
{
return m_visitor.dereference();
return m_impl.dereference();
}
const value_type * operator->() const
{
return boost::addressof(m_visitor.dereference());
return boost::addressof(m_impl.dereference());
}
distance_query_iterator & operator++()
{
m_visitor.increment();
m_impl.increment();
return *this;
}
@@ -177,21 +179,21 @@ public:
friend bool operator==(distance_query_iterator const& l, distance_query_iterator const& r)
{
return l.m_visitor == r.m_visitor;
return l.m_impl == r.m_impl;
}
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();
return l.m_impl.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();
return r.m_impl.is_end();
}
private:
visitor_type m_visitor;
visitors::distance_query_incremental<MembersHolder, Predicates> m_impl;
};
@@ -215,7 +217,7 @@ public:
virtual ~query_iterator_base() {}
virtual query_iterator_base * clone() const = 0;
virtual bool is_end() const = 0;
virtual reference dereference() const = 0;
virtual void increment() = 0;
@@ -259,7 +261,7 @@ template <typename Value, typename Allocators>
class query_iterator
{
typedef query_iterator_base<Value, Allocators> iterator_base;
typedef boost::scoped_ptr<iterator_base> iterator_ptr;
typedef std::unique_ptr<iterator_base> iterator_ptr;
public:
typedef std::forward_iterator_tag iterator_category;
@@ -268,8 +270,7 @@ public:
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
query_iterator()
{}
query_iterator() = default;
template <typename It>
query_iterator(It const& it)
@@ -284,7 +285,8 @@ public:
: m_ptr(o.m_ptr.get() ? o.m_ptr->clone() : 0)
{}
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
query_iterator(query_iterator&&) = default;
query_iterator & operator=(query_iterator const& o)
{
if ( this != boost::addressof(o) )
@@ -293,49 +295,8 @@ public:
}
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
query_iterator(query_iterator && o)
: m_ptr(0)
{
m_ptr.swap(o.m_ptr);
}
query_iterator & operator=(query_iterator && o)
{
if ( this != boost::addressof(o) )
{
m_ptr.swap(o.m_ptr);
o.m_ptr.reset();
}
return *this;
}
#endif
#else // !BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
private:
BOOST_COPYABLE_AND_MOVABLE(query_iterator)
public:
query_iterator & operator=(BOOST_COPY_ASSIGN_REF(query_iterator) o)
{
if ( this != boost::addressof(o) )
{
m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
}
return *this;
}
query_iterator(BOOST_RV_REF(query_iterator) o)
: m_ptr(0)
{
m_ptr.swap(o.m_ptr);
}
query_iterator & operator=(BOOST_RV_REF(query_iterator) o)
{
if ( this != boost::addressof(o) )
{
m_ptr.swap(o.m_ptr);
o.m_ptr.reset();
}
return *this;
}
#endif // BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
query_iterator& operator=(query_iterator &&) = default;
reference operator*() const
{

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2021.
// Modifications copyright (c) 2019-2021 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)
@@ -23,25 +27,28 @@
#include <boost/geometry/index/detail/algorithms/union_content.hpp>
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/options.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
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>
@@ -53,15 +60,20 @@ public:
::boost::ignore_unused(parameters);
children_type & children = rtree::elements(n);
// children are leafs
if ( node_relative_level <= 1 )
{
return choose_by_minimum_overlap_cost(children, indexable, parameters.get_overlap_cost_threshold());
return choose_by_minimum_overlap_cost(children, indexable,
parameters.get_overlap_cost_threshold(),
index::detail::get_strategy(parameters));
}
// children are internal nodes
else
return choose_by_minimum_content_cost(children, indexable);
{
return choose_by_minimum_content_cost(children, indexable,
index::detail::get_strategy(parameters));
}
}
private:
@@ -79,10 +91,11 @@ private:
}
};
template <typename Indexable>
template <typename Indexable, typename Strategy>
static inline size_t choose_by_minimum_overlap_cost(children_type const& children,
Indexable const& indexable,
size_t overlap_cost_threshold)
size_t overlap_cost_threshold,
Strategy const& strategy)
{
const size_t children_count = children.size();
@@ -99,8 +112,8 @@ private:
child_type const& ch_i = children[i];
// expanded child node's box
Box box_exp(ch_i.first);
geometry::expand(box_exp, indexable);
box_type box_exp(ch_i.first);
index::detail::expand(box_exp, indexable, strategy);
// areas difference
content_type content = index::detail::content(box_exp);
@@ -131,7 +144,11 @@ private:
}
// calculate minimum or nearly minimum overlap cost
choosen_index = choose_by_minimum_overlap_cost_first_n(children, indexable, first_n_children_count, children_count, children_contents);
choosen_index = choose_by_minimum_overlap_cost_first_n(children, indexable,
first_n_children_count,
children_count,
children_contents,
strategy);
}
return choosen_index;
@@ -143,12 +160,13 @@ private:
|| (p1.content_diff == p2.content_diff && (p1.content) < (p2.content));
}
template <typename Indexable, typename ChildrenContents>
template <typename Indexable, typename ChildrenContents, typename Strategy>
static inline size_t choose_by_minimum_overlap_cost_first_n(children_type const& children,
Indexable const& indexable,
size_t const first_n_children_count,
size_t const children_count,
ChildrenContents const& children_contents)
ChildrenContents const& children_contents,
Strategy const& strategy)
{
BOOST_GEOMETRY_INDEX_ASSERT(first_n_children_count <= children_count, "unexpected value");
BOOST_GEOMETRY_INDEX_ASSERT(children_contents.size() == children_count, "unexpected number of elements");
@@ -168,9 +186,9 @@ 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
geometry::expand(box_exp, indexable);
index::detail::expand(box_exp, indexable, strategy);
content_type overlap_diff = 0;
@@ -181,10 +199,10 @@ private:
{
child_type const& ch_j = children[j];
content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first, strategy);
if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
{
overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first, strategy);
}
}
}
@@ -205,8 +223,10 @@ private:
return choosen_index;
}
template <typename Indexable>
static inline size_t choose_by_minimum_content_cost(children_type const& children, Indexable const& indexable)
template <typename Indexable, typename Strategy>
static inline size_t choose_by_minimum_content_cost(children_type const& children,
Indexable const& indexable,
Strategy const& strategy)
{
size_t children_count = children.size();
@@ -221,8 +241,8 @@ private:
child_type const& ch_i = children[i];
// expanded child node's box
Box box_exp(ch_i.first);
geometry::expand(box_exp, indexable);
box_type box_exp(ch_i.first);
index::detail::expand(box_exp, indexable, strategy);
// areas difference
content_type content = index::detail::content(box_exp);

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,9 +16,17 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_INSERT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_INSERT_HPP
#include <type_traits>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/algorithms/centroid.hpp>
#include <boost/geometry/algorithms/detail/comparable_distance/interface.hpp>
#include <boost/geometry/index/detail/algorithms/content.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
namespace boost { namespace geometry { namespace index {
@@ -21,15 +34,47 @@ namespace detail { namespace rtree { namespace visitors {
namespace rstar {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
// Utility to distinguish between default and non-default index strategy
template <typename Point1, typename Point2, typename Strategy>
struct comparable_distance
{
typedef typename geometry::comparable_distance_result
<
Point1, Point2, Strategy
>::type result_type;
static inline result_type call(Point1 const& p1, Point2 const& p2, Strategy const& s)
{
return geometry::comparable_distance(p1, p2, s);
}
};
template <typename Point1, typename Point2>
struct comparable_distance<Point1, Point2, default_strategy>
{
typedef typename geometry::default_comparable_distance_result
<
Point1, Point2
>::type result_type;
static inline result_type call(Point1 const& p1, Point2 const& p2, default_strategy const& )
{
return geometry::comparable_distance(p1, p2);
}
};
template <typename MembersHolder>
class remove_elements_to_reinsert
{
public:
typedef typename 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;
@@ -40,16 +85,19 @@ 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 typename
geometry::default_comparable_distance_result<point_type>::type
comparable_distance_type;
typedef rstar::comparable_distance
<
point_type, point_type, strategy_type
> comparable_distance_pp;
typedef typename comparable_distance_pp::result_type comparable_distance_type;
elements_type & elements = rtree::elements(n);
@@ -60,9 +108,12 @@ public:
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected elements number");
BOOST_GEOMETRY_INDEX_ASSERT(0 < reinserted_elements_count, "wrong value of elements to reinsert");
auto const& strategy = index::detail::get_strategy(parameters);
// calculate current node's center
point_type node_center;
geometry::centroid(rtree::elements(*parent)[current_child_index].first, node_center);
geometry::centroid(rtree::elements(*parent)[current_child_index].first, node_center,
strategy);
// fill the container of centers' distances of children from current node's center
typedef typename index::detail::rtree::container_from_elements_type<
@@ -73,14 +124,15 @@ public:
sorted_elements_type sorted_elements;
// If constructor is used instead of resize() MS implementation leaks here
sorted_elements.reserve(elements_count); // MAY THROW, STRONG (V, E: alloc, copy)
for ( typename elements_type::const_iterator it = elements.begin() ;
it != elements.end() ; ++it )
{
point_type element_center;
geometry::centroid( rtree::element_indexable(*it, translator), element_center);
geometry::centroid(rtree::element_indexable(*it, translator), element_center,
strategy);
sorted_elements.push_back(std::make_pair(
geometry::comparable_distance(node_center, element_center),
comparable_distance_pp::call(node_center, element_center, strategy),
*it)); // MAY THROW (V, E: copy)
}
@@ -118,7 +170,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
@@ -136,7 +188,7 @@ private:
{
return d1.first < d2.first;
}
template <typename Distance, typename El>
static inline bool distances_dsc(
std::pair<Distance, El> const& d1,
@@ -146,48 +198,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 = std::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)
@@ -208,7 +281,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)
@@ -246,39 +319,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);
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);
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 = std::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)
{}
@@ -317,8 +402,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
}
@@ -345,26 +429,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)
{}
@@ -378,7 +465,7 @@ struct level_insert<InsertIndex, Value, Value, Options, Translator, Box, Allocat
base::traverse(*this, n); // MAY THROW (V, E: alloc, copy, N: alloc)
BOOST_GEOMETRY_INDEX_ASSERT(0 < base::m_level, "illegal level value, level shouldn't be the root level for 0 < InsertIndex");
if ( base::m_traverse_data.current_level == base::m_level - 1 )
{
base::handle_possible_reinsert_or_split_of_root(n); // MAY THROW (E: alloc, copy, N: alloc)
@@ -394,33 +481,36 @@ struct level_insert<InsertIndex, Value, Value, Options, Translator, Box, Allocat
BOOST_GEOMETRY_INDEX_ASSERT(base::m_level == base::m_traverse_data.current_level ||
base::m_level == (std::numeric_limits<size_t>::max)(),
"unexpected level");
rtree::elements(n).push_back(base::m_element); // MAY THROW, STRONG (V: alloc, copy)
base::handle_possible_split(n); // MAY THROW (V: alloc, copy, N: alloc)
}
};
template <typename Value, typename 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)
{}
@@ -449,7 +539,7 @@ struct level_insert<0, Value, Value, Options, Translator, Box, Allocators>
rtree::elements(n).push_back(base::m_element); // MAY THROW, STRONG (V: alloc, copy)
base::handle_possible_reinsert_or_split_of_root(n); // MAY THROW (V: alloc, copy, N: alloc)
base::recalculate_aabb_if_necessary(n);
}
};
@@ -460,26 +550,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)
@@ -494,7 +586,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)
@@ -506,10 +598,10 @@ 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);
rtree::apply_visitor(ins_v, *m_root);
}
}
@@ -521,7 +613,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)
@@ -531,10 +623,10 @@ 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);
rtree::apply_visitor(ins_v, *m_root);
}
}
@@ -548,7 +640,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
@@ -559,7 +651,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
@@ -579,11 +671,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

@@ -2,7 +2,11 @@
//
// R-tree R*-tree split algorithm implementation
//
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2022 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2020.
// Modifications copyright (c) 2019-2020 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
@@ -13,6 +17,8 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/index/detail/algorithms/intersection_content.hpp>
#include <boost/geometry/index/detail/algorithms/margin.hpp>
#include <boost/geometry/index/detail/algorithms/nth_element.hpp>
@@ -30,37 +36,43 @@ namespace detail { namespace rtree {
namespace rstar {
template <typename Element, typename Translator, typename Tag, size_t Corner, size_t AxisIndex>
template <typename Element, typename Parameters, typename Translator, typename Tag, size_t Corner, size_t AxisIndex>
class element_axis_corner_less
{
typedef typename rtree::element_indexable_type<Element, Translator>::type indexable_type;
typedef typename geometry::point_type<indexable_type>::type point_type;
typedef geometry::model::box<point_type> bounds_type;
typedef index::detail::bounded_view<indexable_type, bounds_type> bounded_view_type;
typedef typename index::detail::strategy_type<Parameters>::type strategy_type;
typedef index::detail::bounded_view
<
indexable_type, bounds_type, strategy_type
> bounded_view_type;
public:
element_axis_corner_less(Translator const& tr)
: m_tr(tr)
element_axis_corner_less(Translator const& tr, strategy_type const& strategy)
: m_tr(tr), m_strategy(strategy)
{}
bool operator()(Element const& e1, Element const& e2) const
{
bounded_view_type bounded_ind1(rtree::element_indexable(e1, m_tr));
bounded_view_type bounded_ind2(rtree::element_indexable(e2, m_tr));
return geometry::get<Corner, AxisIndex>(bounded_ind1)
< geometry::get<Corner, AxisIndex>(bounded_ind2);
indexable_type const& ind1 = rtree::element_indexable(e1, m_tr);
indexable_type const& ind2 = rtree::element_indexable(e2, m_tr);
return geometry::get<Corner, AxisIndex>(bounded_view_type(ind1, m_strategy))
< geometry::get<Corner, AxisIndex>(bounded_view_type(ind2, m_strategy));
}
private:
Translator const& m_tr;
strategy_type const& m_strategy;
};
template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
class element_axis_corner_less<Element, Translator, box_tag, Corner, AxisIndex>
template <typename Element, typename Parameters, typename Translator, size_t Corner, size_t AxisIndex>
class element_axis_corner_less<Element, Parameters, Translator, box_tag, Corner, AxisIndex>
{
typedef typename index::detail::strategy_type<Parameters>::type strategy_type;
public:
element_axis_corner_less(Translator const& tr)
element_axis_corner_less(Translator const& tr, strategy_type const&)
: m_tr(tr)
{}
@@ -74,11 +86,13 @@ private:
Translator const& m_tr;
};
template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
class element_axis_corner_less<Element, Translator, point_tag, Corner, AxisIndex>
template <typename Element, typename Parameters, typename Translator, size_t Corner, size_t AxisIndex>
class element_axis_corner_less<Element, Parameters, Translator, point_tag, Corner, AxisIndex>
{
typedef typename index::detail::strategy_type<Parameters>::type strategy_type;
public:
element_axis_corner_less(Translator const& tr)
element_axis_corner_less(Translator const& tr, strategy_type const& )
: m_tr(tr)
{}
@@ -113,14 +127,20 @@ struct choose_split_axis_and_index_for_corner
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == parameters.get_max_elements() + 1, "wrong number of elements");
typename index::detail::strategy_type<Parameters>::type const&
strategy = index::detail::get_strategy(parameters);
// copy elements
Elements elements_copy(elements); // MAY THROW, STRONG (alloc, copy)
size_t const index_first = parameters.get_min_elements();
size_t const index_last = parameters.get_max_elements() - parameters.get_min_elements() + 2;
// sort elements
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, AxisIndex> elements_less(translator);
element_axis_corner_less
<
element_type, Parameters, Translator, indexable_tag, Corner, AxisIndex
> elements_less(translator, strategy);
std::sort(elements_copy.begin(), elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
// {
// typename Elements::iterator f = elements_copy.begin() + index_first;
@@ -143,12 +163,14 @@ struct choose_split_axis_and_index_for_corner
// TODO - awulkiew: may be optimized - box of group 1 may be initialized with
// box of min_elems number of elements and expanded for each iteration by another element
Box box1 = rtree::elements_box<Box>(elements_copy.begin(), elements_copy.begin() + i, translator);
Box box2 = rtree::elements_box<Box>(elements_copy.begin() + i, elements_copy.end(), translator);
Box box1 = rtree::elements_box<Box>(elements_copy.begin(), elements_copy.begin() + i,
translator, strategy);
Box box2 = rtree::elements_box<Box>(elements_copy.begin() + i, elements_copy.end(),
translator, strategy);
sum_of_margins += index::detail::comparable_margin(box1) + index::detail::comparable_margin(box2);
content_type ovl = index::detail::intersection_content(box1, box2);
content_type ovl = index::detail::intersection_content(box1, box2, strategy);
content_type con = index::detail::content(box1) + index::detail::content(box2);
// TODO - shouldn't here be < instead of <= ?
@@ -167,7 +189,7 @@ struct choose_split_axis_and_index_for_corner
//template <typename Box, size_t AxisIndex, typename ElementIndexableTag>
//struct choose_split_axis_and_index_for_axis
//{
// BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag));
// BOOST_GEOMETRY_STATIC_ASSERT_FALSE("Not implemented for this Tag type.", ElementIndexableTag);
//};
template <typename Box, size_t AxisIndex, typename ElementIndexableTag>
@@ -337,14 +359,15 @@ struct nth_element
BOOST_STATIC_ASSERT(0 < Dimension);
BOOST_STATIC_ASSERT(I < Dimension);
template <typename Elements, typename Translator>
static inline void apply(Elements & elements, const size_t axis, const size_t index, Translator const& tr)
template <typename Elements, typename Parameters, typename Translator>
static inline void apply(Elements & elements, Parameters const& parameters,
const size_t axis, const size_t index, Translator const& tr)
{
//BOOST_GEOMETRY_INDEX_ASSERT(axis < Dimension, "unexpected axis value");
if ( axis != I )
{
nth_element<Corner, Dimension, I + 1>::apply(elements, axis, index, tr); // MAY THROW, BASIC (copy)
nth_element<Corner, Dimension, I + 1>::apply(elements, parameters, axis, index, tr); // MAY THROW, BASIC (copy)
}
else
{
@@ -352,7 +375,13 @@ struct nth_element
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename tag<indexable_type>::type indexable_tag;
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, I> less(tr);
typename index::detail::strategy_type<Parameters>::type
strategy = index::detail::get_strategy(parameters);
element_axis_corner_less
<
element_type, Parameters, Translator, indexable_tag, Corner, I
> less(tr, strategy);
index::detail::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
}
}
@@ -361,40 +390,44 @@ struct nth_element
template <size_t Corner, size_t Dimension>
struct nth_element<Corner, Dimension, Dimension>
{
template <typename Elements, typename Translator>
static inline void apply(Elements & /*elements*/, const size_t /*axis*/, const size_t /*index*/, Translator const& /*tr*/)
template <typename Elements, typename Parameters, typename Translator>
static inline void apply(Elements & /*elements*/, Parameters const& /*parameters*/,
const size_t /*axis*/, const size_t /*index*/, Translator const& /*tr*/)
{}
};
} // 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;
elements_type & elements1 = rtree::elements(n);
elements_type & elements2 = rtree::elements(second_node);
@@ -417,7 +450,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,
@@ -432,23 +465,28 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
if ( split_corner == static_cast<size_t>(min_corner) )
{
rstar::nth_element<min_corner, dimension>
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
::apply(elements_copy, parameters, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
}
else
{
rstar::nth_element<max_corner, dimension>
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
::apply(elements_copy, parameters, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
}
BOOST_TRY
{
typename index::detail::strategy_type<parameters_type>::type const&
strategy = index::detail::get_strategy(parameters);
// copy elements to nodes
elements1.assign(elements_copy.begin(), elements_copy.begin() + split_index); // MAY THROW, BASIC
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);
box2 = rtree::elements_box<Box>(elements2.begin(), elements2.end(), translator);
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(...)
{
@@ -456,7 +494,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

@@ -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)
@@ -18,16 +22,20 @@ 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 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::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
public:
are_boxes_ok(Translator const& tr, bool exact_match)
: result(false), m_tr(tr), m_is_root(true), m_exact_match(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)
{}
void operator()(internal_node const& n)
@@ -41,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;
@@ -60,8 +68,9 @@ public:
m_box = box_bckup;
m_is_root = is_root_bckup;
Box box_exp = rtree::elements_box<Box>(elements.begin(), elements.end(), m_tr);
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);
else
@@ -81,8 +90,9 @@ public:
result = false;
return;
}
Box box_exp = rtree::values_box<Box>(elements.begin(), elements.end(), m_tr);
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);
@@ -96,8 +106,9 @@ public:
bool result;
private:
Translator const& m_tr;
Box m_box;
parameters_type const& m_parameters;
translator_type const& m_tr;
box_type m_box;
bool m_is_root;
bool m_exact_match;
};
@@ -111,13 +122,9 @@ 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
> v(rtv.translator(), exact_match);
typename RTV::members_holder
> v(tree.parameters(), rtv.translator(), exact_match);
rtv.apply_visitor(v);
return v.result;

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -12,22 +17,27 @@
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_COUNTS_OK_HPP
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
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 +46,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 +72,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,28 +88,26 @@ 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);
return v.result;

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -12,17 +17,18 @@
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_LEVELS_OK_HPP
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
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,12 +99,9 @@ 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);
return v.result;

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2021.
// Modifications copyright (c) 2019-2021 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,7 +15,16 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
#include <boost/mpl/assert.hpp>
#include <limits>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
@@ -79,7 +92,9 @@ struct gl_draw_segment<Segment, 2>
template <typename Indexable, typename Tag>
struct gl_draw_indexable
{
BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Indexable type.",
Indexable, Tag);
};
template <typename Box>
@@ -114,16 +129,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)
@@ -162,7 +181,7 @@ struct gl_draw : public rtree::visitor<Value, typename Options::parameters_type,
detail::utilities::gl_draw_indexable(it->first, level_rel * z_mul);
}
}
size_t level_backup = level;
++level;
@@ -197,10 +216,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 +245,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,11 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -13,8 +18,18 @@
#include <iostream>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
namespace utilities {
namespace dispatch {
@@ -66,7 +81,9 @@ struct print_corner<Box, Corner, 1>
template <typename Indexable, typename Tag>
struct print_indexable
{
BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Indexable type.",
Indexable, Tag);
};
template <typename Indexable>
@@ -129,13 +146,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)
{}
@@ -145,7 +165,7 @@ struct print : public rtree::visitor<Value, typename Options::parameters_type, B
elements_type const& elements = rtree::elements(n);
spaces(level) << "INTERNAL NODE - L:" << level << " Ch:" << elements.size() << " @:" << &n << '\n';
for (typename elements_type::const_iterator it = elements.begin();
it != elements.end(); ++it)
{
@@ -189,7 +209,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 +223,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,11 @@
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2013 Mateusz Loskot, London, UK.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -13,17 +18,22 @@
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP
#include <algorithm>
#include <boost/tuple/tuple.hpp>
#include <tuple>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
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)
@@ -39,37 +49,37 @@ struct statistics : public rtree::visitor<Value, typename Options::parameters_ty
{
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n);
++nodes; // count node
size_t const level_backup = level;
++level;
levels += level++ > levels ? 1 : 0; // count level (root already counted)
for (typename elements_type::const_iterator it = elements.begin();
it != elements.end(); ++it)
{
rtree::apply_visitor(*this, *it->second);
}
level = level_backup;
}
inline void operator()(leaf const& n)
{
{
typedef typename rtree::elements_type<leaf>::type elements_type;
elements_type const& elements = rtree::elements(n);
++leaves; // count leaves
std::size_t const v = elements.size();
// count values spread per node and total
values_min = (std::min)(values_min == 0 ? v : values_min, v);
values_max = (std::max)(values_max, v);
values += v;
}
std::size_t level;
std::size_t levels;
std::size_t nodes;
@@ -82,22 +92,19 @@ struct statistics : public rtree::visitor<Value, typename Options::parameters_ty
} // namespace visitors
template <typename Rtree> inline
boost::tuple<std::size_t, std::size_t, std::size_t, std::size_t, std::size_t, std::size_t>
std::tuple<std::size_t, std::size_t, std::size_t, std::size_t, std::size_t, std::size_t>
statistics(Rtree const& tree)
{
typedef utilities::view<Rtree> RTV;
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);
return boost::make_tuple(stats_v.levels, stats_v.nodes, stats_v.leaves, stats_v.values, stats_v.values_min, stats_v.values_max);
return std::make_tuple(stats_v.levels, stats_v.nodes, stats_v.leaves, stats_v.values, stats_v.values_min, stats_v.values_max);
}
}}}}}} // namespace boost::geometry::index::detail::rtree::utilities

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,13 +23,15 @@ 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;
typedef typename Rtree::value_type value_type;
typedef typename Rtree::options_type options_type;
typedef typename Rtree::box_type box_type;
typedef typename Rtree::allocators_type allocators_type;
typedef typename Rtree::allocators_type allocators_type;
view(Rtree const& rt) : m_rtree(rt) {}

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,20 +16,29 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_CHILDREN_BOX_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_CHILDREN_BOX_HPP
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.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 children_box
: 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::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
public:
inline children_box(Box & result, Translator const& tr)
: m_result(result), m_tr(tr)
inline children_box(box_type & result,
parameters_type const& parameters,
translator_type const& tr)
: m_result(result), m_parameters(parameters), m_tr(tr)
{}
inline void operator()(internal_node const& n)
@@ -32,7 +46,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);
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)
@@ -40,12 +55,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);
m_result = rtree::values_box<box_type>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
}
private:
Box & m_result;
Translator const& m_tr;
box_type & m_result;
parameters_type const& m_parameters;
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;
@@ -45,7 +53,7 @@ public:
for (typename elements_type::iterator it = elements.begin();
it != elements.end(); ++it)
{
rtree::apply_visitor(*this, *it->second); // MAY THROW (V, E: alloc, copy, N: alloc)
rtree::apply_visitor(*this, *it->second); // MAY THROW (V, E: alloc, copy, N: alloc)
// for exception safety
subtree_destroyer auto_result(result, m_allocators);
@@ -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

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +16,12 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP
#include <boost/geometry/index/equal_to.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
#include <boost/geometry/index/parameters.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
@@ -23,10 +34,10 @@ struct count_helper
{
return i;
}
template <typename Translator>
static inline bool equals(Indexable const& i, Value const& v, Translator const& tr)
template <typename Translator, typename Strategy>
static inline bool equals(Indexable const& i, Value const& v, Translator const& tr, Strategy const& s)
{
return geometry::equals(i, tr(v));
return index::detail::equals<Indexable>::apply(i, tr(v), s);
}
};
@@ -38,25 +49,29 @@ struct count_helper<Value, Value>
{
return tr(v);
}
template <typename Translator>
static inline bool equals(Value const& v1, Value const& v2, Translator const& tr)
template <typename Translator, typename Strategy>
static inline bool equals(Value const& v1, Value const& v2, Translator const& tr, Strategy const& s)
{
return tr.equals(v1, v2);
return tr.equals(v1, v2, s);
}
};
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 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::value_type value_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef count_helper<ValueOrIndexable, Value> count_help;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
inline count(ValueOrIndexable const& vori, Translator const& t)
: value_or_indexable(vori), tr(t), found_count(0)
typedef count_helper<ValueOrIndexable, value_type> count_help;
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)
{}
inline void operator()(internal_node const& n)
@@ -68,10 +83,9 @@ struct count
for (typename elements_type::const_iterator it = elements.begin();
it != elements.end(); ++it)
{
if ( geometry::covered_by(
return_ref_or_bounds(
count_help::indexable(value_or_indexable, tr)),
it->first) )
if ( index::detail::covered_by_bounds(count_help::indexable(value_or_indexable, tr),
it->first,
index::detail::get_strategy(m_parameters)) )
{
rtree::apply_visitor(*this, *it->second);
}
@@ -88,7 +102,8 @@ struct count
it != elements.end(); ++it)
{
// if value meets predicates
if ( count_help::equals(value_or_indexable, *it, tr) )
if ( count_help::equals(value_or_indexable, *it, tr,
index::detail::get_strategy(m_parameters)) )
{
++found_count;
}
@@ -96,8 +111,9 @@ struct count
}
ValueOrIndexable const& value_or_indexable;
Translator const& tr;
typename Allocators::size_type found_count;
parameters_type const& m_parameters;
translator_type const& tr;
typename MembersHolder::size_type found_count;
};
}}} // namespace detail::rtree::visitors

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,23 +16,28 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_DELETE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_DELETE_HPP
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/weak_visitor.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 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 +58,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 +66,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

@@ -2,7 +2,12 @@
//
// R-tree inserting visitor implementation
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,39 +16,53 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_INSERT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_INSERT_HPP
#include <boost/type_traits/is_same.hpp>
#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
#include <type_traits>
#endif
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/algorithms/content.hpp>
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/index/detail/rtree/options.hpp>
#include <boost/geometry/util/condition.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,
Indexable const& indexable,
parameters_type const& /*parameters*/,
parameters_type const& parameters,
size_t /*node_relative_level*/)
{
children_type & children = rtree::elements(n);
@@ -64,8 +83,9 @@ public:
child_type const& ch_i = children[i];
// expanded child node's box
Box box_exp(ch_i.first);
geometry::expand(box_exp, indexable);
box_type box_exp(ch_i.first);
index::detail::expand(box_exp, indexable,
index::detail::get_strategy(parameters));
// areas difference
content_type content = index::detail::content(box_exp);
@@ -88,39 +108,49 @@ 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(
(false),
NOT_IMPLEMENTED_FOR_THIS_REDISTRIBUTE_TAG_TYPE,
(redistribute_elements));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this RedistributeTag type.",
MembersHolder, RedistributeTag);
};
// ----------------------------------------------------------------------- //
// 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(
(false),
NOT_IMPLEMENTED_FOR_THIS_SPLIT_TAG_TYPE,
(split));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this SplitTag type.",
MembersHolder, SplitTag);
};
// 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<
@@ -131,51 +161,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 std::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
}
};
@@ -226,30 +268,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
: public 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)
@@ -274,17 +320,19 @@ protected:
// NOTE: This is actually only needed because conditionally the bounding
// object may be expanded below. Otherwise the indexable could be
// directly used instead
index::detail::bounds(rtree::element_indexable(m_element, m_translator), m_element_bounds);
index::detail::bounds(rtree::element_indexable(m_element, m_translator),
m_element_bounds,
index::detail::get_strategy(m_parameters));
#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
// Enlarge it in case if it's not bounding geometry type.
// 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
std::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);
@@ -296,14 +344,16 @@ 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
geometry::expand(
index::detail::expand(
rtree::elements(n)[choosen_node_index].first,
m_element_bounds
/*rtree::element_indexable(m_element, m_translator)*/);
m_element_bounds,
index::detail::get_strategy(m_parameters));
// next traversing step
traverse_apply_visitor(visitor, n, choosen_node_index); // MAY THROW (V, E: alloc, copy, N:alloc)
@@ -349,10 +399,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)
@@ -376,10 +426,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<Node, leaf>::value
std::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);
@@ -401,7 +451,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
{
@@ -428,9 +478,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;
@@ -440,30 +490,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;
@@ -471,8 +530,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)
@@ -500,8 +559,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
}
@@ -518,26 +576,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)
@@ -559,7 +622,7 @@ public:
BOOST_GEOMETRY_INDEX_ASSERT(base::m_traverse_data.current_level == base::m_leafs_level, "unexpected level");
BOOST_GEOMETRY_INDEX_ASSERT(base::m_level == base::m_traverse_data.current_level ||
base::m_level == (std::numeric_limits<size_t>::max)(), "unexpected level");
rtree::elements(n).push_back(base::m_element); // MAY THROW, STRONG (V: alloc, copy)
base::post_traverse(n); // MAY THROW (V: alloc, copy, N: alloc)

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

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021-2023.
// Modifications copyright (c) 2021-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +16,10 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,28 +16,39 @@
#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/is_leaf.hpp>
#include <boost/geometry/algorithms/detail/covered_by/interface.hpp>
#include <boost/geometry/index/parameters.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
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;
@@ -42,10 +58,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)
@@ -71,9 +87,9 @@ public:
internal_size_type child_node_index = 0;
for ( ; child_node_index < children.size() ; ++child_node_index )
{
if ( geometry::covered_by(
return_ref_or_bounds(m_translator(m_value)),
children[child_node_index].first) )
if ( index::detail::covered_by_bounds(m_translator(m_value),
children[child_node_index].first,
index::detail::get_strategy(m_parameters)) )
{
// next traversing step
traverse_apply_visitor(n, child_node_index); // MAY THROW
@@ -112,7 +128,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);
= rtree::elements_box<box_type>(elements.begin(), elements.end(), m_translator,
index::detail::get_strategy(m_parameters));
}
// n is root node
else
@@ -135,7 +152,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);
}
}
}
@@ -149,7 +166,7 @@ public:
// find value and remove it
for ( typename elements_type::iterator it = elements.begin() ; it != elements.end() ; ++it )
{
if ( m_translator.equals(*it, m_value) )
if ( m_translator.equals(*it, m_value, index::detail::get_strategy(m_parameters)) )
{
rtree::move_from_back(elements, it); // MAY THROW (V: copy)
elements.pop_back();
@@ -170,7 +187,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);
= rtree::values_box<box_type>(elements.begin(), elements.end(), m_translator,
index::detail::get_strategy(m_parameters));
}
}
}
@@ -182,7 +200,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)
{
@@ -233,14 +251,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
{
@@ -256,13 +274,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);
}
}
@@ -273,7 +291,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();
@@ -294,14 +312,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)
}
@@ -309,24 +323,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

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,116 +16,145 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_SPATIAL_QUERY_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_SPATIAL_QUERY_HPP
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/weak_visitor.hpp>
#include <boost/geometry/index/detail/predicates.hpp>
#include <boost/geometry/index/parameters.hpp>
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
{
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 Allocators::size_type size_type;
typedef typename index::detail::strategy_type<parameters_type>::type strategy_type;
static const unsigned predicates_len = index::detail::predicates_length<Predicates>::value;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
inline spatial_query(Translator const& t, Predicates const& p, OutIter out_it)
: tr(t), pred(p), out_iter(out_it), found_count(0)
typedef typename allocators_type::node_pointer node_pointer;
typedef typename allocators_type::size_type size_type;
spatial_query(MembersHolder const& members, Predicates const& p, OutIter out_it)
: m_tr(members.translator())
, m_strategy(index::detail::get_strategy(members.parameters()))
, m_pred(p)
, m_out_iter(out_it)
, m_found_count(0)
{}
inline void operator()(internal_node const& n)
size_type apply(node_pointer ptr, size_type reverse_level)
{
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n);
// traverse nodes meeting predicates
for (typename elements_type::const_iterator it = elements.begin();
it != elements.end(); ++it)
namespace id = index::detail;
if (reverse_level > 0)
{
// if node meets predicates
// 0 - dummy value
if ( index::detail::predicates_check<index::detail::bounds_tag, 0, predicates_len>(pred, 0, it->first) )
rtree::apply_visitor(*this, *it->second);
}
}
inline void operator()(leaf const& n)
{
typedef typename rtree::elements_type<leaf>::type elements_type;
elements_type const& elements = rtree::elements(n);
// get all values meeting predicates
for (typename elements_type::const_iterator it = elements.begin();
it != elements.end(); ++it)
{
// if value meets predicates
if ( index::detail::predicates_check<index::detail::value_tag, 0, predicates_len>(pred, *it, tr(*it)) )
internal_node& n = rtree::get<internal_node>(*ptr);
// traverse nodes meeting predicates
for (auto const& p : rtree::elements(n))
{
*out_iter = *it;
++out_iter;
++found_count;
// if node meets predicates (0 is dummy value)
if (id::predicates_check<id::bounds_tag>(m_pred, 0, p.first, m_strategy))
{
apply(p.second, reverse_level - 1);
}
}
}
else
{
leaf& n = rtree::get<leaf>(*ptr);
// get all values meeting predicates
for (auto const& v : rtree::elements(n))
{
// if value meets predicates
if (id::predicates_check<id::value_tag>(m_pred, v, m_tr(v), m_strategy))
{
*m_out_iter = v;
++m_out_iter;
++m_found_count;
}
}
}
return m_found_count;
}
Translator const& tr;
size_type apply(MembersHolder const& members)
{
return apply(members.root, members.leafs_level);
}
Predicates pred;
private:
translator_type const& m_tr;
strategy_type m_strategy;
OutIter out_iter;
size_type found_count;
Predicates const& m_pred;
OutIter m_out_iter;
size_type m_found_count;
};
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:
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::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 Allocators::size_type size_type;
typedef typename Allocators::const_reference const_reference;
typedef typename Allocators::node_pointer node_pointer;
typedef typename index::detail::strategy_type<parameters_type>::type strategy_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
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;
typedef typename rtree::elements_type<leaf>::type::const_iterator leaf_iterator;
static const unsigned predicates_len = index::detail::predicates_length<Predicates>::value;
struct internal_data
{
internal_data(internal_iterator f, internal_iterator l, size_type rl)
: first(f), last(l), reverse_level(rl)
{}
internal_iterator first;
internal_iterator last;
size_type reverse_level;
};
inline spatial_query_incremental()
: m_translator(NULL)
public:
spatial_query_incremental()
: m_translator(nullptr)
// , m_strategy()
// , m_pred()
, m_values(NULL)
, m_values(nullptr)
, m_current()
{}
inline spatial_query_incremental(Translator const& t, Predicates const& p)
: m_translator(::boost::addressof(t))
spatial_query_incremental(Predicates const& p)
: m_translator(nullptr)
// , m_strategy()
, m_pred(p)
, m_values(NULL)
, m_values(nullptr)
, m_current()
{}
inline void operator()(internal_node const& n)
{
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n);
m_internal_stack.push_back(std::make_pair(elements.begin(), elements.end()));
}
inline void operator()(leaf const& n)
{
m_values = ::boost::addressof(rtree::elements(n));
m_current = rtree::elements(n).begin();
}
spatial_query_incremental(MembersHolder const& members, Predicates const& p)
: m_translator(::boost::addressof(members.translator()))
, m_strategy(index::detail::get_strategy(members.parameters()))
, m_pred(p)
, m_values(nullptr)
, m_current()
{}
const_reference dereference() const
{
@@ -128,9 +162,9 @@ public:
return *m_current;
}
void initialize(node_pointer root)
void initialize(MembersHolder const& members)
{
rtree::apply_visitor(*this, *root);
apply(members.root, members.leafs_level);
search_value();
}
@@ -140,8 +174,38 @@ public:
search_value();
}
bool is_end() const
{
return 0 == m_values;
}
friend bool operator==(spatial_query_incremental const& l, spatial_query_incremental const& r)
{
return (l.m_values == r.m_values) && (0 == l.m_values || l.m_current == r.m_current);
}
private:
void apply(node_pointer ptr, size_type reverse_level)
{
namespace id = index::detail;
if (reverse_level > 0)
{
internal_node& n = rtree::get<internal_node>(*ptr);
auto const& elements = rtree::elements(n);
m_internal_stack.push_back(internal_data(elements.begin(), elements.end(), reverse_level - 1));
}
else
{
leaf& n = rtree::get<leaf>(*ptr);
m_values = ::boost::addressof(rtree::elements(n));
m_current = rtree::elements(n).begin();
}
}
void search_value()
{
namespace id = index::detail;
for (;;)
{
// if leaf is choosen, move to the next value in leaf
@@ -150,9 +214,11 @@ public:
if ( m_current != m_values->end() )
{
// return if next value is found
Value const& v = *m_current;
if ( index::detail::predicates_check<index::detail::value_tag, 0, predicates_len>(m_pred, v, (*m_translator)(v)) )
value_type const& v = *m_current;
if (id::predicates_check<id::value_tag>(m_pred, v, (*m_translator)(v), m_strategy))
{
return;
}
++m_current;
}
@@ -166,43 +232,38 @@ public:
else
{
// return if there is no more nodes to traverse
if ( m_internal_stack.empty() )
if (m_internal_stack.empty())
{
return;
}
internal_data& current_data = m_internal_stack.back();
// no more children in current node, remove it from stack
if ( m_internal_stack.back().first == m_internal_stack.back().second )
if (current_data.first == current_data.last)
{
m_internal_stack.pop_back();
continue;
}
internal_iterator it = m_internal_stack.back().first;
++m_internal_stack.back().first;
internal_iterator it = current_data.first;
++current_data.first;
// next node is found, push it to the stack
if ( index::detail::predicates_check<index::detail::bounds_tag, 0, predicates_len>(m_pred, 0, it->first) )
rtree::apply_visitor(*this, *(it->second));
if (id::predicates_check<id::bounds_tag>(m_pred, 0, it->first, m_strategy))
{
apply(it->second, current_data.reverse_level);
}
}
}
}
bool is_end() const
{
return 0 == m_values;
}
friend bool operator==(spatial_query_incremental const& l, spatial_query_incremental const& r)
{
return (l.m_values == r.m_values) && (0 == l.m_values || l.m_current == r.m_current );
}
private:
const Translator * m_translator;
const translator_type * m_translator;
strategy_type m_strategy;
Predicates m_pred;
std::vector< std::pair<internal_iterator, internal_iterator> > m_internal_stack;
std::vector<internal_data> m_internal_stack;
const leaf_elements * m_values;
leaf_iterator m_current;
};