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 visitors::spatial_query_incremental<Value, Options, Translator, Box, Allocators, Predicates> visitor_type;
65 typedef typename visitor_type::node_pointer node_pointer;
68 typedef std::forward_iterator_tag iterator_category;
69 typedef Value value_type;
70 typedef typename Allocators::const_reference reference;
71 typedef typename Allocators::difference_type difference_type;
72 typedef typename Allocators::const_pointer pointer;
74 inline spatial_query_iterator()
77 inline spatial_query_iterator(Translator const& t, Predicates const& p)
81 inline spatial_query_iterator(node_pointer root, Translator const& t, Predicates const& p)
84 m_visitor.initialize(root);
87 reference operator*() const
89 return m_visitor.dereference();
92 const value_type * operator->() const
94 return boost::addressof(m_visitor.dereference());
97 spatial_query_iterator & operator++()
99 m_visitor.increment();
103 spatial_query_iterator operator++(int)
105 spatial_query_iterator temp = *this;
110 friend bool operator==(spatial_query_iterator const& l, spatial_query_iterator const& r)
112 return l.m_visitor == r.m_visitor;
115 friend bool operator==(spatial_query_iterator const& l, end_query_iterator<Value, Allocators> const& /*r*/)
117 return l.m_visitor.is_end();
120 friend bool operator==(end_query_iterator<Value, Allocators> const& /*l*/, spatial_query_iterator const& r)
122 return r.m_visitor.is_end();
126 visitor_type m_visitor;
129 template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates, unsigned NearestPredicateIndex>
130 class distance_query_iterator
132 typedef visitors::distance_query_incremental<Value, Options, Translator, Box, Allocators, Predicates, NearestPredicateIndex> visitor_type;
133 typedef typename visitor_type::node_pointer node_pointer;
136 typedef std::forward_iterator_tag iterator_category;
137 typedef Value value_type;
138 typedef typename Allocators::const_reference reference;
139 typedef typename Allocators::difference_type difference_type;
140 typedef typename Allocators::const_pointer pointer;
142 inline distance_query_iterator()
145 inline distance_query_iterator(Translator const& t, Predicates const& p)
149 inline distance_query_iterator(node_pointer root, Translator const& t, Predicates const& p)
152 m_visitor.initialize(root);
155 reference operator*() const
157 return m_visitor.dereference();
160 const value_type * operator->() const
162 return boost::addressof(m_visitor.dereference());
165 distance_query_iterator & operator++()
167 m_visitor.increment();
171 distance_query_iterator operator++(int)
173 distance_query_iterator temp = *this;
178 friend bool operator==(distance_query_iterator const& l, distance_query_iterator const& r)
180 return l.m_visitor == r.m_visitor;
183 friend bool operator==(distance_query_iterator const& l, end_query_iterator<Value, Allocators> const& /*r*/)
185 return l.m_visitor.is_end();
188 friend bool operator==(end_query_iterator<Value, Allocators> const& /*l*/, distance_query_iterator const& r)
190 return r.m_visitor.is_end();
194 visitor_type m_visitor;
198 template <typename L, typename R>
199 inline bool operator!=(L const& l, R const& r)
205 template <typename Value, typename Allocators>
206 class query_iterator_base
209 typedef std::forward_iterator_tag iterator_category;
210 typedef Value value_type;
211 typedef typename Allocators::const_reference reference;
212 typedef typename Allocators::difference_type difference_type;
213 typedef typename Allocators::const_pointer pointer;
215 virtual ~query_iterator_base() {}
217 virtual query_iterator_base * clone() const = 0;
219 virtual bool is_end() const = 0;
220 virtual reference dereference() const = 0;
221 virtual void increment() = 0;
222 virtual bool equals(query_iterator_base const&) const = 0;
225 template <typename Value, typename Allocators, typename Iterator>
226 class query_iterator_wrapper
227 : public query_iterator_base<Value, Allocators>
229 typedef query_iterator_base<Value, Allocators> base_t;
232 typedef std::forward_iterator_tag iterator_category;
233 typedef Value value_type;
234 typedef typename Allocators::const_reference reference;
235 typedef typename Allocators::difference_type difference_type;
236 typedef typename Allocators::const_pointer pointer;
238 query_iterator_wrapper() : m_iterator() {}
239 explicit query_iterator_wrapper(Iterator const& it) : m_iterator(it) {}
241 virtual base_t * clone() const { return new query_iterator_wrapper(m_iterator); }
243 virtual bool is_end() const { return m_iterator == end_query_iterator<Value, Allocators>(); }
244 virtual reference dereference() const { return *m_iterator; }
245 virtual void increment() { ++m_iterator; }
246 virtual bool equals(base_t const& r) const
248 const query_iterator_wrapper * p = dynamic_cast<const query_iterator_wrapper *>(boost::addressof(r));
249 BOOST_GEOMETRY_INDEX_ASSERT(p, "iterators can't be compared");
250 return m_iterator == p->m_iterator;
258 template <typename Value, typename Allocators>
261 typedef query_iterator_base<Value, Allocators> iterator_base;
262 typedef boost::scoped_ptr<iterator_base> iterator_ptr;
265 typedef std::forward_iterator_tag iterator_category;
266 typedef Value value_type;
267 typedef typename Allocators::const_reference reference;
268 typedef typename Allocators::difference_type difference_type;
269 typedef typename Allocators::const_pointer pointer;
274 template <typename It>
275 query_iterator(It const& it)
276 : m_ptr(static_cast<iterator_base*>(
277 new query_iterator_wrapper<Value, Allocators, It>(it) ))
280 query_iterator(end_query_iterator<Value, Allocators> const& /*it*/)
283 query_iterator(query_iterator const& o)
284 : m_ptr(o.m_ptr.get() ? o.m_ptr->clone() : 0)
287 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
288 query_iterator & operator=(query_iterator const& o)
290 if ( this != boost::addressof(o) )
292 m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
296 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
297 query_iterator(query_iterator && o)
302 query_iterator & operator=(query_iterator && o)
304 if ( this != boost::addressof(o) )
312 #else // !BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
314 BOOST_COPYABLE_AND_MOVABLE(query_iterator)
316 query_iterator & operator=(BOOST_COPY_ASSIGN_REF(query_iterator) o)
318 if ( this != boost::addressof(o) )
320 m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
324 query_iterator(BOOST_RV_REF(query_iterator) o)
329 query_iterator & operator=(BOOST_RV_REF(query_iterator) o)
331 if ( this != boost::addressof(o) )
338 #endif // BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
340 reference operator*() const
342 return m_ptr->dereference();
345 const value_type * operator->() const
347 return boost::addressof(m_ptr->dereference());
350 query_iterator & operator++()
356 query_iterator operator++(int)
358 query_iterator temp = *this;
363 friend bool operator==(query_iterator const& l, query_iterator const& r)
368 return l.m_ptr->equals(*r.m_ptr);
370 return l.m_ptr->is_end();
375 return r.m_ptr->is_end();
385 }}}}}} // namespace boost::geometry::index::detail::rtree::iterators
387 #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP