]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/core/access.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / core / access.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 2020.
8 // Modifications copyright (c) 2020, Oracle and/or its affiliates.
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10
11 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
12 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
13
14 // Use, modification and distribution is subject to the Boost Software License,
15 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
16 // http://www.boost.org/LICENSE_1_0.txt)
17
18 #ifndef BOOST_GEOMETRY_CORE_ACCESS_HPP
19 #define BOOST_GEOMETRY_CORE_ACCESS_HPP
20
21
22 #include <cstddef>
23
24 #include <boost/geometry/core/coordinate_type.hpp>
25 #include <boost/geometry/core/point_type.hpp>
26 #include <boost/geometry/core/static_assert.hpp>
27 #include <boost/geometry/core/tag.hpp>
28 #include <boost/geometry/util/type_traits_std.hpp>
29
30
31 namespace boost { namespace geometry
32 {
33
34 /// Index of minimum corner of the box.
35 int const min_corner = 0;
36
37 /// Index of maximum corner of the box.
38 int const max_corner = 1;
39
40 namespace traits
41 {
42
43 /*!
44 \brief Traits class which gives access (get,set) to points.
45 \ingroup traits
46 \par Geometries:
47 /// @li point
48 \par Specializations should provide, per Dimension
49 /// @li static inline T get(G const&)
50 /// @li static inline void set(G&, T const&)
51 \tparam Geometry geometry-type
52 \tparam Dimension dimension to access
53 */
54 template <typename Geometry, std::size_t Dimension, typename Enable = void>
55 struct access
56 {
57 BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
58 "Not implemented for this Geometry type.",
59 Geometry);
60 };
61
62
63 /*!
64 \brief Traits class defining "get" and "set" to get
65 and set point coordinate values
66 \tparam Geometry geometry (box, segment)
67 \tparam Index index (min_corner/max_corner for box, 0/1 for segment)
68 \tparam Dimension dimension
69 \par Geometries:
70 - box
71 - segment
72 \par Specializations should provide:
73 - static inline T get(G const&)
74 - static inline void set(G&, T const&)
75 \ingroup traits
76 */
77 template <typename Geometry, std::size_t Index, std::size_t Dimension>
78 struct indexed_access {};
79
80
81 } // namespace traits
82
83 #ifndef DOXYGEN_NO_DETAIL
84 namespace detail
85 {
86
87 template
88 <
89 typename Geometry,
90 typename CoordinateType,
91 std::size_t Index,
92 std::size_t Dimension
93 >
94 struct indexed_access_non_pointer
95 {
96 static constexpr CoordinateType get(Geometry const& geometry)
97 {
98 return traits::indexed_access<Geometry, Index, Dimension>::get(geometry);
99 }
100 static void set(Geometry& b, CoordinateType const& value)
101 {
102 traits::indexed_access<Geometry, Index, Dimension>::set(b, value);
103 }
104 };
105
106 template
107 <
108 typename Geometry,
109 typename CoordinateType,
110 std::size_t Index,
111 std::size_t Dimension
112 >
113 struct indexed_access_pointer
114 {
115 static constexpr CoordinateType get(Geometry const* geometry)
116 {
117 return traits::indexed_access<typename std::remove_pointer<Geometry>::type, Index, Dimension>::get(*geometry);
118 }
119 static void set(Geometry* geometry, CoordinateType const& value)
120 {
121 traits::indexed_access<typename std::remove_pointer<Geometry>::type, Index, Dimension>::set(*geometry, value);
122 }
123 };
124
125
126 } // namespace detail
127 #endif // DOXYGEN_NO_DETAIL
128
129
130 #ifndef DOXYGEN_NO_DISPATCH
131 namespace core_dispatch
132 {
133
134 template
135 <
136 typename Tag,
137 typename Geometry,
138 typename
139 CoordinateType,
140 std::size_t Dimension,
141 typename IsPointer
142 >
143 struct access
144 {
145 //static inline T get(G const&) {}
146 //static inline void set(G& g, T const& value) {}
147 };
148
149 template
150 <
151 typename Tag,
152 typename Geometry,
153 typename CoordinateType,
154 std::size_t Index,
155 std::size_t Dimension,
156 typename IsPointer
157 >
158 struct indexed_access
159 {
160 //static inline T get(G const&) {}
161 //static inline void set(G& g, T const& value) {}
162 };
163
164 template <typename Point, typename CoordinateType, std::size_t Dimension>
165 struct access<point_tag, Point, CoordinateType, Dimension, std::false_type>
166 {
167 static constexpr CoordinateType get(Point const& point)
168 {
169 return traits::access<Point, Dimension>::get(point);
170 }
171 static void set(Point& p, CoordinateType const& value)
172 {
173 traits::access<Point, Dimension>::set(p, value);
174 }
175 };
176
177 template <typename Point, typename CoordinateType, std::size_t Dimension>
178 struct access<point_tag, Point, CoordinateType, Dimension, std::true_type>
179 {
180 static constexpr CoordinateType get(Point const* point)
181 {
182 return traits::access<typename std::remove_pointer<Point>::type, Dimension>::get(*point);
183 }
184 static void set(Point* p, CoordinateType const& value)
185 {
186 traits::access<typename std::remove_pointer<Point>::type, Dimension>::set(*p, value);
187 }
188 };
189
190
191 template
192 <
193 typename Box,
194 typename CoordinateType,
195 std::size_t Index,
196 std::size_t Dimension
197 >
198 struct indexed_access<box_tag, Box, CoordinateType, Index, Dimension, std::false_type>
199 : detail::indexed_access_non_pointer<Box, CoordinateType, Index, Dimension>
200 {};
201
202 template
203 <
204 typename Box,
205 typename CoordinateType,
206 std::size_t Index,
207 std::size_t Dimension
208 >
209 struct indexed_access<box_tag, Box, CoordinateType, Index, Dimension, std::true_type>
210 : detail::indexed_access_pointer<Box, CoordinateType, Index, Dimension>
211 {};
212
213
214 template
215 <
216 typename Segment,
217 typename CoordinateType,
218 std::size_t Index,
219 std::size_t Dimension
220 >
221 struct indexed_access<segment_tag, Segment, CoordinateType, Index, Dimension, std::false_type>
222 : detail::indexed_access_non_pointer<Segment, CoordinateType, Index, Dimension>
223 {};
224
225
226 template
227 <
228 typename Segment,
229 typename CoordinateType,
230 std::size_t Index,
231 std::size_t Dimension
232 >
233 struct indexed_access<segment_tag, Segment, CoordinateType, Index, Dimension, std::true_type>
234 : detail::indexed_access_pointer<Segment, CoordinateType, Index, Dimension>
235 {};
236
237 } // namespace core_dispatch
238 #endif // DOXYGEN_NO_DISPATCH
239
240
241 #ifndef DOXYGEN_NO_DETAIL
242 namespace detail
243 {
244
245 // Two dummy tags to distinguish get/set variants below.
246 // They don't have to be specified by the user. The functions are distinguished
247 // by template signature also, but for e.g. GCC this is not enough. So give them
248 // a different signature.
249 struct signature_getset_dimension {};
250 struct signature_getset_index_dimension {};
251
252 } // namespace detail
253 #endif // DOXYGEN_NO_DETAIL
254
255
256 /*!
257 \brief Get coordinate value of a geometry (usually a point)
258 \details \details_get_set
259 \ingroup get
260 \tparam Dimension \tparam_dimension_required
261 \tparam Geometry \tparam_geometry (usually a Point Concept)
262 \param geometry \param_geometry (usually a point)
263 \return The coordinate value of specified dimension of specified geometry
264
265 \qbk{[include reference/core/get_point.qbk]}
266 */
267 template <std::size_t Dimension, typename Geometry>
268 constexpr inline typename coordinate_type<Geometry>::type get(Geometry const& geometry
269 #ifndef DOXYGEN_SHOULD_SKIP_THIS
270 , detail::signature_getset_dimension* = 0
271 #endif
272 )
273 {
274 typedef core_dispatch::access
275 <
276 typename tag<Geometry>::type,
277 typename util::remove_cptrref<Geometry>::type,
278 typename coordinate_type<Geometry>::type,
279 Dimension,
280 typename std::is_pointer<Geometry>::type
281 > coord_access_type;
282
283 return coord_access_type::get(geometry);
284 }
285
286
287 /*!
288 \brief Set coordinate value of a geometry (usually a point)
289 \details \details_get_set
290 \tparam Dimension \tparam_dimension_required
291 \tparam Geometry \tparam_geometry (usually a Point Concept)
292 \param geometry geometry to assign coordinate to
293 \param geometry \param_geometry (usually a point)
294 \param value The coordinate value to set
295 \ingroup set
296
297 \qbk{[include reference/core/set_point.qbk]}
298 */
299 template <std::size_t Dimension, typename Geometry>
300 inline void set(Geometry& geometry
301 , typename coordinate_type<Geometry>::type const& value
302 #ifndef DOXYGEN_SHOULD_SKIP_THIS
303 , detail::signature_getset_dimension* = 0
304 #endif
305 )
306 {
307 typedef core_dispatch::access
308 <
309 typename tag<Geometry>::type,
310 typename util::remove_cptrref<Geometry>::type,
311 typename coordinate_type<Geometry>::type,
312 Dimension,
313 typename std::is_pointer<Geometry>::type
314 > coord_access_type;
315
316 coord_access_type::set(geometry, value);
317 }
318
319
320 /*!
321 \brief get coordinate value of a Box or Segment
322 \details \details_get_set
323 \tparam Index \tparam_index_required
324 \tparam Dimension \tparam_dimension_required
325 \tparam Geometry \tparam_box_or_segment
326 \param geometry \param_geometry
327 \return coordinate value
328 \ingroup get
329
330 \qbk{distinguish,with index}
331 \qbk{[include reference/core/get_box.qbk]}
332 */
333 template <std::size_t Index, std::size_t Dimension, typename Geometry>
334 constexpr inline typename coordinate_type<Geometry>::type get(Geometry const& geometry
335 #ifndef DOXYGEN_SHOULD_SKIP_THIS
336 , detail::signature_getset_index_dimension* = 0
337 #endif
338 )
339 {
340 typedef core_dispatch::indexed_access
341 <
342 typename tag<Geometry>::type,
343 typename util::remove_cptrref<Geometry>::type,
344 typename coordinate_type<Geometry>::type,
345 Index,
346 Dimension,
347 typename std::is_pointer<Geometry>::type
348 > coord_access_type;
349
350 return coord_access_type::get(geometry);
351 }
352
353 /*!
354 \brief set coordinate value of a Box / Segment
355 \details \details_get_set
356 \tparam Index \tparam_index_required
357 \tparam Dimension \tparam_dimension_required
358 \tparam Geometry \tparam_box_or_segment
359 \param geometry geometry to assign coordinate to
360 \param geometry \param_geometry
361 \param value The coordinate value to set
362 \ingroup set
363
364 \qbk{distinguish,with index}
365 \qbk{[include reference/core/set_box.qbk]}
366 */
367 template <std::size_t Index, std::size_t Dimension, typename Geometry>
368 inline void set(Geometry& geometry
369 , typename coordinate_type<Geometry>::type const& value
370 #ifndef DOXYGEN_SHOULD_SKIP_THIS
371 , detail::signature_getset_index_dimension* = 0
372 #endif
373 )
374 {
375 typedef core_dispatch::indexed_access
376 <
377 typename tag<Geometry>::type,
378 typename util::remove_cptrref<Geometry>::type,
379 typename coordinate_type<Geometry>::type,
380 Index,
381 Dimension,
382 typename std::is_pointer<Geometry>::type
383 > coord_access_type;
384
385 coord_access_type::set(geometry, value);
386 }
387
388 }} // namespace boost::geometry
389
390 #endif // BOOST_GEOMETRY_CORE_ACCESS_HPP