diff options
Diffstat (limited to 'boost/geometry/algorithms/assign.hpp')
-rw-r--r-- | boost/geometry/algorithms/assign.hpp | 250 |
1 files changed, 229 insertions, 21 deletions
diff --git a/boost/geometry/algorithms/assign.hpp b/boost/geometry/algorithms/assign.hpp index 8c153c878d..32f095b9ac 100644 --- a/boost/geometry/algorithms/assign.hpp +++ b/boost/geometry/algorithms/assign.hpp @@ -3,6 +3,7 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2014 Samuel Debionne, Grenoble, France. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -40,6 +41,8 @@ #include <boost/geometry/util/for_each_coordinate.hpp> +#include <boost/variant/variant_fwd.hpp> + namespace boost { namespace geometry { @@ -122,9 +125,232 @@ inline void assign_zero(Geometry& geometry) } /*! +\brief Assign two coordinates to a geometry (usually a 2D point) +\ingroup assign +\tparam Geometry \tparam_geometry +\tparam Type \tparam_numeric to specify the coordinates +\param geometry \param_geometry +\param c1 \param_x +\param c2 \param_y + +\qbk{distinguish, 2 coordinate values} +\qbk{ +[heading Example] +[assign_2d_point] [assign_2d_point_output] + +[heading See also] +\* [link geometry.reference.algorithms.make.make_2_2_coordinate_values make] +} + */ +template <typename Geometry, typename Type> +inline void assign_values(Geometry& geometry, Type const& c1, Type const& c2) +{ + concept::check<Geometry>(); + + dispatch::assign + < + typename tag<Geometry>::type, + Geometry, + geometry::dimension<Geometry>::type::value + >::apply(geometry, c1, c2); +} + +/*! +\brief Assign three values to a geometry (usually a 3D point) +\ingroup assign +\tparam Geometry \tparam_geometry +\tparam Type \tparam_numeric to specify the coordinates +\param geometry \param_geometry +\param c1 \param_x +\param c2 \param_y +\param c3 \param_z + +\qbk{distinguish, 3 coordinate values} +\qbk{ +[heading Example] +[assign_3d_point] [assign_3d_point_output] + +[heading See also] +\* [link geometry.reference.algorithms.make.make_3_3_coordinate_values make] +} + */ +template <typename Geometry, typename Type> +inline void assign_values(Geometry& geometry, + Type const& c1, Type const& c2, Type const& c3) +{ + concept::check<Geometry>(); + + dispatch::assign + < + typename tag<Geometry>::type, + Geometry, + geometry::dimension<Geometry>::type::value + >::apply(geometry, c1, c2, c3); +} + +/*! +\brief Assign four values to a geometry (usually a box or segment) +\ingroup assign +\tparam Geometry \tparam_geometry +\tparam Type \tparam_numeric to specify the coordinates +\param geometry \param_geometry +\param c1 First coordinate (usually x1) +\param c2 Second coordinate (usually y1) +\param c3 Third coordinate (usually x2) +\param c4 Fourth coordinate (usually y2) + +\qbk{distinguish, 4 coordinate values} + */ +template <typename Geometry, typename Type> +inline void assign_values(Geometry& geometry, + Type const& c1, Type const& c2, Type const& c3, Type const& c4) +{ + concept::check<Geometry>(); + + dispatch::assign + < + typename tag<Geometry>::type, + Geometry, + geometry::dimension<Geometry>::type::value + >::apply(geometry, c1, c2, c3, c4); +} + + + +namespace resolve_variant +{ + +template <typename Geometry1, typename Geometry2> +struct assign +{ + static inline void + apply( + Geometry1& geometry1, + const Geometry2& geometry2) + { + concept::check<Geometry1>(); + concept::check<Geometry2 const>(); + concept::check_concepts_and_equal_dimensions<Geometry1, Geometry2 const>(); + + bool const same_point_order = + point_order<Geometry1>::value == point_order<Geometry2>::value; + bool const same_closure = + closure<Geometry1>::value == closure<Geometry2>::value; + + BOOST_MPL_ASSERT_MSG + ( + same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER + , (types<Geometry1, Geometry2>) + ); + BOOST_MPL_ASSERT_MSG + ( + same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE + , (types<Geometry1, Geometry2>) + ); + + dispatch::convert<Geometry2, Geometry1>::apply(geometry2, geometry1); + } +}; + + +template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2> +struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2> +{ + struct visitor: static_visitor<void> + { + Geometry2 const& m_geometry2; + + visitor(Geometry2 const& geometry2) + : m_geometry2(geometry2) + {} + + template <typename Geometry1> + result_type operator()(Geometry1& geometry1) const + { + return assign + < + Geometry1, + Geometry2 + >::apply + (geometry1, m_geometry2); + } + }; + + static inline void + apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry1, + Geometry2 const& geometry2) + { + return apply_visitor(visitor(geometry2), geometry1); + } +}; + + +template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)> +struct assign<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> > +{ + struct visitor: static_visitor<void> + { + Geometry1& m_geometry1; + + visitor(Geometry1 const& geometry1) + : m_geometry1(geometry1) + {} + + template <typename Geometry2> + result_type operator()(Geometry2 const& geometry2) const + { + return assign + < + Geometry1, + Geometry2 + >::apply + (m_geometry1, geometry2); + } + }; + + static inline void + apply(Geometry1& geometry1, + variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2) + { + return apply_visitor(visitor(geometry1), geometry2); + } +}; + + +template <BOOST_VARIANT_ENUM_PARAMS(typename A), BOOST_VARIANT_ENUM_PARAMS(typename B)> +struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(A)>, variant<BOOST_VARIANT_ENUM_PARAMS(B)> > +{ + struct visitor: static_visitor<void> + { + template <typename Geometry1, typename Geometry2> + result_type operator()( + Geometry1& geometry1, + Geometry2 const& geometry2) const + { + return assign + < + Geometry1, + Geometry2 + >::apply + (geometry1, geometry2); + } + }; + + static inline void + apply(variant<BOOST_VARIANT_ENUM_PARAMS(A)>& geometry1, + variant<BOOST_VARIANT_ENUM_PARAMS(B)> const& geometry2) + { + return apply_visitor(visitor(), geometry1, geometry2); + } +}; + +} // namespace resolve_variant + + +/*! \brief Assigns one geometry to another geometry -\details The assign algorithm assigns one geometry, e.g. a BOX, to another geometry, e.g. a RING. This only -if it is possible and applicable. +\details The assign algorithm assigns one geometry, e.g. a BOX, to another +geometry, e.g. a RING. This only works if it is possible and applicable. \ingroup assign \tparam Geometry1 \tparam_geometry \tparam Geometry2 \tparam_geometry @@ -142,25 +368,7 @@ if it is possible and applicable. template <typename Geometry1, typename Geometry2> inline void assign(Geometry1& geometry1, Geometry2 const& geometry2) { - concept::check_concepts_and_equal_dimensions<Geometry1, Geometry2 const>(); - - bool const same_point_order = - point_order<Geometry1>::value == point_order<Geometry2>::value; - bool const same_closure = - closure<Geometry1>::value == closure<Geometry2>::value; - - BOOST_MPL_ASSERT_MSG - ( - same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER - , (types<Geometry1, Geometry2>) - ); - BOOST_MPL_ASSERT_MSG - ( - same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE - , (types<Geometry1, Geometry2>) - ); - - dispatch::convert<Geometry2, Geometry1>::apply(geometry2, geometry1); + resolve_variant::assign<Geometry1, Geometry2>::apply(geometry1, geometry2); } |