You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
324 lines
8.5 KiB
324 lines
8.5 KiB
// Boost.Geometry (aka GGL, Generic Geometry Library) |
|
|
|
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France. |
|
// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands. |
|
// Copyright (c) 2009-2011 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
|
|
|