]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/strategies/cartesian/distance_pythagoras.hpp
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / boost / boost / geometry / strategies / cartesian / distance_pythagoras.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
4 // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6
7 // This file was modified by Oracle on 2018.
8 // Modifications copyright (c) 2018, Oracle and/or its affiliates.
9
10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
11
12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
14
15 // Use, modification and distribution is subject to the Boost Software License,
16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17 // http://www.boost.org/LICENSE_1_0.txt)
18
19 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
20 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
21
22
23 #include <boost/geometry/core/access.hpp>
24
25 #include <boost/geometry/geometries/concepts/point_concept.hpp>
26
27 #include <boost/geometry/strategies/distance.hpp>
28
29 #include <boost/geometry/util/math.hpp>
30 #include <boost/geometry/util/calculation_type.hpp>
31
32
33 namespace boost { namespace geometry
34 {
35
36 namespace strategy { namespace distance
37 {
38
39 #ifndef DOXYGEN_NO_DETAIL
40 namespace detail
41 {
42
43 template <size_t I, typename T>
44 struct compute_pythagoras
45 {
46 template <typename Point1, typename Point2>
47 static inline T apply(Point1 const& p1, Point2 const& p2)
48 {
49 T const c1 = boost::numeric_cast<T>(get<I-1>(p1));
50 T const c2 = boost::numeric_cast<T>(get<I-1>(p2));
51 T const d = c1 - c2;
52 return d * d + compute_pythagoras<I-1, T>::apply(p1, p2);
53 }
54 };
55
56 template <typename T>
57 struct compute_pythagoras<0, T>
58 {
59 template <typename Point1, typename Point2>
60 static inline T apply(Point1 const&, Point2 const&)
61 {
62 return boost::numeric_cast<T>(0);
63 }
64 };
65
66 }
67 #endif // DOXYGEN_NO_DETAIL
68
69
70 namespace comparable
71 {
72
73 /*!
74 \brief Strategy to calculate comparable distance between two points
75 \ingroup strategies
76 \tparam Point1 \tparam_first_point
77 \tparam Point2 \tparam_second_point
78 \tparam CalculationType \tparam_calculation
79 */
80 template <typename CalculationType = void>
81 class pythagoras
82 {
83 public :
84
85 template <typename Point1, typename Point2>
86 struct calculation_type
87 : util::calculation_type::geometric::binary
88 <
89 Point1,
90 Point2,
91 CalculationType,
92 double,
93 double
94 >
95 {};
96
97 template <typename Point1, typename Point2>
98 static inline typename calculation_type<Point1, Point2>::type
99 apply(Point1 const& p1, Point2 const& p2)
100 {
101 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point1>) );
102 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
103
104 // Calculate distance using Pythagoras
105 // (Leave comment above for Doxygen)
106
107 assert_dimension_equal<Point1, Point2>();
108
109 return detail::compute_pythagoras
110 <
111 dimension<Point1>::value,
112 typename calculation_type<Point1, Point2>::type
113 >::apply(p1, p2);
114 }
115 };
116
117 } // namespace comparable
118
119
120 /*!
121 \brief Strategy to calculate the distance between two points
122 \ingroup strategies
123 \tparam CalculationType \tparam_calculation
124
125 \qbk{
126 [heading Notes]
127 [note Can be used for points with two\, three or more dimensions]
128 [heading See also]
129 [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
130 }
131
132 */
133 template
134 <
135 typename CalculationType = void
136 >
137 class pythagoras
138 {
139 public :
140
141 template <typename P1, typename P2>
142 struct calculation_type
143 : util::calculation_type::geometric::binary
144 <
145 P1,
146 P2,
147 CalculationType,
148 double,
149 double // promote integer to double
150 >
151 {};
152
153 /*!
154 \brief applies the distance calculation using pythagoras
155 \return the calculated distance (including taking the square root)
156 \param p1 first point
157 \param p2 second point
158 */
159 template <typename P1, typename P2>
160 static inline typename calculation_type<P1, P2>::type
161 apply(P1 const& p1, P2 const& p2)
162 {
163 // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call
164 return math::sqrt
165 (
166 boost::numeric_cast<typename calculation_type<P1, P2>::type>
167 (
168 comparable::pythagoras<CalculationType>::apply(p1, p2)
169 )
170 );
171 }
172 };
173
174
175 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
176 namespace services
177 {
178
179 template <typename CalculationType>
180 struct tag<pythagoras<CalculationType> >
181 {
182 typedef strategy_tag_distance_point_point type;
183 };
184
185
186 template <typename CalculationType, typename P1, typename P2>
187 struct return_type<distance::pythagoras<CalculationType>, P1, P2>
188 : pythagoras<CalculationType>::template calculation_type<P1, P2>
189 {};
190
191
192 template <typename CalculationType>
193 struct comparable_type<pythagoras<CalculationType> >
194 {
195 typedef comparable::pythagoras<CalculationType> type;
196 };
197
198
199 template <typename CalculationType>
200 struct get_comparable<pythagoras<CalculationType> >
201 {
202 typedef comparable::pythagoras<CalculationType> comparable_type;
203 public :
204 static inline comparable_type apply(pythagoras<CalculationType> const& )
205 {
206 return comparable_type();
207 }
208 };
209
210
211 template <typename CalculationType, typename Point1, typename Point2>
212 struct result_from_distance<pythagoras<CalculationType>, Point1, Point2>
213 {
214 private :
215 typedef typename return_type<pythagoras<CalculationType>, Point1, Point2>::type return_type;
216 public :
217 template <typename T>
218 static inline return_type apply(pythagoras<CalculationType> const& , T const& value)
219 {
220 return return_type(value);
221 }
222 };
223
224
225 // Specializations for comparable::pythagoras
226 template <typename CalculationType>
227 struct tag<comparable::pythagoras<CalculationType> >
228 {
229 typedef strategy_tag_distance_point_point type;
230 };
231
232
233 template <typename CalculationType, typename P1, typename P2>
234 struct return_type<comparable::pythagoras<CalculationType>, P1, P2>
235 : comparable::pythagoras<CalculationType>::template calculation_type<P1, P2>
236 {};
237
238
239
240
241 template <typename CalculationType>
242 struct comparable_type<comparable::pythagoras<CalculationType> >
243 {
244 typedef comparable::pythagoras<CalculationType> type;
245 };
246
247
248 template <typename CalculationType>
249 struct get_comparable<comparable::pythagoras<CalculationType> >
250 {
251 typedef comparable::pythagoras<CalculationType> comparable_type;
252 public :
253 static inline comparable_type apply(comparable::pythagoras<CalculationType> const& )
254 {
255 return comparable_type();
256 }
257 };
258
259
260 template <typename CalculationType, typename Point1, typename Point2>
261 struct result_from_distance<comparable::pythagoras<CalculationType>, Point1, Point2>
262 {
263 private :
264 typedef typename return_type<comparable::pythagoras<CalculationType>, Point1, Point2>::type return_type;
265 public :
266 template <typename T>
267 static inline return_type apply(comparable::pythagoras<CalculationType> const& , T const& value)
268 {
269 return_type const v = value;
270 return v * v;
271 }
272 };
273
274
275 template <typename Point1, typename Point2>
276 struct default_strategy
277 <
278 point_tag, point_tag, Point1, Point2, cartesian_tag, cartesian_tag
279 >
280 {
281 typedef pythagoras<> type;
282 };
283
284
285 } // namespace services
286 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
287
288
289 }} // namespace strategy::distance
290
291
292 }} // namespace boost::geometry
293
294
295 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP