access.hpp 11 KB

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