• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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