1 // Boost.Geometry Index
2 //
3 // R-tree count visitor implementation
4 //
5 // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
6 //
7 // Use, modification and distribution is subject to the Boost Software License,
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP
12 #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP
13 
14 namespace boost { namespace geometry { namespace index {
15 
16 namespace detail { namespace rtree { namespace visitors {
17 
18 template <typename Indexable, typename Value>
19 struct count_helper
20 {
21     template <typename Translator>
indexableboost::geometry::index::detail::rtree::visitors::count_helper22     static inline typename Translator::result_type indexable(Indexable const& i, Translator const&)
23     {
24         return i;
25     }
26     template <typename Translator>
equalsboost::geometry::index::detail::rtree::visitors::count_helper27     static inline bool equals(Indexable const& i, Value const& v, Translator const& tr)
28     {
29         return geometry::equals(i, tr(v));
30     }
31 };
32 
33 template <typename Value>
34 struct count_helper<Value, Value>
35 {
36     template <typename Translator>
indexableboost::geometry::index::detail::rtree::visitors::count_helper37     static inline typename Translator::result_type indexable(Value const& v, Translator const& tr)
38     {
39         return tr(v);
40     }
41     template <typename Translator>
equalsboost::geometry::index::detail::rtree::visitors::count_helper42     static inline bool equals(Value const& v1, Value const& v2, Translator const& tr)
43     {
44         return tr.equals(v1, v2);
45     }
46 };
47 
48 template <typename ValueOrIndexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
49 struct count
50     : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
51 {
52     typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
53     typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
54     typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
55 
56     typedef count_helper<ValueOrIndexable, Value> count_help;
57 
countboost::geometry::index::detail::rtree::visitors::count58     inline count(ValueOrIndexable const& vori, Translator const& t)
59         : value_or_indexable(vori), tr(t), found_count(0)
60     {}
61 
operator ()boost::geometry::index::detail::rtree::visitors::count62     inline void operator()(internal_node const& n)
63     {
64         typedef typename rtree::elements_type<internal_node>::type elements_type;
65         elements_type const& elements = rtree::elements(n);
66 
67         // traverse nodes meeting predicates
68         for (typename elements_type::const_iterator it = elements.begin();
69              it != elements.end(); ++it)
70         {
71             if ( geometry::covered_by(
72                     return_ref_or_bounds(
73                         count_help::indexable(value_or_indexable, tr)),
74                     it->first) )
75             {
76                 rtree::apply_visitor(*this, *it->second);
77             }
78         }
79     }
80 
operator ()boost::geometry::index::detail::rtree::visitors::count81     inline void operator()(leaf const& n)
82     {
83         typedef typename rtree::elements_type<leaf>::type elements_type;
84         elements_type const& elements = rtree::elements(n);
85 
86         // get all values meeting predicates
87         for (typename elements_type::const_iterator it = elements.begin();
88              it != elements.end(); ++it)
89         {
90             // if value meets predicates
91             if ( count_help::equals(value_or_indexable, *it, tr) )
92             {
93                 ++found_count;
94             }
95         }
96     }
97 
98     ValueOrIndexable const& value_or_indexable;
99     Translator const& tr;
100     typename Allocators::size_type found_count;
101 };
102 
103 }}} // namespace detail::rtree::visitors
104 
105 }}} // namespace boost::geometry::index
106 
107 #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP
108