1 // Boost.Geometry Index
3 // R-tree query iterators
5 // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
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)
11 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP
12 #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP
14 #include <boost/scoped_ptr.hpp>
16 //#define BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
18 namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
20 template <typename Value, typename Allocators>
21 struct end_query_iterator
23 typedef std::forward_iterator_tag iterator_category;
24 typedef Value value_type;
25 typedef typename Allocators::const_reference reference;
26 typedef typename Allocators::difference_type difference_type;
27 typedef typename Allocators::const_pointer pointer;
29 reference operator*() const
31 BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
36 const value_type * operator->() const
38 BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not dereferencable");
39 const value_type * p = 0;
43 end_query_iterator & operator++()
45 BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
49 end_query_iterator operator++(int)
51 BOOST_GEOMETRY_INDEX_ASSERT(false, "iterator not incrementable");
55 friend bool operator==(end_query_iterator const& /*l*/, end_query_iterator const& /*r*/)
61 template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates>
62 class spatial_query_iterator
64 typedef typename Options::parameters_type parameters_type;
65 typedef visitors::spatial_query_incremental<Value, Options, Translator, Box, Allocators, Predicates> visitor_type;
66 typedef typename visitor_type::node_pointer node_pointer;
69 typedef std::forward_iterator_tag iterator_category;
70 typedef Value value_type;
71 typedef typename Allocators::const_reference reference;
72 typedef typename Allocators::difference_type difference_type;
73 typedef typename Allocators::const_pointer pointer;
75 inline spatial_query_iterator()
78 inline spatial_query_iterator(parameters_type const& par, Translator const& t, Predicates const& p)
79 : m_visitor(par, t, p)
82 inline spatial_query_iterator(node_pointer root, parameters_type const& par, Translator const& t, Predicates const& p)
83 : m_visitor(par, t, p)
85 m_visitor.initialize(root);
88 reference operator*() const
90 return m_visitor.dereference();
93 const value_type * operator->() const
95 return boost::addressof(m_visitor.dereference());
98 spatial_query_iterator & operator++()
100 m_visitor.increment();
104 spatial_query_iterator operator++(int)
106 spatial_query_iterator temp = *this;
111 friend bool operator==(spatial_query_iterator const& l, spatial_query_iterator const& r)
113 return l.m_visitor == r.m_visitor;
116 friend bool operator==(spatial_query_iterator const& l, end_query_iterator<Value, Allocators> const& /*r*/)
118 return l.m_visitor.is_end();
121 friend bool operator==(end_query_iterator<Value, Allocators> const& /*l*/, spatial_query_iterator const& r)
123 return r.m_visitor.is_end();
127 visitor_type m_visitor;
130 template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates, unsigned NearestPredicateIndex>
131 class distance_query_iterator
133 typedef typename Options::parameters_type parameters_type;
134 typedef visitors::distance_query_incremental<Value, Options, Translator, Box, Allocators, Predicates, NearestPredicateIndex> visitor_type;
135 typedef typename visitor_type::node_pointer node_pointer;
138 typedef std::forward_iterator_tag iterator_category;
139 typedef Value value_type;
140 typedef typename Allocators::const_reference reference;
141 typedef typename Allocators::difference_type difference_type;
142 typedef typename Allocators::const_pointer pointer;
144 inline distance_query_iterator()
147 inline distance_query_iterator(parameters_type const& par, Translator const& t, Predicates const& p)
148 : m_visitor(par, t, p)
151 inline distance_query_iterator(node_pointer root, parameters_type const& par, Translator const& t, Predicates const& p)
152 : m_visitor(par, t, p)
154 m_visitor.initialize(root);
157 reference operator*() const
159 return m_visitor.dereference();
162 const value_type * operator->() const
164 return boost::addressof(m_visitor.dereference());
167 distance_query_iterator & operator++()
169 m_visitor.increment();
173 distance_query_iterator operator++(int)
175 distance_query_iterator temp = *this;
180 friend bool operator==(distance_query_iterator const& l, distance_query_iterator const& r)
182 return l.m_visitor == r.m_visitor;
185 friend bool operator==(distance_query_iterator const& l, end_query_iterator<Value, Allocators> const& /*r*/)
187 return l.m_visitor.is_end();
190 friend bool operator==(end_query_iterator<Value, Allocators> const& /*l*/, distance_query_iterator const& r)
192 return r.m_visitor.is_end();
196 visitor_type m_visitor;
200 template <typename L, typename R>
201 inline bool operator!=(L const& l, R const& r)
207 template <typename Value, typename Allocators>
208 class query_iterator_base
211 typedef std::forward_iterator_tag iterator_category;
212 typedef Value value_type;
213 typedef typename Allocators::const_reference reference;
214 typedef typename Allocators::difference_type difference_type;
215 typedef typename Allocators::const_pointer pointer;
217 virtual ~query_iterator_base() {}
219 virtual query_iterator_base * clone() const = 0;
221 virtual bool is_end() const = 0;
222 virtual reference dereference() const = 0;
223 virtual void increment() = 0;
224 virtual bool equals(query_iterator_base const&) const = 0;
227 template <typename Value, typename Allocators, typename Iterator>
228 class query_iterator_wrapper
229 : public query_iterator_base<Value, Allocators>
231 typedef query_iterator_base<Value, Allocators> base_t;
234 typedef std::forward_iterator_tag iterator_category;
235 typedef Value value_type;
236 typedef typename Allocators::const_reference reference;
237 typedef typename Allocators::difference_type difference_type;
238 typedef typename Allocators::const_pointer pointer;
240 query_iterator_wrapper() : m_iterator() {}
241 explicit query_iterator_wrapper(Iterator const& it) : m_iterator(it) {}
243 virtual base_t * clone() const { return new query_iterator_wrapper(m_iterator); }
245 virtual bool is_end() const { return m_iterator == end_query_iterator<Value, Allocators>(); }
246 virtual reference dereference() const { return *m_iterator; }
247 virtual void increment() { ++m_iterator; }
248 virtual bool equals(base_t const& r) const
250 const query_iterator_wrapper * p = dynamic_cast<const query_iterator_wrapper *>(boost::addressof(r));
251 BOOST_GEOMETRY_INDEX_ASSERT(p, "iterators can't be compared");
252 return m_iterator == p->m_iterator;
260 template <typename Value, typename Allocators>
263 typedef query_iterator_base<Value, Allocators> iterator_base;
264 typedef boost::scoped_ptr<iterator_base> iterator_ptr;
267 typedef std::forward_iterator_tag iterator_category;
268 typedef Value value_type;
269 typedef typename Allocators::const_reference reference;
270 typedef typename Allocators::difference_type difference_type;
271 typedef typename Allocators::const_pointer pointer;
276 template <typename It>
277 query_iterator(It const& it)
278 : m_ptr(static_cast<iterator_base*>(
279 new query_iterator_wrapper<Value, Allocators, It>(it) ))
282 query_iterator(end_query_iterator<Value, Allocators> const& /*it*/)
285 query_iterator(query_iterator const& o)
286 : m_ptr(o.m_ptr.get() ? o.m_ptr->clone() : 0)
289 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
290 query_iterator & operator=(query_iterator const& o)
292 if ( this != boost::addressof(o) )
294 m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
298 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
299 query_iterator(query_iterator && o)
304 query_iterator & operator=(query_iterator && o)
306 if ( this != boost::addressof(o) )
314 #else // !BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
316 BOOST_COPYABLE_AND_MOVABLE(query_iterator)
318 query_iterator & operator=(BOOST_COPY_ASSIGN_REF(query_iterator) o)
320 if ( this != boost::addressof(o) )
322 m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
326 query_iterator(BOOST_RV_REF(query_iterator) o)
331 query_iterator & operator=(BOOST_RV_REF(query_iterator) o)
333 if ( this != boost::addressof(o) )
340 #endif // BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
342 reference operator*() const
344 return m_ptr->dereference();
347 const value_type * operator->() const
349 return boost::addressof(m_ptr->dereference());
352 query_iterator & operator++()
358 query_iterator operator++(int)
360 query_iterator temp = *this;
365 friend bool operator==(query_iterator const& l, query_iterator const& r)
370 return l.m_ptr->equals(*r.m_ptr);
372 return l.m_ptr->is_end();
377 return r.m_ptr->is_end();
387 }}}}}} // namespace boost::geometry::index::detail::rtree::iterators
389 #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP