diff options
Diffstat (limited to 'boost/geometry/algorithms/expand.hpp')
-rw-r--r-- | boost/geometry/algorithms/expand.hpp | 158 |
1 files changed, 93 insertions, 65 deletions
diff --git a/boost/geometry/algorithms/expand.hpp b/boost/geometry/algorithms/expand.hpp index da7442b593..19e40aa2d0 100644 --- a/boost/geometry/algorithms/expand.hpp +++ b/boost/geometry/algorithms/expand.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. @@ -19,6 +20,7 @@ #include <boost/numeric/conversion/cast.hpp> +#include <boost/geometry/algorithms/not_implemented.hpp> #include <boost/geometry/core/coordinate_dimension.hpp> #include <boost/geometry/geometries/concepts/check.hpp> @@ -27,6 +29,9 @@ #include <boost/geometry/strategies/compare.hpp> #include <boost/geometry/policies/compare.hpp> +#include <boost/variant/static_visitor.hpp> +#include <boost/variant/apply_visitor.hpp> + namespace boost { namespace geometry { @@ -38,26 +43,26 @@ namespace detail { namespace expand template < - typename Box, typename Point, typename StrategyLess, typename StrategyGreater, std::size_t Dimension, std::size_t DimensionCount > struct point_loop { - typedef typename strategy::compare::detail::select_strategy - < - StrategyLess, 1, Point, Dimension - >::type less_type; + template <typename Box, typename Point> + static inline void apply(Box& box, Point const& source) + { + typedef typename strategy::compare::detail::select_strategy + < + StrategyLess, 1, Point, Dimension + >::type less_type; - typedef typename strategy::compare::detail::select_strategy - < - StrategyGreater, -1, Point, Dimension - >::type greater_type; + typedef typename strategy::compare::detail::select_strategy + < + StrategyGreater, -1, Point, Dimension + >::type greater_type; - typedef typename select_coordinate_type<Point, Box>::type coordinate_type; + typedef typename select_coordinate_type<Point, Box>::type coordinate_type; - static inline void apply(Box& box, Point const& source) - { less_type less; greater_type greater; @@ -75,7 +80,6 @@ struct point_loop point_loop < - Box, Point, StrategyLess, StrategyGreater, Dimension + 1, DimensionCount >::apply(box, source); @@ -85,49 +89,47 @@ struct point_loop template < - typename Box, typename Point, typename StrategyLess, typename StrategyGreater, std::size_t DimensionCount > struct point_loop < - Box, Point, StrategyLess, StrategyGreater, DimensionCount, DimensionCount > { + template <typename Box, typename Point> static inline void apply(Box&, Point const&) {} }; template < - typename Box, typename Geometry, typename StrategyLess, typename StrategyGreater, std::size_t Index, std::size_t Dimension, std::size_t DimensionCount > struct indexed_loop { - typedef typename strategy::compare::detail::select_strategy - < - StrategyLess, 1, Box, Dimension - >::type less_type; - - typedef typename strategy::compare::detail::select_strategy - < - StrategyGreater, -1, Box, Dimension - >::type greater_type; + template <typename Box, typename Geometry> + static inline void apply(Box& box, Geometry const& source) + { + typedef typename strategy::compare::detail::select_strategy + < + StrategyLess, 1, Box, Dimension + >::type less_type; - typedef typename select_coordinate_type + typedef typename strategy::compare::detail::select_strategy < - Box, - Geometry - >::type coordinate_type; + StrategyGreater, -1, Box, Dimension + >::type greater_type; + typedef typename select_coordinate_type + < + Box, + Geometry + >::type coordinate_type; - static inline void apply(Box& box, Geometry const& source) - { less_type less; greater_type greater; @@ -145,7 +147,6 @@ struct indexed_loop indexed_loop < - Box, Geometry, StrategyLess, StrategyGreater, Index, Dimension + 1, DimensionCount >::apply(box, source); @@ -155,17 +156,16 @@ struct indexed_loop template < - typename Box, typename Geometry, typename StrategyLess, typename StrategyGreater, std::size_t Index, std::size_t DimensionCount > struct indexed_loop < - Box, Geometry, StrategyLess, StrategyGreater, Index, DimensionCount, DimensionCount > { + template <typename Box, typename Geometry> static inline void apply(Box&, Geometry const&) {} }; @@ -174,23 +174,21 @@ struct indexed_loop // Changes a box such that the other box is also contained by the box template < - typename Box, typename Geometry, typename StrategyLess, typename StrategyGreater > struct expand_indexed { + template <typename Box, typename Geometry> static inline void apply(Box& box, Geometry const& geometry) { indexed_loop < - Box, Geometry, StrategyLess, StrategyGreater, 0, 0, dimension<Geometry>::type::value >::apply(box, geometry); indexed_loop < - Box, Geometry, StrategyLess, StrategyGreater, 1, 0, dimension<Geometry>::type::value >::apply(box, geometry); @@ -206,11 +204,13 @@ namespace dispatch template < - typename Tag, - typename BoxOut, typename Geometry, - typename StrategyLess, typename StrategyGreater + typename GeometryOut, typename Geometry, + typename StrategyLess = strategy::compare::default_strategy, + typename StrategyGreater = strategy::compare::default_strategy, + typename TagOut = typename tag<GeometryOut>::type, + typename Tag = typename tag<Geometry>::type > -struct expand +struct expand: not_implemented<TagOut, Tag> {}; @@ -220,10 +220,9 @@ template typename BoxOut, typename Point, typename StrategyLess, typename StrategyGreater > -struct expand<point_tag, BoxOut, Point, StrategyLess, StrategyGreater> +struct expand<BoxOut, Point, StrategyLess, StrategyGreater, box_tag, point_tag> : detail::expand::point_loop < - BoxOut, Point, StrategyLess, StrategyGreater, 0, dimension<Point>::type::value > @@ -236,9 +235,8 @@ template typename BoxOut, typename BoxIn, typename StrategyLess, typename StrategyGreater > -struct expand<box_tag, BoxOut, BoxIn, StrategyLess, StrategyGreater> - : detail::expand::expand_indexed - <BoxOut, BoxIn, StrategyLess, StrategyGreater> +struct expand<BoxOut, BoxIn, StrategyLess, StrategyGreater, box_tag, box_tag> + : detail::expand::expand_indexed<StrategyLess, StrategyGreater> {}; template @@ -246,9 +244,8 @@ template typename Box, typename Segment, typename StrategyLess, typename StrategyGreater > -struct expand<segment_tag, Box, Segment, StrategyLess, StrategyGreater> - : detail::expand::expand_indexed - <Box, Segment, StrategyLess, StrategyGreater> +struct expand<Box, Segment, StrategyLess, StrategyGreater, box_tag, segment_tag> + : detail::expand::expand_indexed<StrategyLess, StrategyGreater> {}; @@ -256,6 +253,51 @@ struct expand<segment_tag, Box, Segment, StrategyLess, StrategyGreater> #endif // DOXYGEN_NO_DISPATCH +namespace resolve_variant { + +template <typename Geometry> +struct expand +{ + template <typename Box> + static inline void apply(Box& box, Geometry const& geometry) + { + concept::check<Box>(); + concept::check<Geometry const>(); + concept::check_concepts_and_equal_dimensions<Box, Geometry const>(); + + dispatch::expand<Box, Geometry>::apply(box, geometry); + } +}; + +template <BOOST_VARIANT_ENUM_PARAMS(typename T)> +struct expand<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > +{ + template <typename Box> + struct visitor: boost::static_visitor<void> + { + Box& m_box; + + visitor(Box& box) : m_box(box) {} + + template <typename Geometry> + void operator()(Geometry const& geometry) const + { + return expand<Geometry>::apply(m_box, geometry); + } + }; + + template <class Box> + static inline void + apply(Box& box, + boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry) + { + return boost::apply_visitor(visitor<Box>(box), geometry); + } +}; + +} // namespace resolve_variant + + /*** *! \brief Expands a box using the extend (envelope) of another geometry (box, point) @@ -279,13 +321,7 @@ inline void expand(Box& box, Geometry const& geometry, { concept::check_concepts_and_equal_dimensions<Box, Geometry const>(); - dispatch::expand - < - typename tag<Geometry>::type, - Box, - Geometry, - StrategyLess, StrategyGreater - >::apply(box, geometry); + dispatch::expand<Box, Geometry>::apply(box, geometry); } ***/ @@ -303,15 +339,7 @@ inline void expand(Box& box, Geometry const& geometry, template <typename Box, typename Geometry> inline void expand(Box& box, Geometry const& geometry) { - concept::check_concepts_and_equal_dimensions<Box, Geometry const>(); - - dispatch::expand - < - typename tag<Geometry>::type, - Box, Geometry, - strategy::compare::default_strategy, - strategy::compare::default_strategy - >::apply(box, geometry); + resolve_variant::expand<Geometry>::apply(box, geometry); } }} // namespace boost::geometry |