diff --git a/include/boost/geometry/algorithms/sym_difference.hpp b/include/boost/geometry/algorithms/sym_difference.hpp index 6d9992de7..bf55664ec 100644 --- a/include/boost/geometry/algorithms/sym_difference.hpp +++ b/include/boost/geometry/algorithms/sym_difference.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2015-2021. -// Modifications copyright (c) 2015-2021 Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2022. +// Modifications copyright (c) 2015-2022 Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -20,12 +20,10 @@ #include #include -#include -#include -#include - +#include #include #include +#include #include #include #include @@ -512,7 +510,136 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1, #endif // DOXYGEN_NO_DETAIL -namespace resolve_strategy { +namespace resolve_collection +{ + +template +< + typename Geometry1, typename Geometry2, typename Collection, + typename Tag1 = typename geometry::tag::type, + typename Tag2 = typename geometry::tag::type, + typename CollectionTag = typename geometry::tag::type +> +struct sym_difference +{ + template + static void apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Collection & output_collection, + Strategy const& strategy) + { + typedef typename geometry::detail::output_geometry_value + < + Collection + >::type single_out; + + detail::sym_difference::sym_difference_insert( + geometry1, geometry2, + geometry::detail::output_geometry_back_inserter(output_collection), + strategy); + } +}; + + +template +struct sym_difference + < + Geometry1, Geometry2, Collection, + geometry_collection_tag, geometry_collection_tag, geometry_collection_tag + > +{ + template + static void apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Collection& output_collection, + Strategy const& strategy) + { + Collection temp1, temp2; + resolve_collection::difference + < + Geometry1, Geometry2, Collection + >::apply(geometry1, geometry2, temp1, strategy); + resolve_collection::difference + < + Geometry2, Geometry1, Collection + >::apply(geometry2, geometry1, temp2, strategy); + resolve_collection::union_ + < + Collection, Collection, Collection + >::apply(temp1, temp2, output_collection, strategy); + } +}; + +template +struct sym_difference + < + Geometry1, Geometry2, Collection, + Tag1, geometry_collection_tag, geometry_collection_tag + > +{ + template + static void apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Collection & output_collection, + Strategy const& strategy) + { + using gc_view_t = geometry::detail::geometry_collection_view; + sym_difference + < + gc_view_t, Geometry2, Collection + >::apply(gc_view_t(geometry1), geometry2, output_collection, strategy); + } +}; + +template +struct sym_difference + < + Geometry1, Geometry2, Collection, + geometry_collection_tag, Tag2, geometry_collection_tag + > +{ + template + static void apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Collection & output_collection, + Strategy const& strategy) + { + using gc_view_t = geometry::detail::geometry_collection_view; + sym_difference + < + Geometry1, gc_view_t, Collection + >::apply(geometry1, gc_view_t(geometry2), output_collection, strategy); + } +}; + +template +struct sym_difference + < + Geometry1, Geometry2, Collection, + Tag1, Tag2, geometry_collection_tag + > +{ + template + static void apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Collection & output_collection, + Strategy const& strategy) + { + using gc1_view_t = geometry::detail::geometry_collection_view; + using gc2_view_t = geometry::detail::geometry_collection_view; + sym_difference + < + gc1_view_t, gc2_view_t, Collection + >::apply(gc1_view_t(geometry1), gc2_view_t(geometry2), output_collection, strategy); + } +}; + + +} // namespace resolve_collection + + +namespace resolve_strategy +{ template < @@ -527,15 +654,10 @@ struct sym_difference Collection & output_collection, Strategy const& strategy) { - typedef typename geometry::detail::output_geometry_value + resolve_collection::sym_difference < - Collection - >::type single_out; - - detail::sym_difference::sym_difference_insert( - geometry1, geometry2, - geometry::detail::output_geometry_back_inserter(output_collection), - strategy); + Geometry1, Geometry2, Collection + >::apply(geometry1, geometry2, output_collection, strategy); } }; @@ -582,10 +704,15 @@ struct sym_difference } // resolve_strategy -namespace resolve_variant +namespace resolve_dynamic { -template +template +< + typename Geometry1, typename Geometry2, + typename Tag1 = typename geometry::tag::type, + typename Tag2 = typename geometry::tag::type +> struct sym_difference { template @@ -602,134 +729,60 @@ struct sym_difference }; -template -struct sym_difference, Geometry2> +template +struct sym_difference { template - struct visitor: static_visitor<> + static void apply(DynamicGeometry1 const& geometry1, Geometry2 const& geometry2, + Collection& output_collection, Strategy const& strategy) { - 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 - void operator()(Geometry1 const& geometry1) const + traits::visit::apply([&](auto const& g1) { - sym_difference + resolve_strategy::sym_difference < - Geometry1, - Geometry2 - >::apply(geometry1, m_geometry2, m_output_collection, m_strategy); - } - }; - - template - static inline void - apply(variant const& geometry1, - Geometry2 const& geometry2, - Collection& output_collection, - Strategy const& strategy) - { - boost::apply_visitor(visitor(geometry2, - output_collection, - strategy), - geometry1); + Strategy + >::apply(g1, geometry2, output_collection, strategy); + }, geometry1); } }; -template -struct sym_difference > +template +struct sym_difference { template - struct visitor: static_visitor<> + static void apply(Geometry1 const& geometry1, DynamicGeometry2 const& geometry2, + Collection& output_collection, Strategy const& strategy) { - 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 - void operator()(Geometry2 const& geometry2) const + traits::visit::apply([&](auto const& g2) { - sym_difference + resolve_strategy::sym_difference < - Geometry1, - Geometry2 - >::apply(m_geometry1, geometry2, m_output_collection, m_strategy); - } - }; - - template - static inline void - apply(Geometry1 const& geometry1, - variant const& geometry2, - Collection& output_collection, - Strategy const& strategy) - { - boost::apply_visitor(visitor(geometry1, - output_collection, - strategy), - geometry2); + Strategy + >::apply(geometry1, g2, output_collection, strategy); + }, geometry2); } }; -template -struct sym_difference, variant > +template +struct sym_difference { template - struct visitor: static_visitor<> + static void apply(DynamicGeometry1 const& geometry1, DynamicGeometry2 const& geometry2, + Collection& output_collection, Strategy const& strategy) { - Collection& m_output_collection; - Strategy const& m_strategy; - - visitor(Collection& output_collection, Strategy const& strategy) - : m_output_collection(output_collection) - , m_strategy(strategy) - {} - - template - void operator()(Geometry1 const& geometry1, - Geometry2 const& geometry2) const + traits::visit::apply([&](auto const& g1, auto const& g2) { - sym_difference + resolve_strategy::sym_difference < - Geometry1, - Geometry2 - >::apply(geometry1, geometry2, m_output_collection, m_strategy); - } - }; - - template - static inline void - apply(variant const& geometry1, - variant const& geometry2, - Collection& output_collection, - Strategy const& strategy) - { - boost::apply_visitor(visitor(output_collection, - strategy), - geometry1, geometry2); + Strategy + >::apply(g1, g2, output_collection, strategy); + }, geometry1, geometry2); } }; -} // namespace resolve_variant +} // namespace resolve_dynamic /*! @@ -761,7 +814,7 @@ inline void sym_difference(Geometry1 const& geometry1, Collection& output_collection, Strategy const& strategy) { - resolve_variant::sym_difference + resolve_dynamic::sym_difference < Geometry1, Geometry2 @@ -793,7 +846,7 @@ inline void sym_difference(Geometry1 const& geometry1, Geometry2 const& geometry2, Collection& output_collection) { - resolve_variant::sym_difference + resolve_dynamic::sym_difference < Geometry1, Geometry2