summaryrefslogtreecommitdiff
path: root/boost/geometry/index
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:30:07 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:32:57 +0900
commit71d216b90256936a9638f325af9bc69d720e75de (patch)
tree9c5f682d341c7c88ad0c8e3d4b262e00b6fb691a /boost/geometry/index
parent733b5d5ae2c5d625211e2985ac25728ac3f54883 (diff)
downloadboost-71d216b90256936a9638f325af9bc69d720e75de.tar.gz
boost-71d216b90256936a9638f325af9bc69d720e75de.tar.bz2
boost-71d216b90256936a9638f325af9bc69d720e75de.zip
Imported Upstream version 1.59.0
Change-Id: I2dde00f4eca71df3eea9d251dcaecde18a6c90a5 Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/geometry/index')
-rw-r--r--boost/geometry/index/detail/assert.hpp10
-rw-r--r--boost/geometry/index/detail/bounded_view.hpp64
-rw-r--r--boost/geometry/index/detail/predicates.hpp10
-rw-r--r--boost/geometry/index/detail/rtree/iterators.hpp122
-rw-r--r--boost/geometry/index/detail/rtree/node/node.hpp6
-rw-r--r--boost/geometry/index/detail/rtree/pack_create.hpp66
-rw-r--r--boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp5
-rw-r--r--boost/geometry/index/detail/rtree/query_iterators.hpp27
-rw-r--r--boost/geometry/index/detail/rtree/visitors/distance_query.hpp8
-rw-r--r--boost/geometry/index/detail/rtree/visitors/iterator.hpp134
-rw-r--r--boost/geometry/index/detail/rtree/visitors/spatial_query.hpp10
-rw-r--r--boost/geometry/index/rtree.hpp341
12 files changed, 707 insertions, 96 deletions
diff --git a/boost/geometry/index/detail/assert.hpp b/boost/geometry/index/detail/assert.hpp
index 311f37f640..08889df478 100644
--- a/boost/geometry/index/detail/assert.hpp
+++ b/boost/geometry/index/detail/assert.hpp
@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
-// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 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
@@ -9,13 +9,11 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ASSERT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ASSERT_HPP
-#include <boost/assert.hpp>
+#include <boost/geometry/core/assert.hpp>
-#ifndef BOOST_GEOMETRY_INDEX_ASSERT
+#undef BOOST_GEOMETRY_INDEX_ASSERT
#define BOOST_GEOMETRY_INDEX_ASSERT(CONDITION, TEXT_MSG) \
- BOOST_ASSERT_MSG(CONDITION, TEXT_MSG)
-
-#endif // BOOST_GEOMETRY_INDEX_ASSERT
+ BOOST_GEOMETRY_ASSERT_MSG(CONDITION, TEXT_MSG)
#endif // BOOST_GEOMETRY_INDEX_DETAIL_ASSERT_HPP
diff --git a/boost/geometry/index/detail/bounded_view.hpp b/boost/geometry/index/detail/bounded_view.hpp
index 0cd882fc94..e5f489d76b 100644
--- a/boost/geometry/index/detail/bounded_view.hpp
+++ b/boost/geometry/index/detail/bounded_view.hpp
@@ -3,7 +3,7 @@
// This view makes possible to treat some simple primitives as its bounding geometry
// e.g. box, nsphere, etc.
//
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2014-2015 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
@@ -12,6 +12,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
+#include <boost/geometry/algorithms/envelope.hpp>
+
namespace boost { namespace geometry {
namespace index { namespace detail {
@@ -19,7 +21,8 @@ namespace index { namespace detail {
template <typename Geometry,
typename BoundingGeometry,
typename Tag = typename geometry::tag<Geometry>::type,
- typename BoundingTag = typename geometry::tag<BoundingGeometry>::type>
+ typename BoundingTag = typename geometry::tag<BoundingGeometry>::type,
+ typename CSystem = typename geometry::coordinate_system<Geometry>::type>
struct bounded_view
{
BOOST_MPL_ASSERT_MSG(
@@ -32,7 +35,7 @@ struct bounded_view
// Segment -> Box
template <typename Segment, typename Box>
-struct bounded_view<Segment, Box, segment_tag, box_tag>
+struct bounded_view<Segment, Box, segment_tag, box_tag, cs::cartesian>
{
public:
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
@@ -61,10 +64,37 @@ private:
Segment const& m_segment;
};
+template <typename Segment, typename Box, typename CSystem>
+struct bounded_view<Segment, Box, segment_tag, box_tag, CSystem>
+{
+public:
+ typedef typename geometry::coordinate_type<Box>::type coordinate_type;
+
+ explicit bounded_view(Segment const& segment)
+ {
+ geometry::envelope(segment, m_box);
+ }
+
+ template <std::size_t Dimension>
+ inline coordinate_type get_min() const
+ {
+ return geometry::get<min_corner, Dimension>(m_box);
+ }
+
+ template <std::size_t Dimension>
+ inline coordinate_type get_max() const
+ {
+ return geometry::get<max_corner, Dimension>(m_box);
+ }
+
+private:
+ Box m_box;
+};
+
// Box -> Box
-template <typename BoxIn, typename Box>
-struct bounded_view<BoxIn, Box, box_tag, box_tag>
+template <typename BoxIn, typename Box, typename CSystem>
+struct bounded_view<BoxIn, Box, box_tag, box_tag, CSystem>
{
public:
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
@@ -93,8 +123,8 @@ private:
// Point -> Box
-template <typename Point, typename Box>
-struct bounded_view<Point, Box, point_tag, box_tag>
+template <typename Point, typename Box, typename CSystem>
+struct bounded_view<Point, Box, point_tag, box_tag, CSystem>
{
public:
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
@@ -129,23 +159,23 @@ private:
namespace traits
{
-template <typename Geometry, typename Box, typename Tag>
-struct tag< index::detail::bounded_view<Geometry, Box, Tag, box_tag> >
+template <typename Geometry, typename Box, typename Tag, typename CSystem>
+struct tag< index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> >
{
typedef box_tag type;
};
-template <typename Segment, typename Box, typename Tag>
-struct point_type< index::detail::bounded_view<Segment, Box, Tag, box_tag> >
+template <typename Geometry, typename Box, typename Tag, typename CSystem>
+struct point_type< index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> >
{
typedef typename point_type<Box>::type type;
};
-template <typename Segment, typename Box, typename Tag, std::size_t Dimension>
-struct indexed_access<index::detail::bounded_view<Segment, Box, Tag, box_tag>,
+template <typename Geometry, typename Box, typename Tag, typename CSystem, std::size_t Dimension>
+struct indexed_access<index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem>,
min_corner, Dimension>
{
- typedef index::detail::bounded_view<Segment, Box, Tag, box_tag> box_type;
+ typedef index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> box_type;
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
static inline coordinate_type get(box_type const& b)
@@ -159,11 +189,11 @@ struct indexed_access<index::detail::bounded_view<Segment, Box, Tag, box_tag>,
//}
};
-template <typename Segment, typename Box, typename Tag, std::size_t Dimension>
-struct indexed_access<index::detail::bounded_view<Segment, Box, Tag, box_tag>,
+template <typename Geometry, typename Box, typename Tag, typename CSystem, std::size_t Dimension>
+struct indexed_access<index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem>,
max_corner, Dimension>
{
- typedef index::detail::bounded_view<Segment, Box, Tag, box_tag> box_type;
+ typedef index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> box_type;
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
static inline coordinate_type get(box_type const& b)
diff --git a/boost/geometry/index/detail/predicates.hpp b/boost/geometry/index/detail/predicates.hpp
index 60f80207d8..01afd16ba6 100644
--- a/boost/geometry/index/detail/predicates.hpp
+++ b/boost/geometry/index/detail/predicates.hpp
@@ -25,6 +25,7 @@ namespace predicates {
template <typename Fun, bool IsFunction>
struct satisfies_impl
{
+ satisfies_impl() : fun(NULL) {}
satisfies_impl(Fun f) : fun(f) {}
Fun * fun;
};
@@ -32,6 +33,7 @@ struct satisfies_impl
template <typename Fun>
struct satisfies_impl<Fun, false>
{
+ satisfies_impl() {}
satisfies_impl(Fun const& f) : fun(f) {}
Fun fun;
};
@@ -42,6 +44,7 @@ struct satisfies
{
typedef satisfies_impl<Fun, ::boost::is_function<Fun>::value> base;
+ satisfies() {}
satisfies(Fun const& f) : base(f) {}
satisfies(base const& b) : base(b) {}
};
@@ -60,6 +63,7 @@ struct within_tag {};
template <typename Geometry, typename Tag, bool Negated>
struct spatial_predicate
{
+ spatial_predicate() {}
spatial_predicate(Geometry const& g) : geometry(g) {}
Geometry geometry;
};
@@ -75,6 +79,9 @@ struct spatial_predicate
template <typename PointOrRelation>
struct nearest
{
+ nearest()
+// : count(0)
+ {}
nearest(PointOrRelation const& por, unsigned k)
: point_or_relation(por)
, count(k)
@@ -86,6 +93,9 @@ struct nearest
template <typename SegmentOrLinestring>
struct path
{
+ path()
+// : count(0)
+ {}
path(SegmentOrLinestring const& g, unsigned k)
: geometry(g)
, count(k)
diff --git a/boost/geometry/index/detail/rtree/iterators.hpp b/boost/geometry/index/detail/rtree/iterators.hpp
new file mode 100644
index 0000000000..a47dd7ea43
--- /dev/null
+++ b/boost/geometry/index/detail/rtree/iterators.hpp
@@ -0,0 +1,122 @@
+// Boost.Geometry Index
+//
+// R-tree iterators
+//
+// Copyright (c) 2011-2015 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
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
+
+namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
+
+template <typename Value, typename Allocators>
+struct end_iterator
+{
+ 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;
+
+ reference operator*() const
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
+ pointer p(0);
+ return *p;
+ }
+
+ const value_type * operator->() const
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
+ const value_type * p = 0;
+ return p;
+ }
+
+ end_iterator & operator++()
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
+ return *this;
+ }
+
+ end_iterator operator++(int)
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
+ return *this;
+ }
+
+ friend bool operator==(end_iterator const& /*l*/, end_iterator const& /*r*/)
+ {
+ return true;
+ }
+};
+
+template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
+class iterator
+{
+ typedef visitors::iterator<Value, Options, Translator, Box, Allocators> visitor_type;
+ typedef typename visitor_type::node_pointer node_pointer;
+
+public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef Value value_type;
+ typedef typename Allocators::const_reference reference;
+ typedef typename Allocators::difference_type difference_type;
+ typedef typename Allocators::const_pointer pointer;
+
+ inline iterator()
+ {}
+
+ inline iterator(node_pointer root)
+ {
+ m_visitor.initialize(root);
+ }
+
+ reference operator*() const
+ {
+ return m_visitor.dereference();
+ }
+
+ const value_type * operator->() const
+ {
+ return boost::addressof(m_visitor.dereference());
+ }
+
+ iterator & operator++()
+ {
+ m_visitor.increment();
+ return *this;
+ }
+
+ iterator operator++(int)
+ {
+ iterator temp = *this;
+ this->operator++();
+ return temp;
+ }
+
+ friend bool operator==(iterator const& l, iterator const& r)
+ {
+ return l.m_visitor == r.m_visitor;
+ }
+
+ friend bool operator==(iterator const& l, end_iterator<Value, Allocators> const& /*r*/)
+ {
+ return l.m_visitor.is_end();
+ }
+
+ friend bool operator==(end_iterator<Value, Allocators> const& /*l*/, iterator const& r)
+ {
+ return r.m_visitor.is_end();
+ }
+
+private:
+ visitor_type m_visitor;
+};
+
+}}}}}} // namespace boost::geometry::index::detail::rtree::iterators
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
diff --git a/boost/geometry/index/detail/rtree/node/node.hpp b/boost/geometry/index/detail/rtree/node/node.hpp
index 528d473170..b04744c85a 100644
--- a/boost/geometry/index/detail/rtree/node/node.hpp
+++ b/boost/geometry/index/detail/rtree/node/node.hpp
@@ -46,11 +46,7 @@ inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
{
Box result;
- if ( first == last )
- {
- geometry::assign_inverse(result);
- return result;
- }
+ BOOST_GEOMETRY_INDEX_ASSERT(first != last, "non-empty range required");
detail::bounds(element_indexable(*first, tr), result);
++first;
diff --git a/boost/geometry/index/detail/rtree/pack_create.hpp b/boost/geometry/index/detail/rtree/pack_create.hpp
index b7be41ab2b..ce07d293db 100644
--- a/boost/geometry/index/detail/rtree/pack_create.hpp
+++ b/boost/geometry/index/detail/rtree/pack_create.hpp
@@ -11,6 +11,9 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_PACK_CREATE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_PACK_CREATE_HPP
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/index/detail/algorithms/bounds.hpp>
+
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
namespace pack_utils {
@@ -157,8 +160,7 @@ public:
values_count = static_cast<size_type>(diff);
entries.reserve(values_count);
- Box hint_box;
- geometry::assign_inverse(hint_box);
+ expandable_box<Box> hint_box;
for ( ; first != last ; ++first )
{
// NOTE: support for iterators not returning true references adapted
@@ -172,7 +174,7 @@ public:
// CONSIDER: alternative - ignore invalid indexable or throw an exception
BOOST_GEOMETRY_INDEX_ASSERT(detail::is_valid(indexable), "Indexable is invalid");
- geometry::expand(hint_box, indexable);
+ hint_box.expand(indexable);
point_type pt;
geometry::centroid(indexable, pt);
@@ -180,13 +182,49 @@ public:
}
subtree_elements_counts subtree_counts = calculate_subtree_elements_counts(values_count, parameters, leafs_level);
- internal_element el = per_level(entries.begin(), entries.end(), hint_box, values_count, subtree_counts,
+ internal_element el = per_level(entries.begin(), entries.end(), hint_box.get(), values_count, subtree_counts,
parameters, translator, allocators);
return el.second;
}
private:
+ template <typename BoxType>
+ class expandable_box
+ {
+ public:
+ expandable_box()
+ : m_initialized(false)
+ {}
+
+ template <typename Indexable>
+ void expand(Indexable const& indexable)
+ {
+ if ( !m_initialized )
+ {
+ // 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);
+ m_initialized = true;
+ }
+ else
+ {
+ geometry::expand(m_box, indexable);
+ }
+ }
+
+ BoxType const& get() const
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(m_initialized, "uninitialized envelope accessed");
+ return m_box;
+ }
+
+ private:
+ bool m_initialized;
+ BoxType m_box;
+ };
+
struct subtree_elements_counts
{
subtree_elements_counts(std::size_t ma, std::size_t mi) : maxc(ma), minc(mi) {}
@@ -216,19 +254,18 @@ private:
// reserve space for values
rtree::elements(l).reserve(values_count); // MAY THROW (A)
// calculate values box and copy values
- Box elements_box;
- geometry::assign_inverse(elements_box);
+ expandable_box<Box> elements_box;
for ( ; 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<>.
- geometry::expand(elements_box, translator(*(first->second)));
+ elements_box.expand(translator(*(first->second)));
rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C)
}
auto_remover.release();
- return internal_element(elements_box, n);
+ return internal_element(elements_box.get(), n);
}
// calculate next max and min subtree counts
@@ -245,23 +282,22 @@ private:
std::size_t nodes_count = calculate_nodes_count(values_count, subtree_counts);
rtree::elements(in).reserve(nodes_count); // MAY THROW (A)
// calculate values box and copy values
- Box elements_box;
- geometry::assign_inverse(elements_box);
-
+ expandable_box<Box> elements_box;
+
per_level_packets(first, last, hint_box, values_count, subtree_counts, next_subtree_counts,
rtree::elements(in), elements_box,
parameters, translator, allocators);
auto_remover.release();
- return internal_element(elements_box, n);
+ return internal_element(elements_box.get(), n);
}
- template <typename EIt> inline static
+ template <typename EIt, typename ExpandableBox> inline static
void per_level_packets(EIt first, EIt last, Box const& hint_box,
std::size_t values_count,
subtree_elements_counts const& subtree_counts,
subtree_elements_counts const& next_subtree_counts,
- internal_elements & elements, Box & elements_box,
+ internal_elements & elements, ExpandableBox & elements_box,
parameters_type const& parameters, Translator const& translator, Allocators & allocators)
{
BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count,
@@ -285,7 +321,7 @@ private:
elements.push_back(el); // MAY THROW (A?,C) - however in normal conditions shouldn't
auto_remover.release();
- geometry::expand(elements_box, el.first);
+ elements_box.expand(el.first);
return;
}
diff --git a/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp b/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp
index 634d879864..928ffd47d9 100644
--- a/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp
+++ b/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp
@@ -2,7 +2,7 @@
//
// R-tree quadratic split algorithm implementation
//
-// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2015 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
@@ -57,7 +57,6 @@ inline void pick_seeds(Elements const& elements,
indexable_type const& ind2 = rtree::element_indexable(elements[j], tr);
box_type enlarged_box;
- //geometry::convert(ind1, enlarged_box);
detail::bounds(ind1, enlarged_box);
geometry::expand(enlarged_box, ind2);
@@ -133,9 +132,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
elements2.push_back(elements_copy[seed2]); // MAY THROW, STRONG (alloc, copy)
// calculate boxes
- //geometry::convert(rtree::element_indexable(elements_copy[seed1], translator), box1);
detail::bounds(rtree::element_indexable(elements_copy[seed1], translator), box1);
- //geometry::convert(rtree::element_indexable(elements_copy[seed2], translator), box2);
detail::bounds(rtree::element_indexable(elements_copy[seed2], translator), box2);
// remove seeds
diff --git a/boost/geometry/index/detail/rtree/query_iterators.hpp b/boost/geometry/index/detail/rtree/query_iterators.hpp
index 74000d03ef..83be106b8b 100644
--- a/boost/geometry/index/detail/rtree/query_iterators.hpp
+++ b/boost/geometry/index/detail/rtree/query_iterators.hpp
@@ -20,7 +20,7 @@ namespace boost { namespace geometry { namespace index { namespace detail { name
template <typename Value, typename Allocators>
struct end_query_iterator
{
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
@@ -65,12 +65,15 @@ class spatial_query_iterator
typedef typename visitor_type::node_pointer node_pointer;
public:
- typedef std::input_iterator_tag iterator_category;
+ 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;
+ inline spatial_query_iterator()
+ {}
+
inline spatial_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
@@ -130,12 +133,15 @@ class distance_query_iterator
typedef typename visitor_type::node_pointer node_pointer;
public:
- typedef std::input_iterator_tag iterator_category;
+ 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;
+ inline distance_query_iterator()
+ {}
+
inline distance_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
@@ -188,22 +194,19 @@ private:
visitor_type m_visitor;
};
+
template <typename L, typename R>
inline bool operator!=(L const& l, R const& r)
{
return !(l == r);
}
-}}}}}} // namespace boost::geometry::index::detail::rtree::iterators
-
-
-namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
template <typename Value, typename Allocators>
class query_iterator_base
{
public:
- typedef std::input_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
@@ -226,12 +229,13 @@ class query_iterator_wrapper
typedef query_iterator_base<Value, Allocators> base_t;
public:
- typedef std::input_iterator_tag iterator_category;
+ 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;
+ query_iterator_wrapper() : m_iterator() {}
explicit query_iterator_wrapper(Iterator const& it) : m_iterator(it) {}
virtual base_t * clone() const { return new query_iterator_wrapper(m_iterator); }
@@ -258,13 +262,14 @@ class query_iterator
typedef boost::scoped_ptr<iterator_base> iterator_ptr;
public:
- typedef std::input_iterator_tag iterator_category;
+ 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;
- query_iterator() {}
+ query_iterator()
+ {}
template <typename It>
query_iterator(It const& it)
diff --git a/boost/geometry/index/detail/rtree/visitors/distance_query.hpp b/boost/geometry/index/detail/rtree/visitors/distance_query.hpp
index fc0929e9ed..b930714433 100644
--- a/boost/geometry/index/detail/rtree/visitors/distance_query.hpp
+++ b/boost/geometry/index/detail/rtree/visitors/distance_query.hpp
@@ -337,6 +337,13 @@ public:
};
typedef std::vector<internal_stack_element> internal_stack_type;
+ inline distance_query_incremental()
+ : m_translator(NULL)
+// , m_pred()
+ , current_neighbor((std::numeric_limits<size_type>::max)())
+// , next_closest_node_distance((std::numeric_limits<node_distance_type>::max)())
+ {}
+
inline distance_query_incremental(Translator const& translator, Predicates const& pred)
: m_translator(::boost::addressof(translator))
, m_pred(pred)
@@ -428,6 +435,7 @@ public:
{
BOOST_GEOMETRY_INDEX_ASSERT(l.current_neighbor != r.current_neighbor ||
(std::numeric_limits<size_type>::max)() == l.current_neighbor ||
+ (std::numeric_limits<size_type>::max)() == r.current_neighbor ||
l.neighbors[l.current_neighbor].second == r.neighbors[r.current_neighbor].second,
"not corresponding iterators");
return l.current_neighbor == r.current_neighbor;
diff --git a/boost/geometry/index/detail/rtree/visitors/iterator.hpp b/boost/geometry/index/detail/rtree/visitors/iterator.hpp
new file mode 100644
index 0000000000..621231ae9a
--- /dev/null
+++ b/boost/geometry/index/detail/rtree/visitors/iterator.hpp
@@ -0,0 +1,134 @@
+// Boost.Geometry Index
+//
+// R-tree iterator visitor implementation
+//
+// Copyright (c) 2011-2015 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
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail { namespace rtree { namespace visitors {
+
+template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
+class iterator
+ : 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 Allocators::size_type size_type;
+ typedef typename Allocators::const_reference const_reference;
+ typedef typename Allocators::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;
+
+ inline iterator()
+ : m_values(NULL)
+ , 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();
+ }
+
+ const_reference dereference() const
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(m_values, "not dereferencable");
+ return *m_current;
+ }
+
+ void initialize(node_pointer root)
+ {
+ rtree::apply_visitor(*this, *root);
+ search_value();
+ }
+
+ void increment()
+ {
+ ++m_current;
+ search_value();
+ }
+
+ void search_value()
+ {
+ for (;;)
+ {
+ // if leaf is choosen, move to the next value in leaf
+ if ( m_values )
+ {
+ // there are more values in the current leaf
+ if ( m_current != m_values->end() )
+ {
+ return;
+ }
+ // no more values, clear current leaf
+ else
+ {
+ m_values = 0;
+ }
+ }
+ // if leaf isn't choosen, move to the next leaf
+ else
+ {
+ // return if there is no more nodes to traverse
+ if ( m_internal_stack.empty() )
+ return;
+
+ // no more children in current node, remove it from stack
+ if ( m_internal_stack.back().first == m_internal_stack.back().second )
+ {
+ m_internal_stack.pop_back();
+ continue;
+ }
+
+ internal_iterator it = m_internal_stack.back().first;
+ ++m_internal_stack.back().first;
+
+ // push the next node to the stack
+ rtree::apply_visitor(*this, *(it->second));
+ }
+ }
+ }
+
+ bool is_end() const
+ {
+ return 0 == m_values;
+ }
+
+ friend bool operator==(iterator const& l, iterator const& r)
+ {
+ return (l.m_values == r.m_values) && (0 == l.m_values || l.m_current == r.m_current );
+ }
+
+private:
+
+ std::vector< std::pair<internal_iterator, internal_iterator> > m_internal_stack;
+ const leaf_elements * m_values;
+ leaf_iterator m_current;
+};
+
+}}} // namespace detail::rtree::visitors
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
diff --git a/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp b/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp
index f00189fe77..b9cd0ae2c0 100644
--- a/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp
+++ b/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp
@@ -94,10 +94,18 @@ public:
static const unsigned predicates_len = index::detail::predicates_length<Predicates>::value;
+ inline spatial_query_incremental()
+ : m_translator(NULL)
+// , m_pred()
+ , m_values(NULL)
+ , m_current()
+ {}
+
inline spatial_query_incremental(Translator const& t, Predicates const& p)
: m_translator(::boost::addressof(t))
, m_pred(p)
- , m_values(0)
+ , m_values(NULL)
+ , m_current()
{}
inline void operator()(internal_node const& n)
diff --git a/boost/geometry/index/rtree.hpp b/boost/geometry/index/rtree.hpp
index 9d5d57d059..84c4da8a2a 100644
--- a/boost/geometry/index/rtree.hpp
+++ b/boost/geometry/index/rtree.hpp
@@ -59,6 +59,7 @@
#include <boost/geometry/index/detail/algorithms/is_valid.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
+#include <boost/geometry/index/detail/rtree/visitors/iterator.hpp>
#include <boost/geometry/index/detail/rtree/visitors/remove.hpp>
#include <boost/geometry/index/detail/rtree/visitors/copy.hpp>
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
@@ -78,6 +79,7 @@
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
+#include <boost/geometry/index/detail/rtree/iterators.hpp>
#include <boost/geometry/index/detail/rtree/query_iterators.hpp>
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
@@ -220,8 +222,17 @@ public:
/*! \brief Unsigned integral type used by the container. */
typedef typename allocators_type::size_type size_type;
- /*! \brief Type of const query iterator. */
- typedef index::detail::rtree::iterators::query_iterator<value_type, allocators_type> const_query_iterator;
+ /*! \brief Type of const iterator, category ForwardIterator. */
+ typedef index::detail::rtree::iterators::iterator
+ <
+ value_type, options_type, translator_type, box_type, allocators_type
+ > const_iterator;
+
+ /*! \brief Type of const query iterator, category ForwardIterator. */
+ typedef index::detail::rtree::iterators::query_iterator
+ <
+ value_type, allocators_type
+ > const_query_iterator;
public:
@@ -766,6 +777,27 @@ public:
tree.query(bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
// return 5 elements nearest to pt and elements are intersecting box
tree.query(bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
+
+ // For each found value do_something (it is a type of function object)
+ tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator(do_something()));
+
+ // For each value stored in the rtree do_something
+ // always_true is a type of function object always returning true
+ tree.query(bgi::satisfies(always_true()),
+ boost::make_function_output_iterator(do_something()));
+
+ // C++11 (lambda expression)
+ tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator([](value_type const& val){
+ // do something
+ }));
+
+ // C++14 (generic lambda expression)
+ tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator([](auto const& val){
+ // do something
+ }));
\endverbatim
\par Throws
@@ -774,7 +806,7 @@ public:
\warning
Only one \c nearest() perdicate may be passed to the query. Passing more of them results in compile-time error.
-
+
\param predicates Predicates.
\param out_it The output iterator, e.g. generated by std::back_inserter().
@@ -794,11 +826,11 @@ public:
}
/*!
- \brief Returns the query iterator pointing at the begin of the query range.
+ \brief Returns a query iterator pointing at the begin of the query range.
+
+ This method returns an iterator which may be used to perform iterative queries.
+ For the information about predicates which may be passed to this method see query().
- This method returns the iterator which may be used to perform iterative queries. For the information
- about the predicates which may be passed to this method see query().
-
\par Example
\verbatim
for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
@@ -808,12 +840,29 @@ public:
if ( has_enough_nearest_values() )
break;
}
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin(bgi::nearest(pt, 3)) ; it != tree.qend() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++14 (generic lambda expression)
+ std::for_each(tree.qbegin(bgi::nearest(pt, 3)), tree.qend(), [](auto const& val){
+ // do something with value
+ });
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
If predicates copy throws.
If allocation throws.
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
\param predicates Predicates.
\return The iterator pointing at the begin of the query range.
@@ -825,10 +874,10 @@ public:
}
/*!
- \brief Returns the query iterator pointing at the end of the query range.
+ \brief Returns a query iterator pointing at the end of the query range.
+
+ This method returns an iterator which may be used to check if the query has ended.
- This method returns the iterator which may be used to check if the query has ended.
-
\par Example
\verbatim
for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
@@ -838,10 +887,27 @@ public:
if ( has_enough_nearest_values() )
break;
}
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin(bgi::nearest(pt, 3)) ; it != tree.qend() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++14 (generic lambda expression)
+ std::for_each(tree.qbegin(bgi::nearest(pt, 3)), tree.qend(), [](auto const& val){
+ // do something with value
+ });
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
Nothing
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
\return The iterator pointing at the end of the query range.
*/
@@ -854,10 +920,10 @@ public:
private:
#endif
/*!
- \brief Returns the query iterator pointing at the begin of the query range.
+ \brief Returns a query iterator pointing at the begin of the query range.
- This method returns the iterator which may be used to perform iterative queries. For the information
- about the predicates which may be passed to this method see query().
+ This method returns an iterator which may be used to perform iterative queries.
+ For the information about predicates which may be passed to this method see query().
The type of the returned iterator depends on the type of passed Predicates but the iterator of this type
may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator
@@ -867,16 +933,24 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() - it requires both iterators of the same type
- std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
+ std::copy(tree.qbegin_(bgi::intersects(box)), tree.qend_(bgi::intersects(box)), std::back_inserter(result));
// Store the result in the container using std::copy() and type-erased iterators
- Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
- Rtree::const_query_iterator last = tree.qend();
+ Rtree::const_query_iterator first = tree.qbegin_(bgi::intersects(box));
+ Rtree::const_query_iterator last = tree.qend_();
std::copy(first, last, std::back_inserter(result));
// Boost.Typeof
typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
- for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
+ for ( Iter it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
+ {
+ // do something with value
+ if ( has_enough_nearest_values() )
+ break;
+ }
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
@@ -884,10 +958,16 @@ private:
}
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
If predicates copy throws.
If allocation throws.
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
\param predicates Predicates.
\return The iterator pointing at the begin of the query range.
@@ -937,12 +1017,18 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() - it requires both iterators of the same type
- std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
+ std::copy(tree.qbegin_(bgi::intersects(box)), tree.qend_(bgi::intersects(box)), std::back_inserter(result));
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
If predicates copy throws.
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
\param predicates Predicates.
\return The iterator pointing at the end of the query range.
@@ -989,13 +1075,21 @@ private:
\par Example
\verbatim
// Store the result in the container using std::copy() and type-erased iterators
- Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
- Rtree::const_query_iterator last = tree.qend();
+ Rtree::const_query_iterator first = tree.qbegin_(bgi::intersects(box));
+ Rtree::const_query_iterator last = tree.qend_();
std::copy(first, last, std::back_inserter(result));
// Boost.Typeof
typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
- for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
+ for ( Iter it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
+ {
+ // do something with value
+ if ( has_enough_nearest_values() )
+ break;
+ }
+
+ // C++11 (auto)
+ for ( auto it = tree.qbegin_(bgi::nearest(pt, 10000)) ; it != tree.qend_() ; ++it )
{
// do something with value
if ( has_enough_nearest_values() )
@@ -1003,8 +1097,14 @@ private:
}
\endverbatim
+ \par Iterator category
+ ForwardIterator
+
\par Throws
Nothing
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
\return The iterator pointing at the end of the query range.
*/
@@ -1017,6 +1117,88 @@ private:
public:
/*!
+ \brief Returns the iterator pointing at the begin of the rtree values range.
+
+ This method returns the iterator which may be used to iterate over all values
+ stored in the rtree.
+
+ \par Example
+ \verbatim
+ // Copy all values into the vector
+ std::copy(tree.begin(), tree.end(), std::back_inserter(vec));
+
+ for ( Rtree::const_iterator it = tree.begin() ; it != tree.end() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++11 (auto)
+ for ( auto it = tree.begin() ; it != tree.end() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++14 (generic lambda expression)
+ std::for_each(tree.begin(), tree.end(), [](auto const& val){
+ // do something with value
+ })
+ \endverbatim
+
+ \par Iterator category
+ ForwardIterator
+
+ \par Throws
+ If allocation throws.
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
+ \return The iterator pointing at the begin of the range.
+ */
+ const_iterator begin() const
+ {
+ if ( !m_members.root )
+ return const_iterator();
+
+ return const_iterator(m_members.root);
+ }
+
+ /*!
+ \brief Returns the iterator pointing at the end of the rtree values range.
+
+ This method returns the iterator which may be compared with the iterator returned by begin()
+ in order to check if the iteration has ended.
+
+ \par Example
+ \verbatim
+ for ( Rtree::const_iterator it = tree.begin() ; it != tree.end() ; ++it )
+ {
+ // do something with value
+ }
+
+ // C++11 (lambda expression)
+ std::for_each(tree.begin(), tree.end(), [](value_type const& val){
+ // do something with value
+ })
+ \endverbatim
+
+ \par Iterator category
+ ForwardIterator
+
+ \par Throws
+ Nothing.
+
+ \warning
+ The modification of the rtree may invalidate the iterators.
+
+ \return The iterator pointing at the end of the range.
+ */
+ const_iterator end() const
+ {
+ return const_iterator();
+ }
+
+ /*!
\brief Returns the number of stored values.
\return The number of stored values.
@@ -1763,6 +1945,10 @@ bgi::query(tree, bgi::intersects(poly) && !bgi::within(box), std::back_inserter(
bgi::query(tree, bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
// return 5 elements nearest to pt and elements are intersecting box
bgi::query(tree, bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
+
+// For each found value do_something (it is a type of function object)
+tree.query(bgi::intersects(box),
+ boost::make_function_output_iterator(do_something()));
\endverbatim
\par Throws
@@ -1797,20 +1983,19 @@ about the predicates which may be passed to this method see query().
\par Example
\verbatim
-
-for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
- it != qend(tree) ; ++it )
-{
- // do something with value
- if ( has_enough_nearest_values() )
- break;
-}
+std::for_each(bgi::qbegin(tree, bgi::nearest(pt, 3)), bgi::qend(tree), do_something());
\endverbatim
+\par Iterator category
+ForwardIterator
+
\par Throws
If predicates copy throws.
If allocation throws.
+\warning
+The modification of the rtree may invalidate the iterators.
+
\ingroup rtree_functions
\param tree The rtree.
@@ -1834,19 +2019,18 @@ This method returns the iterator which may be used to check if the query has end
\par Example
\verbatim
-
-for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
- it != qend(tree) ; ++it )
-{
- // do something with value
- if ( has_enough_nearest_values() )
- break;
-}
+std::for_each(bgi::qbegin(tree, bgi::nearest(pt, 3)), bgi::qend(tree), do_something());
\endverbatim
+\par Iterator category
+ForwardIterator
+
\par Throws
Nothing
+\warning
+The modification of the rtree may invalidate the iterators.
+
\ingroup rtree_functions
\return The iterator pointing at the end of the query range.
@@ -1859,6 +2043,72 @@ qend(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
}
/*!
+\brief Returns the iterator pointing at the begin of the rtree values range.
+
+This method returns the iterator which may be used to iterate over all values
+stored in the rtree.
+
+\par Example
+\verbatim
+std::for_each(bgi::begin(tree), bgi::end(tree), do_something());
+// the same as
+std::for_each(boost::begin(tree), boost::end(tree), do_something());
+\endverbatim
+
+\par Iterator category
+ForwardIterator
+
+\par Throws
+If allocation throws.
+
+\warning
+The modification of the rtree may invalidate the iterators.
+
+\ingroup rtree_functions
+
+\return The iterator pointing at the begin of the range.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
+typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_iterator
+begin(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
+{
+ return tree.begin();
+}
+
+/*!
+\brief Returns the iterator pointing at the end of the rtree values range.
+
+This method returns the iterator which may be compared with the iterator returned by begin()
+in order to check if the iteration has ended.
+
+\par Example
+\verbatim
+std::for_each(bgi::begin(tree), bgi::end(tree), do_something());
+// the same as
+std::for_each(boost::begin(tree), boost::end(tree), do_something());
+\endverbatim
+
+\par Iterator category
+ForwardIterator
+
+\par Throws
+Nothing.
+
+\warning
+The modification of the rtree may invalidate the iterators.
+
+\ingroup rtree_functions
+
+\return The iterator pointing at the end of the range.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
+typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_iterator
+end(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
+{
+ return tree.end();
+}
+
+/*!
\brief Remove all values from the index.
It calls \c rtree::clear().
@@ -1944,6 +2194,23 @@ inline void swap(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> &
}}} // namespace boost::geometry::index
+// Boost.Range adaptation
+namespace boost {
+
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
+struct range_mutable_iterator
+ <
+ boost::geometry::index::rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>
+ >
+{
+ typedef typename boost::geometry::index::rtree
+ <
+ Value, Parameters, IndexableGetter, EqualTo, Allocator
+ >::const_iterator type;
+};
+
+} // namespace boost
+
// TODO: don't include the implementation at the end of the file
#include <boost/geometry/algorithms/detail/comparable_distance/implementation.hpp>