mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-02 08:52:10 +00:00
[index] Refactor count rtree visitor.
Remove specialization of count visitor for value_type, don't duplicate the same algorithm in 2 places. Move Value/Indexable-aware parts into smaller helper struct and specialize it.
This commit is contained in:
@@ -15,7 +15,37 @@ namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace detail { namespace rtree { namespace visitors {
|
||||
|
||||
template <typename Indexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
||||
template <typename Indexable, typename Value>
|
||||
struct count_helper
|
||||
{
|
||||
template <typename Translator>
|
||||
static inline typename Translator::result_type indexable(Indexable const& i, Translator const&)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
template <typename Translator>
|
||||
static inline bool equals(Indexable const& i, Value const& v, Translator const& tr)
|
||||
{
|
||||
return geometry::equals(i, tr(v));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Value>
|
||||
struct count_helper<Value, Value>
|
||||
{
|
||||
template <typename Translator>
|
||||
static inline typename Translator::result_type indexable(Value const& v, Translator const& tr)
|
||||
{
|
||||
return tr(v);
|
||||
}
|
||||
template <typename Translator>
|
||||
static inline bool equals(Value const& v1, Value const& v2, Translator const& tr)
|
||||
{
|
||||
return tr.equals(v1, v2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ValueOrIndexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
||||
struct count
|
||||
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
|
||||
{
|
||||
@@ -23,8 +53,10 @@ struct count
|
||||
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;
|
||||
|
||||
inline count(Indexable const& i, Translator const& t)
|
||||
: indexable(i), tr(t), found_count(0)
|
||||
typedef count_helper<ValueOrIndexable, Value> count_help;
|
||||
|
||||
inline count(ValueOrIndexable const& vori, Translator const& t)
|
||||
: value_or_indexable(vori), tr(t), found_count(0)
|
||||
{}
|
||||
|
||||
inline void operator()(internal_node const& n)
|
||||
@@ -37,7 +69,8 @@ struct count
|
||||
it != elements.end(); ++it)
|
||||
{
|
||||
if ( geometry::covered_by(
|
||||
return_ref_or_bounds(indexable),
|
||||
return_ref_or_bounds(
|
||||
count_help::indexable(value_or_indexable, tr)),
|
||||
it->first) )
|
||||
{
|
||||
rtree::apply_visitor(*this, *it->second);
|
||||
@@ -55,66 +88,14 @@ struct count
|
||||
it != elements.end(); ++it)
|
||||
{
|
||||
// if value meets predicates
|
||||
if ( geometry::equals(indexable, tr(*it)) )
|
||||
if ( count_help::equals(value_or_indexable, *it, tr) )
|
||||
{
|
||||
++found_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Indexable const& indexable;
|
||||
Translator const& tr;
|
||||
typename Allocators::size_type found_count;
|
||||
};
|
||||
|
||||
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
||||
struct count<Value, Value, Options, Translator, Box, Allocators>
|
||||
: 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;
|
||||
|
||||
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<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)
|
||||
{
|
||||
if ( geometry::covered_by(
|
||||
return_ref_or_bounds(tr(value)),
|
||||
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 ( tr.equals(value, *it) )
|
||||
{
|
||||
++found_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Value const& value;
|
||||
ValueOrIndexable const& value_or_indexable;
|
||||
Translator const& tr;
|
||||
typename Allocators::size_type found_count;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user