]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/distance/distance_brute_force.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / distance / distance_brute_force.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2014, Oracle and/or its affiliates.
5
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
10
11 #ifndef BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
12 #define BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
13
14 #include <iterator>
15
16 #include <boost/mpl/assert.hpp>
17 #include <boost/mpl/or.hpp>
18 #include <boost/range.hpp>
19
20 #include <boost/geometry/core/reverse_dispatch.hpp>
21 #include <boost/geometry/core/tag.hpp>
22 #include <boost/geometry/core/tag_cast.hpp>
23 #include <boost/geometry/core/tags.hpp>
24
25 #include <boost/geometry/iterators/segment_iterator.hpp>
26
27 #include <boost/geometry/algorithms/distance.hpp>
28 #include <boost/geometry/algorithms/intersects.hpp>
29 #include <boost/geometry/algorithms/not_implemented.hpp>
30
31
32 namespace boost { namespace geometry
33 {
34
35 namespace unit_test
36 {
37
38 namespace detail { namespace distance_brute_force
39 {
40
41 struct distance_from_bg
42 {
43 template <typename G>
44 struct use_distance_from_bg
45 {
46 typedef typename boost::mpl::or_
47 <
48 boost::is_same<typename tag<G>::type, point_tag>,
49 typename boost::mpl::or_
50 <
51 boost::is_same<typename tag<G>::type, segment_tag>,
52 boost::is_same<typename tag<G>::type, box_tag>
53 >::type
54 >::type type;
55 };
56
57 template <typename Geometry1, typename Geometry2, typename Strategy>
58 static inline
59 typename distance_result<Geometry1, Geometry2, Strategy>::type
60 apply(Geometry1 const& geometry1,
61 Geometry2 const& geometry2,
62 Strategy const& strategy)
63 {
64 BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry1>::type));
65 BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry2>::type));
66
67 return geometry::distance(geometry1, geometry2, strategy);
68 }
69 };
70
71
72 template <typename Geometry1, typename Geometry2, typename Strategy>
73 inline
74 typename distance_result<Geometry1, Geometry2, Strategy>::type
75 bg_distance(Geometry1 const& geometry1,
76 Geometry2 const& geometry2,
77 Strategy const& strategy)
78 {
79 return distance_from_bg::apply(geometry1, geometry2, strategy);
80 }
81
82
83 template <typename Policy>
84 struct one_to_many
85 {
86 template <typename Geometry, typename Iterator, typename Strategy>
87 static inline typename distance_result
88 <
89 Geometry,
90 typename std::iterator_traits<Iterator>::value_type,
91 Strategy
92 >::type
93 apply(Geometry const& geometry, Iterator begin, Iterator end,
94 Strategy const& strategy)
95 {
96 typedef typename distance_result
97 <
98 Geometry,
99 typename std::iterator_traits<Iterator>::value_type,
100 Strategy
101 >::type distance_type;
102
103 bool first = true;
104 distance_type d_min(0);
105 for (Iterator it = begin; it != end; ++it, first = false)
106 {
107 distance_type d = Policy::apply(geometry, *it, strategy);
108
109 if ( first || d < d_min )
110 {
111 d_min = d;
112 }
113 }
114 return d_min;
115 }
116 };
117
118
119
120 }} // namespace detail::distance_brute_force
121
122
123 namespace dispatch
124 {
125
126 template
127 <
128 typename Geometry1,
129 typename Geometry2,
130 typename Strategy,
131 typename Tag1 = typename tag_cast
132 <
133 typename tag<Geometry1>::type,
134 segment_tag,
135 linear_tag
136 >::type,
137 typename Tag2 = typename tag_cast
138 <
139 typename tag<Geometry2>::type,
140 segment_tag,
141 linear_tag
142 >::type,
143 bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
144 >
145 struct distance_brute_force
146 : not_implemented<Geometry1, Geometry2>
147 {};
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
161 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 template
174 <
175 typename Point1,
176 typename Point2,
177 typename Strategy
178 >
179 struct distance_brute_force
180 <
181 Point1, Point2, Strategy,
182 point_tag, point_tag, false
183 > : detail::distance_brute_force::distance_from_bg
184 {};
185
186
187 template
188 <
189 typename Point,
190 typename Segment,
191 typename Strategy
192 >
193 struct distance_brute_force
194 <
195 Point, Segment, Strategy,
196 point_tag, segment_tag, false
197 > : detail::distance_brute_force::distance_from_bg
198 {};
199
200
201 template
202 <
203 typename Point,
204 typename Box,
205 typename Strategy
206 >
207 struct distance_brute_force
208 <
209 Point, Box, Strategy,
210 point_tag, box_tag, false
211 > : detail::distance_brute_force::distance_from_bg
212 {};
213
214 template
215 <
216 typename Box1,
217 typename Box2,
218 typename Strategy
219 >
220 struct distance_brute_force
221 <
222 Box1, Box2, Strategy,
223 box_tag, box_tag, false
224 > : detail::distance_brute_force::distance_from_bg
225 {};
226
227
228 template
229 <
230 typename Segment1,
231 typename Segment2,
232 typename Strategy
233 >
234 struct distance_brute_force
235 <
236 Segment1, Segment2, Strategy,
237 segment_tag, segment_tag, false
238 > : detail::distance_brute_force::distance_from_bg
239 {};
240
241
242 template
243 <
244 typename Point,
245 typename Linear,
246 typename Strategy
247 >
248 struct distance_brute_force
249 <
250 Point, Linear, Strategy,
251 point_tag, linear_tag, false
252 >
253 {
254 typedef typename distance_result
255 <
256 Point, Linear, Strategy
257 >::type distance_type;
258
259 static inline distance_type apply(Point const& point,
260 Linear const& linear,
261 Strategy const& strategy)
262 {
263 return detail::distance_brute_force::one_to_many
264 <
265 detail::distance_brute_force::distance_from_bg
266 >::apply(point,
267 geometry::segments_begin(linear),
268 geometry::segments_end(linear),
269 strategy);
270 }
271 };
272
273
274 template
275 <
276 typename Point,
277 typename MultiPoint,
278 typename Strategy
279 >
280 struct distance_brute_force
281 <
282 Point, MultiPoint, Strategy,
283 point_tag, multi_point_tag, false
284 >
285 {
286 typedef typename distance_result
287 <
288 Point, MultiPoint, Strategy
289 >::type distance_type;
290
291 static inline distance_type apply(Point const& p,
292 MultiPoint const& mp,
293 Strategy const& strategy)
294 {
295 return detail::distance_brute_force::one_to_many
296 <
297 detail::distance_brute_force::distance_from_bg
298 >::apply(p, boost::begin(mp), boost::end(mp), strategy);
299 }
300 };
301
302 template
303 <
304 typename MultiPoint1,
305 typename MultiPoint2,
306 typename Strategy
307 >
308 struct distance_brute_force
309 <
310 MultiPoint1, MultiPoint2, Strategy,
311 multi_point_tag, multi_point_tag, false
312 >
313 {
314 typedef typename distance_result
315 <
316 MultiPoint1, MultiPoint2, Strategy
317 >::type distance_type;
318
319 static inline distance_type apply(MultiPoint1 const& mp1,
320 MultiPoint2 const& mp2,
321 Strategy const& strategy)
322 {
323 return detail::distance_brute_force::one_to_many
324 <
325 distance_brute_force
326 <
327 MultiPoint1,
328 typename boost::range_value<MultiPoint2>::type,
329 Strategy
330 >
331 >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
332 }
333 };
334
335
336 template
337 <
338 typename MultiPoint,
339 typename Linear,
340 typename Strategy
341 >
342 struct distance_brute_force
343 <
344 MultiPoint, Linear, Strategy,
345 multi_point_tag, linear_tag, false
346 >
347 {
348 typedef typename distance_result
349 <
350 MultiPoint, Linear, Strategy
351 >::type distance_type;
352
353 static inline distance_type apply(MultiPoint const& mp,
354 Linear const& linear,
355 Strategy const& strategy)
356 {
357 return detail::distance_brute_force::one_to_many
358 <
359 distance_brute_force
360 <
361 Linear,
362 typename boost::range_value<MultiPoint>::type,
363 Strategy
364 >
365 >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
366 }
367 };
368
369
370 template
371 <
372 typename Linear,
373 typename MultiPoint,
374 typename Strategy
375 >
376 struct distance_brute_force
377 <
378 Linear, MultiPoint, Strategy,
379 linear_tag, multi_point_tag, false
380 >
381 {
382 typedef typename distance_result
383 <
384 Linear, MultiPoint, Strategy
385 >::type distance_type;
386
387 static inline distance_type apply(Linear const& linear,
388 MultiPoint const& multipoint,
389 Strategy const& strategy)
390 {
391 return distance_brute_force
392 <
393 MultiPoint, Linear, Strategy,
394 multi_point_tag, linear_tag, false
395 >::apply(multipoint, linear, strategy);
396 }
397 };
398
399
400 template
401 <
402 typename MultiPoint,
403 typename Segment,
404 typename Strategy
405 >
406 struct distance_brute_force
407 <
408 MultiPoint, Segment, Strategy,
409 multi_point_tag, segment_tag, false
410 >
411 {
412 typedef typename distance_result
413 <
414 MultiPoint, Segment, Strategy
415 >::type distance_type;
416
417 static inline distance_type apply(MultiPoint const& mp,
418 Segment const& segment,
419 Strategy const& strategy)
420 {
421 return detail::distance_brute_force::one_to_many
422 <
423 detail::distance_brute_force::distance_from_bg
424 >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
425 }
426 };
427
428 template
429 <
430 typename MultiPoint,
431 typename Box,
432 typename Strategy
433 >
434 struct distance_brute_force
435 <
436 MultiPoint, Box, Strategy,
437 multi_point_tag, box_tag, false
438 >
439 {
440 typedef typename distance_result
441 <
442 MultiPoint, Box, Strategy
443 >::type distance_type;
444
445 static inline distance_type apply(MultiPoint const& mp,
446 Box const& box,
447 Strategy const& strategy)
448 {
449 return detail::distance_brute_force::one_to_many
450 <
451 distance_brute_force
452 <
453 Box,
454 typename boost::range_value<MultiPoint>::type,
455 Strategy
456 >
457 >::apply(box, boost::begin(mp), boost::end(mp), strategy);
458 }
459 };
460
461
462 template
463 <
464 typename Linear,
465 typename Segment,
466 typename Strategy
467 >
468 struct distance_brute_force
469 <
470 Linear, Segment, Strategy,
471 linear_tag, segment_tag, false
472 >
473 {
474 typedef typename distance_result
475 <
476 Linear, Segment, Strategy
477 >::type distance_type;
478
479 static inline distance_type apply(Linear const& linear,
480 Segment const& segment,
481 Strategy const& strategy)
482 {
483 return detail::distance_brute_force::one_to_many
484 <
485 detail::distance_brute_force::distance_from_bg
486 >::apply(segment,
487 geometry::segments_begin(linear),
488 geometry::segments_end(linear),
489 strategy);
490 }
491 };
492
493
494 template
495 <
496 typename Linear1,
497 typename Linear2,
498 typename Strategy
499 >
500 struct distance_brute_force
501 <
502 Linear1, Linear2, Strategy,
503 linear_tag, linear_tag, false
504 >
505 {
506 typedef typename distance_result
507 <
508 Linear1, Linear2, Strategy
509 >::type distance_type;
510
511 static inline distance_type apply(Linear1 const& linear1,
512 Linear2 const& linear2,
513 Strategy const& strategy)
514 {
515 return detail::distance_brute_force::one_to_many
516 <
517 distance_brute_force
518 <
519 Linear1,
520 typename std::iterator_traits
521 <
522 segment_iterator<Linear2 const>
523 >::value_type,
524 Strategy
525 >
526 >::apply(linear1,
527 geometry::segments_begin(linear2),
528 geometry::segments_end(linear2),
529 strategy);
530 }
531 };
532
533 } // namespace dispatch
534
535
536
537
538
539 template <typename Geometry1, typename Geometry2, typename Strategy>
540 inline typename distance_result<Geometry1, Geometry2, Strategy>::type
541 distance_brute_force(Geometry1 const& geometry1,
542 Geometry2 const& geometry2,
543 Strategy const& strategy)
544 {
545 return dispatch::distance_brute_force
546 <
547 Geometry1, Geometry2, Strategy
548 >::apply(geometry1, geometry2, strategy);
549 }
550
551 } // namespace unit_test
552
553
554 }} // namespace boost::geometry
555
556 #endif // BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP