Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:35:18

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