Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
0006 // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
0007 
0008 // This file was modified by Oracle on 2014-2023.
0009 // Modifications copyright (c) 2014-2023, Oracle and/or its affiliates.
0010 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0011 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0012 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0013 
0014 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0015 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0016 
0017 // Use, modification and distribution is subject to the Boost Software License,
0018 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0019 // http://www.boost.org/LICENSE_1_0.txt)
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         // TODO: if non-const, we should extract the points from the segment
0069         // and call the functor on those two points
0070 
0071         //model::referring_segment<Point> s(point, point);
0072         //return f(s);
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         // Or should we guarantee that the type of points is
0085         // point_type<Segment>::type ?
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         // Or should we guarantee that the type of segment is
0098         // referring_segment<...> ?
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         // Implementation for real references (both const and mutable)
0149         // and const proxy references.
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         // Implementation for proxy mutable references.
0163         // Temporary point has to be created and assigned afterwards.
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         // Implementation for real references (both const and mutable)
0203         // and const proxy references.
0204         // If const proxy references are returned by iterators
0205         // then const real references here prevents temporary
0206         // objects from being destroyed.
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         // Mutable proxy references returned by iterators.
0222         // Temporary points have to be created and assigned afterwards.
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             // single point ranges already handled in closed case above
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             // NOTE: Currently lvalue iterator required
0328             if (! RangePolicy::apply(*it, f))
0329             {
0330                 return false;
0331             }
0332         }
0333 
0334         return true;
0335     }
0336 
0337 };
0338 
0339 // Implementation of multi, for both point and segment,
0340 // just calling the single version.
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             // NOTE: Currently lvalue iterator required
0351             if (! SinglePolicy::apply(*it, f))
0352             {
0353                 return false;
0354             }
0355         }
0356 
0357         return true;
0358     }
0359 };
0360 
0361 }} // namespace detail::for_each
0362 #endif // DOXYGEN_NO_DETAIL
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             // Specify the dispatch of the single-version as policy
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 // empty
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 // empty
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 } // namespace dispatch
0495 #endif // DOXYGEN_NO_DISPATCH
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 \brief \brf_for_each{point}
0565 \details \det_for_each{point}
0566 \ingroup for_each
0567 \param geometry \param_geometry
0568 \param f \par_for_each_f{point}
0569 \tparam Geometry \tparam_geometry
0570 \tparam Functor \tparam_functor
0571 
0572 \qbk{[include reference/algorithms/for_each_point.qbk]}
0573 \qbk{[heading Example]}
0574 \qbk{[for_each_point] [for_each_point_output]}
0575 \qbk{[for_each_point_const] [for_each_point_const_output]}
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         // TODO: Implement separate function?
0586         return true;
0587     });
0588     return f;
0589 }
0590 
0591 
0592 /*!
0593 \brief \brf_for_each{segment}
0594 \details \det_for_each{segment}
0595 \ingroup for_each
0596 \param geometry \param_geometry
0597 \param f \par_for_each_f{segment}
0598 \tparam Geometry \tparam_geometry
0599 \tparam Functor \tparam_functor
0600 
0601 \qbk{[include reference/algorithms/for_each_segment.qbk]}
0602 \qbk{[heading Example]}
0603 \qbk{[for_each_segment_const] [for_each_segment_const_output]}
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         // TODO: Implement separate function?
0614         return true;
0615     });
0616     return f;
0617 }
0618 
0619 
0620 }} // namespace boost::geometry
0621 
0622 
0623 #endif // BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP