diff options
Diffstat (limited to 'boost/geometry/core/access.hpp')
-rw-r--r-- | boost/geometry/core/access.hpp | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/boost/geometry/core/access.hpp b/boost/geometry/core/access.hpp new file mode 100644 index 0000000000..a463b8cdc3 --- /dev/null +++ b/boost/geometry/core/access.hpp @@ -0,0 +1,324 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. +// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. + +// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library +// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_CORE_ACCESS_HPP +#define BOOST_GEOMETRY_CORE_ACCESS_HPP + + +#include <cstddef> + +#include <boost/mpl/assert.hpp> +#include <boost/type_traits/remove_const.hpp> +#include <boost/concept_check.hpp> + +#include <boost/geometry/core/coordinate_type.hpp> +#include <boost/geometry/core/point_type.hpp> +#include <boost/geometry/core/tag.hpp> + + +namespace boost { namespace geometry +{ + +/// Index of minimum corner of the box. +int const min_corner = 0; + +/// Index of maximum corner of the box. +int const max_corner = 1; + +namespace traits +{ + +/*! +\brief Traits class which gives access (get,set) to points. +\ingroup traits +\par Geometries: +/// @li point +\par Specializations should provide, per Dimension +/// @li static inline T get(G const&) +/// @li static inline void set(G&, T const&) +\tparam Geometry geometry-type +\tparam Dimension dimension to access +*/ +template <typename Geometry, std::size_t Dimension, typename Enable = void> +struct access +{ + BOOST_MPL_ASSERT_MSG + ( + false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types<Geometry>) + ); +}; + + +/*! +\brief Traits class defining "get" and "set" to get + and set point coordinate values +\tparam Geometry geometry (box, segment) +\tparam Index index (min_corner/max_corner for box, 0/1 for segment) +\tparam Dimension dimension +\par Geometries: + - box + - segment +\par Specializations should provide: + - static inline T get(G const&) + - static inline void set(G&, T const&) +\ingroup traits +*/ +template <typename Geometry, std::size_t Index, std::size_t Dimension> +struct indexed_access {}; + + +} // namespace traits + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + +template +< + typename Tag, + typename Geometry, + typename + CoordinateType, std::size_t Dimension +> +struct access +{ + //static inline T get(G const&) {} + //static inline void set(G& g, T const& value) {} +}; + +template +< + typename Tag, + typename Geometry, + typename CoordinateType, + std::size_t Index, + std::size_t Dimension +> +struct indexed_access +{ + //static inline T get(G const&) {} + //static inline void set(G& g, T const& value) {} +}; + +template <typename Point, typename CoordinateType, std::size_t Dimension> +struct access<point_tag, Point, CoordinateType, Dimension> +{ + static inline CoordinateType get(Point const& point) + { + return traits::access<Point, Dimension>::get(point); + } + static inline void set(Point& p, CoordinateType const& value) + { + traits::access<Point, Dimension>::set(p, value); + } +}; + +template +< + typename Box, + typename CoordinateType, + std::size_t Index, + std::size_t Dimension +> +struct indexed_access<box_tag, Box, CoordinateType, Index, Dimension> +{ + static inline CoordinateType get(Box const& box) + { + return traits::indexed_access<Box, Index, Dimension>::get(box); + } + static inline void set(Box& b, CoordinateType const& value) + { + traits::indexed_access<Box, Index, Dimension>::set(b, value); + } +}; + +template +< + typename Segment, + typename CoordinateType, + std::size_t Index, + std::size_t Dimension +> +struct indexed_access<segment_tag, Segment, CoordinateType, Index, Dimension> +{ + static inline CoordinateType get(Segment const& segment) + { + return traits::indexed_access<Segment, Index, Dimension>::get(segment); + } + static inline void set(Segment& segment, CoordinateType const& value) + { + traits::indexed_access<Segment, Index, Dimension>::set(segment, value); + } +}; + +} // namespace core_dispatch +#endif // DOXYGEN_NO_DISPATCH + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +// Two dummy tags to distinguish get/set variants below. +// They don't have to be specified by the user. The functions are distinguished +// by template signature also, but for e.g. GCC this is not enough. So give them +// a different signature. +struct signature_getset_dimension {}; +struct signature_getset_index_dimension {}; + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + + +/*! +\brief Get coordinate value of a geometry (usually a point) +\details \details_get_set +\ingroup get +\tparam Dimension \tparam_dimension_required +\tparam Geometry \tparam_geometry (usually a Point Concept) +\param geometry \param_geometry (usually a point) +\param dummy \qbk_skip +\return The coordinate value of specified dimension of specified geometry +\qbk{[include reference/core/get_point.qbk]} +*/ +template <std::size_t Dimension, typename Geometry> +inline typename coordinate_type<Geometry>::type get(Geometry const& geometry + , detail::signature_getset_dimension* dummy = 0 + ) +{ + boost::ignore_unused_variable_warning(dummy); + + typedef typename boost::remove_const<Geometry>::type ncg_type; + + typedef core_dispatch::access + < + typename tag<Geometry>::type, + ncg_type, + typename coordinate_type<ncg_type>::type, + Dimension + > coord_access_type; + + return coord_access_type::get(geometry); +} + + +/*! +\brief Set coordinate value of a geometry (usually a point) +\details \details_get_set +\tparam Dimension \tparam_dimension_required +\tparam Geometry \tparam_geometry (usually a Point Concept) +\param geometry geometry to assign coordinate to +\param geometry \param_geometry (usually a point) +\param value The coordinate value to set +\param dummy \qbk_skip +\ingroup set + +\qbk{[include reference/core/set_point.qbk]} +*/ +template <std::size_t Dimension, typename Geometry> +inline void set(Geometry& geometry + , typename coordinate_type<Geometry>::type const& value + , detail::signature_getset_dimension* dummy = 0 + ) +{ + boost::ignore_unused_variable_warning(dummy); + + typedef typename boost::remove_const<Geometry>::type ncg_type; + + typedef core_dispatch::access + < + typename tag<Geometry>::type, + ncg_type, + typename coordinate_type<ncg_type>::type, + Dimension + > coord_access_type; + + coord_access_type::set(geometry, value); +} + + +/*! +\brief get coordinate value of a Box or Segment +\details \details_get_set +\tparam Index \tparam_index_required +\tparam Dimension \tparam_dimension_required +\tparam Geometry \tparam_box_or_segment +\param geometry \param_geometry +\param dummy \qbk_skip +\return coordinate value +\ingroup get + +\qbk{distinguish,with index} +\qbk{[include reference/core/get_box.qbk]} +*/ +template <std::size_t Index, std::size_t Dimension, typename Geometry> +inline typename coordinate_type<Geometry>::type get(Geometry const& geometry + , detail::signature_getset_index_dimension* dummy = 0 + ) +{ + boost::ignore_unused_variable_warning(dummy); + + typedef typename boost::remove_const<Geometry>::type ncg_type; + + typedef core_dispatch::indexed_access + < + typename tag<Geometry>::type, + ncg_type, + typename coordinate_type<ncg_type>::type, + Index, + Dimension + > coord_access_type; + + return coord_access_type::get(geometry); +} + +/*! +\brief set coordinate value of a Box / Segment +\details \details_get_set +\tparam Index \tparam_index_required +\tparam Dimension \tparam_dimension_required +\tparam Geometry \tparam_box_or_segment +\param geometry geometry to assign coordinate to +\param geometry \param_geometry +\param value The coordinate value to set +\param dummy \qbk_skip +\ingroup set + +\qbk{distinguish,with index} +\qbk{[include reference/core/set_box.qbk]} +*/ +template <std::size_t Index, std::size_t Dimension, typename Geometry> +inline void set(Geometry& geometry + , typename coordinate_type<Geometry>::type const& value + , detail::signature_getset_index_dimension* dummy = 0 + ) +{ + boost::ignore_unused_variable_warning(dummy); + + typedef typename boost::remove_const<Geometry>::type ncg_type; + + typedef core_dispatch::indexed_access + < + typename tag<Geometry>::type, ncg_type, + typename coordinate_type<ncg_type>::type, + Index, + Dimension + > coord_access_type; + + coord_access_type::set(geometry, value); +} + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_CORE_ACCESS_HPP |