Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:22

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
0004 
0005 // This file was modified by Oracle on 2015-2023.
0006 // Modifications copyright (c) 2015-2023 Oracle and/or its affiliates.
0007 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0008 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0009 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0010 
0011 // Use, modification and distribution is subject to the Boost Software License,
0012 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0013 // http://www.boost.org/LICENSE_1_0.txt)
0014 
0015 #ifndef BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
0016 #define BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP
0017 
0018 
0019 #include <iterator>
0020 
0021 #include <boost/geometry/algorithms/difference.hpp>
0022 #include <boost/geometry/algorithms/union.hpp>
0023 #include <boost/geometry/geometries/adapted/boost_variant.hpp>
0024 #include <boost/geometry/geometries/multi_polygon.hpp>
0025 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
0026 #include <boost/geometry/strategies/default_strategy.hpp>
0027 #include <boost/geometry/strategies/detail.hpp>
0028 #include <boost/geometry/strategies/relate/cartesian.hpp>
0029 #include <boost/geometry/strategies/relate/geographic.hpp>
0030 #include <boost/geometry/strategies/relate/spherical.hpp>
0031 
0032 
0033 namespace boost { namespace geometry
0034 {
0035 
0036 #ifndef DOXYGEN_NO_DETAIL
0037 namespace detail { namespace sym_difference
0038 {
0039 
0040 
0041 template <typename GeometryOut>
0042 struct compute_difference
0043 {
0044     template
0045     <
0046         typename Geometry1,
0047         typename Geometry2,
0048         typename RobustPolicy,
0049         typename OutputIterator,
0050         typename Strategy
0051     >
0052     static inline OutputIterator apply(Geometry1 const& geometry1,
0053                                        Geometry2 const& geometry2,
0054                                        RobustPolicy const& robust_policy,
0055                                        OutputIterator out,
0056                                        Strategy const& strategy)
0057     {
0058         return geometry::dispatch::intersection_insert
0059             <
0060                 Geometry1,
0061                 Geometry2,
0062                 GeometryOut,
0063                 overlay_difference,
0064                 geometry::detail::overlay::do_reverse
0065                     <
0066                         geometry::point_order<Geometry1>::value
0067                     >::value,
0068                 geometry::detail::overlay::do_reverse
0069                     <
0070                         geometry::point_order<Geometry2>::value, true
0071                     >::value
0072             >::apply(geometry1, geometry2, robust_policy, out, strategy);
0073     }
0074 };
0075 
0076 
0077 
0078 template <typename GeometryOut, typename Geometry1, typename Geometry2>
0079 struct sym_difference_generic
0080 {
0081     template
0082     <
0083         typename RobustPolicy,
0084         typename OutputIterator,
0085         typename Strategy
0086     >
0087     static inline OutputIterator apply(Geometry1 const& geometry1,
0088                                        Geometry2 const& geometry2,
0089                                        RobustPolicy const& robust_policy,
0090                                        OutputIterator out,
0091                                        Strategy const& strategy)
0092     {
0093         out = compute_difference
0094             <
0095                 GeometryOut
0096             >::apply(geometry1, geometry2, robust_policy, out, strategy);
0097 
0098         return compute_difference
0099             <
0100                 GeometryOut
0101             >::apply(geometry2, geometry1, robust_policy, out, strategy);
0102     }
0103 };
0104 
0105 
0106 template <typename GeometryOut, typename Areal1, typename Areal2>
0107 struct sym_difference_areal_areal
0108 {
0109     template
0110     <
0111         typename RobustPolicy,
0112         typename OutputIterator,
0113         typename Strategy
0114     >
0115     static inline OutputIterator apply(Areal1 const& areal1,
0116                                        Areal2 const& areal2,
0117                                        RobustPolicy const& robust_policy,
0118                                        OutputIterator out,
0119                                        Strategy const& strategy)
0120     {
0121         typedef geometry::model::multi_polygon
0122             <
0123                 GeometryOut
0124             > helper_geometry_type;
0125 
0126         helper_geometry_type diff12, diff21;
0127 
0128         std::back_insert_iterator<helper_geometry_type> oit12(diff12);
0129         std::back_insert_iterator<helper_geometry_type> oit21(diff21);
0130 
0131         compute_difference
0132             <
0133                 GeometryOut
0134             >::apply(areal1, areal2, robust_policy, oit12, strategy);
0135 
0136         compute_difference
0137             <
0138                 GeometryOut
0139             >::apply(areal2, areal1, robust_policy, oit21, strategy);
0140 
0141         return geometry::dispatch::union_insert
0142             <
0143                 helper_geometry_type,
0144                 helper_geometry_type,
0145                 GeometryOut
0146             >::apply(diff12, diff21, robust_policy, out, strategy);
0147     }
0148 };
0149 
0150 
0151 template
0152 <
0153     typename GeometryOut,
0154     typename SingleTag,
0155     template <typename, typename, typename> class Algorithm
0156 >
0157 struct sym_difference_same_inputs_tupled_output
0158 {
0159     template
0160     <
0161         typename Geometry1,
0162         typename Geometry2,
0163         typename RobustPolicy,
0164         typename OutputIterator,
0165         typename Strategy
0166     >
0167     static inline OutputIterator apply(Geometry1 const& geometry1,
0168                                        Geometry2 const& geometry2,
0169                                        RobustPolicy const& robust_policy,
0170                                        OutputIterator out,
0171                                        Strategy const& strategy)
0172     {
0173         typedef typename geometry::detail::output_geometry_access
0174             <
0175                 GeometryOut, SingleTag, SingleTag
0176             > access;
0177 
0178         access::get(out) = Algorithm
0179             <
0180                 typename access::type, Geometry1, Geometry2
0181             >::apply(geometry1, geometry2, robust_policy, access::get(out), strategy);
0182 
0183         return out;
0184     }
0185 };
0186 
0187 
0188 template
0189 <
0190     typename GeometryOut,
0191     typename SingleTag1,
0192     typename SingleTag2,
0193     bool Reverse = (geometry::core_dispatch::top_dim<SingleTag1>::value
0194                     > geometry::core_dispatch::top_dim<SingleTag2>::value)
0195 >
0196 struct sym_difference_different_inputs_tupled_output
0197 {
0198     template
0199     <
0200         typename Geometry1,
0201         typename Geometry2,
0202         typename RobustPolicy,
0203         typename OutputIterator,
0204         typename Strategy
0205     >
0206     static inline OutputIterator apply(Geometry1 const& geometry1,
0207                                        Geometry2 const& geometry2,
0208                                        RobustPolicy const& robust_policy,
0209                                        OutputIterator out,
0210                                        Strategy const& strategy)
0211     {
0212         return sym_difference_different_inputs_tupled_output
0213             <
0214                 GeometryOut, SingleTag2, SingleTag1
0215             >::apply(geometry2, geometry1, robust_policy, out, strategy);
0216     }
0217 };
0218 
0219 template
0220 <
0221     typename GeometryOut,
0222     typename SingleTag1,
0223     typename SingleTag2
0224 >
0225 struct sym_difference_different_inputs_tupled_output
0226     <
0227         GeometryOut, SingleTag1, SingleTag2, false
0228     >
0229 {
0230     template
0231     <
0232         typename Geometry1,
0233         typename Geometry2,
0234         typename RobustPolicy,
0235         typename OutputIterator,
0236         typename Strategy
0237     >
0238     static inline OutputIterator apply(Geometry1 const& geometry1,
0239                                        Geometry2 const& geometry2,
0240                                        RobustPolicy const& robust_policy,
0241                                        OutputIterator out,
0242                                        Strategy const& strategy)
0243     {
0244         typedef typename geometry::detail::output_geometry_access
0245             <
0246                 GeometryOut, SingleTag1, SingleTag1
0247             > access1;
0248         typedef typename geometry::detail::output_geometry_access
0249             <
0250                 GeometryOut, SingleTag2, SingleTag2
0251             > access2;
0252 
0253         access1::get(out) = compute_difference
0254             <
0255                 typename access1::type
0256             >::apply(geometry1, geometry2, robust_policy, access1::get(out), strategy);
0257 
0258         access2::get(out) = geometry::detail::convert_to_output
0259             <
0260                 Geometry2,
0261                 typename access2::type
0262             >::apply(geometry2, access2::get(out));
0263 
0264         return out;
0265     }
0266 };
0267 
0268 
0269 }} // namespace detail::sym_difference
0270 #endif // DOXYGEN_NO_DETAIL
0271 
0272 
0273 
0274 #ifndef DOXYGEN_NO_DISPATCH
0275 namespace dispatch
0276 {
0277 
0278 
0279 template
0280 <
0281     typename Geometry1,
0282     typename Geometry2,
0283     typename GeometryOut,
0284     typename TagIn1 = typename geometry::tag_cast
0285         <
0286             typename tag<Geometry1>::type, pointlike_tag, linear_tag, areal_tag
0287         >::type,
0288     typename TagIn2 = typename geometry::tag_cast
0289         <
0290             typename tag<Geometry2>::type, pointlike_tag, linear_tag, areal_tag
0291         >::type,
0292     typename TagOut = typename detail::setop_insert_output_tag<GeometryOut>::type
0293 >
0294 struct sym_difference_insert
0295     : detail::sym_difference::sym_difference_generic
0296         <
0297             GeometryOut, Geometry1, Geometry2
0298         >
0299 {};
0300 
0301 
0302 template
0303 <
0304     typename Areal1,
0305     typename Areal2,
0306     typename GeometryOut,
0307     typename TagOut
0308 >
0309 struct sym_difference_insert
0310     <
0311         Areal1, Areal2, GeometryOut,
0312         areal_tag, areal_tag, TagOut
0313     > : detail::sym_difference::sym_difference_areal_areal
0314         <
0315             GeometryOut, Areal1, Areal2
0316         >
0317 {};
0318 
0319 
0320 
0321 template
0322 <
0323     typename PointLike1,
0324     typename PointLike2,
0325     typename GeometryOut
0326 >
0327 struct sym_difference_insert
0328     <
0329         PointLike1, PointLike2, GeometryOut,
0330         pointlike_tag, pointlike_tag, detail::tupled_output_tag
0331     >
0332     : detail::expect_output<PointLike1, PointLike2, GeometryOut, point_tag>
0333     , detail::sym_difference::sym_difference_same_inputs_tupled_output
0334         <
0335             GeometryOut,
0336             point_tag,
0337             detail::sym_difference::sym_difference_generic
0338         >
0339 {};
0340 
0341 template
0342 <
0343     typename Linear1,
0344     typename Linear2,
0345     typename GeometryOut
0346 >
0347 struct sym_difference_insert
0348     <
0349         Linear1, Linear2, GeometryOut,
0350         linear_tag, linear_tag, detail::tupled_output_tag
0351     >
0352     : detail::expect_output<Linear1, Linear2, GeometryOut, linestring_tag>
0353     , detail::sym_difference::sym_difference_same_inputs_tupled_output
0354         <
0355             GeometryOut,
0356             linestring_tag,
0357             detail::sym_difference::sym_difference_generic
0358         >
0359 {};
0360 
0361 template
0362 <
0363     typename Areal1,
0364     typename Areal2,
0365     typename GeometryOut
0366 >
0367 struct sym_difference_insert
0368     <
0369         Areal1, Areal2, GeometryOut,
0370         areal_tag, areal_tag, detail::tupled_output_tag
0371     >
0372     : detail::expect_output<Areal1, Areal2, GeometryOut, polygon_tag>
0373     , detail::sym_difference::sym_difference_same_inputs_tupled_output
0374         <
0375             GeometryOut,
0376             polygon_tag,
0377             detail::sym_difference::sym_difference_areal_areal
0378         >
0379 {};
0380 
0381 template
0382 <
0383     typename Geometry1,
0384     typename Geometry2,
0385     typename GeometryOut,
0386     typename TagIn1,
0387     typename TagIn2
0388 >
0389 struct sym_difference_insert
0390     <
0391         Geometry1, Geometry2, GeometryOut,
0392         TagIn1, TagIn2, detail::tupled_output_tag
0393     >
0394     : detail::expect_output
0395         <
0396             Geometry1, Geometry2, GeometryOut,
0397             typename detail::single_tag_from_base_tag<TagIn1>::type,
0398             typename detail::single_tag_from_base_tag<TagIn2>::type
0399         >
0400     , detail::sym_difference::sym_difference_different_inputs_tupled_output
0401         <
0402             GeometryOut,
0403             typename detail::single_tag_from_base_tag<TagIn1>::type,
0404             typename detail::single_tag_from_base_tag<TagIn2>::type
0405         >
0406 {};
0407 
0408 
0409 } // namespace dispatch
0410 #endif // DOXYGEN_NO_DISPATCH
0411 
0412 
0413 
0414 #ifndef DOXYGEN_NO_DETAIL
0415 namespace detail { namespace sym_difference
0416 {
0417 
0418 
0419 
0420 /*!
0421 \brief \brief_calc2{symmetric difference}  \brief_strategy
0422 \ingroup sym_difference
0423 \details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
0424     \brief_strategy. \details_insert{sym_difference}
0425 \tparam GeometryOut output geometry type, must be specified
0426 \tparam Geometry1 \tparam_geometry
0427 \tparam Geometry2 \tparam_geometry
0428 \tparam Strategy \tparam_strategy_overlay
0429 \param geometry1 \param_geometry
0430 \param geometry2 \param_geometry
0431 \param out \param_out{difference}
0432 \param strategy \param_strategy{difference}
0433 \return \return_out
0434 
0435 \qbk{distinguish,with strategy}
0436 */
0437 template
0438 <
0439     typename GeometryOut,
0440     typename Geometry1,
0441     typename Geometry2,
0442     typename OutputIterator,
0443     typename Strategy
0444 >
0445 inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
0446             Geometry2 const& geometry2,
0447             OutputIterator out,
0448             Strategy const& strategy)
0449 {
0450     concepts::check<Geometry1 const>();
0451     concepts::check<Geometry2 const>();
0452     //concepts::check<GeometryOut>();
0453     geometry::detail::output_geometry_concept_check<GeometryOut>::apply();
0454 
0455     typedef typename geometry::rescale_overlay_policy_type
0456         <
0457             Geometry1,
0458             Geometry2,
0459             typename Strategy::cs_tag
0460         >::type rescale_policy_type;
0461 
0462     rescale_policy_type robust_policy
0463             = geometry::get_rescale_policy<rescale_policy_type>(
0464                 geometry1, geometry2, strategy);
0465 
0466     return dispatch::sym_difference_insert
0467         <
0468             Geometry1, Geometry2, GeometryOut
0469         >::apply(geometry1, geometry2, robust_policy, out, strategy);
0470 }
0471 
0472 
0473 /*!
0474 \brief \brief_calc2{symmetric difference}
0475 \ingroup sym_difference
0476 \details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}
0477     \details_insert{sym_difference}
0478 \tparam GeometryOut output geometry type, must be specified
0479 \tparam Geometry1 \tparam_geometry
0480 \tparam Geometry2 \tparam_geometry
0481 \param geometry1 \param_geometry
0482 \param geometry2 \param_geometry
0483 \param out \param_out{difference}
0484 \return \return_out
0485 
0486 */
0487 template
0488 <
0489     typename GeometryOut,
0490     typename Geometry1,
0491     typename Geometry2,
0492     typename OutputIterator
0493 >
0494 inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
0495             Geometry2 const& geometry2, OutputIterator out)
0496 {
0497     typedef typename strategies::relate::services::default_strategy
0498         <
0499             Geometry1, Geometry2
0500         >::type strategy_type;
0501 
0502     return sym_difference_insert<GeometryOut>(geometry1, geometry2, out, strategy_type());
0503 }
0504 
0505 }} // namespace detail::sym_difference
0506 #endif // DOXYGEN_NO_DETAIL
0507 
0508 
0509 namespace resolve_collection
0510 {
0511 
0512 template
0513 <
0514     typename Geometry1, typename Geometry2, typename Collection,
0515     typename Tag1 = typename geometry::tag<Geometry1>::type,
0516     typename Tag2 = typename geometry::tag<Geometry2>::type,
0517     typename CollectionTag = typename geometry::tag<Collection>::type
0518 >
0519 struct sym_difference
0520 {
0521     template <typename Strategy>
0522     static void apply(Geometry1 const& geometry1,
0523                       Geometry2 const& geometry2,
0524                       Collection & output_collection,
0525                       Strategy const& strategy)
0526     {
0527         typedef typename geometry::detail::output_geometry_value
0528             <
0529                 Collection
0530             >::type single_out;
0531 
0532         detail::sym_difference::sym_difference_insert<single_out>(
0533             geometry1, geometry2,
0534             geometry::detail::output_geometry_back_inserter(output_collection),
0535             strategy);
0536     }
0537 };
0538 
0539 
0540 template <typename Geometry1, typename Geometry2, typename Collection>
0541 struct sym_difference
0542     <
0543         Geometry1, Geometry2, Collection,
0544         geometry_collection_tag, geometry_collection_tag, geometry_collection_tag
0545     >
0546 {
0547     template <typename Strategy>
0548     static void apply(Geometry1 const& geometry1,
0549                       Geometry2 const& geometry2,
0550                       Collection& output_collection,
0551                       Strategy const& strategy)
0552     {
0553         Collection temp1, temp2;
0554         resolve_collection::difference
0555             <
0556                 Geometry1, Geometry2, Collection
0557             >::apply(geometry1, geometry2, temp1, strategy);
0558         resolve_collection::difference
0559             <
0560                 Geometry2, Geometry1, Collection
0561             >::apply(geometry2, geometry1, temp2, strategy);
0562         resolve_collection::union_
0563             <
0564                 Collection, Collection, Collection
0565             >::apply(temp1, temp2, output_collection, strategy);
0566     }
0567 };
0568 
0569 template <typename Geometry1, typename Geometry2, typename Collection, typename Tag1>
0570 struct sym_difference
0571     <
0572         Geometry1, Geometry2, Collection,
0573         Tag1, geometry_collection_tag, geometry_collection_tag
0574     >
0575 {
0576     template <typename Strategy>
0577     static void apply(Geometry1 const& geometry1,
0578                       Geometry2 const& geometry2,
0579                       Collection & output_collection,
0580                       Strategy const& strategy)
0581     {
0582         using gc_view_t = geometry::detail::geometry_collection_view<Geometry1>;
0583         sym_difference
0584             <
0585                 gc_view_t, Geometry2, Collection
0586             >::apply(gc_view_t(geometry1), geometry2, output_collection, strategy);
0587     }
0588 };
0589 
0590 template <typename Geometry1, typename Geometry2, typename Collection, typename Tag2>
0591 struct sym_difference
0592     <
0593         Geometry1, Geometry2, Collection,
0594         geometry_collection_tag, Tag2, geometry_collection_tag
0595     >
0596 {
0597     template <typename Strategy>
0598     static void apply(Geometry1 const& geometry1,
0599                       Geometry2 const& geometry2,
0600                       Collection & output_collection,
0601                       Strategy const& strategy)
0602     {
0603         using gc_view_t = geometry::detail::geometry_collection_view<Geometry2>;
0604         sym_difference
0605             <
0606                 Geometry1, gc_view_t, Collection
0607             >::apply(geometry1, gc_view_t(geometry2), output_collection, strategy);
0608     }
0609 };
0610 
0611 template <typename Geometry1, typename Geometry2, typename Collection, typename Tag1, typename Tag2>
0612 struct sym_difference
0613     <
0614         Geometry1, Geometry2, Collection,
0615         Tag1, Tag2, geometry_collection_tag
0616     >
0617 {
0618     template <typename Strategy>
0619     static void apply(Geometry1 const& geometry1,
0620                       Geometry2 const& geometry2,
0621                       Collection & output_collection,
0622                       Strategy const& strategy)
0623     {
0624         using gc1_view_t = geometry::detail::geometry_collection_view<Geometry1>;
0625         using gc2_view_t = geometry::detail::geometry_collection_view<Geometry2>;
0626         sym_difference
0627             <
0628                 gc1_view_t, gc2_view_t, Collection
0629             >::apply(gc1_view_t(geometry1), gc2_view_t(geometry2), output_collection, strategy);
0630     }
0631 };
0632 
0633 
0634 } // namespace resolve_collection
0635 
0636 
0637 namespace resolve_strategy
0638 {
0639 
0640 template
0641 <
0642     typename Strategy,
0643     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0644 >
0645 struct sym_difference
0646 {
0647     template <typename Geometry1, typename Geometry2, typename Collection>
0648     static inline void apply(Geometry1 const& geometry1,
0649                              Geometry2 const& geometry2,
0650                              Collection & output_collection,
0651                              Strategy const& strategy)
0652     {
0653         resolve_collection::sym_difference
0654             <
0655                 Geometry1, Geometry2, Collection
0656             >::apply(geometry1, geometry2, output_collection, strategy);
0657     }
0658 };
0659 
0660 template <typename Strategy>
0661 struct sym_difference<Strategy, false>
0662 {
0663     template <typename Geometry1, typename Geometry2, typename Collection>
0664     static inline void apply(Geometry1 const& geometry1,
0665                              Geometry2 const& geometry2,
0666                              Collection & output_collection,
0667                              Strategy const& strategy)
0668     {
0669         using strategies::relate::services::strategy_converter;
0670 
0671         sym_difference
0672             <
0673                 decltype(strategy_converter<Strategy>::get(strategy))
0674             >::apply(geometry1, geometry2, output_collection,
0675                      strategy_converter<Strategy>::get(strategy));
0676     }
0677 };
0678 
0679 template <>
0680 struct sym_difference<default_strategy, false>
0681 {
0682     template <typename Geometry1, typename Geometry2, typename Collection>
0683     static inline void apply(Geometry1 const& geometry1,
0684                              Geometry2 const& geometry2,
0685                              Collection & output_collection,
0686                              default_strategy)
0687     {
0688         typedef typename strategies::relate::services::default_strategy
0689             <
0690                 Geometry1, Geometry2
0691             >::type strategy_type;
0692 
0693         sym_difference
0694             <
0695                 strategy_type
0696             >::apply(geometry1, geometry2, output_collection, strategy_type());
0697     }
0698 };
0699 
0700 } // resolve_strategy
0701 
0702 
0703 namespace resolve_dynamic
0704 {
0705 
0706 template
0707 <
0708     typename Geometry1, typename Geometry2,
0709     typename Tag1 = typename geometry::tag<Geometry1>::type,
0710     typename Tag2 = typename geometry::tag<Geometry2>::type
0711 >
0712 struct sym_difference
0713 {
0714     template <typename Collection, typename Strategy>
0715     static inline void apply(Geometry1 const& geometry1,
0716                              Geometry2 const& geometry2,
0717                              Collection& output_collection,
0718                              Strategy const& strategy)
0719     {
0720         resolve_strategy::sym_difference
0721             <
0722                 Strategy
0723             >::apply(geometry1, geometry2, output_collection, strategy);
0724     }
0725 };
0726 
0727 
0728 template <typename DynamicGeometry1, typename Geometry2, typename Tag2>
0729 struct sym_difference<DynamicGeometry1, Geometry2, dynamic_geometry_tag, Tag2>
0730 {
0731     template <typename Collection, typename Strategy>
0732     static void apply(DynamicGeometry1 const& geometry1, Geometry2 const& geometry2,
0733                       Collection& output_collection, Strategy const& strategy)
0734     {
0735         traits::visit<DynamicGeometry1>::apply([&](auto const& g1)
0736         {
0737             resolve_strategy::sym_difference
0738                 <
0739                     Strategy
0740                 >::apply(g1, geometry2, output_collection, strategy);
0741         }, geometry1);
0742     }
0743 };
0744 
0745 
0746 template <typename Geometry1, typename DynamicGeometry2, typename Tag1>
0747 struct sym_difference<Geometry1, DynamicGeometry2, Tag1, dynamic_geometry_tag>
0748 {
0749     template <typename Collection, typename Strategy>
0750     static void apply(Geometry1 const& geometry1, DynamicGeometry2 const& geometry2,
0751                       Collection& output_collection, Strategy const& strategy)
0752     {
0753         traits::visit<DynamicGeometry2>::apply([&](auto const& g2)
0754         {
0755             resolve_strategy::sym_difference
0756                 <
0757                     Strategy
0758                 >::apply(geometry1, g2, output_collection, strategy);
0759         }, geometry2);
0760     }
0761 };
0762 
0763 
0764 template <typename DynamicGeometry1, typename DynamicGeometry2>
0765 struct sym_difference<DynamicGeometry1, DynamicGeometry2, dynamic_geometry_tag, dynamic_geometry_tag>
0766 {
0767     template <typename Collection, typename Strategy>
0768     static void apply(DynamicGeometry1 const& geometry1, DynamicGeometry2 const& geometry2,
0769                       Collection& output_collection, Strategy const& strategy)
0770     {
0771         traits::visit<DynamicGeometry1, DynamicGeometry2>::apply([&](auto const& g1, auto const& g2)
0772         {
0773             resolve_strategy::sym_difference
0774                 <
0775                     Strategy
0776                 >::apply(g1, g2, output_collection, strategy);
0777         }, geometry1, geometry2);
0778     }
0779 };
0780 
0781 } // namespace resolve_dynamic
0782 
0783 
0784 /*!
0785 \brief \brief_calc2{symmetric difference}
0786 \ingroup sym_difference
0787 \details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}.
0788 \tparam Geometry1 \tparam_geometry
0789 \tparam Geometry2 \tparam_geometry
0790 \tparam Collection output collection, either a multi-geometry,
0791     or a std::vector<Geometry> / std::deque<Geometry> etc
0792 \tparam Strategy \tparam_strategy{Sym_difference}
0793 \param geometry1 \param_geometry
0794 \param geometry2 \param_geometry
0795 \param output_collection the output collection
0796 \param strategy \param_strategy{sym_difference}
0797 
0798 \qbk{distinguish,with strategy}
0799 \qbk{[include reference/algorithms/sym_difference.qbk]}
0800 */
0801 template
0802 <
0803     typename Geometry1,
0804     typename Geometry2,
0805     typename Collection,
0806     typename Strategy
0807 >
0808 inline void sym_difference(Geometry1 const& geometry1,
0809                            Geometry2 const& geometry2,
0810                            Collection& output_collection,
0811                            Strategy const& strategy)
0812 {
0813     resolve_dynamic::sym_difference
0814         <
0815             Geometry1,
0816             Geometry2
0817         >::apply(geometry1, geometry2, output_collection, strategy);
0818 }
0819 
0820 
0821 /*!
0822 \brief \brief_calc2{symmetric difference}
0823 \ingroup sym_difference
0824 \details \details_calc2{symmetric difference, spatial set theoretic symmetric difference (XOR)}.
0825 \tparam Geometry1 \tparam_geometry
0826 \tparam Geometry2 \tparam_geometry
0827 \tparam Collection output collection, either a multi-geometry,
0828     or a std::vector<Geometry> / std::deque<Geometry> etc
0829 \param geometry1 \param_geometry
0830 \param geometry2 \param_geometry
0831 \param output_collection the output collection
0832 
0833 \qbk{[include reference/algorithms/sym_difference.qbk]}
0834 */
0835 template
0836 <
0837     typename Geometry1,
0838     typename Geometry2,
0839     typename Collection
0840 >
0841 inline void sym_difference(Geometry1 const& geometry1,
0842                            Geometry2 const& geometry2,
0843                            Collection& output_collection)
0844 {
0845     resolve_dynamic::sym_difference
0846         <
0847             Geometry1,
0848             Geometry2
0849         >::apply(geometry1, geometry2, output_collection, default_strategy());
0850 }
0851 
0852 
0853 }} // namespace boost::geometry
0854 
0855 
0856 #endif // BOOST_GEOMETRY_ALGORITHMS_SYM_DIFFERENCE_HPP