]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/distance/distance_brute_force.hpp
add subtree-ish sources for 12.0.3
[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
215 template
216 <
217 typename Segment1,
218 typename Segment2,
219 typename Strategy
220 >
221 struct distance_brute_force
222 <
223 Segment1, Segment2, Strategy,
224 segment_tag, segment_tag, false
225 > : detail::distance_brute_force::distance_from_bg
226 {};
227
228
229 template
230 <
231 typename Point,
232 typename Linear,
233 typename Strategy
234 >
235 struct distance_brute_force
236 <
237 Point, Linear, Strategy,
238 point_tag, linear_tag, false
239 >
240 {
241 typedef typename distance_result
242 <
243 Point, Linear, Strategy
244 >::type distance_type;
245
246 static inline distance_type apply(Point const& point,
247 Linear const& linear,
248 Strategy const& strategy)
249 {
250 return detail::distance_brute_force::one_to_many
251 <
252 detail::distance_brute_force::distance_from_bg
253 >::apply(point,
254 geometry::segments_begin(linear),
255 geometry::segments_end(linear),
256 strategy);
257 }
258 };
259
260
261 template
262 <
263 typename Point,
264 typename MultiPoint,
265 typename Strategy
266 >
267 struct distance_brute_force
268 <
269 Point, MultiPoint, Strategy,
270 point_tag, multi_point_tag, false
271 >
272 {
273 typedef typename distance_result
274 <
275 Point, MultiPoint, Strategy
276 >::type distance_type;
277
278 static inline distance_type apply(Point const& p,
279 MultiPoint const& mp,
280 Strategy const& strategy)
281 {
282 return detail::distance_brute_force::one_to_many
283 <
284 detail::distance_brute_force::distance_from_bg
285 >::apply(p, boost::begin(mp), boost::end(mp), strategy);
286 }
287 };
288
289 template
290 <
291 typename MultiPoint1,
292 typename MultiPoint2,
293 typename Strategy
294 >
295 struct distance_brute_force
296 <
297 MultiPoint1, MultiPoint2, Strategy,
298 multi_point_tag, multi_point_tag, false
299 >
300 {
301 typedef typename distance_result
302 <
303 MultiPoint1, MultiPoint2, Strategy
304 >::type distance_type;
305
306 static inline distance_type apply(MultiPoint1 const& mp1,
307 MultiPoint2 const& mp2,
308 Strategy const& strategy)
309 {
310 return detail::distance_brute_force::one_to_many
311 <
312 distance_brute_force
313 <
314 MultiPoint1,
315 typename boost::range_value<MultiPoint2>::type,
316 Strategy
317 >
318 >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
319 }
320 };
321
322
323 template
324 <
325 typename MultiPoint,
326 typename Linear,
327 typename Strategy
328 >
329 struct distance_brute_force
330 <
331 MultiPoint, Linear, Strategy,
332 multi_point_tag, linear_tag, false
333 >
334 {
335 typedef typename distance_result
336 <
337 MultiPoint, Linear, Strategy
338 >::type distance_type;
339
340 static inline distance_type apply(MultiPoint const& mp,
341 Linear const& linear,
342 Strategy const& strategy)
343 {
344 return detail::distance_brute_force::one_to_many
345 <
346 distance_brute_force
347 <
348 Linear,
349 typename boost::range_value<MultiPoint>::type,
350 Strategy
351 >
352 >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
353 }
354 };
355
356
357 template
358 <
359 typename Linear,
360 typename MultiPoint,
361 typename Strategy
362 >
363 struct distance_brute_force
364 <
365 Linear, MultiPoint, Strategy,
366 linear_tag, multi_point_tag, false
367 >
368 {
369 typedef typename distance_result
370 <
371 Linear, MultiPoint, Strategy
372 >::type distance_type;
373
374 static inline distance_type apply(Linear const& linear,
375 MultiPoint const& multipoint,
376 Strategy const& strategy)
377 {
378 return distance_brute_force
379 <
380 MultiPoint, Linear, Strategy,
381 multi_point_tag, linear_tag, false
382 >::apply(multipoint, linear, strategy);
383 }
384 };
385
386
387 template
388 <
389 typename MultiPoint,
390 typename Segment,
391 typename Strategy
392 >
393 struct distance_brute_force
394 <
395 MultiPoint, Segment, Strategy,
396 multi_point_tag, segment_tag, false
397 >
398 {
399 typedef typename distance_result
400 <
401 MultiPoint, Segment, Strategy
402 >::type distance_type;
403
404 static inline distance_type apply(MultiPoint const& mp,
405 Segment const& segment,
406 Strategy const& strategy)
407 {
408 return detail::distance_brute_force::one_to_many
409 <
410 detail::distance_brute_force::distance_from_bg
411 >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
412 }
413 };
414
415
416 template
417 <
418 typename Linear,
419 typename Segment,
420 typename Strategy
421 >
422 struct distance_brute_force
423 <
424 Linear, Segment, Strategy,
425 linear_tag, segment_tag, false
426 >
427 {
428 typedef typename distance_result
429 <
430 Linear, Segment, Strategy
431 >::type distance_type;
432
433 static inline distance_type apply(Linear const& linear,
434 Segment const& segment,
435 Strategy const& strategy)
436 {
437 return detail::distance_brute_force::one_to_many
438 <
439 detail::distance_brute_force::distance_from_bg
440 >::apply(segment,
441 geometry::segments_begin(linear),
442 geometry::segments_end(linear),
443 strategy);
444 }
445 };
446
447
448 template
449 <
450 typename Linear1,
451 typename Linear2,
452 typename Strategy
453 >
454 struct distance_brute_force
455 <
456 Linear1, Linear2, Strategy,
457 linear_tag, linear_tag, false
458 >
459 {
460 typedef typename distance_result
461 <
462 Linear1, Linear2, Strategy
463 >::type distance_type;
464
465 static inline distance_type apply(Linear1 const& linear1,
466 Linear2 const& linear2,
467 Strategy const& strategy)
468 {
469 return detail::distance_brute_force::one_to_many
470 <
471 distance_brute_force
472 <
473 Linear1,
474 typename std::iterator_traits
475 <
476 segment_iterator<Linear2 const>
477 >::value_type,
478 Strategy
479 >
480 >::apply(linear1,
481 geometry::segments_begin(linear2),
482 geometry::segments_end(linear2),
483 strategy);
484 }
485 };
486
487 } // namespace dispatch
488
489
490
491
492
493 template <typename Geometry1, typename Geometry2, typename Strategy>
494 inline typename distance_result<Geometry1, Geometry2, Strategy>::type
495 distance_brute_force(Geometry1 const& geometry1,
496 Geometry2 const& geometry2,
497 Strategy const& strategy)
498 {
499 return dispatch::distance_brute_force
500 <
501 Geometry1, Geometry2, Strategy
502 >::apply(geometry1, geometry2, strategy);
503 }
504
505 } // namespace unit_test
506
507
508 }} // namespace boost::geometry
509
510 #endif // BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP