1 // Boost.Geometry Index
2 //
3 // R-tree count visitor implementation
4 //
5 // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
6 //
7 // This file was modified by Oracle on 2019.
8 // Modifications copyright (c) 2019 Oracle and/or its affiliates.
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 //
11 // Use, modification and distribution is subject to the Boost Software License,
12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
13 // http://www.boost.org/LICENSE_1_0.txt)
14 
15 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP
16 #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP
17 
18 namespace boost { namespace geometry { namespace index {
19 
20 namespace detail { namespace rtree { namespace visitors {
21 
22 template <typename Indexable, typename Value>
23 struct count_helper
24 {
25     template <typename Translator>
indexableboost::geometry::index::detail::rtree::visitors::count_helper26     static inline typename Translator::result_type indexable(Indexable const& i, Translator const&)
27     {
28         return i;
29     }
30     template <typename Translator, typename Strategy>
equalsboost::geometry::index::detail::rtree::visitors::count_helper31     static inline bool equals(Indexable const& i, Value const& v, Translator const& tr, Strategy const& s)
32     {
33         return index::detail::equals<Indexable>::apply(i, tr(v), s);
34     }
35 };
36 
37 template <typename Value>
38 struct count_helper<Value, Value>
39 {
40     template <typename Translator>
indexableboost::geometry::index::detail::rtree::visitors::count_helper41     static inline typename Translator::result_type indexable(Value const& v, Translator const& tr)
42     {
43         return tr(v);
44     }
45     template <typename Translator, typename Strategy>
equalsboost::geometry::index::detail::rtree::visitors::count_helper46     static inline bool equals(Value const& v1, Value const& v2, Translator const& tr, Strategy const& s)
47     {
48         return tr.equals(v1, v2, s);
49     }
50 };
51 
52 template <typename ValueOrIndexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
53 struct count
54     : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
55 {
56     typedef typename Options::parameters_type parameters_type;
57 
58     typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
59     typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
60     typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
61 
62     typedef count_helper<ValueOrIndexable, Value> count_help;
63 
countboost::geometry::index::detail::rtree::visitors::count64     inline count(ValueOrIndexable const& vori, parameters_type const& parameters, Translator const& t)
65         : value_or_indexable(vori), m_parameters(parameters), tr(t), found_count(0)
66     {}
67 
operator ()boost::geometry::index::detail::rtree::visitors::count68     inline void operator()(internal_node const& n)
69     {
70         typedef typename rtree::elements_type<internal_node>::type elements_type;
71         elements_type const& elements = rtree::elements(n);
72 
73         // traverse nodes meeting predicates
74         for (typename elements_type::const_iterator it = elements.begin();
75              it != elements.end(); ++it)
76         {
77             if ( index::detail::covered_by_bounds(count_help::indexable(value_or_indexable, tr),
78                                                   it->first,
79                                                   index::detail::get_strategy(m_parameters)) )
80             {
81                 rtree::apply_visitor(*this, *it->second);
82             }
83         }
84     }
85 
operator ()boost::geometry::index::detail::rtree::visitors::count86     inline void operator()(leaf const& n)
87     {
88         typedef typename rtree::elements_type<leaf>::type elements_type;
89         elements_type const& elements = rtree::elements(n);
90 
91         // get all values meeting predicates
92         for (typename elements_type::const_iterator it = elements.begin();
93              it != elements.end(); ++it)
94         {
95             // if value meets predicates
96             if ( count_help::equals(value_or_indexable, *it, tr,
97                                     index::detail::get_strategy(m_parameters)) )
98             {
99                 ++found_count;
100             }
101         }
102     }
103 
104     ValueOrIndexable const& value_or_indexable;
105     parameters_type const& m_parameters;
106     Translator const& tr;
107     typename Allocators::size_type found_count;
108 };
109 
110 }}} // namespace detail::rtree::visitors
111 
112 }}} // namespace boost::geometry::index
113 
114 #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP
115