File indexing completed on 2025-01-18 09:35:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #ifndef BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
0022 #define BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
0023
0024
0025 #include <boost/range/begin.hpp>
0026 #include <boost/range/end.hpp>
0027 #include <boost/range/reference.hpp>
0028 #include <boost/range/value_type.hpp>
0029
0030 #include <boost/geometry/algorithms/not_implemented.hpp>
0031 #include <boost/geometry/core/closure.hpp>
0032 #include <boost/geometry/core/exterior_ring.hpp>
0033 #include <boost/geometry/core/interior_rings.hpp>
0034 #include <boost/geometry/core/point_type.hpp>
0035 #include <boost/geometry/core/tag_cast.hpp>
0036 #include <boost/geometry/core/tags.hpp>
0037
0038 #include <boost/geometry/geometries/concepts/check.hpp>
0039
0040 #include <boost/geometry/geometries/segment.hpp>
0041
0042 #include <boost/geometry/views/detail/indexed_point_view.hpp>
0043
0044
0045 namespace boost { namespace geometry
0046 {
0047
0048 #ifndef DOXYGEN_NO_DETAIL
0049 namespace detail { namespace for_each
0050 {
0051
0052
0053 struct fe_point_point
0054 {
0055 template <typename Point, typename Functor>
0056 static inline bool apply(Point& point, Functor&& f)
0057 {
0058 return f(point);
0059 }
0060 };
0061
0062
0063 struct fe_segment_point
0064 {
0065 template <typename Point, typename Functor>
0066 static inline bool apply(Point& , Functor&& )
0067 {
0068
0069
0070
0071
0072
0073
0074 return true;
0075 }
0076 };
0077
0078
0079 struct fe_point_segment
0080 {
0081 template <typename Segment, typename Functor>
0082 static inline bool apply(Segment& s, Functor&& f)
0083 {
0084
0085
0086 geometry::detail::indexed_point_view<Segment, 0> p0(s);
0087 geometry::detail::indexed_point_view<Segment, 1> p1(s);
0088 return f(p0) && f(p1);
0089 }
0090 };
0091
0092 struct fe_segment_segment
0093 {
0094 template <typename Segment, typename Functor>
0095 static inline bool apply(Segment& s, Functor&& f)
0096 {
0097
0098
0099 return f(s);
0100 }
0101 };
0102
0103
0104 template <typename Range>
0105 struct fe_range_value
0106 {
0107 typedef util::transcribe_const_t
0108 <
0109 Range,
0110 typename boost::range_value<Range>::type
0111 > type;
0112 };
0113
0114 template <typename Range>
0115 struct fe_point_type
0116 {
0117 typedef util::transcribe_const_t
0118 <
0119 Range,
0120 typename point_type<Range>::type
0121 > type;
0122 };
0123
0124
0125 template <typename Range>
0126 struct fe_point_type_is_referencable
0127 {
0128 static const bool value =
0129 std::is_const<Range>::value
0130 || std::is_same
0131 <
0132 typename boost::range_reference<Range>::type,
0133 typename fe_point_type<Range>::type&
0134 >::value;
0135 };
0136
0137
0138 template
0139 <
0140 typename Range,
0141 bool UseReferences = fe_point_type_is_referencable<Range>::value
0142 >
0143 struct fe_point_call_f
0144 {
0145 template <typename Iterator, typename Functor>
0146 static inline bool apply(Iterator it, Functor&& f)
0147 {
0148
0149
0150 typedef typename fe_point_type<Range>::type point_type;
0151 point_type& p = *it;
0152 return f(p);
0153 }
0154 };
0155
0156 template <typename Range>
0157 struct fe_point_call_f<Range, false>
0158 {
0159 template <typename Iterator, typename Functor>
0160 static inline bool apply(Iterator it, Functor&& f)
0161 {
0162
0163
0164 typedef typename fe_point_type<Range>::type point_type;
0165 point_type p = *it;
0166 bool result = f(p);
0167 *it = p;
0168 return result;
0169 }
0170 };
0171
0172
0173 struct fe_point_range
0174 {
0175 template <typename Range, typename Functor>
0176 static inline bool apply(Range& range, Functor&& f)
0177 {
0178 auto const end = boost::end(range);
0179 for (auto it = boost::begin(range); it != end; ++it)
0180 {
0181 if (! fe_point_call_f<Range>::apply(it, f))
0182 {
0183 return false;
0184 }
0185 }
0186
0187 return true;
0188 }
0189 };
0190
0191
0192 template
0193 <
0194 typename Range,
0195 bool UseReferences = fe_point_type_is_referencable<Range>::value
0196 >
0197 struct fe_segment_call_f
0198 {
0199 template <typename Iterator, typename Functor>
0200 static inline bool apply(Iterator it0, Iterator it1, Functor&& f)
0201 {
0202
0203
0204
0205
0206
0207 typedef typename fe_point_type<Range>::type point_type;
0208 point_type& p0 = *it0;
0209 point_type& p1 = *it1;
0210 model::referring_segment<point_type> s(p0, p1);
0211 return f(s);
0212 }
0213 };
0214
0215 template <typename Range>
0216 struct fe_segment_call_f<Range, false>
0217 {
0218 template <typename Iterator, typename Functor>
0219 static inline bool apply(Iterator it0, Iterator it1, Functor&& f)
0220 {
0221
0222
0223 typedef typename fe_point_type<Range>::type point_type;
0224 point_type p0 = *it0;
0225 point_type p1 = *it1;
0226 model::referring_segment<point_type> s(p0, p1);
0227 bool result = f(s);
0228 *it0 = p0;
0229 *it1 = p1;
0230 return result;
0231 }
0232 };
0233
0234
0235 template <closure_selector Closure>
0236 struct fe_segment_range_with_closure
0237 {
0238 template <typename Range, typename Functor>
0239 static inline bool apply(Range& range, Functor&& f)
0240 {
0241 auto it = boost::begin(range);
0242 auto const end = boost::end(range);
0243 if (it == end)
0244 {
0245 return true;
0246 }
0247
0248 auto previous = it++;
0249 if (it == end)
0250 {
0251 return fe_segment_call_f<Range>::apply(previous, previous, f);
0252 }
0253
0254 while (it != end)
0255 {
0256 if (! fe_segment_call_f<Range>::apply(previous, it, f))
0257 {
0258 return false;
0259 }
0260 previous = it++;
0261 }
0262
0263 return true;
0264 }
0265 };
0266
0267
0268 template <>
0269 struct fe_segment_range_with_closure<open>
0270 {
0271 template <typename Range, typename Functor>
0272 static inline bool apply(Range& range, Functor&& f)
0273 {
0274 if (! fe_segment_range_with_closure<closed>::apply(range, f))
0275 {
0276 return false;
0277 }
0278
0279 auto const begin = boost::begin(range);
0280 auto end = boost::end(range);
0281 if (begin == end)
0282 {
0283 return true;
0284 }
0285
0286 --end;
0287
0288 if (begin == end)
0289 {
0290
0291 return true;
0292 }
0293
0294 return fe_segment_call_f<Range>::apply(end, begin, f);
0295 }
0296 };
0297
0298
0299 struct fe_segment_range
0300 {
0301 template <typename Range, typename Functor>
0302 static inline bool apply(Range& range, Functor&& f)
0303 {
0304 return fe_segment_range_with_closure
0305 <
0306 closure<Range>::value
0307 >::apply(range, f);
0308 }
0309 };
0310
0311
0312 template <typename RangePolicy>
0313 struct for_each_polygon
0314 {
0315 template <typename Polygon, typename Functor>
0316 static inline bool apply(Polygon& poly, Functor&& f)
0317 {
0318 if (! RangePolicy::apply(exterior_ring(poly), f))
0319 {
0320 return false;
0321 }
0322
0323 auto&& rings = interior_rings(poly);
0324 auto const end = boost::end(rings);
0325 for (auto it = boost::begin(rings); it != end; ++it)
0326 {
0327
0328 if (! RangePolicy::apply(*it, f))
0329 {
0330 return false;
0331 }
0332 }
0333
0334 return true;
0335 }
0336
0337 };
0338
0339
0340
0341 template <typename SinglePolicy>
0342 struct for_each_multi
0343 {
0344 template <typename MultiGeometry, typename Functor>
0345 static inline bool apply(MultiGeometry& multi, Functor&& f)
0346 {
0347 auto const end = boost::end(multi);
0348 for (auto it = boost::begin(multi); it != end; ++it)
0349 {
0350
0351 if (! SinglePolicy::apply(*it, f))
0352 {
0353 return false;
0354 }
0355 }
0356
0357 return true;
0358 }
0359 };
0360
0361 }}
0362 #endif
0363
0364
0365 #ifndef DOXYGEN_NO_DISPATCH
0366 namespace dispatch
0367 {
0368
0369 template
0370 <
0371 typename Geometry,
0372 typename Tag = typename tag_cast<typename tag<Geometry>::type, multi_tag>::type
0373 >
0374 struct for_each_point: not_implemented<Tag>
0375 {};
0376
0377
0378 template <typename Point>
0379 struct for_each_point<Point, point_tag>
0380 : detail::for_each::fe_point_point
0381 {};
0382
0383
0384 template <typename Segment>
0385 struct for_each_point<Segment, segment_tag>
0386 : detail::for_each::fe_point_segment
0387 {};
0388
0389
0390 template <typename Linestring>
0391 struct for_each_point<Linestring, linestring_tag>
0392 : detail::for_each::fe_point_range
0393 {};
0394
0395
0396 template <typename Ring>
0397 struct for_each_point<Ring, ring_tag>
0398 : detail::for_each::fe_point_range
0399 {};
0400
0401
0402 template <typename Polygon>
0403 struct for_each_point<Polygon, polygon_tag>
0404 : detail::for_each::for_each_polygon
0405 <
0406 detail::for_each::fe_point_range
0407 >
0408 {};
0409
0410
0411 template <typename MultiGeometry>
0412 struct for_each_point<MultiGeometry, multi_tag>
0413 : detail::for_each::for_each_multi
0414 <
0415
0416 for_each_point
0417 <
0418 typename detail::for_each::fe_range_value
0419 <
0420 MultiGeometry
0421 >::type
0422 >
0423 >
0424 {};
0425
0426
0427 template
0428 <
0429 typename Geometry,
0430 typename Tag = typename tag<Geometry>::type
0431 >
0432 struct for_each_segment: not_implemented<Tag>
0433 {};
0434
0435 template <typename Point>
0436 struct for_each_segment<Point, point_tag>
0437 : detail::for_each::fe_segment_point
0438 {};
0439
0440
0441 template <typename Segment>
0442 struct for_each_segment<Segment, segment_tag>
0443 : detail::for_each::fe_segment_segment
0444 {};
0445
0446
0447 template <typename Linestring>
0448 struct for_each_segment<Linestring, linestring_tag>
0449 : detail::for_each::fe_segment_range
0450 {};
0451
0452
0453 template <typename Ring>
0454 struct for_each_segment<Ring, ring_tag>
0455 : detail::for_each::fe_segment_range
0456 {};
0457
0458
0459 template <typename Polygon>
0460 struct for_each_segment<Polygon, polygon_tag>
0461 : detail::for_each::for_each_polygon
0462 <
0463 detail::for_each::fe_segment_range
0464 >
0465 {};
0466
0467
0468 template <typename MultiPoint>
0469 struct for_each_segment<MultiPoint, multi_point_tag>
0470 : detail::for_each::fe_segment_point
0471 {};
0472
0473
0474 template <typename MultiLinestring>
0475 struct for_each_segment<MultiLinestring, multi_linestring_tag>
0476 : detail::for_each::for_each_multi
0477 <
0478 detail::for_each::fe_segment_range
0479 >
0480 {};
0481
0482 template <typename MultiPolygon>
0483 struct for_each_segment<MultiPolygon, multi_polygon_tag>
0484 : detail::for_each::for_each_multi
0485 <
0486 detail::for_each::for_each_polygon
0487 <
0488 detail::for_each::fe_segment_range
0489 >
0490 >
0491 {};
0492
0493
0494 }
0495 #endif
0496
0497
0498 template<typename Geometry, typename UnaryPredicate>
0499 inline bool all_points_of(Geometry& geometry, UnaryPredicate p)
0500 {
0501 concepts::check<Geometry>();
0502
0503 return dispatch::for_each_point<Geometry>::apply(geometry, p);
0504 }
0505
0506
0507 template<typename Geometry, typename UnaryPredicate>
0508 inline bool all_segments_of(Geometry const& geometry, UnaryPredicate p)
0509 {
0510 concepts::check<Geometry const>();
0511
0512 return dispatch::for_each_segment<Geometry const>::apply(geometry, p);
0513 }
0514
0515
0516 template<typename Geometry, typename UnaryPredicate>
0517 inline bool any_point_of(Geometry& geometry, UnaryPredicate p)
0518 {
0519 concepts::check<Geometry>();
0520
0521 return ! dispatch::for_each_point<Geometry>::apply(geometry, [&](auto&& pt)
0522 {
0523 return ! p(pt);
0524 });
0525 }
0526
0527
0528 template<typename Geometry, typename UnaryPredicate>
0529 inline bool any_segment_of(Geometry const& geometry, UnaryPredicate p)
0530 {
0531 concepts::check<Geometry const>();
0532
0533 return ! dispatch::for_each_segment<Geometry const>::apply(geometry, [&](auto&& s)
0534 {
0535 return ! p(s);
0536 });
0537 }
0538
0539 template<typename Geometry, typename UnaryPredicate>
0540 inline bool none_point_of(Geometry& geometry, UnaryPredicate p)
0541 {
0542 concepts::check<Geometry>();
0543
0544 return dispatch::for_each_point<Geometry>::apply(geometry, [&](auto&& pt)
0545 {
0546 return ! p(pt);
0547 });
0548 }
0549
0550
0551 template<typename Geometry, typename UnaryPredicate>
0552 inline bool none_segment_of(Geometry const& geometry, UnaryPredicate p)
0553 {
0554 concepts::check<Geometry const>();
0555
0556 return dispatch::for_each_segment<Geometry const>::apply(geometry, [&](auto&& s)
0557 {
0558 return ! p(s);
0559 });
0560 }
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577 template<typename Geometry, typename Functor>
0578 inline Functor for_each_point(Geometry& geometry, Functor f)
0579 {
0580 concepts::check<Geometry>();
0581
0582 dispatch::for_each_point<Geometry>::apply(geometry, [&](auto&& pt)
0583 {
0584 f(pt);
0585
0586 return true;
0587 });
0588 return f;
0589 }
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605 template<typename Geometry, typename Functor>
0606 inline Functor for_each_segment(Geometry& geometry, Functor f)
0607 {
0608 concepts::check<Geometry>();
0609
0610 dispatch::for_each_segment<Geometry>::apply(geometry, [&](auto&& s)
0611 {
0612 f(s);
0613
0614 return true;
0615 });
0616 return f;
0617 }
0618
0619
0620 }}
0621
0622
0623 #endif