Warning, file /include/boost/geometry/algorithms/union.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
0016 #define BOOST_GEOMETRY_ALGORITHMS_UNION_HPP
0017
0018
0019 #include <boost/geometry/algorithms/detail/gc_group_elements.hpp>
0020 #include <boost/geometry/algorithms/detail/intersection/gc.hpp>
0021 #include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
0022 #include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
0023 #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
0024 #include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
0025 #include <boost/geometry/algorithms/not_implemented.hpp>
0026 #include <boost/geometry/core/point_order.hpp>
0027 #include <boost/geometry/core/primary_single_tag.hpp>
0028 #include <boost/geometry/core/reverse_dispatch.hpp>
0029 #include <boost/geometry/core/tag_cast.hpp>
0030 #include <boost/geometry/geometries/adapted/boost_variant.hpp>
0031 #include <boost/geometry/geometries/concepts/check.hpp>
0032 #include <boost/geometry/strategies/default_strategy.hpp>
0033 #include <boost/geometry/strategies/detail.hpp>
0034 #include <boost/geometry/strategies/relate/cartesian.hpp>
0035 #include <boost/geometry/strategies/relate/geographic.hpp>
0036 #include <boost/geometry/strategies/relate/spherical.hpp>
0037 #include <boost/geometry/util/type_traits_std.hpp>
0038 #include <boost/geometry/views/detail/geometry_collection_view.hpp>
0039 #include <boost/geometry/views/detail/random_access_view.hpp>
0040
0041
0042 namespace boost { namespace geometry
0043 {
0044
0045 #ifndef DOXYGEN_NO_DISPATCH
0046 namespace dispatch
0047 {
0048
0049 template
0050 <
0051 typename Geometry1, typename Geometry2, typename GeometryOut,
0052 typename TagIn1 = tag_t<Geometry1>,
0053 typename TagIn2 = tag_t<Geometry2>,
0054 typename TagOut = typename detail::setop_insert_output_tag<GeometryOut>::type,
0055 typename CastedTagIn1 = tag_cast_t<TagIn1, areal_tag, linear_tag, pointlike_tag>,
0056 typename CastedTagIn2 = tag_cast_t<TagIn2, areal_tag, linear_tag, pointlike_tag>,
0057 typename CastedTagOut = tag_cast_t<TagOut, areal_tag, linear_tag, pointlike_tag>,
0058 bool Reverse = geometry::reverse_dispatch<Geometry1, Geometry2>::type::value
0059 >
0060 struct union_insert: not_implemented<TagIn1, TagIn2, TagOut>
0061 {};
0062
0063
0064
0065
0066 template
0067 <
0068 typename Geometry1, typename Geometry2, typename GeometryOut,
0069 typename TagIn1, typename TagIn2, typename TagOut,
0070 typename CastedTagIn1, typename CastedTagIn2, typename CastedTagOut
0071 >
0072 struct union_insert
0073 <
0074 Geometry1, Geometry2, GeometryOut,
0075 TagIn1, TagIn2, TagOut,
0076 CastedTagIn1, CastedTagIn2, CastedTagOut,
0077 true
0078 >
0079 {
0080 template <typename OutputIterator, typename Strategy>
0081 static inline OutputIterator apply(Geometry1 const& g1,
0082 Geometry2 const& g2,
0083 OutputIterator out,
0084 Strategy const& strategy)
0085 {
0086 return union_insert
0087 <
0088 Geometry2, Geometry1, GeometryOut
0089 >::apply(g2, g1, out, strategy);
0090 }
0091 };
0092
0093
0094 template
0095 <
0096 typename Geometry1, typename Geometry2, typename GeometryOut,
0097 typename TagIn1, typename TagIn2, typename TagOut
0098 >
0099 struct union_insert
0100 <
0101 Geometry1, Geometry2, GeometryOut,
0102 TagIn1, TagIn2, TagOut,
0103 areal_tag, areal_tag, areal_tag,
0104 false
0105 > : detail::overlay::overlay
0106 <
0107 Geometry1, Geometry2,
0108 detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
0109 detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
0110 detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
0111 GeometryOut,
0112 overlay_union
0113 >
0114 {};
0115
0116
0117
0118 template
0119 <
0120 typename Linear1, typename Linear2, typename LineStringOut,
0121 typename TagIn1, typename TagIn2
0122 >
0123 struct union_insert
0124 <
0125 Linear1, Linear2, LineStringOut,
0126 TagIn1, TagIn2, linestring_tag,
0127 linear_tag, linear_tag, linear_tag,
0128 false
0129 > : detail::overlay::linear_linear_linestring
0130 <
0131 Linear1, Linear2, LineStringOut, overlay_union
0132 >
0133 {};
0134
0135
0136
0137 template
0138 <
0139 typename PointLike1, typename PointLike2, typename PointOut,
0140 typename TagIn1, typename TagIn2
0141 >
0142 struct union_insert
0143 <
0144 PointLike1, PointLike2, PointOut,
0145 TagIn1, TagIn2, point_tag,
0146 pointlike_tag, pointlike_tag, pointlike_tag,
0147 false
0148 > : detail::overlay::union_pointlike_pointlike_point
0149 <
0150 PointLike1, PointLike2, PointOut
0151 >
0152 {};
0153
0154
0155 template
0156 <
0157 typename Geometry1, typename Geometry2, typename SingleTupledOut,
0158 typename TagIn1, typename TagIn2,
0159 typename CastedTagIn
0160 >
0161 struct union_insert
0162 <
0163 Geometry1, Geometry2, SingleTupledOut,
0164 TagIn1, TagIn2, detail::tupled_output_tag,
0165 CastedTagIn, CastedTagIn, detail::tupled_output_tag,
0166 false
0167 >
0168 {
0169 using single_tag = primary_single_tag_t<CastedTagIn>;
0170
0171 using expect_check = detail::expect_output
0172 <
0173 Geometry1, Geometry2, SingleTupledOut, single_tag
0174 >;
0175
0176 using access = typename geometry::detail::output_geometry_access
0177 <
0178 SingleTupledOut, single_tag, single_tag
0179 >;
0180
0181 template <typename OutputIterator, typename Strategy>
0182 static inline OutputIterator apply(Geometry1 const& g1,
0183 Geometry2 const& g2,
0184 OutputIterator out,
0185 Strategy const& strategy)
0186 {
0187 access::get(out) = union_insert
0188 <
0189 Geometry2, Geometry1, typename access::type
0190 >::apply(g2, g1, access::get(out), strategy);
0191
0192 return out;
0193 }
0194 };
0195
0196
0197 template
0198 <
0199 typename Geometry1, typename Geometry2, typename SingleTupledOut,
0200 typename SingleTag1, typename SingleTag2,
0201 bool Geometry1LesserTopoDim = (topological_dimension<Geometry1>::value
0202 < topological_dimension<Geometry2>::value)
0203 >
0204 struct union_insert_tupled_different
0205 {
0206 using access1 = typename geometry::detail::output_geometry_access
0207 <
0208 SingleTupledOut, SingleTag1, SingleTag1
0209 >;
0210
0211 using access2 = typename geometry::detail::output_geometry_access
0212 <
0213 SingleTupledOut, SingleTag2, SingleTag2
0214 >;
0215
0216 template <typename OutputIterator, typename Strategy>
0217 static inline OutputIterator apply(Geometry1 const& g1,
0218 Geometry2 const& g2,
0219 OutputIterator out,
0220 Strategy const& strategy)
0221 {
0222 access1::get(out) = geometry::dispatch::intersection_insert
0223 <
0224 Geometry1, Geometry2,
0225 typename access1::type,
0226 overlay_difference,
0227 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
0228 geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
0229 >::apply(g1, g2, access1::get(out), strategy);
0230
0231 access2::get(out) = geometry::detail::convert_to_output
0232 <
0233 Geometry2,
0234 typename access2::type
0235 >::apply(g2, access2::get(out));
0236
0237 return out;
0238 }
0239 };
0240
0241
0242 template
0243 <
0244 typename Geometry1, typename Geometry2, typename SingleTupledOut,
0245 typename SingleTag1, typename SingleTag2
0246 >
0247 struct union_insert_tupled_different
0248 <
0249 Geometry1, Geometry2, SingleTupledOut, SingleTag1, SingleTag2, false
0250 >
0251 {
0252 template <typename OutputIterator, typename Strategy>
0253 static inline OutputIterator apply(Geometry1 const& g1,
0254 Geometry2 const& g2,
0255 OutputIterator out,
0256 Strategy const& strategy)
0257 {
0258 return union_insert_tupled_different
0259 <
0260 Geometry2, Geometry1, SingleTupledOut, SingleTag2, SingleTag1, true
0261 >::apply(g2, g1, out, strategy);
0262 }
0263 };
0264
0265
0266 template
0267 <
0268 typename Geometry1, typename Geometry2, typename SingleTupledOut,
0269 typename TagIn1, typename TagIn2,
0270 typename CastedTagIn1, typename CastedTagIn2
0271 >
0272 struct union_insert
0273 <
0274 Geometry1, Geometry2, SingleTupledOut,
0275 TagIn1, TagIn2, detail::tupled_output_tag,
0276 CastedTagIn1, CastedTagIn2, detail::tupled_output_tag,
0277 false
0278 >
0279 {
0280 using single_tag1 = primary_single_tag_t<CastedTagIn1>;
0281
0282 using expect_check1 = detail::expect_output
0283 <
0284 Geometry1, Geometry2, SingleTupledOut, single_tag1
0285 >;
0286
0287 using single_tag2 = primary_single_tag_t<CastedTagIn2>;
0288
0289 using expect_check2 = detail::expect_output
0290 <
0291 Geometry1, Geometry2, SingleTupledOut, single_tag2
0292 >;
0293
0294 template <typename OutputIterator, typename Strategy>
0295 static inline OutputIterator apply(Geometry1 const& g1,
0296 Geometry2 const& g2,
0297 OutputIterator out,
0298 Strategy const& strategy)
0299 {
0300 return union_insert_tupled_different
0301 <
0302 Geometry1, Geometry2, SingleTupledOut, single_tag1, single_tag2
0303 >::apply(g1, g2, out, strategy);
0304 }
0305 };
0306
0307
0308 }
0309 #endif
0310
0311 #ifndef DOXYGEN_NO_DETAIL
0312 namespace detail { namespace union_
0313 {
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329 template
0330 <
0331 typename GeometryOut,
0332 typename Geometry1,
0333 typename Geometry2,
0334 typename OutputIterator
0335 >
0336 inline OutputIterator union_insert(Geometry1 const& geometry1,
0337 Geometry2 const& geometry2,
0338 OutputIterator out)
0339 {
0340 concepts::check<Geometry1 const>();
0341 concepts::check<Geometry2 const>();
0342 geometry::detail::output_geometry_concept_check<GeometryOut>::apply();
0343
0344 typename strategies::relate::services::default_strategy
0345 <
0346 Geometry1, Geometry2
0347 >::type strategy;
0348
0349 return dispatch::union_insert
0350 <
0351 Geometry1, Geometry2, GeometryOut
0352 >::apply(geometry1, geometry2, out, strategy);
0353 }
0354
0355
0356 }}
0357 #endif
0358
0359
0360 namespace resolve_collection
0361 {
0362
0363 template
0364 <
0365 typename Geometry1, typename Geometry2, typename GeometryOut,
0366 typename Tag1 = geometry::tag_t<Geometry1>,
0367 typename Tag2 = geometry::tag_t<Geometry2>,
0368 typename TagOut = geometry::tag_t<GeometryOut>
0369 >
0370 struct union_
0371 {
0372 template <typename Strategy>
0373 static void apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0374 GeometryOut & geometry_out, Strategy const& strategy)
0375 {
0376 using single_out = typename geometry::detail::output_geometry_value
0377 <
0378 GeometryOut
0379 >::type;
0380
0381 dispatch::union_insert
0382 <
0383 Geometry1, Geometry2, single_out
0384 >::apply(geometry1, geometry2,
0385 geometry::detail::output_geometry_back_inserter(geometry_out),
0386 strategy);
0387 }
0388 };
0389
0390 template
0391 <
0392 typename Geometry1, typename Geometry2, typename GeometryOut
0393 >
0394 struct union_
0395 <
0396 Geometry1, Geometry2, GeometryOut,
0397 geometry_collection_tag, geometry_collection_tag, geometry_collection_tag
0398 >
0399 {
0400
0401
0402 using multi_point_t = typename util::sequence_find_if
0403 <
0404 typename traits::geometry_types<GeometryOut>::type,
0405 util::is_multi_point
0406 >::type;
0407 using multi_linestring_t = typename util::sequence_find_if
0408 <
0409 typename traits::geometry_types<GeometryOut>::type,
0410 util::is_multi_linestring
0411 >::type;
0412 using multi_polygon_t = typename util::sequence_find_if
0413 <
0414 typename traits::geometry_types<GeometryOut>::type,
0415 util::is_multi_polygon
0416 >::type;
0417 using tuple_out_t = boost::tuple<multi_point_t, multi_linestring_t, multi_polygon_t>;
0418
0419 template <typename Strategy>
0420 static inline void apply(Geometry1 const& geometry1,
0421 Geometry2 const& geometry2,
0422 GeometryOut& geometry_out,
0423 Strategy const& strategy)
0424 {
0425 detail::random_access_view<Geometry1 const> gc1_view(geometry1);
0426 detail::random_access_view<Geometry2 const> gc2_view(geometry2);
0427
0428 detail::gc_group_elements(gc1_view, gc2_view, strategy,
0429 [&](auto const& inters_group)
0430 {
0431 tuple_out_t out;
0432 merge_group(gc1_view, gc2_view, strategy, inters_group, out);
0433 detail::intersection::gc_move_multi_back(geometry_out, boost::get<0>(out));
0434 detail::intersection::gc_move_multi_back(geometry_out, boost::get<1>(out));
0435 detail::intersection::gc_move_multi_back(geometry_out, boost::get<2>(out));
0436 return true;
0437 },
0438 [&](auto const& disjoint_group)
0439 {
0440 copy_disjoint(gc1_view, gc2_view, disjoint_group, geometry_out);
0441 });
0442 }
0443
0444 private:
0445 template <typename GC1View, typename GC2View, typename Strategy, typename Group>
0446 static inline void merge_group(GC1View const& gc1_view, GC2View const& gc2_view,
0447 Strategy const& strategy, Group const& inters_group,
0448 tuple_out_t& out)
0449 {
0450 for (auto const& id : inters_group)
0451 {
0452 if (id.source_id == 0)
0453 {
0454 traits::iter_visit<GC1View>::apply([&](auto const& g1)
0455 {
0456 merge_one(out, g1, strategy);
0457 }, boost::begin(gc1_view) + id.gc_id);
0458 }
0459 else
0460 {
0461 traits::iter_visit<GC2View>::apply([&](auto const& g2)
0462 {
0463 merge_one(out, g2, strategy);
0464 }, boost::begin(gc2_view) + id.gc_id);
0465 }
0466 }
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487 }
0488
0489 template <typename G, typename Strategy, std::enable_if_t<util::is_pointlike<G>::value, int> = 0>
0490 static inline void merge_one(tuple_out_t& out, G const& g, Strategy const& strategy)
0491 {
0492 multi_point_t p;
0493 union_<multi_point_t, G, multi_point_t>::apply(boost::get<0>(out), g, p, strategy);
0494 boost::get<0>(out) = std::move(p);
0495 }
0496
0497 template <typename G, typename Strategy, std::enable_if_t<util::is_linear<G>::value, int> = 0>
0498 static inline void merge_one(tuple_out_t& out, G const& g, Strategy const& strategy)
0499 {
0500 multi_linestring_t l;
0501 union_<multi_linestring_t, G, multi_linestring_t>::apply(boost::get<1>(out), g, l, strategy);
0502 boost::get<1>(out) = std::move(l);
0503 }
0504
0505 template <typename G, typename Strategy, std::enable_if_t<util::is_areal<G>::value, int> = 0>
0506 static inline void merge_one(tuple_out_t& out, G const& g, Strategy const& strategy)
0507 {
0508 multi_polygon_t a;
0509 union_<multi_polygon_t, G, multi_polygon_t>::apply(boost::get<2>(out), g, a, strategy);
0510 boost::get<2>(out) = std::move(a);
0511 }
0512
0513 template <typename GC1View, typename GC2View, typename Group>
0514 static inline void copy_disjoint(GC1View const& gc1_view, GC2View const& gc2_view,
0515 Group const& disjoint_group, GeometryOut& geometry_out)
0516 {
0517 for (auto const& id : disjoint_group)
0518 {
0519 if (id.source_id == 0)
0520 {
0521 traits::iter_visit<GC1View>::apply([&](auto const& g1)
0522 {
0523 copy_one(g1, geometry_out);
0524 }, boost::begin(gc1_view) + id.gc_id);
0525 }
0526 else
0527 {
0528 traits::iter_visit<GC2View>::apply([&](auto const& g2)
0529 {
0530 copy_one(g2, geometry_out);
0531 }, boost::begin(gc2_view) + id.gc_id);
0532 }
0533 }
0534 }
0535
0536 template <typename G, std::enable_if_t<util::is_pointlike<G>::value, int> = 0>
0537 static inline void copy_one(G const& g, GeometryOut& geometry_out)
0538 {
0539 multi_point_t p;
0540 geometry::convert(g, p);
0541 detail::intersection::gc_move_multi_back(geometry_out, p);
0542 }
0543
0544 template <typename G, std::enable_if_t<util::is_linear<G>::value, int> = 0>
0545 static inline void copy_one(G const& g, GeometryOut& geometry_out)
0546 {
0547 multi_linestring_t l;
0548 geometry::convert(g, l);
0549 detail::intersection::gc_move_multi_back(geometry_out, l);
0550 }
0551
0552 template <typename G, std::enable_if_t<util::is_areal<G>::value, int> = 0>
0553 static inline void copy_one(G const& g, GeometryOut& geometry_out)
0554 {
0555 multi_polygon_t a;
0556 geometry::convert(g, a);
0557 detail::intersection::gc_move_multi_back(geometry_out, a);
0558 }
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573 };
0574
0575 template
0576 <
0577 typename Geometry1, typename Geometry2, typename GeometryOut, typename Tag1
0578 >
0579 struct union_
0580 <
0581 Geometry1, Geometry2, GeometryOut,
0582 Tag1, geometry_collection_tag, geometry_collection_tag
0583 >
0584 {
0585 template <typename Strategy>
0586 static inline void apply(Geometry1 const& geometry1,
0587 Geometry2 const& geometry2,
0588 GeometryOut& geometry_out,
0589 Strategy const& strategy)
0590 {
0591 using gc_view_t = geometry::detail::geometry_collection_view<Geometry1>;
0592 union_
0593 <
0594 gc_view_t, Geometry2, GeometryOut
0595 >::apply(gc_view_t(geometry1), geometry2, geometry_out, strategy);
0596 }
0597 };
0598
0599 template
0600 <
0601 typename Geometry1, typename Geometry2, typename GeometryOut, typename Tag2
0602 >
0603 struct union_
0604 <
0605 Geometry1, Geometry2, GeometryOut,
0606 geometry_collection_tag, Tag2, geometry_collection_tag
0607 >
0608 {
0609 template <typename Strategy>
0610 static inline void apply(Geometry1 const& geometry1,
0611 Geometry2 const& geometry2,
0612 GeometryOut& geometry_out,
0613 Strategy const& strategy)
0614 {
0615 using gc_view_t = geometry::detail::geometry_collection_view<Geometry2>;
0616 union_
0617 <
0618 Geometry1, gc_view_t, GeometryOut
0619 >::apply(geometry1, gc_view_t(geometry2), geometry_out, strategy);
0620 }
0621 };
0622
0623 template
0624 <
0625 typename Geometry1, typename Geometry2, typename GeometryOut, typename Tag1, typename Tag2
0626 >
0627 struct union_
0628 <
0629 Geometry1, Geometry2, GeometryOut,
0630 Tag1, Tag2, geometry_collection_tag
0631 >
0632 {
0633 template <typename Strategy>
0634 static inline void apply(Geometry1 const& geometry1,
0635 Geometry2 const& geometry2,
0636 GeometryOut& geometry_out,
0637 Strategy const& strategy)
0638 {
0639 using gc1_view_t = geometry::detail::geometry_collection_view<Geometry1>;
0640 using gc2_view_t = geometry::detail::geometry_collection_view<Geometry2>;
0641 union_
0642 <
0643 gc1_view_t, gc2_view_t, GeometryOut
0644 >::apply(gc1_view_t(geometry1), gc2_view_t(geometry2), geometry_out, strategy);
0645 }
0646 };
0647
0648 }
0649
0650
0651 namespace resolve_strategy {
0652
0653 template
0654 <
0655 typename Strategy,
0656 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0657 >
0658 struct union_
0659 {
0660 template <typename Geometry1, typename Geometry2, typename Collection>
0661 static inline void apply(Geometry1 const& geometry1,
0662 Geometry2 const& geometry2,
0663 Collection & output_collection,
0664 Strategy const& strategy)
0665 {
0666 resolve_collection::union_
0667 <
0668 Geometry1, Geometry2, Collection
0669 >::apply(geometry1, geometry2, output_collection, strategy);
0670 }
0671 };
0672
0673 template <typename Strategy>
0674 struct union_<Strategy, false>
0675 {
0676 template <typename Geometry1, typename Geometry2, typename Collection>
0677 static inline void apply(Geometry1 const& geometry1,
0678 Geometry2 const& geometry2,
0679 Collection & output_collection,
0680 Strategy const& strategy)
0681 {
0682 using strategies::relate::services::strategy_converter;
0683
0684 union_
0685 <
0686 decltype(strategy_converter<Strategy>::get(strategy))
0687 >::apply(geometry1, geometry2, output_collection,
0688 strategy_converter<Strategy>::get(strategy));
0689 }
0690 };
0691
0692 template <>
0693 struct union_<default_strategy, false>
0694 {
0695 template <typename Geometry1, typename Geometry2, typename Collection>
0696 static inline void apply(Geometry1 const& geometry1,
0697 Geometry2 const& geometry2,
0698 Collection & output_collection,
0699 default_strategy)
0700 {
0701 using strategy_type = typename strategies::relate::services::default_strategy
0702 <
0703 Geometry1,
0704 Geometry2
0705 >::type;
0706
0707 union_
0708 <
0709 strategy_type
0710 >::apply(geometry1, geometry2, output_collection, strategy_type());
0711 }
0712 };
0713
0714 }
0715
0716
0717 namespace resolve_dynamic
0718 {
0719
0720 template
0721 <
0722 typename Geometry1, typename Geometry2,
0723 typename Tag1 = geometry::tag_t<Geometry1>,
0724 typename Tag2 = geometry::tag_t<Geometry2>
0725 >
0726 struct union_
0727 {
0728 template <typename Collection, typename Strategy>
0729 static inline void apply(Geometry1 const& geometry1,
0730 Geometry2 const& geometry2,
0731 Collection& output_collection,
0732 Strategy const& strategy)
0733 {
0734 concepts::check<Geometry1 const>();
0735 concepts::check<Geometry2 const>();
0736
0737 geometry::detail::output_geometry_concept_check
0738 <
0739 typename geometry::detail::output_geometry_value
0740 <
0741 Collection
0742 >::type
0743 >::apply();
0744
0745 resolve_strategy::union_
0746 <
0747 Strategy
0748 >::apply(geometry1, geometry2, output_collection, strategy);
0749 }
0750 };
0751
0752
0753 template <typename DynamicGeometry1, typename Geometry2, typename Tag2>
0754 struct union_<DynamicGeometry1, Geometry2, dynamic_geometry_tag, Tag2>
0755 {
0756 template <typename Collection, typename Strategy>
0757 static inline void apply(DynamicGeometry1 const& geometry1, Geometry2 const& geometry2,
0758 Collection& output_collection, Strategy const& strategy)
0759 {
0760 traits::visit<DynamicGeometry1>::apply([&](auto const& g1)
0761 {
0762 union_
0763 <
0764 util::remove_cref_t<decltype(g1)>,
0765 Geometry2
0766 >::apply(g1, geometry2, output_collection, strategy);
0767 }, geometry1);
0768 }
0769 };
0770
0771
0772 template <typename Geometry1, typename DynamicGeometry2, typename Tag1>
0773 struct union_<Geometry1, DynamicGeometry2, Tag1, dynamic_geometry_tag>
0774 {
0775 template <typename Collection, typename Strategy>
0776 static inline void apply(Geometry1 const& geometry1, DynamicGeometry2 const& geometry2,
0777 Collection& output_collection, Strategy const& strategy)
0778 {
0779 traits::visit<DynamicGeometry2>::apply([&](auto const& g2)
0780 {
0781 union_
0782 <
0783 Geometry1,
0784 util::remove_cref_t<decltype(g2)>
0785 >::apply(geometry1, g2, output_collection, strategy);
0786 }, geometry2);
0787 }
0788 };
0789
0790
0791 template <typename DynamicGeometry1, typename DynamicGeometry2>
0792 struct union_<DynamicGeometry1, DynamicGeometry2, dynamic_geometry_tag, dynamic_geometry_tag>
0793 {
0794 template <typename Collection, typename Strategy>
0795 static inline void apply(DynamicGeometry1 const& geometry1, DynamicGeometry2 const& geometry2,
0796 Collection& output_collection, Strategy const& strategy)
0797 {
0798 traits::visit<DynamicGeometry1, DynamicGeometry2>::apply([&](auto const& g1, auto const& g2)
0799 {
0800 union_
0801 <
0802 util::remove_cref_t<decltype(g1)>,
0803 util::remove_cref_t<decltype(g2)>
0804 >::apply(g1, g2, output_collection, strategy);
0805 }, geometry1, geometry2);
0806 }
0807 };
0808
0809
0810 }
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831 template
0832 <
0833 typename Geometry1,
0834 typename Geometry2,
0835 typename Collection,
0836 typename Strategy
0837 >
0838 inline void union_(Geometry1 const& geometry1,
0839 Geometry2 const& geometry2,
0840 Collection& output_collection,
0841 Strategy const& strategy)
0842 {
0843 resolve_dynamic::union_
0844 <
0845 Geometry1,
0846 Geometry2
0847 >::apply(geometry1, geometry2, output_collection, strategy);
0848 }
0849
0850
0851
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866 template
0867 <
0868 typename Geometry1,
0869 typename Geometry2,
0870 typename Collection
0871 >
0872 inline void union_(Geometry1 const& geometry1,
0873 Geometry2 const& geometry2,
0874 Collection& output_collection)
0875 {
0876 resolve_dynamic::union_
0877 <
0878 Geometry1,
0879 Geometry2
0880 >::apply(geometry1, geometry2, output_collection, default_strategy());
0881 }
0882
0883
0884 }}
0885
0886
0887 #endif