Chris@16: // Boost.Geometry (aka GGL, Generic Geometry Library) Chris@16: Chris@16: // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. Chris@16: // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. Chris@16: // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. Chris@101: // Copyright (c) 2014 Samuel Debionne, Grenoble, France. Chris@16: Chris@16: // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library Chris@16: // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. Chris@16: Chris@16: // Use, modification and distribution is subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP Chris@16: #define BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP Chris@16: Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@101: #include Chris@101: #include Chris@101: #include Chris@101: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: Chris@16: namespace boost { namespace geometry Chris@16: { Chris@16: Chris@16: #ifndef DOXYGEN_NO_DETAIL Chris@16: namespace detail { namespace expand Chris@16: { Chris@16: Chris@16: Chris@16: template Chris@16: < Chris@16: typename StrategyLess, typename StrategyGreater, Chris@16: std::size_t Dimension, std::size_t DimensionCount Chris@16: > Chris@16: struct point_loop Chris@16: { Chris@16: template Chris@16: static inline void apply(Box& box, Point const& source) Chris@16: { Chris@16: typedef typename strategy::compare::detail::select_strategy Chris@16: < Chris@16: StrategyLess, 1, Point, Dimension Chris@16: >::type less_type; Chris@16: Chris@16: typedef typename strategy::compare::detail::select_strategy Chris@16: < Chris@16: StrategyGreater, -1, Point, Dimension Chris@16: >::type greater_type; Chris@16: Chris@16: typedef typename select_coordinate_type::type coordinate_type; Chris@16: Chris@16: less_type less; Chris@16: greater_type greater; Chris@16: Chris@16: coordinate_type const coord = get(source); Chris@16: Chris@16: if (less(coord, get(box))) Chris@16: { Chris@16: set(box, coord); Chris@16: } Chris@16: Chris@16: if (greater(coord, get(box))) Chris@16: { Chris@16: set(box, coord); Chris@16: } Chris@16: Chris@16: point_loop Chris@16: < Chris@16: StrategyLess, StrategyGreater, Chris@16: Dimension + 1, DimensionCount Chris@16: >::apply(box, source); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: < Chris@16: typename StrategyLess, typename StrategyGreater, Chris@16: std::size_t DimensionCount Chris@16: > Chris@16: struct point_loop Chris@16: < Chris@16: StrategyLess, StrategyGreater, Chris@16: DimensionCount, DimensionCount Chris@16: > Chris@16: { Chris@16: template Chris@16: static inline void apply(Box&, Point const&) {} Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: < Chris@16: typename StrategyLess, typename StrategyGreater, Chris@16: std::size_t Index, Chris@16: std::size_t Dimension, std::size_t DimensionCount Chris@16: > Chris@16: struct indexed_loop Chris@16: { Chris@16: template Chris@16: static inline void apply(Box& box, Geometry const& source) Chris@16: { Chris@16: typedef typename strategy::compare::detail::select_strategy Chris@16: < Chris@16: StrategyLess, 1, Box, Dimension Chris@16: >::type less_type; Chris@16: Chris@16: typedef typename strategy::compare::detail::select_strategy Chris@16: < Chris@16: StrategyGreater, -1, Box, Dimension Chris@16: >::type greater_type; Chris@16: Chris@16: typedef typename select_coordinate_type Chris@16: < Chris@16: Box, Chris@16: Geometry Chris@16: >::type coordinate_type; Chris@16: Chris@16: less_type less; Chris@16: greater_type greater; Chris@16: Chris@16: coordinate_type const coord = get(source); Chris@16: Chris@16: if (less(coord, get(box))) Chris@16: { Chris@16: set(box, coord); Chris@16: } Chris@16: Chris@16: if (greater(coord, get(box))) Chris@16: { Chris@16: set(box, coord); Chris@16: } Chris@16: Chris@16: indexed_loop Chris@16: < Chris@16: StrategyLess, StrategyGreater, Chris@16: Index, Dimension + 1, DimensionCount Chris@16: >::apply(box, source); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: < Chris@16: typename StrategyLess, typename StrategyGreater, Chris@16: std::size_t Index, std::size_t DimensionCount Chris@16: > Chris@16: struct indexed_loop Chris@16: < Chris@16: StrategyLess, StrategyGreater, Chris@16: Index, DimensionCount, DimensionCount Chris@16: > Chris@16: { Chris@16: template Chris@16: static inline void apply(Box&, Geometry const&) {} Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@16: // Changes a box such that the other box is also contained by the box Chris@16: template Chris@16: < Chris@16: typename StrategyLess, typename StrategyGreater Chris@16: > Chris@16: struct expand_indexed Chris@16: { Chris@16: template Chris@16: static inline void apply(Box& box, Geometry const& geometry) Chris@16: { Chris@16: indexed_loop Chris@16: < Chris@16: StrategyLess, StrategyGreater, Chris@16: 0, 0, dimension::type::value Chris@16: >::apply(box, geometry); Chris@16: Chris@16: indexed_loop Chris@16: < Chris@16: StrategyLess, StrategyGreater, Chris@16: 1, 0, dimension::type::value Chris@16: >::apply(box, geometry); Chris@16: } Chris@16: }; Chris@16: Chris@16: }} // namespace detail::expand Chris@16: #endif // DOXYGEN_NO_DETAIL Chris@16: Chris@16: #ifndef DOXYGEN_NO_DISPATCH Chris@16: namespace dispatch Chris@16: { Chris@16: Chris@16: template Chris@16: < Chris@16: typename GeometryOut, typename Geometry, Chris@16: typename StrategyLess = strategy::compare::default_strategy, Chris@16: typename StrategyGreater = strategy::compare::default_strategy, Chris@16: typename TagOut = typename tag::type, Chris@16: typename Tag = typename tag::type Chris@16: > Chris@16: struct expand: not_implemented Chris@16: {}; Chris@16: Chris@16: Chris@16: // Box + point -> new box containing also point Chris@16: template Chris@16: < Chris@16: typename BoxOut, typename Point, Chris@16: typename StrategyLess, typename StrategyGreater Chris@16: > Chris@16: struct expand Chris@16: : detail::expand::point_loop Chris@16: < Chris@16: StrategyLess, StrategyGreater, Chris@16: 0, dimension::type::value Chris@16: > Chris@16: {}; Chris@16: Chris@16: Chris@16: // Box + box -> new box containing two input boxes Chris@16: template Chris@16: < Chris@16: typename BoxOut, typename BoxIn, Chris@16: typename StrategyLess, typename StrategyGreater Chris@16: > Chris@16: struct expand Chris@16: : detail::expand::expand_indexed Chris@16: {}; Chris@16: Chris@16: template Chris@16: < Chris@16: typename Box, typename Segment, Chris@16: typename StrategyLess, typename StrategyGreater Chris@16: > Chris@16: struct expand Chris@16: : detail::expand::expand_indexed Chris@16: {}; Chris@16: Chris@16: Chris@16: } // namespace dispatch Chris@16: #endif // DOXYGEN_NO_DISPATCH Chris@16: Chris@16: Chris@101: namespace resolve_variant { Chris@101: Chris@101: template Chris@101: struct expand Chris@101: { Chris@101: template Chris@101: static inline void apply(Box& box, Geometry const& geometry) Chris@101: { Chris@101: concept::check(); Chris@101: concept::check(); Chris@101: concept::check_concepts_and_equal_dimensions(); Chris@101: Chris@101: dispatch::expand::apply(box, geometry); Chris@101: } Chris@101: }; Chris@101: Chris@101: template Chris@101: struct expand > Chris@101: { Chris@101: template Chris@101: struct visitor: boost::static_visitor Chris@101: { Chris@101: Box& m_box; Chris@101: Chris@101: visitor(Box& box) : m_box(box) {} Chris@101: Chris@101: template Chris@101: void operator()(Geometry const& geometry) const Chris@101: { Chris@101: return expand::apply(m_box, geometry); Chris@101: } Chris@101: }; Chris@101: Chris@101: template Chris@101: static inline void Chris@101: apply(Box& box, Chris@101: boost::variant const& geometry) Chris@101: { Chris@101: return boost::apply_visitor(visitor(box), geometry); Chris@101: } Chris@101: }; Chris@101: Chris@101: } // namespace resolve_variant Chris@101: Chris@101: Chris@16: /*** Chris@16: *! Chris@16: \brief Expands a box using the extend (envelope) of another geometry (box, point) Chris@16: \ingroup expand Chris@16: \tparam Box type of the box Chris@16: \tparam Geometry of second geometry, to be expanded with the box Chris@16: \param box box to expand another geometry with, might be changed Chris@16: \param geometry other geometry Chris@16: \param strategy_less Chris@16: \param strategy_greater Chris@16: \note Strategy is currently ignored Chris@16: * Chris@16: template Chris@16: < Chris@16: typename Box, typename Geometry, Chris@16: typename StrategyLess, typename StrategyGreater Chris@16: > Chris@16: inline void expand(Box& box, Geometry const& geometry, Chris@16: StrategyLess const& strategy_less, Chris@16: StrategyGreater const& strategy_greater) Chris@16: { Chris@16: concept::check_concepts_and_equal_dimensions(); Chris@16: Chris@16: dispatch::expand::apply(box, geometry); Chris@16: } Chris@16: ***/ Chris@16: Chris@16: Chris@16: /*! Chris@16: \brief Expands a box using the bounding box (envelope) of another geometry (box, point) Chris@16: \ingroup expand Chris@16: \tparam Box type of the box Chris@16: \tparam Geometry \tparam_geometry Chris@16: \param box box to be expanded using another geometry, mutable Chris@16: \param geometry \param_geometry geometry which envelope (bounding box) will be added to the box Chris@16: Chris@16: \qbk{[include reference/algorithms/expand.qbk]} Chris@16: */ Chris@16: template Chris@16: inline void expand(Box& box, Geometry const& geometry) Chris@16: { Chris@101: resolve_variant::expand::apply(box, geometry); Chris@16: } Chris@16: Chris@16: }} // namespace boost::geometry Chris@16: Chris@16: #endif // BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP