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 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8 // (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)
14 #ifndef BOOST_GEOMETRY_CORE_ACCESS_HPP
15 #define BOOST_GEOMETRY_CORE_ACCESS_HPP
20 #include <boost/core/ignore_unused.hpp>
21 #include <boost/mpl/assert.hpp>
22 #include <boost/type_traits/is_pointer.hpp>
23 #include <boost/type_traits/remove_pointer.hpp>
25 #include <boost/geometry/core/coordinate_type.hpp>
26 #include <boost/geometry/core/point_type.hpp>
27 #include <boost/geometry/core/tag.hpp>
28 #include <boost/geometry/util/bare_type.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>
59 false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types<Geometry>)
65 \brief Traits class defining "get" and "set" to get
66 and set point coordinate values
67 \tparam Geometry geometry (box, segment)
68 \tparam Index index (min_corner/max_corner for box, 0/1 for segment)
69 \tparam Dimension dimension
73 \par Specializations should provide:
74 - static inline T get(G const&)
75 - static inline void set(G&, T const&)
78 template <typename Geometry, std::size_t Index, std::size_t Dimension>
79 struct indexed_access {};
84 #ifndef DOXYGEN_NO_DETAIL
91 typename CoordinateType,
95 struct indexed_access_non_pointer
97 static inline CoordinateType get(Geometry const& geometry)
99 return traits::indexed_access<Geometry, Index, Dimension>::get(geometry);
101 static inline void set(Geometry& b, CoordinateType const& value)
103 traits::indexed_access<Geometry, Index, Dimension>::set(b, value);
110 typename CoordinateType,
112 std::size_t Dimension
114 struct indexed_access_pointer
116 static inline CoordinateType get(Geometry const* geometry)
118 return traits::indexed_access<typename boost::remove_pointer<Geometry>::type, Index, Dimension>::get(*geometry);
120 static inline void set(Geometry* geometry, CoordinateType const& value)
122 traits::indexed_access<typename boost::remove_pointer<Geometry>::type, Index, Dimension>::set(*geometry, value);
127 } // namespace detail
128 #endif // DOXYGEN_NO_DETAIL
131 #ifndef DOXYGEN_NO_DISPATCH
132 namespace core_dispatch
141 std::size_t Dimension,
146 //static inline T get(G const&) {}
147 //static inline void set(G& g, T const& value) {}
154 typename CoordinateType,
156 std::size_t Dimension,
159 struct indexed_access
161 //static inline T get(G const&) {}
162 //static inline void set(G& g, T const& value) {}
165 template <typename Point, typename CoordinateType, std::size_t Dimension>
166 struct access<point_tag, Point, CoordinateType, Dimension, boost::false_type>
168 static inline CoordinateType get(Point const& point)
170 return traits::access<Point, Dimension>::get(point);
172 static inline void set(Point& p, CoordinateType const& value)
174 traits::access<Point, Dimension>::set(p, value);
178 template <typename Point, typename CoordinateType, std::size_t Dimension>
179 struct access<point_tag, Point, CoordinateType, Dimension, boost::true_type>
181 static inline CoordinateType get(Point const* point)
183 return traits::access<typename boost::remove_pointer<Point>::type, Dimension>::get(*point);
185 static inline void set(Point* p, CoordinateType const& value)
187 traits::access<typename boost::remove_pointer<Point>::type, Dimension>::set(*p, value);
195 typename CoordinateType,
197 std::size_t Dimension
199 struct indexed_access<box_tag, Box, CoordinateType, Index, Dimension, boost::false_type>
200 : detail::indexed_access_non_pointer<Box, CoordinateType, Index, Dimension>
206 typename CoordinateType,
208 std::size_t Dimension
210 struct indexed_access<box_tag, Box, CoordinateType, Index, Dimension, boost::true_type>
211 : detail::indexed_access_pointer<Box, CoordinateType, Index, Dimension>
218 typename CoordinateType,
220 std::size_t Dimension
222 struct indexed_access<segment_tag, Segment, CoordinateType, Index, Dimension, boost::false_type>
223 : detail::indexed_access_non_pointer<Segment, CoordinateType, Index, Dimension>
230 typename CoordinateType,
232 std::size_t Dimension
234 struct indexed_access<segment_tag, Segment, CoordinateType, Index, Dimension, boost::true_type>
235 : detail::indexed_access_pointer<Segment, CoordinateType, Index, Dimension>
238 } // namespace core_dispatch
239 #endif // DOXYGEN_NO_DISPATCH
242 #ifndef DOXYGEN_NO_DETAIL
246 // Two dummy tags to distinguish get/set variants below.
247 // They don't have to be specified by the user. The functions are distinguished
248 // by template signature also, but for e.g. GCC this is not enough. So give them
249 // a different signature.
250 struct signature_getset_dimension {};
251 struct signature_getset_index_dimension {};
253 } // namespace detail
254 #endif // DOXYGEN_NO_DETAIL
258 \brief Get coordinate value of a geometry (usually a point)
259 \details \details_get_set
261 \tparam Dimension \tparam_dimension_required
262 \tparam Geometry \tparam_geometry (usually a Point Concept)
263 \param geometry \param_geometry (usually a point)
264 \return The coordinate value of specified dimension of specified geometry
266 \qbk{[include reference/core/get_point.qbk]}
268 template <std::size_t Dimension, typename Geometry>
269 inline typename coordinate_type<Geometry>::type get(Geometry const& geometry
270 #ifndef DOXYGEN_SHOULD_SKIP_THIS
271 , detail::signature_getset_dimension* dummy = 0
275 boost::ignore_unused(dummy);
277 typedef core_dispatch::access
279 typename tag<Geometry>::type,
280 typename geometry::util::bare_type<Geometry>::type,
281 typename coordinate_type<Geometry>::type,
283 typename boost::is_pointer<Geometry>::type
286 return coord_access_type::get(geometry);
291 \brief Set coordinate value of a geometry (usually a point)
292 \details \details_get_set
293 \tparam Dimension \tparam_dimension_required
294 \tparam Geometry \tparam_geometry (usually a Point Concept)
295 \param geometry geometry to assign coordinate to
296 \param geometry \param_geometry (usually a point)
297 \param value The coordinate value to set
300 \qbk{[include reference/core/set_point.qbk]}
302 template <std::size_t Dimension, typename Geometry>
303 inline void set(Geometry& geometry
304 , typename coordinate_type<Geometry>::type const& value
305 #ifndef DOXYGEN_SHOULD_SKIP_THIS
306 , detail::signature_getset_dimension* dummy = 0
310 boost::ignore_unused(dummy);
312 typedef core_dispatch::access
314 typename tag<Geometry>::type,
315 typename geometry::util::bare_type<Geometry>::type,
316 typename coordinate_type<Geometry>::type,
318 typename boost::is_pointer<Geometry>::type
321 coord_access_type::set(geometry, value);
326 \brief get coordinate value of a Box or Segment
327 \details \details_get_set
328 \tparam Index \tparam_index_required
329 \tparam Dimension \tparam_dimension_required
330 \tparam Geometry \tparam_box_or_segment
331 \param geometry \param_geometry
332 \return coordinate value
335 \qbk{distinguish,with index}
336 \qbk{[include reference/core/get_box.qbk]}
338 template <std::size_t Index, std::size_t Dimension, typename Geometry>
339 inline typename coordinate_type<Geometry>::type get(Geometry const& geometry
340 #ifndef DOXYGEN_SHOULD_SKIP_THIS
341 , detail::signature_getset_index_dimension* dummy = 0
345 boost::ignore_unused(dummy);
347 typedef core_dispatch::indexed_access
349 typename tag<Geometry>::type,
350 typename geometry::util::bare_type<Geometry>::type,
351 typename coordinate_type<Geometry>::type,
354 typename boost::is_pointer<Geometry>::type
357 return coord_access_type::get(geometry);
361 \brief set coordinate value of a Box / Segment
362 \details \details_get_set
363 \tparam Index \tparam_index_required
364 \tparam Dimension \tparam_dimension_required
365 \tparam Geometry \tparam_box_or_segment
366 \param geometry geometry to assign coordinate to
367 \param geometry \param_geometry
368 \param value The coordinate value to set
371 \qbk{distinguish,with index}
372 \qbk{[include reference/core/set_box.qbk]}
374 template <std::size_t Index, std::size_t Dimension, typename Geometry>
375 inline void set(Geometry& geometry
376 , typename coordinate_type<Geometry>::type const& value
377 #ifndef DOXYGEN_SHOULD_SKIP_THIS
378 , detail::signature_getset_index_dimension* dummy = 0
382 boost::ignore_unused(dummy);
384 typedef core_dispatch::indexed_access
386 typename tag<Geometry>::type,
387 typename geometry::util::bare_type<Geometry>::type,
388 typename coordinate_type<Geometry>::type,
391 typename boost::is_pointer<Geometry>::type
394 coord_access_type::set(geometry, value);
397 }} // namespace boost::geometry
399 #endif // BOOST_GEOMETRY_CORE_ACCESS_HPP