]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/detail/comparable_distance/interface.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / comparable_distance / interface.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
6
7 // This file was modified by Oracle on 2014-2021.
8 // Modifications copyright (c) 2014-2021, Oracle and/or its affiliates.
9
10 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12
13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
15
16 // Use, modification and distribution is subject to the Boost Software License,
17 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
19
20 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP
21 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP
22
23
24 #include <boost/geometry/algorithms/detail/distance/interface.hpp>
25
26 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
27 #include <boost/geometry/geometries/concepts/check.hpp>
28
29 #include <boost/geometry/strategies/comparable_distance_result.hpp>
30 #include <boost/geometry/strategies/default_comparable_distance_result.hpp>
31 #include <boost/geometry/strategies/distance.hpp>
32
33 #include <boost/geometry/strategies/distance/comparable.hpp>
34 #include <boost/geometry/strategies/distance/services.hpp>
35
36
37 namespace boost { namespace geometry
38 {
39
40
41 namespace resolve_strategy
42 {
43
44
45 template
46 <
47 typename Strategies,
48 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategies>::value
49 >
50 struct comparable_distance
51 {
52 template <typename Geometry1, typename Geometry2>
53 static inline
54 typename comparable_distance_result<Geometry1, Geometry2, Strategies>::type
55 apply(Geometry1 const& geometry1,
56 Geometry2 const& geometry2,
57 Strategies const& strategies)
58 {
59 return dispatch::distance
60 <
61 Geometry1, Geometry2,
62 strategies::distance::detail::comparable<Strategies>
63 >::apply(geometry1,
64 geometry2,
65 strategies::distance::detail::comparable<Strategies>(strategies));
66 }
67 };
68
69 template <typename Strategy>
70 struct comparable_distance<Strategy, false>
71 {
72 template <typename Geometry1, typename Geometry2>
73 static inline
74 typename comparable_distance_result<Geometry1, Geometry2, Strategy>::type
75 apply(Geometry1 const& geometry1,
76 Geometry2 const& geometry2,
77 Strategy const& strategy)
78 {
79 using strategies::distance::services::strategy_converter;
80
81 typedef decltype(strategy_converter<Strategy>::get(strategy))
82 strategies_type;
83 typedef strategies::distance::detail::comparable
84 <
85 strategies_type
86 > comparable_strategies_type;
87
88 return dispatch::distance
89 <
90 Geometry1, Geometry2,
91 comparable_strategies_type
92 >::apply(geometry1,
93 geometry2,
94 comparable_strategies_type(
95 strategy_converter<Strategy>::get(strategy)));
96 }
97 };
98
99 template <>
100 struct comparable_distance<default_strategy, false>
101 {
102 template <typename Geometry1, typename Geometry2>
103 static inline typename comparable_distance_result
104 <
105 Geometry1, Geometry2, default_strategy
106 >::type
107 apply(Geometry1 const& geometry1,
108 Geometry2 const& geometry2,
109 default_strategy)
110 {
111 typedef strategies::distance::detail::comparable
112 <
113 typename strategies::distance::services::default_strategy
114 <
115 Geometry1, Geometry2
116 >::type
117 > comparable_strategy_type;
118
119 return dispatch::distance
120 <
121 Geometry1, Geometry2, comparable_strategy_type
122 >::apply(geometry1, geometry2, comparable_strategy_type());
123 }
124 };
125
126 } // namespace resolve_strategy
127
128
129 namespace resolve_variant
130 {
131
132
133 template <typename Geometry1, typename Geometry2>
134 struct comparable_distance
135 {
136 template <typename Strategy>
137 static inline
138 typename comparable_distance_result<Geometry1, Geometry2, Strategy>::type
139 apply(Geometry1 const& geometry1,
140 Geometry2 const& geometry2,
141 Strategy const& strategy)
142 {
143 return resolve_strategy::comparable_distance
144 <
145 Strategy
146 >::apply(geometry1, geometry2, strategy);
147 }
148 };
149
150
151 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
152 struct comparable_distance
153 <
154 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
155 Geometry2
156 >
157 {
158 template <typename Strategy>
159 struct visitor: static_visitor
160 <
161 typename comparable_distance_result
162 <
163 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
164 Geometry2,
165 Strategy
166 >::type
167 >
168 {
169 Geometry2 const& m_geometry2;
170 Strategy const& m_strategy;
171
172 visitor(Geometry2 const& geometry2,
173 Strategy const& strategy)
174 : m_geometry2(geometry2),
175 m_strategy(strategy)
176 {}
177
178 template <typename Geometry1>
179 typename comparable_distance_result
180 <
181 Geometry1, Geometry2, Strategy
182 >::type
183 operator()(Geometry1 const& geometry1) const
184 {
185 return comparable_distance
186 <
187 Geometry1,
188 Geometry2
189 >::template apply
190 <
191 Strategy
192 >(geometry1, m_geometry2, m_strategy);
193 }
194 };
195
196 template <typename Strategy>
197 static inline typename comparable_distance_result
198 <
199 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
200 Geometry2,
201 Strategy
202 >::type
203 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
204 Geometry2 const& geometry2,
205 Strategy const& strategy)
206 {
207 return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
208 }
209 };
210
211
212 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
213 struct comparable_distance
214 <
215 Geometry1,
216 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>
217 >
218 {
219 template <typename Strategy>
220 struct visitor: static_visitor
221 <
222 typename comparable_distance_result
223 <
224 Geometry1,
225 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
226 Strategy
227 >::type
228 >
229 {
230 Geometry1 const& m_geometry1;
231 Strategy const& m_strategy;
232
233 visitor(Geometry1 const& geometry1,
234 Strategy const& strategy)
235 : m_geometry1(geometry1),
236 m_strategy(strategy)
237 {}
238
239 template <typename Geometry2>
240 typename comparable_distance_result
241 <
242 Geometry1, Geometry2, Strategy
243 >::type
244 operator()(Geometry2 const& geometry2) const
245 {
246 return comparable_distance
247 <
248 Geometry1,
249 Geometry2
250 >::template apply
251 <
252 Strategy
253 >(m_geometry1, geometry2, m_strategy);
254 }
255 };
256
257 template <typename Strategy>
258 static inline typename comparable_distance_result
259 <
260 Geometry1,
261 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>,
262 Strategy
263 >::type
264 apply(Geometry1 const& geometry1,
265 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
266 Strategy const& strategy)
267 {
268 return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
269 }
270 };
271
272
273 template
274 <
275 BOOST_VARIANT_ENUM_PARAMS(typename T1),
276 BOOST_VARIANT_ENUM_PARAMS(typename T2)
277 >
278 struct comparable_distance
279 <
280 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
281 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
282 >
283 {
284 template <typename Strategy>
285 struct visitor: static_visitor
286 <
287 typename comparable_distance_result
288 <
289 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
290 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
291 Strategy
292 >::type
293 >
294 {
295 Strategy const& m_strategy;
296
297 visitor(Strategy const& strategy)
298 : m_strategy(strategy)
299 {}
300
301 template <typename Geometry1, typename Geometry2>
302 typename comparable_distance_result
303 <
304 Geometry1, Geometry2, Strategy
305 >::type
306 operator()(Geometry1 const& geometry1, Geometry2 const& geometry2) const
307 {
308 return comparable_distance
309 <
310 Geometry1,
311 Geometry2
312 >::template apply
313 <
314 Strategy
315 >(geometry1, geometry2, m_strategy);
316 }
317 };
318
319 template <typename Strategy>
320 static inline typename comparable_distance_result
321 <
322 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
323 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>,
324 Strategy
325 >::type
326 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
327 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
328 Strategy const& strategy)
329 {
330 return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
331 }
332 };
333
334 } // namespace resolve_variant
335
336
337
338 /*!
339 \brief \brief_calc2{comparable distance measurement} \brief_strategy
340 \ingroup distance
341 \details The free function comparable_distance does not necessarily calculate the distance,
342 but it calculates a distance measure such that two distances are comparable to each other.
343 For example: for the Cartesian coordinate system, Pythagoras is used but the square root
344 is not taken, which makes it faster and the results of two point pairs can still be
345 compared to each other.
346 \tparam Geometry1 first geometry type
347 \tparam Geometry2 second geometry type
348 \tparam Strategy \tparam_strategy{Distance}
349 \param geometry1 \param_geometry
350 \param geometry2 \param_geometry
351 \param strategy \param_strategy{distance}
352 \return \return_calc{comparable distance}
353
354 \qbk{distinguish,with strategy}
355 */
356 template <typename Geometry1, typename Geometry2, typename Strategy>
357 inline typename comparable_distance_result<Geometry1, Geometry2, Strategy>::type
358 comparable_distance(Geometry1 const& geometry1, Geometry2 const& geometry2,
359 Strategy const& strategy)
360 {
361 concepts::check<Geometry1 const>();
362 concepts::check<Geometry2 const>();
363
364 return resolve_variant::comparable_distance
365 <
366 Geometry1,
367 Geometry2
368 >::apply(geometry1, geometry2, strategy);
369 }
370
371
372
373 /*!
374 \brief \brief_calc2{comparable distance measurement}
375 \ingroup distance
376 \details The free function comparable_distance does not necessarily calculate the distance,
377 but it calculates a distance measure such that two distances are comparable to each other.
378 For example: for the Cartesian coordinate system, Pythagoras is used but the square root
379 is not taken, which makes it faster and the results of two point pairs can still be
380 compared to each other.
381 \tparam Geometry1 first geometry type
382 \tparam Geometry2 second geometry type
383 \param geometry1 \param_geometry
384 \param geometry2 \param_geometry
385 \return \return_calc{comparable distance}
386
387 \qbk{[include reference/algorithms/comparable_distance.qbk]}
388 */
389 template <typename Geometry1, typename Geometry2>
390 inline typename default_comparable_distance_result<Geometry1, Geometry2>::type
391 comparable_distance(Geometry1 const& geometry1, Geometry2 const& geometry2)
392 {
393 concepts::check<Geometry1 const>();
394 concepts::check<Geometry2 const>();
395
396 return geometry::comparable_distance(geometry1, geometry2, default_strategy());
397 }
398
399
400 }} // namespace boost::geometry
401
402
403 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COMPARABLE_DISTANCE_INTERFACE_HPP