1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3 
4 // Copyright (c) 2014, 2018 Oracle and/or its affiliates.
5 
6 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
7 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
8 
9 // Licensed under the Boost Software License version 1.0.
10 // http://www.boost.org/users/license.html
11 
12 #ifndef BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
13 #define BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
14 
15 #include <iterator>
16 
17 #include <boost/mpl/assert.hpp>
18 #include <boost/mpl/or.hpp>
19 #include <boost/range.hpp>
20 
21 #include <boost/geometry/core/reverse_dispatch.hpp>
22 #include <boost/geometry/core/tag.hpp>
23 #include <boost/geometry/core/tag_cast.hpp>
24 #include <boost/geometry/core/tags.hpp>
25 
26 #include <boost/geometry/iterators/segment_iterator.hpp>
27 
28 #include <boost/geometry/algorithms/distance.hpp>
29 #include <boost/geometry/algorithms/intersects.hpp>
30 #include <boost/geometry/algorithms/not_implemented.hpp>
31 
32 
33 namespace boost { namespace geometry
34 {
35 
36 namespace unit_test
37 {
38 
39 namespace detail { namespace distance_brute_force
40 {
41 
42 struct distance_from_bg
43 {
44     template <typename G>
45     struct use_distance_from_bg
46     {
47         typedef typename boost::mpl::or_
48             <
49                 boost::is_same<typename tag<G>::type, point_tag>,
50                 typename boost::mpl::or_
51                     <
52                         boost::is_same<typename tag<G>::type, segment_tag>,
53                         boost::is_same<typename tag<G>::type, box_tag>
54                     >::type
55             >::type type;
56     };
57 
58     template <typename Geometry1, typename Geometry2, typename Strategy>
59     static inline
60     typename distance_result<Geometry1, Geometry2, Strategy>::type
applyboost::geometry::unit_test::detail::distance_brute_force::distance_from_bg61     apply(Geometry1 const& geometry1,
62           Geometry2 const& geometry2,
63           Strategy const& strategy)
64     {
65         BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry1>::type));
66         BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry2>::type));
67 
68         return geometry::distance(geometry1, geometry2, strategy);
69     }
70 };
71 
72 
73 template <typename Geometry1, typename Geometry2, typename Strategy>
74 inline
75 typename distance_result<Geometry1, Geometry2, Strategy>::type
bg_distance(Geometry1 const & geometry1,Geometry2 const & geometry2,Strategy const & strategy)76 bg_distance(Geometry1 const& geometry1,
77             Geometry2 const& geometry2,
78             Strategy const& strategy)
79 {
80     return distance_from_bg::apply(geometry1, geometry2, strategy);
81 }
82 
83 
84 template <typename Policy>
85 struct one_to_many
86 {
87     template <typename Geometry, typename Iterator, typename Strategy>
88     static inline typename distance_result
89         <
90             Geometry,
91             typename std::iterator_traits<Iterator>::value_type,
92             Strategy
93         >::type
applyboost::geometry::unit_test::detail::distance_brute_force::one_to_many94     apply(Geometry const& geometry, Iterator begin, Iterator end,
95           Strategy const& strategy)
96     {
97         typedef typename distance_result
98         <
99             Geometry,
100             typename std::iterator_traits<Iterator>::value_type,
101             Strategy
102         >::type distance_type;
103 
104         bool first = true;
105         distance_type d_min(0);
106         for (Iterator it = begin; it != end; ++it, first = false)
107         {
108             distance_type d = Policy::apply(geometry, *it, strategy);
109 
110             if ( first || d < d_min )
111             {
112                 d_min = d;
113             }
114         }
115         return d_min;
116     }
117 };
118 
119 
120 
121 }} // namespace detail::distance_brute_force
122 
123 
124 namespace dispatch
125 {
126 
127 template
128 <
129     typename Geometry1,
130     typename Geometry2,
131     typename Strategy,
132     typename Tag1 = typename tag_cast
133         <
134             typename tag<Geometry1>::type,
135             segment_tag,
136             linear_tag
137         >::type,
138     typename Tag2 = typename tag_cast
139         <
140             typename tag<Geometry2>::type,
141             segment_tag,
142             linear_tag
143         >::type,
144     bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
145 >
146 struct distance_brute_force
147     : not_implemented<Geometry1, Geometry2>
148 {};
149 
150 template
151 <
152     typename Geometry1,
153     typename Geometry2,
154     typename Strategy,
155     typename Tag1,
156     typename Tag2
157 >
158 struct distance_brute_force<Geometry1, Geometry2, Strategy, Tag1, Tag2, true>
159 {
160     static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
applyboost::geometry::unit_test::dispatch::distance_brute_force161     apply(Geometry1 const& geometry1,
162           Geometry2 const& geometry2,
163           Strategy const& strategy)
164     {
165         return distance_brute_force
166             <
167                 Geometry2, Geometry1, Strategy
168             >::apply(geometry2, geometry1, strategy);
169     }
170 };
171 
172 //===================================================================
173 
174 template
175 <
176     typename Point1,
177     typename Point2,
178     typename Strategy
179 >
180 struct distance_brute_force
181 <
182     Point1, Point2, Strategy,
183     point_tag, point_tag, false
184 > : detail::distance_brute_force::distance_from_bg
185 {};
186 
187 
188 template
189 <
190     typename Point,
191     typename Segment,
192     typename Strategy
193 >
194 struct distance_brute_force
195 <
196     Point, Segment, Strategy,
197     point_tag, segment_tag, false
198 > : detail::distance_brute_force::distance_from_bg
199 {};
200 
201 template
202 <
203     typename Point,
204     typename Linear,
205     typename Strategy
206 >
207 struct distance_brute_force
208 <
209     Point, Linear, Strategy,
210     point_tag, linear_tag, false
211 >
212 {
213     typedef typename distance_result
214         <
215             Point, Linear, Strategy
216         >::type distance_type;
217 
applyboost::geometry::unit_test::dispatch::distance_brute_force218     static inline distance_type apply(Point const& point,
219                                       Linear const& linear,
220                                       Strategy const& strategy)
221     {
222         return detail::distance_brute_force::one_to_many
223             <
224                 detail::distance_brute_force::distance_from_bg
225             >::apply(point,
226                      geometry::segments_begin(linear),
227                      geometry::segments_end(linear),
228                      strategy);
229     }
230 };
231 
232 template
233 <
234     typename Point,
235     typename Ring,
236     typename Strategy
237 >
238 struct distance_brute_force
239 <
240     Point, Ring, Strategy,
241     point_tag, ring_tag, false
242 >
243 {
244     typedef typename distance_result
245         <
246             Point, Ring, Strategy
247         >::type distance_type;
248 
applyboost::geometry::unit_test::dispatch::distance_brute_force249     static inline distance_type apply(Point const& point,
250                                       Ring const& ring,
251                                       Strategy const& strategy)
252     {
253 
254         if (geometry::covered_by(point, ring))
255         {
256             return 0;
257         }
258 
259         return detail::distance_brute_force::one_to_many
260             <
261                 distance_brute_force
262                     <
263                         Point,
264                         typename std::iterator_traits
265                             <
266                                 segment_iterator<Ring const>
267                             >::value_type,
268                         Strategy
269                     >
270             >::apply(point,
271                      geometry::segments_begin(ring),
272                      geometry::segments_end(ring),
273                      strategy);
274     }
275 };
276 
277 //TODO do it more brute force (also in all polygon-geometry cases)
278 template
279 <
280     typename Point,
281     typename Polygon,
282     typename Strategy
283 >
284 struct distance_brute_force
285 <
286     Point, Polygon, Strategy,
287     point_tag, polygon_tag, false
288 >
289 {
290     typedef typename distance_result
291         <
292             Point, Polygon, Strategy
293         >::type distance_type;
294 
applyboost::geometry::unit_test::dispatch::distance_brute_force295     static inline distance_type apply(Point const& point,
296                                       Polygon const& polygon,
297                                       Strategy const& strategy)
298     {
299         return geometry::distance(point, polygon, strategy);
300     }
301 };
302 
303 template
304 <
305     typename Point,
306     typename Box,
307     typename Strategy
308 >
309 struct distance_brute_force
310 <
311     Point, Box, Strategy,
312     point_tag, box_tag, false
313 > : detail::distance_brute_force::distance_from_bg
314 {};
315 
316 template
317 <
318     typename Point,
319     typename MultiPoint,
320     typename Strategy
321 >
322 struct distance_brute_force
323 <
324     Point, MultiPoint, Strategy,
325     point_tag, multi_point_tag, false
326 >
327 {
328     typedef typename distance_result
329         <
330             Point, MultiPoint, Strategy
331         >::type distance_type;
332 
applyboost::geometry::unit_test::dispatch::distance_brute_force333     static inline distance_type apply(Point const& p,
334                                       MultiPoint const& mp,
335                                       Strategy const& strategy)
336     {
337         return detail::distance_brute_force::one_to_many
338             <
339                 detail::distance_brute_force::distance_from_bg
340             >::apply(p, boost::begin(mp), boost::end(mp), strategy);
341     }
342 };
343 
344 template
345 <
346     typename Point,
347     typename MultiPolygon,
348     typename Strategy
349 >
350 struct distance_brute_force
351 <
352     Point, MultiPolygon, Strategy,
353     point_tag, multi_polygon_tag, false
354 >
355 {
356     typedef typename distance_result
357         <
358             Point, MultiPolygon, Strategy
359         >::type distance_type;
360 
applyboost::geometry::unit_test::dispatch::distance_brute_force361     static inline distance_type apply(Point const& p,
362                                       MultiPolygon const& mp,
363                                       Strategy const& strategy)
364     {
365         return detail::distance_brute_force::one_to_many
366             <
367                 distance_brute_force
368                 <
369                     Point,
370                     typename boost::range_value<MultiPolygon>::type,
371                     Strategy
372                 >
373             >::apply(p, boost::begin(mp), boost::end(mp), strategy);
374     }
375 };
376 
377 //=======================================================================
378 
379 template
380 <
381     typename Linear,
382     typename Segment,
383     typename Strategy
384 >
385 struct distance_brute_force
386 <
387     Linear, Segment, Strategy,
388     linear_tag, segment_tag, false
389 >
390 {
391     typedef typename distance_result
392         <
393             Linear, Segment, Strategy
394         >::type distance_type;
395 
applyboost::geometry::unit_test::dispatch::distance_brute_force396     static inline distance_type apply(Linear const& linear,
397                                       Segment const& segment,
398                                       Strategy const& strategy)
399     {
400         return detail::distance_brute_force::one_to_many
401             <
402                 detail::distance_brute_force::distance_from_bg
403             >::apply(segment,
404                      geometry::segments_begin(linear),
405                      geometry::segments_end(linear),
406                      strategy);
407     }
408 };
409 
410 
411 template
412 <
413     typename Linear1,
414     typename Linear2,
415     typename Strategy
416 >
417 struct distance_brute_force
418 <
419     Linear1, Linear2, Strategy,
420     linear_tag, linear_tag, false
421 >
422 {
423     typedef typename distance_result
424         <
425             Linear1, Linear2, Strategy
426         >::type distance_type;
427 
applyboost::geometry::unit_test::dispatch::distance_brute_force428     static inline distance_type apply(Linear1 const& linear1,
429                                       Linear2 const& linear2,
430                                       Strategy const& strategy)
431     {
432         return detail::distance_brute_force::one_to_many
433             <
434                 distance_brute_force
435                     <
436                         Linear1,
437                         typename std::iterator_traits
438                             <
439                                 segment_iterator<Linear2 const>
440                             >::value_type,
441                         Strategy
442                     >
443             >::apply(linear1,
444                      geometry::segments_begin(linear2),
445                      geometry::segments_end(linear2),
446                      strategy);
447     }
448 };
449 
450 template
451 <
452     typename Linear,
453     typename Ring,
454     typename Strategy
455 >
456 struct distance_brute_force
457 <
458     Linear, Ring, Strategy,
459     linear_tag, ring_tag, false
460 >
461 {
462     typedef typename distance_result
463         <
464             Linear, Ring, Strategy
465         >::type distance_type;
466 
applyboost::geometry::unit_test::dispatch::distance_brute_force467     static inline distance_type apply(Linear const& linear,
468                                       Ring const& ring,
469                                       Strategy const& strategy)
470     {
471         return detail::distance_brute_force::one_to_many
472             <
473                 distance_brute_force
474                     <
475                         Linear,
476                         typename std::iterator_traits
477                             <
478                                 segment_iterator<Ring const>
479                             >::value_type,
480                         Strategy
481                     >
482             >::apply(linear,
483                      geometry::segments_begin(ring),
484                      geometry::segments_end(ring),
485                      strategy);
486     }
487 };
488 
489 template
490 <
491     typename Linear,
492     typename Polygon,
493     typename Strategy
494 >
495 struct distance_brute_force
496 <
497     Linear, Polygon, Strategy,
498     linear_tag, polygon_tag, false
499 >
500 {
501     typedef typename distance_result
502         <
503             Linear, Polygon, Strategy
504         >::type distance_type;
505 
applyboost::geometry::unit_test::dispatch::distance_brute_force506     static inline distance_type apply(Linear const& linear,
507                                       Polygon const& polygon,
508                                       Strategy const& strategy)
509     {
510         return detail::distance_brute_force::one_to_many
511             <
512                 distance_brute_force
513                     <
514                         Polygon,
515                         typename std::iterator_traits
516                             <
517                                 segment_iterator<Linear const>
518                             >::value_type,
519                         Strategy
520                     >
521             >::apply(polygon,
522                      geometry::segments_begin(linear),
523                      geometry::segments_end(linear),
524                      strategy);
525     }
526 };
527 
528 
529 template
530 <
531     typename Linear,
532     typename Box,
533     typename Strategy
534 >
535 struct distance_brute_force
536 <
537     Linear, Box, Strategy,
538     linear_tag, box_tag, false
539 >
540 {
541     typedef typename distance_result
542         <
543             Linear, Box, Strategy
544         >::type distance_type;
545 
applyboost::geometry::unit_test::dispatch::distance_brute_force546     static inline distance_type apply(Linear const& linear,
547                                       Box const& box,
548                                       Strategy const& strategy)
549     {
550         return detail::distance_brute_force::one_to_many
551             <
552                 detail::distance_brute_force::distance_from_bg
553             >::apply(box,
554                      geometry::segments_begin(linear),
555                      geometry::segments_end(linear),
556                      strategy);
557     }
558 };
559 
560 template
561 <
562     typename Linear,
563     typename MultiPoint,
564     typename Strategy
565 >
566 struct distance_brute_force
567 <
568     Linear, MultiPoint, Strategy,
569     linear_tag, multi_point_tag, false
570 >
571 {
572     typedef typename distance_result
573         <
574             Linear, MultiPoint, Strategy
575         >::type distance_type;
576 
applyboost::geometry::unit_test::dispatch::distance_brute_force577     static inline distance_type apply(Linear const& linear,
578                                       MultiPoint const& mp,
579                                       Strategy const& strategy)
580     {
581         return detail::distance_brute_force::one_to_many
582             <
583                 distance_brute_force
584                 <
585                     Linear,
586                     typename boost::range_value<MultiPoint>::type,
587                     Strategy
588                 >
589             >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
590     }
591 };
592 
593 template
594 <
595     typename Linear,
596     typename MultiPolygon,
597     typename Strategy
598 >
599 struct distance_brute_force
600 <
601     Linear, MultiPolygon, Strategy,
602     linear_tag, multi_polygon_tag, false
603 >
604 {
605     typedef typename distance_result
606         <
607             Linear, MultiPolygon, Strategy
608         >::type distance_type;
609 
applyboost::geometry::unit_test::dispatch::distance_brute_force610     static inline distance_type apply(Linear const& linear,
611                                       MultiPolygon const& mp,
612                                       Strategy const& strategy)
613     {
614         return detail::distance_brute_force::one_to_many
615             <
616                 distance_brute_force
617                 <
618                     Linear,
619                     typename boost::range_value<MultiPolygon>::type,
620                     Strategy
621                 >
622             >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
623     }
624 };
625 
626 //=================================================================
627 
628 template
629 <
630     typename Polygon,
631     typename Segment,
632     typename Strategy
633 >
634 struct distance_brute_force
635 <
636     Polygon, Segment, Strategy,
637     polygon_tag, segment_tag, false
638 >
639 {
640     typedef typename distance_result
641         <
642             Polygon, Segment, Strategy
643         >::type distance_type;
644 
applyboost::geometry::unit_test::dispatch::distance_brute_force645     static inline distance_type apply(Polygon const& polygon,
646                                       Segment const& segment,
647                                       Strategy const& strategy)
648     {
649         return geometry::distance(segment, polygon, strategy);
650     }
651 };
652 
653 template
654 <
655     typename Polygon,
656     typename Linear,
657     typename Strategy
658 >
659 struct distance_brute_force
660 <
661     Polygon, Linear, Strategy,
662     polygon_tag, linear_tag, false
663 >
664 {
665     typedef typename distance_result
666         <
667             Polygon, Linear, Strategy
668         >::type distance_type;
669 
applyboost::geometry::unit_test::dispatch::distance_brute_force670     static inline distance_type apply(Polygon const& polygon,
671                                       Linear const& linear,
672                                       Strategy const& strategy)
673     {
674         return detail::distance_brute_force::one_to_many
675             <
676                 distance_brute_force
677                     <
678                         Polygon,
679                         typename std::iterator_traits
680                             <
681                                 segment_iterator<Linear const>
682                             >::value_type,
683                         Strategy
684                     >
685             >::apply(polygon,
686                      geometry::segments_begin(linear),
687                      geometry::segments_end(linear),
688                      strategy);
689     }
690 };
691 
692 template
693 <
694     typename Polygon1,
695     typename Polygon2,
696     typename Strategy
697 >
698 struct distance_brute_force
699 <
700     Polygon1, Polygon2, Strategy,
701     polygon_tag, polygon_tag, false
702 >
703 {
704     typedef typename distance_result
705         <
706             Polygon1, Polygon2, Strategy
707         >::type distance_type;
708 
applyboost::geometry::unit_test::dispatch::distance_brute_force709     static inline distance_type apply(Polygon1 const& polygon1,
710                                       Polygon2 const& polygon2,
711                                       Strategy const& strategy)
712     {
713         return geometry::distance(polygon1, polygon2, strategy);
714     }
715 };
716 
717 
718 template
719 <
720     typename Polygon,
721     typename MultiPoint,
722     typename Strategy
723 >
724 struct distance_brute_force
725 <
726     Polygon, MultiPoint, Strategy,
727     polygon_tag, multi_point_tag, false
728 >
729 {
730     typedef typename distance_result
731         <
732             Polygon, MultiPoint, Strategy
733         >::type distance_type;
734 
applyboost::geometry::unit_test::dispatch::distance_brute_force735     static inline distance_type apply(Polygon const& polygon,
736                                       MultiPoint const& mp,
737                                       Strategy const& strategy)
738     {
739         return detail::distance_brute_force::one_to_many
740             <
741                 distance_brute_force
742                 <
743                     Polygon,
744                     typename boost::range_value<MultiPoint>::type,
745                     Strategy
746                 >
747             >::apply(polygon, boost::begin(mp), boost::end(mp), strategy);
748     }
749 };
750 
751 template
752 <
753     typename Polygon,
754     typename MultiPolygon,
755     typename Strategy
756 >
757 struct distance_brute_force
758 <
759     Polygon, MultiPolygon, Strategy,
760     polygon_tag, multi_polygon_tag, false
761 >
762 {
763     typedef typename distance_result
764         <
765             Polygon, MultiPolygon, Strategy
766         >::type distance_type;
767 
applyboost::geometry::unit_test::dispatch::distance_brute_force768     static inline distance_type apply(Polygon const& poly,
769                                       MultiPolygon const& mp,
770                                       Strategy const& strategy)
771     {
772         return detail::distance_brute_force::one_to_many
773             <
774                 distance_brute_force
775                 <
776                     Polygon,
777                     typename boost::range_value<MultiPolygon>::type,
778                     Strategy
779                 >
780             >::apply(poly, boost::begin(mp), boost::end(mp), strategy);
781     }
782 };
783 
784 template
785 <
786     typename Polygon,
787     typename Ring,
788     typename Strategy
789 >
790 struct distance_brute_force
791 <
792     Polygon, Ring, Strategy,
793     polygon_tag, ring_tag, false
794 >
795 {
796     typedef typename distance_result
797         <
798             Polygon, Ring, Strategy
799         >::type distance_type;
800 
applyboost::geometry::unit_test::dispatch::distance_brute_force801     static inline distance_type apply(Polygon const& polygon,
802                                       Ring const& ring,
803                                       Strategy const& strategy)
804     {
805         return geometry::distance(ring, polygon, strategy);
806     }
807 };
808 
809 template
810 <
811     typename Polygon,
812     typename Box,
813     typename Strategy
814 >
815 struct distance_brute_force
816 <
817     Polygon, Box, Strategy,
818     polygon_tag, box_tag, false
819 >
820 {
821     typedef typename distance_result
822         <
823             Polygon, Box, Strategy
824         >::type distance_type;
825 
applyboost::geometry::unit_test::dispatch::distance_brute_force826     static inline distance_type apply(Polygon const& polygon,
827                                       Box const& box,
828                                       Strategy const& strategy)
829     {
830         return geometry::distance(box, polygon, strategy);
831     }
832 };
833 
834 //========================================================================
835 
836 template
837 <
838     typename MultiPoint1,
839     typename MultiPoint2,
840     typename Strategy
841 >
842 struct distance_brute_force
843 <
844     MultiPoint1, MultiPoint2, Strategy,
845     multi_point_tag, multi_point_tag, false
846 >
847 {
848     typedef typename distance_result
849         <
850             MultiPoint1, MultiPoint2, Strategy
851         >::type distance_type;
852 
applyboost::geometry::unit_test::dispatch::distance_brute_force853     static inline distance_type apply(MultiPoint1 const& mp1,
854                                       MultiPoint2 const& mp2,
855                                       Strategy const& strategy)
856     {
857         return detail::distance_brute_force::one_to_many
858             <
859                 distance_brute_force
860                 <
861                     MultiPoint1,
862                     typename boost::range_value<MultiPoint2>::type,
863                     Strategy
864                 >
865             >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
866     }
867 };
868 
869 template
870 <
871     typename MultiPoint,
872     typename Linear,
873     typename Strategy
874 >
875 struct distance_brute_force
876 <
877     MultiPoint, Linear, Strategy,
878     multi_point_tag, linear_tag, false
879 >
880 {
881     typedef typename distance_result
882         <
883             MultiPoint, Linear, Strategy
884         >::type distance_type;
885 
applyboost::geometry::unit_test::dispatch::distance_brute_force886     static inline distance_type apply(MultiPoint const& mp,
887                                       Linear const& l,
888                                       Strategy const& strategy)
889     {
890         return detail::distance_brute_force::one_to_many
891             <
892                 distance_brute_force
893                 <
894                     MultiPoint,
895                     typename boost::range_value<Linear>::type,
896                     Strategy
897                 >
898             >::apply(mp, boost::begin(l), boost::end(l), strategy);
899     }
900 };
901 
902 template
903 <
904     typename MultiPoint,
905     typename MultiPolygon,
906     typename Strategy
907 >
908 struct distance_brute_force
909 <
910     MultiPoint, MultiPolygon, Strategy,
911     multi_point_tag, multi_polygon_tag, false
912 >
913 {
914     typedef typename distance_result
915         <
916             MultiPoint, MultiPolygon, Strategy
917         >::type distance_type;
918 
applyboost::geometry::unit_test::dispatch::distance_brute_force919     static inline distance_type apply(MultiPoint const& mp,
920                                       MultiPolygon const& mpl,
921                                       Strategy const& strategy)
922     {
923         return detail::distance_brute_force::one_to_many
924             <
925                 distance_brute_force
926                 <
927                     MultiPoint,
928                     typename boost::range_value<MultiPolygon>::type,
929                     Strategy
930                 >
931             >::apply(mp, boost::begin(mpl), boost::end(mpl), strategy);
932     }
933 };
934 
935 template
936 <
937     typename MultiPoint,
938     typename Segment,
939     typename Strategy
940 >
941 struct distance_brute_force
942 <
943     MultiPoint, Segment, Strategy,
944     multi_point_tag, segment_tag, false
945 >
946 {
947     typedef typename distance_result
948         <
949             MultiPoint, Segment, Strategy
950         >::type distance_type;
951 
applyboost::geometry::unit_test::dispatch::distance_brute_force952     static inline distance_type apply(MultiPoint const& mp,
953                                       Segment const& segment,
954                                       Strategy const& strategy)
955     {
956         return detail::distance_brute_force::one_to_many
957             <
958                 detail::distance_brute_force::distance_from_bg
959             >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
960     }
961 };
962 
963 template
964 <
965     typename MultiPoint,
966     typename Ring,
967     typename Strategy
968 >
969 struct distance_brute_force
970 <
971     MultiPoint, Ring, Strategy,
972     multi_point_tag, ring_tag, false
973 >
974 {
975     typedef typename distance_result
976         <
977             MultiPoint, Ring, Strategy
978         >::type distance_type;
979 
applyboost::geometry::unit_test::dispatch::distance_brute_force980     static inline distance_type apply(MultiPoint const& mp,
981                                       Ring const& ring,
982                                       Strategy const& strategy)
983     {
984 
985 
986         return detail::distance_brute_force::one_to_many
987             <
988                 distance_brute_force
989                 <
990                     MultiPoint,
991                     typename std::iterator_traits
992                     <
993                         segment_iterator<Ring const>
994                     >::value_type,
995                     Strategy
996                 >
997             >::apply(mp,
998                      geometry::segments_begin(ring),
999                      geometry::segments_end(ring),
1000                      strategy);
1001     }
1002 };
1003 
1004 template
1005 <
1006     typename MultiPoint,
1007     typename Box,
1008     typename Strategy
1009 >
1010 struct distance_brute_force
1011 <
1012     MultiPoint, Box, Strategy,
1013     multi_point_tag, box_tag, false
1014 >
1015 {
1016     typedef typename distance_result
1017         <
1018             MultiPoint, Box, Strategy
1019         >::type distance_type;
1020 
applyboost::geometry::unit_test::dispatch::distance_brute_force1021     static inline distance_type apply(MultiPoint const& mp,
1022                                       Box const& box,
1023                                       Strategy const& strategy)
1024     {
1025         return detail::distance_brute_force::one_to_many
1026             <
1027                 distance_brute_force
1028                 <
1029                     Box,
1030                     typename boost::range_value<MultiPoint>::type,
1031                     Strategy
1032                 >
1033             >::apply(box, boost::begin(mp), boost::end(mp), strategy);
1034     }
1035 };
1036 
1037 //=====================================================================
1038 
1039 template
1040 <
1041     typename MultiPolygon1,
1042     typename MultiPolygon2,
1043     typename Strategy
1044 >
1045 struct distance_brute_force
1046 <
1047     MultiPolygon1, MultiPolygon2, Strategy,
1048     multi_polygon_tag, multi_polygon_tag, false
1049 >
1050 {
1051     typedef typename distance_result
1052         <
1053             MultiPolygon1, MultiPolygon2, Strategy
1054         >::type distance_type;
1055 
applyboost::geometry::unit_test::dispatch::distance_brute_force1056     static inline distance_type apply(MultiPolygon1 const& mp1,
1057                                       MultiPolygon2 const& mp2,
1058                                       Strategy const& strategy)
1059     {
1060         return detail::distance_brute_force::one_to_many
1061             <
1062                 distance_brute_force
1063                 <
1064                     MultiPolygon1,
1065                     typename boost::range_value<MultiPolygon2>::type,
1066                     Strategy
1067                 >
1068             >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
1069     }
1070 };
1071 
1072 template
1073 <
1074     typename MultiPolygon,
1075     typename Segment,
1076     typename Strategy
1077 >
1078 struct distance_brute_force
1079 <
1080     MultiPolygon, Segment, Strategy,
1081     multi_polygon_tag, segment_tag, false
1082 >
1083 {
1084     typedef typename distance_result
1085         <
1086             MultiPolygon, Segment, Strategy
1087         >::type distance_type;
1088 
applyboost::geometry::unit_test::dispatch::distance_brute_force1089     static inline distance_type apply(MultiPolygon const& mp,
1090                                       Segment const& segment,
1091                                       Strategy const& strategy)
1092     {
1093         return detail::distance_brute_force::one_to_many
1094             <
1095                 distance_brute_force
1096                 <
1097                     Segment,
1098                     typename boost::range_value<MultiPolygon>::type,
1099                     Strategy
1100                 >
1101             >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
1102     }
1103 };
1104 
1105 template
1106 <
1107     typename MultiPolygon,
1108     typename Ring,
1109     typename Strategy
1110 >
1111 struct distance_brute_force
1112 <
1113     MultiPolygon, Ring, Strategy,
1114     multi_polygon_tag, ring_tag, false
1115 >
1116 {
1117     typedef typename distance_result
1118         <
1119             MultiPolygon, Ring, Strategy
1120         >::type distance_type;
1121 
applyboost::geometry::unit_test::dispatch::distance_brute_force1122     static inline distance_type apply(MultiPolygon const& mp,
1123                                       Ring const& ring,
1124                                       Strategy const& strategy)
1125     {
1126         return detail::distance_brute_force::one_to_many
1127             <
1128                 distance_brute_force
1129                 <
1130                     Ring,
1131                     typename boost::range_value<MultiPolygon>::type,
1132                     Strategy
1133                 >
1134             >::apply(ring, boost::begin(mp), boost::end(mp), strategy);
1135     }
1136 };
1137 
1138 template
1139 <
1140     typename MultiPolygon,
1141     typename Box,
1142     typename Strategy
1143 >
1144 struct distance_brute_force
1145 <
1146     MultiPolygon, Box, Strategy,
1147     multi_polygon_tag, box_tag, false
1148 >
1149 {
1150     typedef typename distance_result
1151         <
1152             MultiPolygon, Box, Strategy
1153         >::type distance_type;
1154 
applyboost::geometry::unit_test::dispatch::distance_brute_force1155     static inline distance_type apply(MultiPolygon const& mp,
1156                                       Box const& box,
1157                                       Strategy const& strategy)
1158     {
1159         return detail::distance_brute_force::one_to_many
1160             <
1161                 distance_brute_force
1162                 <
1163                     Box,
1164                     typename boost::range_value<MultiPolygon>::type,
1165                     Strategy
1166                 >
1167             >::apply(box, boost::begin(mp), boost::end(mp), strategy);
1168     }
1169 };
1170 
1171 
1172 //========================================================================
1173 
1174 template
1175 <
1176     typename Ring,
1177     typename Box,
1178     typename Strategy
1179 >
1180 struct distance_brute_force
1181 <
1182     Ring, Box, Strategy,
1183     ring_tag, box_tag, false
1184 >
1185 {
1186     typedef typename distance_result
1187         <
1188             Ring, Box, Strategy
1189         >::type distance_type;
1190 
applyboost::geometry::unit_test::dispatch::distance_brute_force1191     static inline distance_type apply(Ring const& ring,
1192                                       Box const& box,
1193                                       Strategy const& strategy)
1194     {
1195         return detail::distance_brute_force::one_to_many
1196             <
1197                 distance_brute_force
1198                     <
1199                         Box,
1200                         typename std::iterator_traits
1201                             <
1202                                 segment_iterator<Ring const>
1203                             >::value_type,
1204                         Strategy
1205                     >
1206             >::apply(box,
1207                      geometry::segments_begin(ring),
1208                      geometry::segments_end(ring),
1209                      strategy);
1210     }
1211 };
1212 
1213 template
1214 <
1215     typename Ring1,
1216     typename Ring2,
1217     typename Strategy
1218 >
1219 struct distance_brute_force
1220 <
1221     Ring1, Ring2, Strategy,
1222     ring_tag, ring_tag, false
1223 >
1224 {
1225     typedef typename distance_result
1226         <
1227             Ring1, Ring2, Strategy
1228         >::type distance_type;
1229 
applyboost::geometry::unit_test::dispatch::distance_brute_force1230     static inline distance_type apply(Ring1 const& ring1,
1231                                       Ring2 const& ring2,
1232                                       Strategy const& strategy)
1233     {
1234         return detail::distance_brute_force::one_to_many
1235             <
1236                 distance_brute_force
1237                     <
1238                         Ring1,
1239                         typename std::iterator_traits
1240                             <
1241                                 segment_iterator<Ring2 const>
1242                             >::value_type,
1243                         Strategy
1244                     >
1245             >::apply(ring1,
1246                      geometry::segments_begin(ring2),
1247                      geometry::segments_end(ring2),
1248                      strategy);
1249     }
1250 };
1251 
1252 //========================================================================
1253 
1254 template
1255 <
1256     typename Segment1,
1257     typename Segment2,
1258     typename Strategy
1259 >
1260 struct distance_brute_force
1261 <
1262     Segment1, Segment2, Strategy,
1263     segment_tag, segment_tag, false
1264 > : detail::distance_brute_force::distance_from_bg
1265 {};
1266 
1267 template
1268 <
1269     typename Segment,
1270     typename Ring,
1271     typename Strategy
1272 >
1273 struct distance_brute_force
1274 <
1275     Segment, Ring, Strategy,
1276     segment_tag, ring_tag, false
1277 >
1278 {
1279     typedef typename distance_result
1280         <
1281             Segment, Ring, Strategy
1282         >::type distance_type;
1283 
applyboost::geometry::unit_test::dispatch::distance_brute_force1284     static inline distance_type apply(Segment const& segment,
1285                                       Ring const& ring,
1286                                       Strategy const& strategy)
1287     {
1288         return detail::distance_brute_force::one_to_many
1289             <
1290                 distance_brute_force
1291                     <
1292                         Segment,
1293                         typename std::iterator_traits
1294                             <
1295                                 segment_iterator<Ring const>
1296                             >::value_type,
1297                         Strategy
1298                     >
1299             >::apply(segment,
1300                      geometry::segments_begin(ring),
1301                      geometry::segments_end(ring),
1302                      strategy);
1303     }
1304 };
1305 
1306 template
1307 <
1308     typename Segment,
1309     typename Box,
1310     typename Strategy
1311 >
1312 struct distance_brute_force
1313 <
1314     Segment, Box, Strategy,
1315     segment_tag, box_tag, false
1316 > : detail::distance_brute_force::distance_from_bg
1317 {};
1318 
1319 //====================================================================
1320 
1321 template
1322 <
1323     typename Box1,
1324     typename Box2,
1325     typename Strategy
1326 >
1327 struct distance_brute_force
1328 <
1329     Box1, Box2, Strategy,
1330     box_tag, box_tag, false
1331 > : detail::distance_brute_force::distance_from_bg
1332 {};
1333 
1334 } // namespace dispatch
1335 
1336 
1337 
1338 
1339 
1340 template <typename Geometry1, typename Geometry2, typename Strategy>
1341 inline typename distance_result<Geometry1, Geometry2, Strategy>::type
distance_brute_force(Geometry1 const & geometry1,Geometry2 const & geometry2,Strategy const & strategy)1342 distance_brute_force(Geometry1 const& geometry1,
1343                      Geometry2 const& geometry2,
1344                      Strategy const& strategy)
1345 {
1346     return dispatch::distance_brute_force
1347         <
1348             Geometry1, Geometry2, Strategy
1349         >::apply(geometry1, geometry2, strategy);
1350 }
1351 
1352 } // namespace unit_test
1353 
1354 
1355 }} // namespace boost::geometry
1356 #endif // BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
1357