diff options
Diffstat (limited to 'boost/geometry/algorithms/difference.hpp')
-rw-r--r-- | boost/geometry/algorithms/difference.hpp | 305 |
1 files changed, 271 insertions, 34 deletions
diff --git a/boost/geometry/algorithms/difference.hpp b/boost/geometry/algorithms/difference.hpp index f7ca48cbe6..c11ceca243 100644 --- a/boost/geometry/algorithms/difference.hpp +++ b/boost/geometry/algorithms/difference.hpp @@ -2,6 +2,11 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2017. +// Modifications copyright (c) 2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -9,10 +14,16 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP #define BOOST_GEOMETRY_ALGORITHMS_DIFFERENCE_HPP -#include <algorithm> + +#include <boost/variant/apply_visitor.hpp> +#include <boost/variant/static_visitor.hpp> +#include <boost/variant/variant_fwd.hpp> #include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp> #include <boost/geometry/policies/robustness/get_rescale_policy.hpp> +#include <boost/geometry/strategies/default_strategy.hpp> +#include <boost/geometry/util/range.hpp> + namespace boost { namespace geometry { @@ -49,10 +60,10 @@ template typename Strategy > inline OutputIterator difference_insert(Geometry1 const& geometry1, - Geometry2 const& geometry2, - RobustPolicy const& robust_policy, - OutputIterator out, - Strategy const& strategy) + Geometry2 const& geometry2, + RobustPolicy const& robust_policy, + OutputIterator out, + Strategy const& strategy) { concepts::check<Geometry1 const>(); concepts::check<Geometry2 const>(); @@ -93,25 +104,18 @@ template typename OutputIterator > inline OutputIterator difference_insert(Geometry1 const& geometry1, - Geometry2 const& geometry2, - RobustPolicy const& robust_policy, - OutputIterator out) + Geometry2 const& geometry2, + RobustPolicy const& robust_policy, + OutputIterator out) { - concepts::check<Geometry1 const>(); - concepts::check<Geometry2 const>(); - concepts::check<GeometryOut>(); - - typedef intersection_strategies + typedef typename strategy::relate::services::default_strategy < - typename cs_tag<GeometryOut>::type, Geometry1, - Geometry2, - typename geometry::point_type<GeometryOut>::type, - RobustPolicy - > strategy; + Geometry2 + >::type strategy_type; return difference_insert<GeometryOut>(geometry1, geometry2, - robust_policy, out, strategy()); + robust_policy, out, strategy_type()); } @@ -119,6 +123,215 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1, #endif // DOXYGEN_NO_DETAIL +namespace resolve_strategy { + +struct difference +{ + template + < + typename Geometry1, + typename Geometry2, + typename RobustPolicy, + typename Collection, + typename Strategy + > + static inline void apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + RobustPolicy const& robust_policy, + Collection & output_collection, + Strategy const& strategy) + { + typedef typename boost::range_value<Collection>::type geometry_out; + + detail::difference::difference_insert<geometry_out>( + geometry1, geometry2, robust_policy, + range::back_inserter(output_collection), + strategy); + } + + template + < + typename Geometry1, + typename Geometry2, + typename RobustPolicy, + typename Collection + > + static inline void apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + RobustPolicy const& robust_policy, + Collection & output_collection, + default_strategy) + { + typedef typename boost::range_value<Collection>::type geometry_out; + + detail::difference::difference_insert<geometry_out>( + geometry1, geometry2, robust_policy, + range::back_inserter(output_collection)); + } +}; + +} // resolve_strategy + + +namespace resolve_variant +{ + +template <typename Geometry1, typename Geometry2> +struct difference +{ + template <typename Collection, typename Strategy> + static inline void apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Collection& output_collection, + Strategy const& strategy) + { + typedef typename geometry::rescale_overlay_policy_type + < + Geometry1, + Geometry2 + >::type rescale_policy_type; + + rescale_policy_type robust_policy + = geometry::get_rescale_policy<rescale_policy_type>(geometry1, + geometry2); + + resolve_strategy::difference::apply(geometry1, geometry2, + robust_policy, + output_collection, + strategy); + } +}; + + +template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2> +struct difference<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2> +{ + template <typename Collection, typename Strategy> + struct visitor: static_visitor<> + { + Geometry2 const& m_geometry2; + Collection& m_output_collection; + Strategy const& m_strategy; + + visitor(Geometry2 const& geometry2, + Collection& output_collection, + Strategy const& strategy) + : m_geometry2(geometry2) + , m_output_collection(output_collection) + , m_strategy(strategy) + {} + + template <typename Geometry1> + void operator()(Geometry1 const& geometry1) const + { + difference + < + Geometry1, + Geometry2 + >::apply(geometry1, m_geometry2, m_output_collection, m_strategy); + } + }; + + template <typename Collection, typename Strategy> + static inline void + apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1, + Geometry2 const& geometry2, + Collection& output_collection, + Strategy const& strategy) + { + boost::apply_visitor(visitor<Collection, Strategy>(geometry2, + output_collection, + strategy), + geometry1); + } +}; + + +template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)> +struct difference<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> > +{ + template <typename Collection, typename Strategy> + struct visitor: static_visitor<> + { + Geometry1 const& m_geometry1; + Collection& m_output_collection; + Strategy const& m_strategy; + + visitor(Geometry1 const& geometry1, + Collection& output_collection, + Strategy const& strategy) + : m_geometry1(geometry1) + , m_output_collection(output_collection) + , m_strategy(strategy) + {} + + template <typename Geometry2> + void operator()(Geometry2 const& geometry2) const + { + difference + < + Geometry1, + Geometry2 + >::apply(m_geometry1, geometry2, m_output_collection, m_strategy); + } + }; + + template <typename Collection, typename Strategy> + static inline void + apply(Geometry1 const& geometry1, + variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2, + Collection& output_collection, + Strategy const& strategy) + { + boost::apply_visitor(visitor<Collection, Strategy>(geometry1, + output_collection, + strategy), + geometry2); + } +}; + + +template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)> +struct difference<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> > +{ + template <typename Collection, typename Strategy> + struct visitor: static_visitor<> + { + Collection& m_output_collection; + Strategy const& m_strategy; + + visitor(Collection& output_collection, Strategy const& strategy) + : m_output_collection(output_collection) + , m_strategy(strategy) + {} + + template <typename Geometry1, typename Geometry2> + void operator()(Geometry1 const& geometry1, + Geometry2 const& geometry2) const + { + difference + < + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, m_output_collection, m_strategy); + } + }; + + template <typename Collection, typename Strategy> + static inline void + apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1, + variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2, + Collection& output_collection, + Strategy const& strategy) + { + boost::apply_visitor(visitor<Collection, Strategy>(output_collection, + strategy), + geometry1, geometry2); + } +}; + +} // namespace resolve_variant + /*! \brief_calc2{difference} @@ -127,39 +340,63 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1, \tparam Geometry1 \tparam_geometry \tparam Geometry2 \tparam_geometry \tparam Collection \tparam_output_collection +\tparam Strategy \tparam_strategy{Difference} \param geometry1 \param_geometry \param geometry2 \param_geometry \param output_collection the output collection +\param strategy \param_strategy{difference} +\qbk{distinguish,with strategy} \qbk{[include reference/algorithms/difference.qbk]} */ template < typename Geometry1, typename Geometry2, - typename Collection + typename Collection, + typename Strategy > inline void difference(Geometry1 const& geometry1, - Geometry2 const& geometry2, Collection& output_collection) + Geometry2 const& geometry2, + Collection& output_collection, + Strategy const& strategy) { - concepts::check<Geometry1 const>(); - concepts::check<Geometry2 const>(); - - typedef typename boost::range_value<Collection>::type geometry_out; - concepts::check<geometry_out>(); - - typedef typename geometry::rescale_overlay_policy_type + resolve_variant::difference < Geometry1, Geometry2 - >::type rescale_policy_type; + >::apply(geometry1, geometry2, output_collection, strategy); +} - rescale_policy_type robust_policy - = geometry::get_rescale_policy<rescale_policy_type>(geometry1, geometry2); - detail::difference::difference_insert<geometry_out>( - geometry1, geometry2, robust_policy, - range::back_inserter(output_collection)); +/*! +\brief_calc2{difference} +\ingroup difference +\details \details_calc2{difference, spatial set theoretic difference}. +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam Collection \tparam_output_collection +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param output_collection the output collection + +\qbk{[include reference/algorithms/difference.qbk]} +*/ +template +< + typename Geometry1, + typename Geometry2, + typename Collection +> +inline void difference(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Collection& output_collection) +{ + resolve_variant::difference + < + Geometry1, + Geometry2 + >::apply(geometry1, geometry2, output_collection, default_strategy()); } |