access.hpp 10 KB

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