access.hpp 9.7 KB

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