1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
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
11 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
12 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
18 #ifndef BOOST_GEOMETRY_CORE_ACCESS_HPP
19 #define BOOST_GEOMETRY_CORE_ACCESS_HPP
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>
31 namespace boost { namespace geometry
34 /// Index of minimum corner of the box.
35 int const min_corner = 0;
37 /// Index of maximum corner of the box.
38 int const max_corner = 1;
44 \brief Traits class which gives access (get,set) to points.
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
54 template <typename Geometry, std::size_t Dimension, typename Enable = void>
57 BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
58 "Not implemented for this Geometry type.",
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
72 \par Specializations should provide:
73 - static inline T get(G const&)
74 - static inline void set(G&, T const&)
77 template <typename Geometry, std::size_t Index, std::size_t Dimension>
78 struct indexed_access {};
83 #ifndef DOXYGEN_NO_DETAIL
90 typename CoordinateType,
94 struct indexed_access_non_pointer
96 static constexpr CoordinateType get(Geometry const& geometry)
98 return traits::indexed_access<Geometry, Index, Dimension>::get(geometry);
100 static void set(Geometry& b, CoordinateType const& value)
102 traits::indexed_access<Geometry, Index, Dimension>::set(b, value);
109 typename CoordinateType,
111 std::size_t Dimension
113 struct indexed_access_pointer
115 static constexpr CoordinateType get(Geometry const* geometry)
117 return traits::indexed_access<typename std::remove_pointer<Geometry>::type, Index, Dimension>::get(*geometry);
119 static void set(Geometry* geometry, CoordinateType const& value)
121 traits::indexed_access<typename std::remove_pointer<Geometry>::type, Index, Dimension>::set(*geometry, value);
126 } // namespace detail
127 #endif // DOXYGEN_NO_DETAIL
130 #ifndef DOXYGEN_NO_DISPATCH
131 namespace core_dispatch
140 std::size_t Dimension,
145 //static inline T get(G const&) {}
146 //static inline void set(G& g, T const& value) {}
153 typename CoordinateType,
155 std::size_t Dimension,
158 struct indexed_access
160 //static inline T get(G const&) {}
161 //static inline void set(G& g, T const& value) {}
164 template <typename Point, typename CoordinateType, std::size_t Dimension>
165 struct access<point_tag, Point, CoordinateType, Dimension, std::false_type>
167 static constexpr CoordinateType get(Point const& point)
169 return traits::access<Point, Dimension>::get(point);
171 static void set(Point& p, CoordinateType const& value)
173 traits::access<Point, Dimension>::set(p, value);
177 template <typename Point, typename CoordinateType, std::size_t Dimension>
178 struct access<point_tag, Point, CoordinateType, Dimension, std::true_type>
180 static constexpr CoordinateType get(Point const* point)
182 return traits::access<typename std::remove_pointer<Point>::type, Dimension>::get(*point);
184 static void set(Point* p, CoordinateType const& value)
186 traits::access<typename std::remove_pointer<Point>::type, Dimension>::set(*p, value);
194 typename CoordinateType,
196 std::size_t Dimension
198 struct indexed_access<box_tag, Box, CoordinateType, Index, Dimension, std::false_type>
199 : detail::indexed_access_non_pointer<Box, CoordinateType, Index, Dimension>
205 typename CoordinateType,
207 std::size_t Dimension
209 struct indexed_access<box_tag, Box, CoordinateType, Index, Dimension, std::true_type>
210 : detail::indexed_access_pointer<Box, CoordinateType, Index, Dimension>
217 typename CoordinateType,
219 std::size_t Dimension
221 struct indexed_access<segment_tag, Segment, CoordinateType, Index, Dimension, std::false_type>
222 : detail::indexed_access_non_pointer<Segment, CoordinateType, Index, Dimension>
229 typename CoordinateType,
231 std::size_t Dimension
233 struct indexed_access<segment_tag, Segment, CoordinateType, Index, Dimension, std::true_type>
234 : detail::indexed_access_pointer<Segment, CoordinateType, Index, Dimension>
237 } // namespace core_dispatch
238 #endif // DOXYGEN_NO_DISPATCH
241 #ifndef DOXYGEN_NO_DETAIL
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 {};
252 } // namespace detail
253 #endif // DOXYGEN_NO_DETAIL
257 \brief Get coordinate value of a geometry (usually a point)
258 \details \details_get_set
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
265 \qbk{[include reference/core/get_point.qbk]}
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
274 typedef core_dispatch::access
276 typename tag<Geometry>::type,
277 typename util::remove_cptrref<Geometry>::type,
278 typename coordinate_type<Geometry>::type,
280 typename std::is_pointer<Geometry>::type
283 return coord_access_type::get(geometry);
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
297 \qbk{[include reference/core/set_point.qbk]}
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
307 typedef core_dispatch::access
309 typename tag<Geometry>::type,
310 typename util::remove_cptrref<Geometry>::type,
311 typename coordinate_type<Geometry>::type,
313 typename std::is_pointer<Geometry>::type
316 coord_access_type::set(geometry, value);
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
330 \qbk{distinguish,with index}
331 \qbk{[include reference/core/get_box.qbk]}
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
340 typedef core_dispatch::indexed_access
342 typename tag<Geometry>::type,
343 typename util::remove_cptrref<Geometry>::type,
344 typename coordinate_type<Geometry>::type,
347 typename std::is_pointer<Geometry>::type
350 return coord_access_type::get(geometry);
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
364 \qbk{distinguish,with index}
365 \qbk{[include reference/core/set_box.qbk]}
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
375 typedef core_dispatch::indexed_access
377 typename tag<Geometry>::type,
378 typename util::remove_cptrref<Geometry>::type,
379 typename coordinate_type<Geometry>::type,
382 typename std::is_pointer<Geometry>::type
385 coord_access_type::set(geometry, value);
388 }} // namespace boost::geometry
390 #endif // BOOST_GEOMETRY_CORE_ACCESS_HPP