diff --git a/doc/html/geometry_index/r_tree/exception_safety.html b/doc/html/geometry_index/r_tree/exception_safety.html
index 04dd96621..08be8978b 100644
--- a/doc/html/geometry_index/r_tree/exception_safety.html
+++ b/doc/html/geometry_index/r_tree/exception_safety.html
@@ -75,8 +75,8 @@
|
size()
diff --git a/doc/html/index.html b/doc/html/index.html
index e369d528c..2084b6801 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -56,7 +56,7 @@
-Last revised: December 14, 2012 at 15:00:09 GMT |
+Last revised: December 14, 2012 at 19:10:44 GMT |
|
diff --git a/doc/rtree/exception_safety.qbk b/doc/rtree/exception_safety.qbk
index 2e6cad42f..37b91ced3 100644
--- a/doc/rtree/exception_safety.qbk
+++ b/doc/rtree/exception_safety.qbk
@@ -20,7 +20,7 @@ In order to be exception-safe the __rtree__ requires:
[table
[[Operation] [exception-safety]]
[[`rtree()`] [ /nothrow/ ]]
-[[`rtree(first, last)`] [ *strong* ]]
+[[`rtree(Iterator, Iterator)`] [ *strong* ]]
[[`~rtree()`] [ /nothrow/ ]]
[[][]]
[[`rtree(rtree const&)`] [ *strong* ]]
@@ -32,15 +32,16 @@ In order to be exception-safe the __rtree__ requires:
[[`swap(rtree &)`] [ /nothrow/ ]]
[[][]]
[[`insert(__value__)`] [ basic ]]
-[[`insert(first, last)`] [ basic ]]
-[[`insert(range)`] [ basic ]]
+[[`insert(Iterator, Iterator)`][ basic ]]
+[[`insert(Range)`] [ basic ]]
[[`remove(__value__)`] [ basic ]]
-[[`remove(first, last)`] [ basic ]]
-[[`remove(range)`] [ basic ]]
+[[`remove(Iterator, Iterator)`][ basic ]]
+[[`remove(Range)`] [ basic ]]
[[][]]
[[`spatial_query(...)`] [ *strong* ]]
[[`nearest_query(...)`] [ *strong* ]]
[[][]]
+[[`count(ValueOrIndexable)`] [ /nothrow/ ]]
[[`size()`] [ /nothrow/ ]]
[[`empty()`] [ /nothrow/ ]]
[[`clear()`] [ /nothrow/ ]]
diff --git a/include/boost/geometry/extensions/index/rtree/rtree.hpp b/include/boost/geometry/extensions/index/rtree/rtree.hpp
index 90ac2b5dd..601273803 100644
--- a/include/boost/geometry/extensions/index/rtree/rtree.hpp
+++ b/include/boost/geometry/extensions/index/rtree/rtree.hpp
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
@@ -644,6 +645,30 @@ public:
return children_box_v.result;
}
+ /*!
+ For indexable_type it returns the number of values which indexables equals the parameter.
+ For value_type it returns the number of values which equals the parameter.
+
+ \note Exception-safety: nothrow.
+
+ \param The value or indexable which will be counted.
+
+ \return The number of values found.
+ */
+ template
+ size_type count(ValueOrIndexable const& vori) const
+ {
+ if ( !m_root )
+ return 0;
+
+ detail::rtree::visitors::count
+ count_v(vori, m_translator);
+
+ detail::rtree::apply_visitor(count_v, *m_root);
+
+ return count_v.found_count;
+ }
+
/*!
Returns parameters.
diff --git a/include/boost/geometry/extensions/index/rtree/visitors/count.hpp b/include/boost/geometry/extensions/index/rtree/visitors/count.hpp
new file mode 100644
index 000000000..2b8a324c6
--- /dev/null
+++ b/include/boost/geometry/extensions/index/rtree/visitors/count.hpp
@@ -0,0 +1,124 @@
+// Boost.Geometry Index
+//
+// R-tree count visitor implementation
+//
+// Copyright (c) 2011-2012 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_EXTENSIONS_INDEX_RTREE_VISITORS_COUNT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_COUNT_HPP
+
+#include
+
+#include
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail { namespace rtree { namespace visitors {
+
+template
+struct count
+ : public rtree::visitor::type
+ , index::nonassignable
+{
+ typedef typename rtree::node::type node;
+ typedef typename rtree::internal_node::type internal_node;
+ typedef typename rtree::leaf::type leaf;
+
+ inline count(Indexable const& i, Translator const& t)
+ : indexable(i), tr(t), found_count(0)
+ {}
+
+ inline void operator()(internal_node const& n)
+ {
+ typedef typename rtree::elements_type::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)
+ {
+ if ( geometry::covered_by(indexable, it->first) )
+ rtree::apply_visitor(*this, *it->second);
+ }
+ }
+
+ inline void operator()(leaf const& n)
+ {
+ typedef typename rtree::elements_type::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 ( geometry::equals(indexable, tr(*it)) )
+ {
+ ++found_count;
+ }
+ }
+ }
+
+ Indexable const& indexable;
+ Translator const& tr;
+ typename Allocators::size_type found_count;
+};
+
+template
+struct count
+ : public rtree::visitor::type
+ , index::nonassignable
+{
+ typedef typename rtree::node::type node;
+ typedef typename rtree::internal_node::type internal_node;
+ typedef typename rtree::leaf::type leaf;
+
+ inline count(Value const& v, Translator const& t)
+ : value(v), tr(t), found_count(0)
+ {}
+
+ inline void operator()(internal_node const& n)
+ {
+ typedef typename rtree::elements_type::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)
+ {
+ if ( geometry::covered_by(tr(value), it->first) )
+ rtree::apply_visitor(*this, *it->second);
+ }
+ }
+
+ inline void operator()(leaf const& n)
+ {
+ typedef typename rtree::elements_type::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 ( tr.equals(value, *it) )
+ {
+ ++found_count;
+ }
+ }
+ }
+
+ Value const& value;
+ Translator const& tr;
+ typename Allocators::size_type found_count;
+};
+
+}}} // namespace detail::rtree::visitors
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_COUNT_HPP
diff --git a/test/rtree/test_rtree.hpp b/test/rtree/test_rtree.hpp
index 0281fd4b2..07c9bc37e 100644
--- a/test/rtree/test_rtree.hpp
+++ b/test/rtree/test_rtree.hpp
@@ -1192,7 +1192,7 @@ void test_rtree_by_value(Parameters const& parameters)
test_copy_assignment_swap_move(empty_tree, qbox);
}
-// rtree inserting removing by use of counting_value
+// rtree inserting and removing of counting_value
template
void test_count_rtree_values(Parameters const& parameters)
@@ -1207,11 +1207,6 @@ void test_count_rtree_values(Parameters const& parameters)
generate_rtree(t, input, qbox);
- {
- BOOST_FOREACH(Value const& v, input)
- t.insert(v);
- }
-
size_t rest_count = input.size();
BOOST_CHECK(t.size() + rest_count == Value::counter());
@@ -1235,6 +1230,35 @@ void test_count_rtree_values(Parameters const& parameters)
}
}
+// rtree count
+
+template
+void test_rtree_count(Parameters const& parameters)
+{
+ typedef std::pair Value;
+ typedef bgi::rtree Tree;
+ typedef typename Tree::box_type B;
+
+ Tree t(parameters);
+ std::vector input;
+ B qbox;
+
+ generate_rtree(t, input, qbox);
+
+ BOOST_CHECK(t.count(input[0]) == 1);
+ BOOST_CHECK(t.count(input[0].first) == 1);
+
+ t.insert(input[0]);
+
+ BOOST_CHECK(t.count(input[0]) == 2);
+ BOOST_CHECK(t.count(input[0].first) == 2);
+
+ t.insert(std::make_pair(input[0].first, -1));
+
+ BOOST_CHECK(t.count(input[0]) == 2);
+ BOOST_CHECK(t.count(input[0].first) == 3);
+}
+
// run all tests for one Algorithm for some number of rtrees
// defined by some number of Values constructed from given Point
@@ -1254,6 +1278,8 @@ void test_rtree_for_point(Parameters const& parameters = Parameters())
test_rtree_by_value(parameters);
test_count_rtree_values(parameters);
+
+ test_rtree_count(parameters);
}
template
@@ -1271,6 +1297,8 @@ void test_rtree_for_box(Parameters const& parameters = Parameters())
test_rtree_by_value(parameters);
test_count_rtree_values(parameters);
+
+ test_rtree_count(parameters);
}
#endif
|