[index] Simplify rtree query(), qbegin() and qend().

This commit is contained in:
Adam Wulkiewicz
2021-07-22 17:16:35 +02:00
parent 5701d7bef0
commit f838b88a9d
4 changed files with 69 additions and 108 deletions

View File

@@ -4,8 +4,8 @@
//
// 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.
// 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,
@@ -134,14 +134,14 @@ private:
visitor_type m_visitor;
};
template <typename MembersHolder, typename Predicates, unsigned NearestPredicateIndex>
template <typename MembersHolder, typename Predicates>
class distance_query_iterator
{
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef visitors::distance_query_incremental<MembersHolder, Predicates, NearestPredicateIndex> visitor_type;
typedef visitors::distance_query_incremental<MembersHolder, Predicates> visitor_type;
typedef typename visitor_type::node_pointer node_pointer;
public:

View File

@@ -17,6 +17,7 @@
#include <queue>
#include <boost/geometry/index/detail/predicates.hpp>
#include <boost/geometry/index/detail/priority_dequeue.hpp>
namespace boost { namespace geometry { namespace index {
@@ -48,24 +49,24 @@ template <typename T, typename Comp>
struct priority_dequeue : index::detail::priority_dequeue<T, std::vector<T>, Comp>
{
priority_dequeue() = default;
void reserve(typename std::vector<T>::size_type n)
{
this->c.reserve(n);
}
void clear()
{
this->c.clear();
}
//void reserve(typename std::vector<T>::size_type n)
//{
// this->c.reserve(n);
//}
//void clear()
//{
// this->c.clear();
//}
};
template <typename T, typename Comp>
struct priority_queue : std::priority_queue<T, std::vector<T>, Comp>
{
priority_queue() = default;
void reserve(typename std::vector<T>::size_type n)
{
this->c.reserve(n);
}
//void reserve(typename std::vector<T>::size_type n)
//{
// this->c.reserve(n);
//}
void clear()
{
this->c.clear();
@@ -131,12 +132,7 @@ private:
neighbors_type m_neighbors;
};
template
<
typename MembersHolder,
typename Predicates,
std::size_t DistancePredicateIndex
>
template <typename MembersHolder, typename Predicates>
class distance_query
: public MembersHolder::visitor_const
{
@@ -153,7 +149,10 @@ public:
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef index::detail::predicates_element<DistancePredicateIndex, Predicates> nearest_predicate_access;
typedef index::detail::predicates_element
<
index::detail::predicates_find_distance<Predicates>::value, Predicates
> nearest_predicate_access;
typedef typename nearest_predicate_access::type nearest_predicate_type;
typedef typename indexable_type<translator_type>::type indexable_type;
@@ -298,11 +297,7 @@ private:
strategy_type m_strategy;
};
template <
typename MembersHolder,
typename Predicates,
std::size_t DistancePredicateIndex
>
template <typename MembersHolder, typename Predicates>
class distance_query_incremental
: public MembersHolder::visitor_const
{
@@ -319,7 +314,10 @@ public:
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef index::detail::predicates_element<DistancePredicateIndex, Predicates> nearest_predicate_access;
typedef index::detail::predicates_element
<
index::detail::predicates_find_distance<Predicates>::value, Predicates
> nearest_predicate_access;
typedef typename nearest_predicate_access::type nearest_predicate_type;
typedef typename indexable_type<translator_type>::type indexable_type;

View File

@@ -15,6 +15,8 @@
#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/predicates.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {

View File

@@ -1079,17 +1079,9 @@ public:
template <typename Predicates, typename OutIter>
size_type query(Predicates const& predicates, OutIter out_it) const
{
if ( !m_members.root )
return 0;
static const std::size_t distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
static const bool is_distance_predicate = 0 < distance_predicates_count;
BOOST_GEOMETRY_STATIC_ASSERT((distance_predicates_count <= 1),
"Only one distance predicate can be passed.",
Predicates);
return query_dispatch(predicates, out_it,
std::integral_constant<bool, is_distance_predicate>());
return m_members.root
? query_dispatch(predicates, out_it)
: 0;
}
/*!
@@ -1183,6 +1175,15 @@ public:
return const_query_iterator();
}
private:
template <typename Predicates>
using query_iterator_t = std::conditional_t
<
detail::predicates_count_distance<Predicates>::value == 0,
detail::rtree::iterators::spatial_query_iterator<members_holder, Predicates>,
detail::rtree::iterators::distance_query_iterator<members_holder, Predicates>
>;
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
private:
#endif
@@ -1240,38 +1241,15 @@ private:
\return The iterator pointing at the begin of the query range.
*/
template <typename Predicates>
std::conditional_t
<
detail::predicates_count_distance<Predicates>::value == 0,
detail::rtree::iterators::spatial_query_iterator<members_holder, Predicates>,
detail::rtree::iterators::distance_query_iterator
<
members_holder, Predicates,
detail::predicates_find_distance<Predicates>::value
>
>
qbegin_(Predicates const& predicates) const
query_iterator_t<Predicates> qbegin_(Predicates const& predicates) const
{
static const std::size_t distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
BOOST_GEOMETRY_STATIC_ASSERT((distance_predicates_count <= 1),
BOOST_GEOMETRY_STATIC_ASSERT((detail::predicates_count_distance<Predicates>::value <= 1),
"Only one distance predicate can be passed.",
Predicates);
typedef std::conditional_t
<
detail::predicates_count_distance<Predicates>::value == 0,
detail::rtree::iterators::spatial_query_iterator<members_holder, Predicates>,
detail::rtree::iterators::distance_query_iterator
<
members_holder, Predicates,
detail::predicates_find_distance<Predicates>::value
>
> iterator_type;
if ( !m_members.root )
return iterator_type(m_members.parameters(), m_members.translator(), predicates);
return iterator_type(m_members.root, m_members.parameters(), m_members.translator(), predicates);
return m_members.root
? query_iterator_t<Predicates>(m_members.root, m_members.parameters(), m_members.translator(), predicates)
: query_iterator_t<Predicates>(m_members.parameters(), m_members.translator(), predicates);
}
/*!
@@ -1307,35 +1285,13 @@ private:
\return The iterator pointing at the end of the query range.
*/
template <typename Predicates>
std::conditional_t
<
detail::predicates_count_distance<Predicates>::value == 0,
detail::rtree::iterators::spatial_query_iterator<members_holder, Predicates>,
detail::rtree::iterators::distance_query_iterator
<
members_holder, Predicates,
detail::predicates_find_distance<Predicates>::value
>
>
qend_(Predicates const& predicates) const
query_iterator_t<Predicates> qend_(Predicates const& predicates) const
{
static const std::size_t distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
BOOST_GEOMETRY_STATIC_ASSERT((distance_predicates_count <= 1),
BOOST_GEOMETRY_STATIC_ASSERT((detail::predicates_count_distance<Predicates>::value <= 1),
"Only one distance predicate can be passed.",
Predicates);
typedef std::conditional_t
<
detail::predicates_count_distance<Predicates>::value == 0,
detail::rtree::iterators::spatial_query_iterator<members_holder, Predicates>,
detail::rtree::iterators::distance_query_iterator
<
members_holder, Predicates,
detail::predicates_find_distance<Predicates>::value
>
> iterator_type;
return iterator_type(m_members.parameters(), m_members.translator(), predicates);
return query_iterator_t<Predicates>(m_members.parameters(), m_members.translator(), predicates);
}
/*!
@@ -1436,10 +1392,9 @@ public:
*/
const_iterator begin() const
{
if ( !m_members.root )
return const_iterator();
return const_iterator(m_members.root);
return m_members.root
? const_iterator(m_members.root)
: const_iterator();
}
/*!
@@ -1894,8 +1849,12 @@ private:
\par Exception-safety
strong
*/
template <typename Predicates, typename OutIter>
size_type query_dispatch(Predicates const& predicates, OutIter out_it, std::false_type /*is_distance_predicate*/) const
template
<
typename Predicates, typename OutIter,
std::enable_if_t<(detail::predicates_count_distance<Predicates>::value == 0), int> = 0
>
size_type query_dispatch(Predicates const& predicates, OutIter out_it) const
{
detail::rtree::visitors::spatial_query<members_holder, Predicates, OutIter>
find_v(m_members.parameters(), m_members.translator(), predicates, out_it);
@@ -1909,17 +1868,19 @@ private:
\par Exception-safety
strong
*/
template <typename Predicates, typename OutIter>
size_type query_dispatch(Predicates const& predicates, OutIter out_it, std::true_type /*is_distance_predicate*/) const
template
<
typename Predicates, typename OutIter,
std::enable_if_t<(detail::predicates_count_distance<Predicates>::value > 0), int> = 0
>
size_type query_dispatch(Predicates const& predicates, OutIter out_it) const
{
BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
BOOST_GEOMETRY_STATIC_ASSERT((detail::predicates_count_distance<Predicates>::value == 1),
"Only one distance predicate can be passed.",
Predicates);
static const std::size_t distance_predicate_index = detail::predicates_find_distance<Predicates>::value;
detail::rtree::visitors::distance_query<
members_holder,
Predicates,
distance_predicate_index
> distance_v(m_members.parameters(), m_members.translator(), predicates);
detail::rtree::visitors::distance_query<members_holder, Predicates>
distance_v(m_members.parameters(), m_members.translator(), predicates);
return distance_v.apply(m_members.root, out_it);
}