1 // Boost.Geometry Index
2 // Unit Test
3
4 // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
5
6 // This file was modified by Oracle on 2019.
7 // Modifications copyright (c) 2019, Oracle and/or its affiliates.
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
13
14 #ifndef BOOST_GEOMETRY_INDEX_TEST_RTREE_HPP
15 #define BOOST_GEOMETRY_INDEX_TEST_RTREE_HPP
16
17 #include <boost/foreach.hpp>
18 #include <vector>
19 #include <algorithm>
20
21 #include <geometry_index_test_common.hpp>
22
23 #include <boost/geometry/index/rtree.hpp>
24
25 #include <boost/geometry/geometries/point.hpp>
26 #include <boost/geometry/geometries/box.hpp>
27 #include <boost/geometry/geometries/segment.hpp>
28
29 #include <boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp>
30 #include <boost/geometry/index/detail/rtree/utilities/are_counts_ok.hpp>
31 #include <boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp>
32
33 //#include <boost/geometry/geometries/ring.hpp>
34 //#include <boost/geometry/geometries/polygon.hpp>
35
36 namespace generate {
37
38 // Set point's coordinates
39
40 template <typename Point>
41 struct outside_point
42 {};
43
44 template <typename T, typename C>
45 struct outside_point< bg::model::point<T, 2, C> >
46 {
47 typedef bg::model::point<T, 2, C> P;
applygenerate::outside_point48 static P apply()
49 {
50 return P(13, 26);
51 }
52 };
53
54 template <typename T, typename C>
55 struct outside_point< bg::model::point<T, 3, C> >
56 {
57 typedef bg::model::point<T, 3, C> P;
applygenerate::outside_point58 static P apply()
59 {
60 return P(13, 26, 13);
61 }
62 };
63
64 // Default value generation
65
66 template <typename Value>
67 struct value_default
68 {
applygenerate::value_default69 static Value apply(){ return Value(); }
70 };
71
72 // Values, input and rtree generation
73
74 template <typename Value>
75 struct value
76 {};
77
78 template <typename T, typename C>
79 struct value< bg::model::point<T, 2, C> >
80 {
81 typedef bg::model::point<T, 2, C> P;
applygenerate::value82 static P apply(int x, int y)
83 {
84 return P(x, y);
85 }
86 };
87
88 template <typename T, typename C>
89 struct value< bg::model::box< bg::model::point<T, 2, C> > >
90 {
91 typedef bg::model::point<T, 2, C> P;
92 typedef bg::model::box<P> B;
applygenerate::value93 static B apply(int x, int y)
94 {
95 return B(P(x, y), P(x + 2, y + 3));
96 }
97 };
98
99 template <typename T, typename C>
100 struct value< bg::model::segment< bg::model::point<T, 2, C> > >
101 {
102 typedef bg::model::point<T, 2, C> P;
103 typedef bg::model::segment<P> S;
applygenerate::value104 static S apply(int x, int y)
105 {
106 return S(P(x, y), P(x + 2, y + 3));
107 }
108 };
109
110 template <typename T, typename C>
111 struct value< std::pair<bg::model::point<T, 2, C>, int> >
112 {
113 typedef bg::model::point<T, 2, C> P;
114 typedef std::pair<P, int> R;
applygenerate::value115 static R apply(int x, int y)
116 {
117 return std::make_pair(P(x, y), x + y * 100);
118 }
119 };
120
121 template <typename T, typename C>
122 struct value< std::pair<bg::model::box< bg::model::point<T, 2, C> >, int> >
123 {
124 typedef bg::model::point<T, 2, C> P;
125 typedef bg::model::box<P> B;
126 typedef std::pair<B, int> R;
applygenerate::value127 static R apply(int x, int y)
128 {
129 return std::make_pair(B(P(x, y), P(x + 2, y + 3)), x + y * 100);
130 }
131 };
132
133 template <typename T, typename C>
134 struct value< std::pair<bg::model::segment< bg::model::point<T, 2, C> >, int> >
135 {
136 typedef bg::model::point<T, 2, C> P;
137 typedef bg::model::segment<P> S;
138 typedef std::pair<S, int> R;
applygenerate::value139 static R apply(int x, int y)
140 {
141 return std::make_pair(S(P(x, y), P(x + 2, y + 3)), x + y * 100);
142 }
143 };
144
145 template <typename T, typename C>
146 struct value< boost::tuple<bg::model::point<T, 2, C>, int, int> >
147 {
148 typedef bg::model::point<T, 2, C> P;
149 typedef boost::tuple<P, int, int> R;
applygenerate::value150 static R apply(int x, int y)
151 {
152 return boost::make_tuple(P(x, y), x + y * 100, 0);
153 }
154 };
155
156 template <typename T, typename C>
157 struct value< boost::tuple<bg::model::box< bg::model::point<T, 2, C> >, int, int> >
158 {
159 typedef bg::model::point<T, 2, C> P;
160 typedef bg::model::box<P> B;
161 typedef boost::tuple<B, int, int> R;
applygenerate::value162 static R apply(int x, int y)
163 {
164 return boost::make_tuple(B(P(x, y), P(x + 2, y + 3)), x + y * 100, 0);
165 }
166 };
167
168 template <typename T, typename C>
169 struct value< boost::tuple<bg::model::segment< bg::model::point<T, 2, C> >, int, int> >
170 {
171 typedef bg::model::point<T, 2, C> P;
172 typedef bg::model::segment<P> S;
173 typedef boost::tuple<S, int, int> R;
applygenerate::value174 static R apply(int x, int y)
175 {
176 return boost::make_tuple(S(P(x, y), P(x + 2, y + 3)), x + y * 100, 0);
177 }
178 };
179
180 template <typename T, typename C>
181 struct value< bg::model::point<T, 3, C> >
182 {
183 typedef bg::model::point<T, 3, C> P;
applygenerate::value184 static P apply(int x, int y, int z)
185 {
186 return P(x, y, z);
187 }
188 };
189
190 template <typename T, typename C>
191 struct value< bg::model::box< bg::model::point<T, 3, C> > >
192 {
193 typedef bg::model::point<T, 3, C> P;
194 typedef bg::model::box<P> B;
applygenerate::value195 static B apply(int x, int y, int z)
196 {
197 return B(P(x, y, z), P(x + 2, y + 3, z + 4));
198 }
199 };
200
201 template <typename T, typename C>
202 struct value< std::pair<bg::model::point<T, 3, C>, int> >
203 {
204 typedef bg::model::point<T, 3, C> P;
205 typedef std::pair<P, int> R;
applygenerate::value206 static R apply(int x, int y, int z)
207 {
208 return std::make_pair(P(x, y, z), x + y * 100 + z * 10000);
209 }
210 };
211
212 template <typename T, typename C>
213 struct value< std::pair<bg::model::box< bg::model::point<T, 3, C> >, int> >
214 {
215 typedef bg::model::point<T, 3, C> P;
216 typedef bg::model::box<P> B;
217 typedef std::pair<B, int> R;
applygenerate::value218 static R apply(int x, int y, int z)
219 {
220 return std::make_pair(B(P(x, y, z), P(x + 2, y + 3, z + 4)), x + y * 100 + z * 10000);
221 }
222 };
223
224 template <typename T, typename C>
225 struct value< boost::tuple<bg::model::point<T, 3, C>, int, int> >
226 {
227 typedef bg::model::point<T, 3, C> P;
228 typedef boost::tuple<P, int, int> R;
applygenerate::value229 static R apply(int x, int y, int z)
230 {
231 return boost::make_tuple(P(x, y, z), x + y * 100 + z * 10000, 0);
232 }
233 };
234
235 template <typename T, typename C>
236 struct value< boost::tuple<bg::model::box< bg::model::point<T, 3, C> >, int, int> >
237 {
238 typedef bg::model::point<T, 3, C> P;
239 typedef bg::model::box<P> B;
240 typedef boost::tuple<B, int, int> R;
applygenerate::value241 static R apply(int x, int y, int z)
242 {
243 return boost::make_tuple(B(P(x, y, z), P(x + 2, y + 3, z + 4)), x + y * 100 + z * 10000, 0);
244 }
245 };
246
247 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
248
249 template <typename T, typename C>
250 struct value< std::tuple<bg::model::point<T, 2, C>, int, int> >
251 {
252 typedef bg::model::point<T, 2, C> P;
253 typedef std::tuple<P, int, int> R;
applygenerate::value254 static R apply(int x, int y)
255 {
256 return std::make_tuple(P(x, y), x + y * 100, 0);
257 }
258 };
259
260 template <typename T, typename C>
261 struct value< std::tuple<bg::model::box< bg::model::point<T, 2, C> >, int, int> >
262 {
263 typedef bg::model::point<T, 2, C> P;
264 typedef bg::model::box<P> B;
265 typedef std::tuple<B, int, int> R;
applygenerate::value266 static R apply(int x, int y)
267 {
268 return std::make_tuple(B(P(x, y), P(x + 2, y + 3)), x + y * 100, 0);
269 }
270 };
271
272 template <typename T, typename C>
273 struct value< std::tuple<bg::model::segment< bg::model::point<T, 2, C> >, int, int> >
274 {
275 typedef bg::model::point<T, 2, C> P;
276 typedef bg::model::segment<P> S;
277 typedef std::tuple<S, int, int> R;
applygenerate::value278 static R apply(int x, int y)
279 {
280 return std::make_tuple(S(P(x, y), P(x + 2, y + 3)), x + y * 100, 0);
281 }
282 };
283
284 template <typename T, typename C>
285 struct value< std::tuple<bg::model::point<T, 3, C>, int, int> >
286 {
287 typedef bg::model::point<T, 3, C> P;
288 typedef std::tuple<P, int, int> R;
applygenerate::value289 static R apply(int x, int y, int z)
290 {
291 return std::make_tuple(P(x, y, z), x + y * 100 + z * 10000, 0);
292 }
293 };
294
295 template <typename T, typename C>
296 struct value< std::tuple<bg::model::box< bg::model::point<T, 3, C> >, int, int> >
297 {
298 typedef bg::model::point<T, 3, C> P;
299 typedef bg::model::box<P> B;
300 typedef std::tuple<B, int, int> R;
applygenerate::value301 static R apply(int x, int y, int z)
302 {
303 return std::make_tuple(B(P(x, y, z), P(x + 2, y + 3, z + 4)), x + y * 100 + z * 10000, 0);
304 }
305 };
306
307 #endif // #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
308
309 } // namespace generate
310
311 // shared_ptr value
312
313 template <typename Indexable>
314 struct test_object
315 {
test_objecttest_object316 test_object(Indexable const& indexable_) : indexable(indexable_) {}
317 Indexable indexable;
318 };
319
320 namespace boost { namespace geometry { namespace index {
321
322 template <typename Indexable>
323 struct indexable< boost::shared_ptr< test_object<Indexable> > >
324 {
325 typedef boost::shared_ptr< test_object<Indexable> > value_type;
326 typedef Indexable const& result_type;
327
operator ()boost::geometry::index::indexable328 result_type operator()(value_type const& value) const
329 {
330 return value->indexable;
331 }
332 };
333
334 }}}
335
336 namespace generate {
337
338 template <typename T, typename C>
339 struct value< boost::shared_ptr<test_object<bg::model::point<T, 2, C> > > >
340 {
341 typedef bg::model::point<T, 2, C> P;
342 typedef test_object<P> O;
343 typedef boost::shared_ptr<O> R;
344
applygenerate::value345 static R apply(int x, int y)
346 {
347 return R(new O(P(x, y)));
348 }
349 };
350
351 template <typename T, typename C>
352 struct value< boost::shared_ptr<test_object<bg::model::point<T, 3, C> > > >
353 {
354 typedef bg::model::point<T, 3, C> P;
355 typedef test_object<P> O;
356 typedef boost::shared_ptr<O> R;
357
applygenerate::value358 static R apply(int x, int y, int z)
359 {
360 return R(new O(P(x, y, z)));
361 }
362 };
363
364 template <typename T, typename C>
365 struct value< boost::shared_ptr<test_object<bg::model::box<bg::model::point<T, 2, C> > > > >
366 {
367 typedef bg::model::point<T, 2, C> P;
368 typedef bg::model::box<P> B;
369 typedef test_object<B> O;
370 typedef boost::shared_ptr<O> R;
371
applygenerate::value372 static R apply(int x, int y)
373 {
374 return R(new O(B(P(x, y), P(x + 2, y + 3))));
375 }
376 };
377
378 template <typename T, typename C>
379 struct value< boost::shared_ptr<test_object<bg::model::box<bg::model::point<T, 3, C> > > > >
380 {
381 typedef bg::model::point<T, 3, C> P;
382 typedef bg::model::box<P> B;
383 typedef test_object<B> O;
384 typedef boost::shared_ptr<O> R;
385
applygenerate::value386 static R apply(int x, int y, int z)
387 {
388 return R(new O(B(P(x, y, z), P(x + 2, y + 3, z + 4))));
389 }
390 };
391
392 template <typename T, typename C>
393 struct value< boost::shared_ptr<test_object<bg::model::segment<bg::model::point<T, 2, C> > > > >
394 {
395 typedef bg::model::point<T, 2, C> P;
396 typedef bg::model::segment<P> S;
397 typedef test_object<S> O;
398 typedef boost::shared_ptr<O> R;
399
applygenerate::value400 static R apply(int x, int y)
401 {
402 return R(new O(S(P(x, y), P(x + 2, y + 3))));
403 }
404 };
405
406 } //namespace generate
407
408 // counting value
409
410 template <typename Indexable>
411 struct counting_value
412 {
counting_valuecounting_value413 counting_value() { counter()++; }
counting_valuecounting_value414 counting_value(Indexable const& i) : indexable(i) { counter()++; }
counting_valuecounting_value415 counting_value(counting_value const& c) : indexable(c.indexable) { counter()++; }
~counting_valuecounting_value416 ~counting_value() { counter()--; }
417
countercounting_value418 static size_t & counter() { static size_t c = 0; return c; }
419 Indexable indexable;
420 };
421
422 namespace boost { namespace geometry { namespace index {
423
424 template <typename Indexable>
425 struct indexable< counting_value<Indexable> >
426 {
427 typedef counting_value<Indexable> value_type;
428 typedef Indexable const& result_type;
operator ()boost::geometry::index::indexable429 result_type operator()(value_type const& value) const
430 {
431 return value.indexable;
432 }
433 };
434
435 template <typename Indexable>
436 struct equal_to< counting_value<Indexable> >
437 {
438 typedef counting_value<Indexable> value_type;
439 typedef bool result_type;
operator ()boost::geometry::index::equal_to440 bool operator()(value_type const& v1, value_type const& v2) const
441 {
442 return boost::geometry::equals(v1.indexable, v2.indexable);
443 }
444 };
445
446 }}}
447
448 namespace generate {
449
450 template <typename T, typename C>
451 struct value< counting_value<bg::model::point<T, 2, C> > >
452 {
453 typedef bg::model::point<T, 2, C> P;
454 typedef counting_value<P> R;
applygenerate::value455 static R apply(int x, int y) { return R(P(x, y)); }
456 };
457
458 template <typename T, typename C>
459 struct value< counting_value<bg::model::point<T, 3, C> > >
460 {
461 typedef bg::model::point<T, 3, C> P;
462 typedef counting_value<P> R;
applygenerate::value463 static R apply(int x, int y, int z) { return R(P(x, y, z)); }
464 };
465
466 template <typename T, typename C>
467 struct value< counting_value<bg::model::box<bg::model::point<T, 2, C> > > >
468 {
469 typedef bg::model::point<T, 2, C> P;
470 typedef bg::model::box<P> B;
471 typedef counting_value<B> R;
applygenerate::value472 static R apply(int x, int y) { return R(B(P(x, y), P(x+2, y+3))); }
473 };
474
475 template <typename T, typename C>
476 struct value< counting_value<bg::model::box<bg::model::point<T, 3, C> > > >
477 {
478 typedef bg::model::point<T, 3, C> P;
479 typedef bg::model::box<P> B;
480 typedef counting_value<B> R;
applygenerate::value481 static R apply(int x, int y, int z) { return R(B(P(x, y, z), P(x+2, y+3, z+4))); }
482 };
483
484 template <typename T, typename C>
485 struct value< counting_value<bg::model::segment<bg::model::point<T, 2, C> > > >
486 {
487 typedef bg::model::point<T, 2, C> P;
488 typedef bg::model::segment<P> S;
489 typedef counting_value<S> R;
applygenerate::value490 static R apply(int x, int y) { return R(S(P(x, y), P(x+2, y+3))); }
491 };
492
493 } // namespace generate
494
495 // value without default constructor
496
497 template <typename Indexable>
498 struct value_no_dctor
499 {
value_no_dctorvalue_no_dctor500 value_no_dctor(Indexable const& i) : indexable(i) {}
501 Indexable indexable;
502 };
503
504 namespace boost { namespace geometry { namespace index {
505
506 template <typename Indexable>
507 struct indexable< value_no_dctor<Indexable> >
508 {
509 typedef value_no_dctor<Indexable> value_type;
510 typedef Indexable const& result_type;
operator ()boost::geometry::index::indexable511 result_type operator()(value_type const& value) const
512 {
513 return value.indexable;
514 }
515 };
516
517 template <typename Indexable>
518 struct equal_to< value_no_dctor<Indexable> >
519 {
520 typedef value_no_dctor<Indexable> value_type;
521 typedef bool result_type;
operator ()boost::geometry::index::equal_to522 bool operator()(value_type const& v1, value_type const& v2) const
523 {
524 return boost::geometry::equals(v1.indexable, v2.indexable);
525 }
526 };
527
528 }}}
529
530 namespace generate {
531
532 template <typename Indexable>
533 struct value_default< value_no_dctor<Indexable> >
534 {
applygenerate::value_default535 static value_no_dctor<Indexable> apply() { return value_no_dctor<Indexable>(Indexable()); }
536 };
537
538 template <typename T, typename C>
539 struct value< value_no_dctor<bg::model::point<T, 2, C> > >
540 {
541 typedef bg::model::point<T, 2, C> P;
542 typedef value_no_dctor<P> R;
applygenerate::value543 static R apply(int x, int y) { return R(P(x, y)); }
544 };
545
546 template <typename T, typename C>
547 struct value< value_no_dctor<bg::model::point<T, 3, C> > >
548 {
549 typedef bg::model::point<T, 3, C> P;
550 typedef value_no_dctor<P> R;
applygenerate::value551 static R apply(int x, int y, int z) { return R(P(x, y, z)); }
552 };
553
554 template <typename T, typename C>
555 struct value< value_no_dctor<bg::model::box<bg::model::point<T, 2, C> > > >
556 {
557 typedef bg::model::point<T, 2, C> P;
558 typedef bg::model::box<P> B;
559 typedef value_no_dctor<B> R;
applygenerate::value560 static R apply(int x, int y) { return R(B(P(x, y), P(x+2, y+3))); }
561 };
562
563 template <typename T, typename C>
564 struct value< value_no_dctor<bg::model::box<bg::model::point<T, 3, C> > > >
565 {
566 typedef bg::model::point<T, 3, C> P;
567 typedef bg::model::box<P> B;
568 typedef value_no_dctor<B> R;
applygenerate::value569 static R apply(int x, int y, int z) { return R(B(P(x, y, z), P(x+2, y+3, z+4))); }
570 };
571
572 template <typename T, typename C>
573 struct value< value_no_dctor<bg::model::segment<bg::model::point<T, 2, C> > > >
574 {
575 typedef bg::model::point<T, 2, C> P;
576 typedef bg::model::segment<P> S;
577 typedef value_no_dctor<S> R;
applygenerate::value578 static R apply(int x, int y) { return R(S(P(x, y), P(x+2, y+3))); }
579 };
580
581 // generate input
582
583 template <size_t Dimension>
584 struct input
585 {};
586
587 template <>
588 struct input<2>
589 {
590 template <typename Value, typename Box>
applygenerate::input591 static void apply(std::vector<Value> & input, Box & qbox, int size = 1)
592 {
593 BOOST_GEOMETRY_INDEX_ASSERT(0 < size, "the value must be greather than 0");
594
595 for ( int i = 0 ; i < 12 * size ; i += 3 )
596 {
597 for ( int j = 1 ; j < 25 * size ; j += 4 )
598 {
599 input.push_back( generate::value<Value>::apply(i, j) );
600 }
601 }
602
603 typedef typename bg::traits::point_type<Box>::type P;
604
605 qbox = Box(P(3, 0), P(10, 9));
606 }
607 };
608
609 template <>
610 struct input<3>
611 {
612 template <typename Value, typename Box>
applygenerate::input613 static void apply(std::vector<Value> & input, Box & qbox, int size = 1)
614 {
615 BOOST_GEOMETRY_INDEX_ASSERT(0 < size, "the value must be greather than 0");
616
617 for ( int i = 0 ; i < 12 * size ; i += 3 )
618 {
619 for ( int j = 1 ; j < 25 * size ; j += 4 )
620 {
621 for ( int k = 2 ; k < 12 * size ; k += 5 )
622 {
623 input.push_back( generate::value<Value>::apply(i, j, k) );
624 }
625 }
626 }
627
628 typedef typename bg::traits::point_type<Box>::type P;
629
630 qbox = Box(P(3, 0, 3), P(10, 9, 11));
631 }
632 };
633
634 // generate_value_outside
635
636 template <typename Value, size_t Dimension>
637 struct value_outside_impl
638 {};
639
640 template <typename Value>
641 struct value_outside_impl<Value, 2>
642 {
applygenerate::value_outside_impl643 static Value apply()
644 {
645 //TODO - for size > 1 in generate_input<> this won't be outside
646 return generate::value<Value>::apply(13, 26);
647 }
648 };
649
650 template <typename Value>
651 struct value_outside_impl<Value, 3>
652 {
applygenerate::value_outside_impl653 static Value apply()
654 {
655 //TODO - for size > 1 in generate_input<> this won't be outside
656 return generate::value<Value>::apply(13, 26, 13);
657 }
658 };
659
660 template <typename Rtree>
661 inline typename Rtree::value_type
value_outside()662 value_outside()
663 {
664 typedef typename Rtree::value_type V;
665 typedef typename Rtree::indexable_type I;
666
667 return value_outside_impl<V, bg::dimension<I>::value>::apply();
668 }
669
670 template<typename Rtree, typename Elements, typename Box>
rtree(Rtree & tree,Elements & input,Box & qbox)671 void rtree(Rtree & tree, Elements & input, Box & qbox)
672 {
673 typedef typename Rtree::indexable_type I;
674
675 generate::input<
676 bg::dimension<I>::value
677 >::apply(input, qbox);
678
679 tree.insert(input.begin(), input.end());
680 }
681
682 } // namespace generate
683
684 namespace basictest {
685
686 // low level test functions
687
688 template <typename Rtree, typename Iter, typename Value>
find(Rtree const & rtree,Iter first,Iter last,Value const & value)689 Iter find(Rtree const& rtree, Iter first, Iter last, Value const& value)
690 {
691 for ( ; first != last ; ++first )
692 if ( rtree.value_eq()(value, *first) )
693 return first;
694 return first;
695 }
696
697 template <typename Rtree, typename Value>
compare_outputs(Rtree const & rtree,std::vector<Value> const & output,std::vector<Value> const & expected_output)698 void compare_outputs(Rtree const& rtree, std::vector<Value> const& output, std::vector<Value> const& expected_output)
699 {
700 bool are_sizes_ok = (expected_output.size() == output.size());
701 BOOST_CHECK( are_sizes_ok );
702 if ( are_sizes_ok )
703 {
704 BOOST_FOREACH(Value const& v, expected_output)
705 {
706 BOOST_CHECK(find(rtree, output.begin(), output.end(), v) != output.end() );
707 }
708 }
709 }
710
711 template <typename Rtree, typename Range1, typename Range2>
exactly_the_same_outputs(Rtree const & rtree,Range1 const & output,Range2 const & expected_output)712 void exactly_the_same_outputs(Rtree const& rtree, Range1 const& output, Range2 const& expected_output)
713 {
714 size_t s1 = std::distance(output.begin(), output.end());
715 size_t s2 = std::distance(expected_output.begin(), expected_output.end());
716 BOOST_CHECK(s1 == s2);
717
718 if ( s1 == s2 )
719 {
720 typename Range1::const_iterator it1 = output.begin();
721 typename Range2::const_iterator it2 = expected_output.begin();
722 for ( ; it1 != output.end() && it2 != expected_output.end() ; ++it1, ++it2 )
723 {
724 if ( !rtree.value_eq()(*it1, *it2) )
725 {
726 BOOST_CHECK(false && "rtree.translator().equals(*it1, *it2)");
727 break;
728 }
729 }
730 }
731 }
732
733 // alternative version of std::copy taking iterators of differnet types
734 template <typename First, typename Last, typename Out>
copy_alt(First first,Last last,Out out)735 void copy_alt(First first, Last last, Out out)
736 {
737 for ( ; first != last ; ++first, ++out )
738 *out = *first;
739 }
740
741 // test query iterators
742 template <typename QItF, typename QItL>
check_fwd_iterators(QItF first,QItL last)743 void check_fwd_iterators(QItF first, QItL last)
744 {
745 QItF vinit = QItF();
746 BOOST_CHECK(vinit == last);
747
748 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
749 QItL vinit2 = QItL();
750 BOOST_CHECK(vinit2 == last);
751 #endif
752
753 QItF def;
754 BOOST_CHECK(def == last);
755
756 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
757 QItL def2;
758 BOOST_CHECK(def2 == last);
759 #endif
760
761 QItF it = first;
762 for ( ; it != last && first != last ; ++it, ++first)
763 {
764 BOOST_CHECK(it == first);
765
766 bg::index::equal_to<typename std::iterator_traits<QItF>::value_type> eq;
767 BOOST_CHECK(eq(*it, *first));
768 }
769 BOOST_CHECK(it == last);
770 BOOST_CHECK(first == last);
771 }
772
773 // spatial query
774
775 template <typename Rtree, typename Value, typename Predicates>
spatial_query(Rtree & rtree,Predicates const & pred,std::vector<Value> const & expected_output)776 void spatial_query(Rtree & rtree, Predicates const& pred, std::vector<Value> const& expected_output)
777 {
778 BOOST_CHECK( bgi::detail::rtree::utilities::are_levels_ok(rtree) );
779 if ( !rtree.empty() )
780 BOOST_CHECK( bgi::detail::rtree::utilities::are_boxes_ok(rtree) );
781
782 std::vector<Value> output;
783 size_t n = rtree.query(pred, std::back_inserter(output));
784
785 BOOST_CHECK( expected_output.size() == n );
786 compare_outputs(rtree, output, expected_output);
787
788 std::vector<Value> output2;
789 size_t n2 = query(rtree, pred, std::back_inserter(output2));
790
791 BOOST_CHECK( n == n2 );
792 exactly_the_same_outputs(rtree, output, output2);
793
794 exactly_the_same_outputs(rtree, output, rtree | bgi::adaptors::queried(pred));
795
796 std::vector<Value> output3;
797 std::copy(rtree.qbegin(pred), rtree.qend(), std::back_inserter(output3));
798
799 compare_outputs(rtree, output3, expected_output);
800
801 std::vector<Value> output4;
802 std::copy(qbegin(rtree, pred), qend(rtree), std::back_inserter(output4));
803
804 exactly_the_same_outputs(rtree, output3, output4);
805
806 check_fwd_iterators(rtree.qbegin(pred), rtree.qend());
807
808 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
809 {
810 std::vector<Value> output4;
811 std::copy(rtree.qbegin_(pred), rtree.qend_(pred), std::back_inserter(output4));
812 compare_outputs(rtree, output4, expected_output);
813 output4.clear();
814 copy_alt(rtree.qbegin_(pred), rtree.qend_(), std::back_inserter(output4));
815 compare_outputs(rtree, output4, expected_output);
816
817 check_fwd_iterators(rtree.qbegin_(pred), rtree.qend_(pred));
818 check_fwd_iterators(rtree.qbegin_(pred), rtree.qend_());
819 }
820 #endif
821 }
822
823 // rtree specific queries tests
824
825 template <typename Rtree, typename Value, typename Box>
intersects(Rtree const & tree,std::vector<Value> const & input,Box const & qbox)826 void intersects(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
827 {
828 std::vector<Value> expected_output;
829
830 BOOST_FOREACH(Value const& v, input)
831 if ( bg::intersects(tree.indexable_get()(v), qbox) )
832 expected_output.push_back(v);
833
834 //spatial_query(tree, qbox, expected_output);
835 spatial_query(tree, bgi::intersects(qbox), expected_output);
836 spatial_query(tree, !bgi::disjoint(qbox), expected_output);
837
838 /*typedef bg::traits::point_type<Box>::type P;
839 bg::model::ring<P> qring;
840 bg::convert(qbox, qring);
841 spatial_query(tree, bgi::intersects(qring), expected_output);
842 spatial_query(tree, !bgi::disjoint(qring), expected_output);
843 bg::model::polygon<P> qpoly;
844 bg::convert(qbox, qpoly);
845 spatial_query(tree, bgi::intersects(qpoly), expected_output);
846 spatial_query(tree, !bgi::disjoint(qpoly), expected_output);*/
847 }
848
849 template <typename Rtree, typename Value, typename Box>
disjoint(Rtree const & tree,std::vector<Value> const & input,Box const & qbox)850 void disjoint(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
851 {
852 std::vector<Value> expected_output;
853
854 BOOST_FOREACH(Value const& v, input)
855 if ( bg::disjoint(tree.indexable_get()(v), qbox) )
856 expected_output.push_back(v);
857
858 spatial_query(tree, bgi::disjoint(qbox), expected_output);
859 spatial_query(tree, !bgi::intersects(qbox), expected_output);
860
861 /*typedef bg::traits::point_type<Box>::type P;
862 bg::model::ring<P> qring;
863 bg::convert(qbox, qring);
864 spatial_query(tree, bgi::disjoint(qring), expected_output);
865 bg::model::polygon<P> qpoly;
866 bg::convert(qbox, qpoly);
867 spatial_query(tree, bgi::disjoint(qpoly), expected_output);*/
868 }
869
870 template <typename Tag>
871 struct contains_impl
872 {
873 template <typename Rtree, typename Value, typename Box>
applybasictest::contains_impl874 static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
875 {
876 std::vector<Value> expected_output;
877
878 BOOST_FOREACH(Value const& v, input)
879 if ( bg::within(qbox, tree.indexable_get()(v)) )
880 expected_output.push_back(v);
881
882 spatial_query(tree, bgi::contains(qbox), expected_output);
883
884 /*typedef bg::traits::point_type<Box>::type P;
885 bg::model::ring<P> qring;
886 bg::convert(qbox, qring);
887 spatial_query(tree, bgi::contains(qring), expected_output);
888 bg::model::polygon<P> qpoly;
889 bg::convert(qbox, qpoly);
890 spatial_query(tree, bgi::contains(qpoly), expected_output);*/
891 }
892 };
893
894 template <>
895 struct contains_impl<bg::point_tag>
896 {
897 template <typename Rtree, typename Value, typename Box>
applybasictest::contains_impl898 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
899 {}
900 };
901
902 template <>
903 struct contains_impl<bg::segment_tag>
904 {
905 template <typename Rtree, typename Value, typename Box>
applybasictest::contains_impl906 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
907 {}
908 };
909
910 template <typename Rtree, typename Value, typename Box>
contains(Rtree const & tree,std::vector<Value> const & input,Box const & qbox)911 void contains(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
912 {
913 contains_impl<
914 typename bg::tag<
915 typename Rtree::indexable_type
916 >::type
917 >::apply(tree, input, qbox);
918 }
919
920 template <typename Tag>
921 struct covered_by_impl
922 {
923 template <typename Rtree, typename Value, typename Box>
applybasictest::covered_by_impl924 static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
925 {
926 std::vector<Value> expected_output;
927
928 BOOST_FOREACH(Value const& v, input)
929 {
930 if ( bgi::detail::covered_by_bounds(
931 tree.indexable_get()(v),
932 qbox,
933 bgi::detail::get_strategy(tree.parameters())) )
934 {
935 expected_output.push_back(v);
936 }
937 }
938
939 spatial_query(tree, bgi::covered_by(qbox), expected_output);
940
941 /*typedef bg::traits::point_type<Box>::type P;
942 bg::model::ring<P> qring;
943 bg::convert(qbox, qring);
944 spatial_query(tree, bgi::covered_by(qring), expected_output);
945 bg::model::polygon<P> qpoly;
946 bg::convert(qbox, qpoly);
947 spatial_query(tree, bgi::covered_by(qpoly), expected_output);*/
948 }
949 };
950
951 template <>
952 struct covered_by_impl<bg::segment_tag>
953 {
954 template <typename Rtree, typename Value, typename Box>
applybasictest::covered_by_impl955 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
956 {}
957 };
958
959 template <typename Rtree, typename Value, typename Box>
covered_by(Rtree const & tree,std::vector<Value> const & input,Box const & qbox)960 void covered_by(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
961 {
962 covered_by_impl<
963 typename bg::tag<
964 typename Rtree::indexable_type
965 >::type
966 >::apply(tree, input, qbox);
967 }
968
969 template <typename Tag>
970 struct covers_impl
971 {
972 template <typename Rtree, typename Value, typename Box>
applybasictest::covers_impl973 static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
974 {
975 std::vector<Value> expected_output;
976
977 BOOST_FOREACH(Value const& v, input)
978 if ( bg::covered_by(qbox, tree.indexable_get()(v)) )
979 expected_output.push_back(v);
980
981 spatial_query(tree, bgi::covers(qbox), expected_output);
982
983 /*typedef bg::traits::point_type<Box>::type P;
984 bg::model::ring<P> qring;
985 bg::convert(qbox, qring);
986 spatial_query(tree, bgi::covers(qring), expected_output);
987 bg::model::polygon<P> qpoly;
988 bg::convert(qbox, qpoly);
989 spatial_query(tree, bgi::covers(qpoly), expected_output);*/
990 }
991 };
992
993 template <>
994 struct covers_impl<bg::point_tag>
995 {
996 template <typename Rtree, typename Value, typename Box>
applybasictest::covers_impl997 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
998 {}
999 };
1000
1001 template <>
1002 struct covers_impl<bg::segment_tag>
1003 {
1004 template <typename Rtree, typename Value, typename Box>
applybasictest::covers_impl1005 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
1006 {}
1007 };
1008
1009 template <typename Rtree, typename Value, typename Box>
covers(Rtree const & tree,std::vector<Value> const & input,Box const & qbox)1010 void covers(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1011 {
1012 covers_impl<
1013 typename bg::tag<
1014 typename Rtree::indexable_type
1015 >::type
1016 >::apply(tree, input, qbox);
1017 }
1018
1019 template <typename Tag>
1020 struct overlaps_impl
1021 {
1022 template <typename Rtree, typename Value, typename Box>
applybasictest::overlaps_impl1023 static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1024 {
1025 std::vector<Value> expected_output;
1026
1027 BOOST_FOREACH(Value const& v, input)
1028 if ( bg::overlaps(tree.indexable_get()(v), qbox) )
1029 expected_output.push_back(v);
1030
1031 spatial_query(tree, bgi::overlaps(qbox), expected_output);
1032
1033 /*typedef bg::traits::point_type<Box>::type P;
1034 bg::model::ring<P> qring;
1035 bg::convert(qbox, qring);
1036 spatial_query(tree, bgi::overlaps(qring), expected_output);
1037 bg::model::polygon<P> qpoly;
1038 bg::convert(qbox, qpoly);
1039 spatial_query(tree, bgi::overlaps(qpoly), expected_output);*/
1040 }
1041 };
1042
1043 template <>
1044 struct overlaps_impl<bg::point_tag>
1045 {
1046 template <typename Rtree, typename Value, typename Box>
applybasictest::overlaps_impl1047 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
1048 {}
1049 };
1050
1051 template <>
1052 struct overlaps_impl<bg::segment_tag>
1053 {
1054 template <typename Rtree, typename Value, typename Box>
applybasictest::overlaps_impl1055 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
1056 {}
1057 };
1058
1059 template <typename Rtree, typename Value, typename Box>
overlaps(Rtree const & tree,std::vector<Value> const & input,Box const & qbox)1060 void overlaps(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1061 {
1062 overlaps_impl<
1063 typename bg::tag<
1064 typename Rtree::indexable_type
1065 >::type
1066 >::apply(tree, input, qbox);
1067 }
1068
1069 //template <typename Tag, size_t Dimension>
1070 //struct touches_impl
1071 //{
1072 // template <typename Rtree, typename Value, typename Box>
1073 // static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1074 // {}
1075 //};
1076 //
1077 //template <>
1078 //struct touches_impl<bg::box_tag, 2>
1079 //{
1080 // template <typename Rtree, typename Value, typename Box>
1081 // static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1082 // {
1083 // std::vector<Value> expected_output;
1084 //
1085 // BOOST_FOREACH(Value const& v, input)
1086 // if ( bg::touches(tree.translator()(v), qbox) )
1087 // expected_output.push_back(v);
1088 //
1089 // spatial_query(tree, bgi::touches(qbox), expected_output);
1090 // }
1091 //};
1092 //
1093 //template <typename Rtree, typename Value, typename Box>
1094 //void touches(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1095 //{
1096 // touches_impl<
1097 // bgi::traits::tag<typename Rtree::indexable_type>::type,
1098 // bgi::traits::dimension<typename Rtree::indexable_type>::value
1099 // >::apply(tree, input, qbox);
1100 //}
1101
1102 template <typename Tag>
1103 struct within_impl
1104 {
1105 template <typename Rtree, typename Value, typename Box>
applybasictest::within_impl1106 static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1107 {
1108 std::vector<Value> expected_output;
1109
1110 BOOST_FOREACH(Value const& v, input)
1111 if ( bg::within(tree.indexable_get()(v), qbox) )
1112 expected_output.push_back(v);
1113
1114 spatial_query(tree, bgi::within(qbox), expected_output);
1115
1116 /*typedef bg::traits::point_type<Box>::type P;
1117 bg::model::ring<P> qring;
1118 bg::convert(qbox, qring);
1119 spatial_query(tree, bgi::within(qring), expected_output);
1120 bg::model::polygon<P> qpoly;
1121 bg::convert(qbox, qpoly);
1122 spatial_query(tree, bgi::within(qpoly), expected_output);*/
1123 }
1124 };
1125
1126 template <>
1127 struct within_impl<bg::segment_tag>
1128 {
1129 template <typename Rtree, typename Value, typename Box>
applybasictest::within_impl1130 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
1131 {}
1132 };
1133
1134 template <typename Rtree, typename Value, typename Box>
within(Rtree const & tree,std::vector<Value> const & input,Box const & qbox)1135 void within(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1136 {
1137 within_impl<
1138 typename bg::tag<
1139 typename Rtree::indexable_type
1140 >::type
1141 >::apply(tree, input, qbox);
1142 }
1143
1144 // rtree nearest queries
1145
1146 template <typename Rtree, typename Point>
1147 struct NearestKLess
1148 {
1149 typedef typename bg::default_distance_result<Point, typename Rtree::indexable_type>::type D;
1150
1151 template <typename Value>
operator ()basictest::NearestKLess1152 bool operator()(std::pair<D, Value> const& p1, std::pair<D, Value> const& p2) const
1153 {
1154 return p1.first < p2.first;
1155 }
1156 };
1157
1158 template <typename Rtree, typename Point>
1159 struct NearestKTransform
1160 {
1161 typedef typename bg::default_distance_result<Point, typename Rtree::indexable_type>::type D;
1162
1163 template <typename Value>
operator ()basictest::NearestKTransform1164 Value const& operator()(std::pair<D, Value> const& p) const
1165 {
1166 return p.second;
1167 }
1168 };
1169
1170 template <typename Rtree, typename Value, typename Point, typename Distance>
compare_nearest_outputs(Rtree const & rtree,std::vector<Value> const & output,std::vector<Value> const & expected_output,Point const & pt,Distance greatest_distance)1171 inline void compare_nearest_outputs(Rtree const& rtree, std::vector<Value> const& output, std::vector<Value> const& expected_output, Point const& pt, Distance greatest_distance)
1172 {
1173 // check output
1174 bool are_sizes_ok = (expected_output.size() == output.size());
1175 BOOST_CHECK( are_sizes_ok );
1176 if ( are_sizes_ok )
1177 {
1178 BOOST_FOREACH(Value const& v, output)
1179 {
1180 // TODO - perform explicit check here?
1181 // should all objects which are closest be checked and should exactly the same be found?
1182
1183 if ( find(rtree, expected_output.begin(), expected_output.end(), v) == expected_output.end() )
1184 {
1185 Distance d = bg::comparable_distance(pt, rtree.indexable_get()(v));
1186 BOOST_CHECK(d == greatest_distance);
1187 }
1188 }
1189 }
1190 }
1191
1192 template <typename Rtree, typename Value, typename Point>
check_sorted_by_distance(Rtree const & rtree,std::vector<Value> const & output,Point const & pt)1193 inline void check_sorted_by_distance(Rtree const& rtree, std::vector<Value> const& output, Point const& pt)
1194 {
1195 typedef typename bg::default_distance_result<Point, typename Rtree::indexable_type>::type D;
1196
1197 D prev_dist = 0;
1198 BOOST_FOREACH(Value const& v, output)
1199 {
1200 D d = bg::comparable_distance(pt, rtree.indexable_get()(v));
1201 BOOST_CHECK(prev_dist <= d);
1202 prev_dist = d;
1203 }
1204 }
1205
1206 template <typename Rtree, typename Value, typename Point>
nearest_query_k(Rtree const & rtree,std::vector<Value> const & input,Point const & pt,unsigned int k)1207 inline void nearest_query_k(Rtree const& rtree, std::vector<Value> const& input, Point const& pt, unsigned int k)
1208 {
1209 // TODO: Nearest object may not be the same as found by the rtree if distances are equal
1210 // All objects with the same closest distance should be picked
1211
1212 typedef typename bg::default_distance_result<Point, typename Rtree::indexable_type>::type D;
1213
1214 std::vector< std::pair<D, Value> > test_output;
1215
1216 // calculate test output - k closest values pairs
1217 BOOST_FOREACH(Value const& v, input)
1218 {
1219 D d = bg::comparable_distance(pt, rtree.indexable_get()(v));
1220
1221 if ( test_output.size() < k )
1222 test_output.push_back(std::make_pair(d, v));
1223 else
1224 {
1225 std::sort(test_output.begin(), test_output.end(), NearestKLess<Rtree, Point>());
1226 if ( d < test_output.back().first )
1227 test_output.back() = std::make_pair(d, v);
1228 }
1229 }
1230
1231 // caluclate biggest distance
1232 std::sort(test_output.begin(), test_output.end(), NearestKLess<Rtree, Point>());
1233 D greatest_distance = 0;
1234 if ( !test_output.empty() )
1235 greatest_distance = test_output.back().first;
1236
1237 // transform test output to vector of values
1238 std::vector<Value> expected_output(test_output.size(), generate::value_default<Value>::apply());
1239 std::transform(test_output.begin(), test_output.end(), expected_output.begin(), NearestKTransform<Rtree, Point>());
1240
1241 // calculate output using rtree
1242 std::vector<Value> output;
1243 rtree.query(bgi::nearest(pt, k), std::back_inserter(output));
1244
1245 // check output
1246 compare_nearest_outputs(rtree, output, expected_output, pt, greatest_distance);
1247
1248 exactly_the_same_outputs(rtree, output, rtree | bgi::adaptors::queried(bgi::nearest(pt, k)));
1249
1250 std::vector<Value> output2(k, generate::value_default<Value>::apply());
1251 typename Rtree::size_type found_count = rtree.query(bgi::nearest(pt, k), output2.begin());
1252 output2.resize(found_count, generate::value_default<Value>::apply());
1253
1254 exactly_the_same_outputs(rtree, output, output2);
1255
1256 std::vector<Value> output3;
1257 std::copy(rtree.qbegin(bgi::nearest(pt, k)), rtree.qend(), std::back_inserter(output3));
1258
1259 compare_nearest_outputs(rtree, output3, expected_output, pt, greatest_distance);
1260 check_sorted_by_distance(rtree, output3, pt);
1261
1262 check_fwd_iterators(rtree.qbegin(bgi::nearest(pt, k)), rtree.qend());
1263
1264 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
1265 {
1266 std::vector<Value> output4;
1267 std::copy(rtree.qbegin_(bgi::nearest(pt, k)), rtree.qend_(bgi::nearest(pt, k)), std::back_inserter(output4));
1268 exactly_the_same_outputs(rtree, output4, output3);
1269 output4.clear();
1270 copy_alt(rtree.qbegin_(bgi::nearest(pt, k)), rtree.qend_(), std::back_inserter(output4));
1271 exactly_the_same_outputs(rtree, output4, output3);
1272
1273 check_fwd_iterators(rtree.qbegin_(bgi::nearest(pt, k)), rtree.qend_(bgi::nearest(pt, k)));
1274 check_fwd_iterators(rtree.qbegin_(bgi::nearest(pt, k)), rtree.qend_());
1275 }
1276 #endif
1277 }
1278
1279 // rtree nearest not found
1280
1281 struct AlwaysFalse
1282 {
1283 template <typename Value>
operator ()basictest::AlwaysFalse1284 bool operator()(Value const& ) const { return false; }
1285 };
1286
1287 template <typename Rtree, typename Point>
nearest_query_not_found(Rtree const & rtree,Point const & pt)1288 void nearest_query_not_found(Rtree const& rtree, Point const& pt)
1289 {
1290 typedef typename Rtree::value_type Value;
1291
1292 std::vector<Value> output_v;
1293 size_t n_res = rtree.query(bgi::nearest(pt, 5) && bgi::satisfies(AlwaysFalse()), std::back_inserter(output_v));
1294 BOOST_CHECK(output_v.size() == n_res);
1295 BOOST_CHECK(n_res < 5);
1296 }
1297
1298 template <typename Value>
satisfies_fun(Value const &)1299 bool satisfies_fun(Value const& ) { return true; }
1300
1301 struct satisfies_obj
1302 {
1303 template <typename Value>
operator ()basictest::satisfies_obj1304 bool operator()(Value const& ) const { return true; }
1305 };
1306
1307 template <typename Rtree, typename Value>
satisfies(Rtree const & rtree,std::vector<Value> const & input)1308 void satisfies(Rtree const& rtree, std::vector<Value> const& input)
1309 {
1310 std::vector<Value> result;
1311 rtree.query(bgi::satisfies(satisfies_obj()), std::back_inserter(result));
1312 BOOST_CHECK(result.size() == input.size());
1313 result.clear();
1314 rtree.query(!bgi::satisfies(satisfies_obj()), std::back_inserter(result));
1315 BOOST_CHECK(result.size() == 0);
1316
1317 result.clear();
1318 rtree.query(bgi::satisfies(satisfies_fun<Value>), std::back_inserter(result));
1319 BOOST_CHECK(result.size() == input.size());
1320 result.clear();
1321 rtree.query(!bgi::satisfies(satisfies_fun<Value>), std::back_inserter(result));
1322 BOOST_CHECK(result.size() == 0);
1323
1324 #ifndef BOOST_NO_CXX11_LAMBDAS
1325 result.clear();
1326 rtree.query(bgi::satisfies([](Value const&){ return true; }), std::back_inserter(result));
1327 BOOST_CHECK(result.size() == input.size());
1328 result.clear();
1329 rtree.query(!bgi::satisfies([](Value const&){ return true; }), std::back_inserter(result));
1330 BOOST_CHECK(result.size() == 0);
1331 #endif
1332 }
1333
1334 // rtree copying and moving
1335
1336 template <typename Rtree, typename Box>
copy_swap_move(Rtree const & tree,Box const & qbox)1337 void copy_swap_move(Rtree const& tree, Box const& qbox)
1338 {
1339 typedef typename Rtree::value_type Value;
1340 typedef typename Rtree::parameters_type Params;
1341
1342 size_t s = tree.size();
1343 Params params = tree.parameters();
1344
1345 std::vector<Value> expected_output;
1346 tree.query(bgi::intersects(qbox), std::back_inserter(expected_output));
1347
1348 // copy constructor
1349 Rtree t1(tree);
1350
1351 BOOST_CHECK(tree.empty() == t1.empty());
1352 BOOST_CHECK(tree.size() == t1.size());
1353 BOOST_CHECK(t1.parameters().get_max_elements() == params.get_max_elements());
1354 BOOST_CHECK(t1.parameters().get_min_elements() == params.get_min_elements());
1355
1356 std::vector<Value> output;
1357 t1.query(bgi::intersects(qbox), std::back_inserter(output));
1358 exactly_the_same_outputs(t1, output, expected_output);
1359
1360 // copying assignment operator
1361 t1 = tree;
1362
1363 BOOST_CHECK(tree.empty() == t1.empty());
1364 BOOST_CHECK(tree.size() == t1.size());
1365 BOOST_CHECK(t1.parameters().get_max_elements() == params.get_max_elements());
1366 BOOST_CHECK(t1.parameters().get_min_elements() == params.get_min_elements());
1367
1368 output.clear();
1369 t1.query(bgi::intersects(qbox), std::back_inserter(output));
1370 exactly_the_same_outputs(t1, output, expected_output);
1371
1372 Rtree t2(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1373 t2.swap(t1);
1374 BOOST_CHECK(tree.empty() == t2.empty());
1375 BOOST_CHECK(tree.size() == t2.size());
1376 BOOST_CHECK(true == t1.empty());
1377 BOOST_CHECK(0 == t1.size());
1378 // those fails e.g. on darwin 4.2.1 because it can't copy base obejcts properly
1379 BOOST_CHECK(t1.parameters().get_max_elements() == params.get_max_elements());
1380 BOOST_CHECK(t1.parameters().get_min_elements() == params.get_min_elements());
1381 BOOST_CHECK(t2.parameters().get_max_elements() == params.get_max_elements());
1382 BOOST_CHECK(t2.parameters().get_min_elements() == params.get_min_elements());
1383
1384 output.clear();
1385 t1.query(bgi::intersects(qbox), std::back_inserter(output));
1386 BOOST_CHECK(output.empty());
1387
1388 output.clear();
1389 t2.query(bgi::intersects(qbox), std::back_inserter(output));
1390 exactly_the_same_outputs(t2, output, expected_output);
1391 t2.swap(t1);
1392 // those fails e.g. on darwin 4.2.1 because it can't copy base obejcts properly
1393 BOOST_CHECK(t1.parameters().get_max_elements() == params.get_max_elements());
1394 BOOST_CHECK(t1.parameters().get_min_elements() == params.get_min_elements());
1395 BOOST_CHECK(t2.parameters().get_max_elements() == params.get_max_elements());
1396 BOOST_CHECK(t2.parameters().get_min_elements() == params.get_min_elements());
1397
1398 // moving constructor
1399 Rtree t3(boost::move(t1), tree.get_allocator());
1400
1401 BOOST_CHECK(t3.size() == s);
1402 BOOST_CHECK(t1.size() == 0);
1403 BOOST_CHECK(t3.parameters().get_max_elements() == params.get_max_elements());
1404 BOOST_CHECK(t3.parameters().get_min_elements() == params.get_min_elements());
1405
1406 output.clear();
1407 t3.query(bgi::intersects(qbox), std::back_inserter(output));
1408 exactly_the_same_outputs(t3, output, expected_output);
1409
1410 // moving assignment operator
1411 t1 = boost::move(t3);
1412
1413 BOOST_CHECK(t1.size() == s);
1414 BOOST_CHECK(t3.size() == 0);
1415 BOOST_CHECK(t1.parameters().get_max_elements() == params.get_max_elements());
1416 BOOST_CHECK(t1.parameters().get_min_elements() == params.get_min_elements());
1417
1418 output.clear();
1419 t1.query(bgi::intersects(qbox), std::back_inserter(output));
1420 exactly_the_same_outputs(t1, output, expected_output);
1421
1422 //TODO - test SWAP
1423
1424 ::boost::ignore_unused(params);
1425 }
1426
1427 template <typename I, typename O>
my_copy(I first,I last,O out)1428 inline void my_copy(I first, I last, O out)
1429 {
1430 for ( ; first != last ; ++first, ++out )
1431 *out = *first;
1432 }
1433
1434 // rtree creation and insertion
1435
1436 template <typename Rtree, typename Value, typename Box>
create_insert(Rtree const & tree,std::vector<Value> const & input,Box const & qbox)1437 void create_insert(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1438 {
1439 std::vector<Value> expected_output;
1440 tree.query(bgi::intersects(qbox), std::back_inserter(expected_output));
1441
1442 {
1443 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1444 BOOST_FOREACH(Value const& v, input)
1445 t.insert(v);
1446 BOOST_CHECK(tree.size() == t.size());
1447 std::vector<Value> output;
1448 t.query(bgi::intersects(qbox), std::back_inserter(output));
1449 exactly_the_same_outputs(t, output, expected_output);
1450 }
1451 {
1452 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1453 //std::copy(input.begin(), input.end(), bgi::inserter(t));
1454 my_copy(input.begin(), input.end(), bgi::inserter(t)); // to suppress MSVC warnings
1455 BOOST_CHECK(tree.size() == t.size());
1456 std::vector<Value> output;
1457 t.query(bgi::intersects(qbox), std::back_inserter(output));
1458 exactly_the_same_outputs(t, output, expected_output);
1459 }
1460 {
1461 Rtree t(input.begin(), input.end(), tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1462 BOOST_CHECK(tree.size() == t.size());
1463 std::vector<Value> output;
1464 t.query(bgi::intersects(qbox), std::back_inserter(output));
1465 compare_outputs(t, output, expected_output);
1466 }
1467 {
1468 Rtree t(input, tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1469 BOOST_CHECK(tree.size() == t.size());
1470 std::vector<Value> output;
1471 t.query(bgi::intersects(qbox), std::back_inserter(output));
1472 compare_outputs(t, output, expected_output);
1473 }
1474 {
1475 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1476 t.insert(input.begin(), input.end());
1477 BOOST_CHECK(tree.size() == t.size());
1478 std::vector<Value> output;
1479 t.query(bgi::intersects(qbox), std::back_inserter(output));
1480 exactly_the_same_outputs(t, output, expected_output);
1481 }
1482 {
1483 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1484 t.insert(input);
1485 BOOST_CHECK(tree.size() == t.size());
1486 std::vector<Value> output;
1487 t.query(bgi::intersects(qbox), std::back_inserter(output));
1488 exactly_the_same_outputs(t, output, expected_output);
1489 }
1490
1491 {
1492 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1493 BOOST_FOREACH(Value const& v, input)
1494 bgi::insert(t, v);
1495 BOOST_CHECK(tree.size() == t.size());
1496 std::vector<Value> output;
1497 bgi::query(t, bgi::intersects(qbox), std::back_inserter(output));
1498 exactly_the_same_outputs(t, output, expected_output);
1499 }
1500 {
1501 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1502 bgi::insert(t, input.begin(), input.end());
1503 BOOST_CHECK(tree.size() == t.size());
1504 std::vector<Value> output;
1505 bgi::query(t, bgi::intersects(qbox), std::back_inserter(output));
1506 exactly_the_same_outputs(t, output, expected_output);
1507 }
1508 {
1509 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1510 bgi::insert(t, input);
1511 BOOST_CHECK(tree.size() == t.size());
1512 std::vector<Value> output;
1513 bgi::query(t, bgi::intersects(qbox), std::back_inserter(output));
1514 exactly_the_same_outputs(t, output, expected_output);
1515 }
1516 }
1517
1518 // rtree removing
1519
1520 template <typename Rtree, typename Box>
remove(Rtree const & tree,Box const & qbox)1521 void remove(Rtree const& tree, Box const& qbox)
1522 {
1523 typedef typename Rtree::value_type Value;
1524
1525 std::vector<Value> values_to_remove;
1526 tree.query(bgi::intersects(qbox), std::back_inserter(values_to_remove));
1527 BOOST_CHECK(0 < values_to_remove.size());
1528
1529 std::vector<Value> expected_output;
1530 tree.query(bgi::disjoint(qbox), std::back_inserter(expected_output));
1531 size_t expected_removed_count = values_to_remove.size();
1532 size_t expected_size_after_remove = tree.size() - values_to_remove.size();
1533
1534 // Add value which is not stored in the Rtree
1535 Value outsider = generate::value_outside<Rtree>();
1536 values_to_remove.push_back(outsider);
1537
1538 {
1539 Rtree t(tree);
1540 size_t r = 0;
1541 BOOST_FOREACH(Value const& v, values_to_remove)
1542 r += t.remove(v);
1543 BOOST_CHECK( r == expected_removed_count );
1544 std::vector<Value> output;
1545 t.query(bgi::disjoint(qbox), std::back_inserter(output));
1546 BOOST_CHECK( t.size() == expected_size_after_remove );
1547 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1548 compare_outputs(t, output, expected_output);
1549 }
1550 {
1551 Rtree t(tree);
1552 size_t r = t.remove(values_to_remove.begin(), values_to_remove.end());
1553 BOOST_CHECK( r == expected_removed_count );
1554 std::vector<Value> output;
1555 t.query(bgi::disjoint(qbox), std::back_inserter(output));
1556 BOOST_CHECK( t.size() == expected_size_after_remove );
1557 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1558 compare_outputs(t, output, expected_output);
1559 }
1560 {
1561 Rtree t(tree);
1562 size_t r = t.remove(values_to_remove);
1563 BOOST_CHECK( r == expected_removed_count );
1564 std::vector<Value> output;
1565 t.query(bgi::disjoint(qbox), std::back_inserter(output));
1566 BOOST_CHECK( t.size() == expected_size_after_remove );
1567 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1568 compare_outputs(t, output, expected_output);
1569 }
1570
1571 {
1572 Rtree t(tree);
1573 size_t r = 0;
1574 BOOST_FOREACH(Value const& v, values_to_remove)
1575 r += bgi::remove(t, v);
1576 BOOST_CHECK( r == expected_removed_count );
1577 std::vector<Value> output;
1578 bgi::query(t, bgi::disjoint(qbox), std::back_inserter(output));
1579 BOOST_CHECK( t.size() == expected_size_after_remove );
1580 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1581 compare_outputs(t, output, expected_output);
1582 }
1583 {
1584 Rtree t(tree);
1585 size_t r = bgi::remove(t, values_to_remove.begin(), values_to_remove.end());
1586 BOOST_CHECK( r == expected_removed_count );
1587 std::vector<Value> output;
1588 bgi::query(t, bgi::disjoint(qbox), std::back_inserter(output));
1589 BOOST_CHECK( t.size() == expected_size_after_remove );
1590 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1591 compare_outputs(t, output, expected_output);
1592 }
1593 {
1594 Rtree t(tree);
1595 size_t r = bgi::remove(t, values_to_remove);
1596 BOOST_CHECK( r == expected_removed_count );
1597 std::vector<Value> output;
1598 bgi::query(t, bgi::disjoint(qbox), std::back_inserter(output));
1599 BOOST_CHECK( t.size() == expected_size_after_remove );
1600 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1601 compare_outputs(t, output, expected_output);
1602 }
1603 }
1604
1605 template <typename Rtree, typename Value, typename Box>
clear(Rtree const & tree,std::vector<Value> const & input,Box const & qbox)1606 void clear(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1607 {
1608 std::vector<Value> values_to_remove;
1609 tree.query(bgi::intersects(qbox), std::back_inserter(values_to_remove));
1610 BOOST_CHECK(0 < values_to_remove.size());
1611
1612 //clear
1613 {
1614 Rtree t(tree);
1615
1616 std::vector<Value> expected_output;
1617 t.query(bgi::intersects(qbox), std::back_inserter(expected_output));
1618 size_t s = t.size();
1619 t.clear();
1620 BOOST_CHECK(t.empty());
1621 BOOST_CHECK(t.size() == 0);
1622 t.insert(input);
1623 BOOST_CHECK(t.size() == s);
1624 std::vector<Value> output;
1625 t.query(bgi::intersects(qbox), std::back_inserter(output));
1626 exactly_the_same_outputs(t, output, expected_output);
1627 }
1628 }
1629
1630 template <typename Rtree, typename Value>
range(Rtree & tree,std::vector<Value> const & input)1631 void range(Rtree & tree, std::vector<Value> const& input)
1632 {
1633 check_fwd_iterators(tree.begin(), tree.end());
1634
1635 size_t count = std::distance(tree.begin(), tree.end());
1636 BOOST_CHECK(count == tree.size());
1637 BOOST_CHECK(count == input.size());
1638
1639 count = std::distance(boost::begin(tree), boost::end(tree));
1640 BOOST_CHECK(count == tree.size());
1641
1642 count = boost::size(tree);
1643 BOOST_CHECK(count == tree.size());
1644
1645 count = 0;
1646 BOOST_FOREACH(Value const& v, tree)
1647 {
1648 boost::ignore_unused(v);
1649 ++count;
1650 }
1651 BOOST_CHECK(count == tree.size());
1652
1653 }
1654
1655 // rtree queries
1656
1657 template <typename Rtree, typename Value, typename Box>
queries(Rtree const & tree,std::vector<Value> const & input,Box const & qbox)1658 void queries(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1659 {
1660 basictest::intersects(tree, input, qbox);
1661 basictest::disjoint(tree, input, qbox);
1662 basictest::covered_by(tree, input, qbox);
1663 basictest::overlaps(tree, input, qbox);
1664 //basictest::touches(tree, input, qbox);
1665 basictest::within(tree, input, qbox);
1666 basictest::contains(tree, input, qbox);
1667 basictest::covers(tree, input, qbox);
1668
1669 typedef typename bg::point_type<Box>::type P;
1670 P pt;
1671 bg::centroid(qbox, pt);
1672
1673 basictest::nearest_query_k(tree, input, pt, 10);
1674 basictest::nearest_query_not_found(tree, generate::outside_point<P>::apply());
1675
1676 basictest::satisfies(tree, input);
1677 }
1678
1679 // rtree creation and modification
1680
1681 template <typename Rtree, typename Value, typename Box>
modifiers(Rtree const & tree,std::vector<Value> const & input,Box const & qbox)1682 void modifiers(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1683 {
1684 basictest::copy_swap_move(tree, qbox);
1685 basictest::create_insert(tree, input, qbox);
1686 basictest::remove(tree, qbox);
1687 basictest::clear(tree, input, qbox);
1688 }
1689
1690 } // namespace basictest
1691
1692 template <typename Value, typename Parameters, typename Allocator>
test_rtree_queries(Parameters const & parameters,Allocator const & allocator)1693 void test_rtree_queries(Parameters const& parameters, Allocator const& allocator)
1694 {
1695 typedef bgi::indexable<Value> I;
1696 typedef bgi::equal_to<Value> E;
1697 typedef typename Allocator::template rebind<Value>::other A;
1698 typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
1699 typedef typename Tree::bounds_type B;
1700
1701 Tree tree(parameters, I(), E(), allocator);
1702 std::vector<Value> input;
1703 B qbox;
1704
1705 generate::rtree(tree, input, qbox);
1706
1707 basictest::queries(tree, input, qbox);
1708
1709 Tree empty_tree(parameters, I(), E(), allocator);
1710 std::vector<Value> empty_input;
1711
1712 basictest::queries(empty_tree, empty_input, qbox);
1713 }
1714
1715 template <typename Value, typename Parameters, typename Allocator>
test_rtree_modifiers(Parameters const & parameters,Allocator const & allocator)1716 void test_rtree_modifiers(Parameters const& parameters, Allocator const& allocator)
1717 {
1718 typedef bgi::indexable<Value> I;
1719 typedef bgi::equal_to<Value> E;
1720 typedef typename Allocator::template rebind<Value>::other A;
1721 typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
1722 typedef typename Tree::bounds_type B;
1723
1724 Tree tree(parameters, I(), E(), allocator);
1725 std::vector<Value> input;
1726 B qbox;
1727
1728 generate::rtree(tree, input, qbox);
1729
1730 basictest::modifiers(tree, input, qbox);
1731
1732 Tree empty_tree(parameters, I(), E(), allocator);
1733 std::vector<Value> empty_input;
1734
1735 basictest::copy_swap_move(empty_tree, qbox);
1736 }
1737
1738 // run all tests for a single Algorithm and single rtree
1739 // defined by Value
1740
1741 template <typename Value, typename Parameters, typename Allocator>
test_rtree_by_value(Parameters const & parameters,Allocator const & allocator)1742 void test_rtree_by_value(Parameters const& parameters, Allocator const& allocator)
1743 {
1744 test_rtree_queries<Value>(parameters, allocator);
1745 test_rtree_modifiers<Value>(parameters, allocator);
1746 }
1747
1748 // rtree inserting and removing of counting_value
1749
1750 template <typename Indexable, typename Parameters, typename Allocator>
test_count_rtree_values(Parameters const & parameters,Allocator const & allocator)1751 void test_count_rtree_values(Parameters const& parameters, Allocator const& allocator)
1752 {
1753 typedef counting_value<Indexable> Value;
1754
1755 typedef bgi::indexable<Value> I;
1756 typedef bgi::equal_to<Value> E;
1757 typedef typename Allocator::template rebind<Value>::other A;
1758 typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
1759 typedef typename Tree::bounds_type B;
1760
1761 Tree t(parameters, I(), E(), allocator);
1762 std::vector<Value> input;
1763 B qbox;
1764
1765 generate::rtree(t, input, qbox);
1766
1767 size_t rest_count = input.size();
1768
1769 BOOST_CHECK(t.size() + rest_count == Value::counter());
1770
1771 std::vector<Value> values_to_remove;
1772 t.query(bgi::intersects(qbox), std::back_inserter(values_to_remove));
1773
1774 rest_count += values_to_remove.size();
1775
1776 BOOST_CHECK(t.size() + rest_count == Value::counter());
1777
1778 size_t values_count = Value::counter();
1779
1780 BOOST_FOREACH(Value const& v, values_to_remove)
1781 {
1782 size_t r = t.remove(v);
1783 --values_count;
1784
1785 BOOST_CHECK(1 == r);
1786 BOOST_CHECK(Value::counter() == values_count);
1787 BOOST_CHECK(t.size() + rest_count == values_count);
1788 }
1789 }
1790
1791 // rtree count
1792
1793 template <typename Indexable, typename Parameters, typename Allocator>
test_rtree_count(Parameters const & parameters,Allocator const & allocator)1794 void test_rtree_count(Parameters const& parameters, Allocator const& allocator)
1795 {
1796 typedef std::pair<Indexable, int> Value;
1797
1798 typedef bgi::indexable<Value> I;
1799 typedef bgi::equal_to<Value> E;
1800 typedef typename Allocator::template rebind<Value>::other A;
1801 typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
1802 typedef typename Tree::bounds_type B;
1803
1804 Tree t(parameters, I(), E(), allocator);
1805 std::vector<Value> input;
1806 B qbox;
1807
1808 generate::rtree(t, input, qbox);
1809
1810 BOOST_CHECK(t.count(input[0]) == 1);
1811 BOOST_CHECK(t.count(input[0].first) == 1);
1812
1813 t.insert(input[0]);
1814
1815 BOOST_CHECK(t.count(input[0]) == 2);
1816 BOOST_CHECK(t.count(input[0].first) == 2);
1817
1818 t.insert(std::make_pair(input[0].first, -1));
1819
1820 BOOST_CHECK(t.count(input[0]) == 2);
1821 BOOST_CHECK(t.count(input[0].first) == 3);
1822 }
1823
1824 // test rtree box
1825
1826 template <typename Value, typename Parameters, typename Allocator>
test_rtree_bounds(Parameters const & parameters,Allocator const & allocator)1827 void test_rtree_bounds(Parameters const& parameters, Allocator const& allocator)
1828 {
1829 typedef bgi::indexable<Value> I;
1830 typedef bgi::equal_to<Value> E;
1831 typedef typename Allocator::template rebind<Value>::other A;
1832 typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
1833 typedef typename Tree::bounds_type B;
1834 //typedef typename bg::traits::point_type<B>::type P;
1835
1836 Tree t(parameters, I(), E(), allocator);
1837 std::vector<Value> input;
1838 B qbox;
1839
1840 B b;
1841 bg::assign_inverse(b);
1842
1843 BOOST_CHECK(bg::equals(t.bounds(), b));
1844
1845 generate::rtree(t, input, qbox);
1846
1847 b = bgi::detail::rtree::values_box<B>(input.begin(), input.end(), t.indexable_get(),
1848 bgi::detail::get_strategy(parameters));
1849
1850 BOOST_CHECK(bg::equals(t.bounds(), b));
1851 BOOST_CHECK(bg::equals(t.bounds(), bgi::bounds(t)));
1852
1853 size_t s = input.size();
1854 while ( s/2 < input.size() && !input.empty() )
1855 {
1856 t.remove(input.back());
1857 input.pop_back();
1858 }
1859
1860 b = bgi::detail::rtree::values_box<B>(input.begin(), input.end(), t.indexable_get(),
1861 bgi::detail::get_strategy(parameters));
1862
1863 BOOST_CHECK(bg::equals(t.bounds(), b));
1864
1865 Tree t2(t);
1866 BOOST_CHECK(bg::equals(t2.bounds(), b));
1867 t2.clear();
1868 t2 = t;
1869 BOOST_CHECK(bg::equals(t2.bounds(), b));
1870 t2.clear();
1871 t2 = boost::move(t);
1872 BOOST_CHECK(bg::equals(t2.bounds(), b));
1873
1874 t.clear();
1875
1876 bg::assign_inverse(b);
1877 BOOST_CHECK(bg::equals(t.bounds(), b));
1878 }
1879
1880 // test rtree iterator
1881
1882 template <typename Indexable, typename Parameters, typename Allocator>
test_rtree_range(Parameters const & parameters,Allocator const & allocator)1883 void test_rtree_range(Parameters const& parameters, Allocator const& allocator)
1884 {
1885 typedef std::pair<Indexable, int> Value;
1886
1887 typedef bgi::indexable<Value> I;
1888 typedef bgi::equal_to<Value> E;
1889 typedef typename Allocator::template rebind<Value>::other A;
1890 typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
1891 typedef typename Tree::bounds_type B;
1892
1893 Tree t(parameters, I(), E(), allocator);
1894 std::vector<Value> input;
1895 B qbox;
1896
1897 generate::rtree(t, input, qbox);
1898
1899 basictest::range(t, input);
1900 basictest::range((Tree const&)t, input);
1901 }
1902
1903 template <typename Indexable, typename Parameters, typename Allocator>
test_rtree_additional(Parameters const & parameters,Allocator const & allocator)1904 void test_rtree_additional(Parameters const& parameters, Allocator const& allocator)
1905 {
1906 test_count_rtree_values<Indexable>(parameters, allocator);
1907 test_rtree_count<Indexable>(parameters, allocator);
1908 test_rtree_bounds<Indexable>(parameters, allocator);
1909 test_rtree_range<Indexable>(parameters, allocator);
1910 }
1911
1912 // run all tests for one Algorithm for some number of rtrees
1913 // defined by some number of Values constructed from given Point
1914
1915 template<typename Point, typename Parameters, typename Allocator>
test_rtree_for_point(Parameters const & parameters,Allocator const & allocator)1916 void test_rtree_for_point(Parameters const& parameters, Allocator const& allocator)
1917 {
1918 typedef std::pair<Point, int> PairP;
1919 typedef boost::tuple<Point, int, int> TupleP;
1920 typedef boost::shared_ptr< test_object<Point> > SharedPtrP;
1921 typedef value_no_dctor<Point> VNoDCtor;
1922
1923 test_rtree_by_value<Point, Parameters>(parameters, allocator);
1924 test_rtree_by_value<PairP, Parameters>(parameters, allocator);
1925 test_rtree_by_value<TupleP, Parameters>(parameters, allocator);
1926
1927 test_rtree_by_value<SharedPtrP, Parameters>(parameters, allocator);
1928 test_rtree_by_value<VNoDCtor, Parameters>(parameters, allocator);
1929
1930 test_rtree_additional<Point>(parameters, allocator);
1931
1932 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1933 typedef std::tuple<Point, int, int> StdTupleP;
1934 test_rtree_by_value<StdTupleP, Parameters>(parameters, allocator);
1935 #endif
1936 }
1937
1938 template<typename Point, typename Parameters, typename Allocator>
test_rtree_for_box(Parameters const & parameters,Allocator const & allocator)1939 void test_rtree_for_box(Parameters const& parameters, Allocator const& allocator)
1940 {
1941 typedef bg::model::box<Point> Box;
1942 typedef std::pair<Box, int> PairB;
1943 typedef boost::tuple<Box, int, int> TupleB;
1944 typedef value_no_dctor<Box> VNoDCtor;
1945
1946 test_rtree_by_value<Box, Parameters>(parameters, allocator);
1947 test_rtree_by_value<PairB, Parameters>(parameters, allocator);
1948 test_rtree_by_value<TupleB, Parameters>(parameters, allocator);
1949
1950 test_rtree_by_value<VNoDCtor, Parameters>(parameters, allocator);
1951
1952 test_rtree_additional<Box>(parameters, allocator);
1953
1954 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1955 typedef std::tuple<Box, int, int> StdTupleB;
1956 test_rtree_by_value<StdTupleB, Parameters>(parameters, allocator);
1957 #endif
1958 }
1959
1960 template<typename Point, typename Parameters>
test_rtree_for_point(Parameters const & parameters)1961 void test_rtree_for_point(Parameters const& parameters)
1962 {
1963 test_rtree_for_point<Point>(parameters, std::allocator<int>());
1964 }
1965
1966 template<typename Point, typename Parameters>
test_rtree_for_box(Parameters const & parameters)1967 void test_rtree_for_box(Parameters const& parameters)
1968 {
1969 test_rtree_for_box<Point>(parameters, std::allocator<int>());
1970 }
1971
1972 namespace testset {
1973
1974 template<typename Indexable, typename Parameters, typename Allocator>
modifiers(Parameters const & parameters,Allocator const & allocator)1975 void modifiers(Parameters const& parameters, Allocator const& allocator)
1976 {
1977 typedef std::pair<Indexable, int> Pair;
1978 typedef boost::tuple<Indexable, int, int> Tuple;
1979 typedef boost::shared_ptr< test_object<Indexable> > SharedPtr;
1980 typedef value_no_dctor<Indexable> VNoDCtor;
1981
1982 test_rtree_modifiers<Indexable>(parameters, allocator);
1983 test_rtree_modifiers<Pair>(parameters, allocator);
1984 test_rtree_modifiers<Tuple>(parameters, allocator);
1985
1986 test_rtree_modifiers<SharedPtr>(parameters, allocator);
1987 test_rtree_modifiers<VNoDCtor>(parameters, allocator);
1988
1989 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1990 typedef std::tuple<Indexable, int, int> StdTuple;
1991 test_rtree_modifiers<StdTuple>(parameters, allocator);
1992 #endif
1993 }
1994
1995 template<typename Indexable, typename Parameters, typename Allocator>
queries(Parameters const & parameters,Allocator const & allocator)1996 void queries(Parameters const& parameters, Allocator const& allocator)
1997 {
1998 typedef std::pair<Indexable, int> Pair;
1999 typedef boost::tuple<Indexable, int, int> Tuple;
2000 typedef boost::shared_ptr< test_object<Indexable> > SharedPtr;
2001 typedef value_no_dctor<Indexable> VNoDCtor;
2002
2003 test_rtree_queries<Indexable>(parameters, allocator);
2004 test_rtree_queries<Pair>(parameters, allocator);
2005 test_rtree_queries<Tuple>(parameters, allocator);
2006
2007 test_rtree_queries<SharedPtr>(parameters, allocator);
2008 test_rtree_queries<VNoDCtor>(parameters, allocator);
2009
2010 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
2011 typedef std::tuple<Indexable, int, int> StdTuple;
2012 test_rtree_queries<StdTuple>(parameters, allocator);
2013 #endif
2014 }
2015
2016 template<typename Indexable, typename Parameters, typename Allocator>
additional(Parameters const & parameters,Allocator const & allocator)2017 void additional(Parameters const& parameters, Allocator const& allocator)
2018 {
2019 test_rtree_additional<Indexable, Parameters>(parameters, allocator);
2020 }
2021
2022 } // namespace testset
2023
2024 #endif // BOOST_GEOMETRY_INDEX_TEST_RTREE_HPP
2025