File indexing completed on 2025-12-15 09:50:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
0019 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
0020
0021
0022 #include <type_traits>
0023 #include <utility>
0024
0025 #include <boost/concept/requires.hpp>
0026 #include <boost/core/addressof.hpp>
0027 #include <boost/range/begin.hpp>
0028 #include <boost/range/end.hpp>
0029
0030 #include <boost/geometry/core/static_assert.hpp>
0031 #include <boost/geometry/core/tag.hpp>
0032 #include <boost/geometry/core/tags.hpp>
0033
0034 #include <boost/geometry/util/type_traits.hpp>
0035
0036 #include <boost/geometry/views/box_view.hpp>
0037 #include <boost/geometry/views/segment_view.hpp>
0038
0039
0040 namespace boost { namespace geometry
0041 {
0042
0043
0044 #ifndef DOXYGEN_NO_DETAIL
0045 namespace detail { namespace for_each
0046 {
0047
0048
0049 template <typename Point>
0050 struct fe_range_point
0051 {
0052 template <typename Functor>
0053 static inline bool apply(Point& point, Functor&& f)
0054 {
0055 Point* ptr = boost::addressof(point);
0056 return f(std::pair<Point*, Point*>(ptr, ptr + 1));
0057 }
0058 };
0059
0060
0061 template <typename Segment>
0062 struct fe_range_segment
0063 {
0064 template <typename Functor>
0065 static inline bool apply(Segment& segment, Functor&& f)
0066 {
0067 return f(segment_view<typename std::remove_const<Segment>::type>(segment));
0068 }
0069 };
0070
0071
0072 template <typename Range>
0073 struct fe_range_range
0074 {
0075 template <typename Functor>
0076 static inline bool apply(Range& range, Functor&& f)
0077 {
0078 return f(range);
0079 }
0080 };
0081
0082
0083 template <typename Polygon>
0084 struct fe_range_polygon
0085 {
0086 template <typename Functor>
0087 static inline bool apply(Polygon& polygon, Functor&& f)
0088 {
0089 return f(exterior_ring(polygon));
0090
0091
0092
0093 }
0094 };
0095
0096 template <typename Box>
0097 struct fe_range_box
0098 {
0099 template <typename Functor>
0100 static inline bool apply(Box& box, Functor&& f)
0101 {
0102 return f(box_view<typename std::remove_const<Box>::type>(box));
0103 }
0104 };
0105
0106 template <typename Multi, typename SinglePolicy>
0107 struct fe_range_multi
0108 {
0109 template <typename Functor>
0110 static inline bool apply(Multi& multi, Functor&& f)
0111 {
0112 auto const end = boost::end(multi);
0113 for (auto it = boost::begin(multi); it != end; ++it)
0114 {
0115 if (! SinglePolicy::apply(*it, f))
0116 {
0117 return false;
0118 }
0119 }
0120 return true;
0121 }
0122 };
0123
0124 }}
0125 #endif
0126
0127
0128 #ifndef DOXYGEN_NO_DISPATCH
0129 namespace dispatch
0130 {
0131
0132
0133 template
0134 <
0135 typename Geometry,
0136 typename Tag = tag_t<Geometry>
0137 >
0138 struct for_each_range
0139 {
0140 BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
0141 "Not or not yet implemented for this Geometry type.",
0142 Geometry, Tag);
0143 };
0144
0145
0146 template <typename Point>
0147 struct for_each_range<Point, point_tag>
0148 : detail::for_each::fe_range_point<Point>
0149 {};
0150
0151
0152 template <typename Segment>
0153 struct for_each_range<Segment, segment_tag>
0154 : detail::for_each::fe_range_segment<Segment>
0155 {};
0156
0157
0158 template <typename Linestring>
0159 struct for_each_range<Linestring, linestring_tag>
0160 : detail::for_each::fe_range_range<Linestring>
0161 {};
0162
0163
0164 template <typename Ring>
0165 struct for_each_range<Ring, ring_tag>
0166 : detail::for_each::fe_range_range<Ring>
0167 {};
0168
0169
0170 template <typename Polygon>
0171 struct for_each_range<Polygon, polygon_tag>
0172 : detail::for_each::fe_range_polygon<Polygon>
0173 {};
0174
0175
0176 template <typename Box>
0177 struct for_each_range<Box, box_tag>
0178 : detail::for_each::fe_range_box<Box>
0179 {};
0180
0181
0182 template <typename MultiPoint>
0183 struct for_each_range<MultiPoint, multi_point_tag>
0184 : detail::for_each::fe_range_range<MultiPoint>
0185 {};
0186
0187
0188 template <typename Geometry>
0189 struct for_each_range<Geometry, multi_linestring_tag>
0190 : detail::for_each::fe_range_multi
0191 <
0192 Geometry,
0193 detail::for_each::fe_range_range
0194 <
0195 util::transcribe_const_t
0196 <
0197 Geometry,
0198 typename boost::range_value<Geometry>::type
0199 >
0200 >
0201 >
0202 {};
0203
0204
0205 template <typename Geometry>
0206 struct for_each_range<Geometry, multi_polygon_tag>
0207 : detail::for_each::fe_range_multi
0208 <
0209 Geometry,
0210 detail::for_each::fe_range_polygon
0211 <
0212 util::transcribe_const_t
0213 <
0214 Geometry,
0215 typename boost::range_value<Geometry>::type
0216 >
0217 >
0218 >
0219 {};
0220
0221
0222 }
0223 #endif
0224
0225 namespace detail
0226 {
0227
0228
0229
0230
0231 template <typename Geometry, typename UnaryPredicate>
0232 inline bool all_ranges_of(Geometry const& geometry, UnaryPredicate p)
0233 {
0234 return dispatch::for_each_range<Geometry const>::apply(geometry, p);
0235 }
0236
0237
0238
0239
0240 template <typename Geometry, typename UnaryPredicate>
0241 inline bool any_range_of(Geometry const& geometry, UnaryPredicate p)
0242 {
0243 return ! dispatch::for_each_range<Geometry const>::apply(geometry,
0244 [&](auto&& range)
0245 {
0246 return ! p(range);
0247 });
0248 }
0249
0250
0251
0252
0253 template <typename Geometry, typename UnaryPredicate>
0254 inline bool none_range_of(Geometry const& geometry, UnaryPredicate p)
0255 {
0256 return dispatch::for_each_range<Geometry const>::apply(geometry,
0257 [&](auto&& range)
0258 {
0259 return ! p(range);
0260 });
0261 }
0262
0263
0264
0265
0266 template <typename Geometry, typename Functor>
0267 inline Functor for_each_range(Geometry const& geometry, Functor f)
0268 {
0269 dispatch::for_each_range<Geometry const>::apply(geometry,
0270 [&](auto&& range)
0271 {
0272 f(range);
0273
0274 return true;
0275 });
0276 return f;
0277 }
0278
0279
0280 }
0281
0282
0283 }}
0284
0285
0286 #endif