access.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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/mpl/assert.hpp>
  14. #include <boost/concept_check.hpp>
  15. #include <boost/type_traits/is_pointer.hpp>
  16. #include <boost/geometry/core/coordinate_type.hpp>
  17. #include <boost/geometry/core/point_type.hpp>
  18. #include <boost/geometry/core/tag.hpp>
  19. #include <boost/geometry/util/bare_type.hpp>
  20. namespace boost { namespace geometry
  21. {
  22. /// Index of minimum corner of the box.
  23. int const min_corner = 0;
  24. /// Index of maximum corner of the box.
  25. int const max_corner = 1;
  26. namespace traits
  27. {
  28. /*!
  29. \brief Traits class which gives access (get,set) to points.
  30. \ingroup traits
  31. \par Geometries:
  32. /// @li point
  33. \par Specializations should provide, per Dimension
  34. /// @li static inline T get(G const&)
  35. /// @li static inline void set(G&, T const&)
  36. \tparam Geometry geometry-type
  37. \tparam Dimension dimension to access
  38. */
  39. template <typename Geometry, std::size_t Dimension, typename Enable = void>
  40. struct access
  41. {
  42. BOOST_MPL_ASSERT_MSG
  43. (
  44. false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types<Geometry>)
  45. );
  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 inline CoordinateType get(Geometry const& geometry)
  77. {
  78. return traits::indexed_access<Geometry, Index, Dimension>::get(geometry);
  79. }
  80. static inline 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 inline CoordinateType get(Geometry const* geometry)
  95. {
  96. return traits::indexed_access<typename boost::remove_pointer<Geometry>::type, Index, Dimension>::get(*geometry);
  97. }
  98. static inline void set(Geometry* geometry, CoordinateType const& value)
  99. {
  100. traits::indexed_access<typename boost::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, boost::false_type>
  138. {
  139. static inline CoordinateType get(Point const& point)
  140. {
  141. return traits::access<Point, Dimension>::get(point);
  142. }
  143. static inline 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, boost::true_type>
  150. {
  151. static inline CoordinateType get(Point const* point)
  152. {
  153. return traits::access<typename boost::remove_pointer<Point>::type, Dimension>::get(*point);
  154. }
  155. static inline void set(Point* p, CoordinateType const& value)
  156. {
  157. traits::access<typename boost::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, boost::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, boost::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, boost::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, boost::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. inline typename coordinate_type<Geometry>::type get(Geometry const& geometry
  225. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  226. , detail::signature_getset_dimension* dummy = 0
  227. #endif
  228. )
  229. {
  230. boost::ignore_unused_variable_warning(dummy);
  231. typedef core_dispatch::access
  232. <
  233. typename tag<Geometry>::type,
  234. typename geometry::util::bare_type<Geometry>::type,
  235. typename coordinate_type<Geometry>::type,
  236. Dimension,
  237. typename boost::is_pointer<Geometry>::type
  238. > coord_access_type;
  239. return coord_access_type::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 geometry to assign coordinate to
  247. \param geometry \param_geometry (usually a point)
  248. \param value The coordinate value to set
  249. \ingroup set
  250. \qbk{[include reference/core/set_point.qbk]}
  251. */
  252. template <std::size_t Dimension, typename Geometry>
  253. inline void set(Geometry& geometry
  254. , typename coordinate_type<Geometry>::type const& value
  255. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  256. , detail::signature_getset_dimension* dummy = 0
  257. #endif
  258. )
  259. {
  260. boost::ignore_unused_variable_warning(dummy);
  261. typedef core_dispatch::access
  262. <
  263. typename tag<Geometry>::type,
  264. typename geometry::util::bare_type<Geometry>::type,
  265. typename coordinate_type<Geometry>::type,
  266. Dimension,
  267. typename boost::is_pointer<Geometry>::type
  268. > coord_access_type;
  269. coord_access_type::set(geometry, value);
  270. }
  271. /*!
  272. \brief get coordinate value of a Box or Segment
  273. \details \details_get_set
  274. \tparam Index \tparam_index_required
  275. \tparam Dimension \tparam_dimension_required
  276. \tparam Geometry \tparam_box_or_segment
  277. \param geometry \param_geometry
  278. \return coordinate value
  279. \ingroup get
  280. \qbk{distinguish,with index}
  281. \qbk{[include reference/core/get_box.qbk]}
  282. */
  283. template <std::size_t Index, std::size_t Dimension, typename Geometry>
  284. inline typename coordinate_type<Geometry>::type get(Geometry const& geometry
  285. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  286. , detail::signature_getset_index_dimension* dummy = 0
  287. #endif
  288. )
  289. {
  290. boost::ignore_unused_variable_warning(dummy);
  291. typedef core_dispatch::indexed_access
  292. <
  293. typename tag<Geometry>::type,
  294. typename geometry::util::bare_type<Geometry>::type,
  295. typename coordinate_type<Geometry>::type,
  296. Index,
  297. Dimension,
  298. typename boost::is_pointer<Geometry>::type
  299. > coord_access_type;
  300. return coord_access_type::get(geometry);
  301. }
  302. /*!
  303. \brief set coordinate value of a Box / Segment
  304. \details \details_get_set
  305. \tparam Index \tparam_index_required
  306. \tparam Dimension \tparam_dimension_required
  307. \tparam Geometry \tparam_box_or_segment
  308. \param geometry geometry to assign coordinate to
  309. \param geometry \param_geometry
  310. \param value The coordinate value to set
  311. \ingroup set
  312. \qbk{distinguish,with index}
  313. \qbk{[include reference/core/set_box.qbk]}
  314. */
  315. template <std::size_t Index, std::size_t Dimension, typename Geometry>
  316. inline void set(Geometry& geometry
  317. , typename coordinate_type<Geometry>::type const& value
  318. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  319. , detail::signature_getset_index_dimension* dummy = 0
  320. #endif
  321. )
  322. {
  323. boost::ignore_unused_variable_warning(dummy);
  324. typedef core_dispatch::indexed_access
  325. <
  326. typename tag<Geometry>::type,
  327. typename geometry::util::bare_type<Geometry>::type,
  328. typename coordinate_type<Geometry>::type,
  329. Index,
  330. Dimension,
  331. typename boost::is_pointer<Geometry>::type
  332. > coord_access_type;
  333. coord_access_type::set(geometry, value);
  334. }
  335. }} // namespace boost::geometry
  336. #endif // BOOST_GEOMETRY_CORE_ACCESS_HPP