]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/include/boost/geometry/algorithms/for_each.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / algorithms / for_each.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
6 // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
7
8 // This file was modified by Oracle on 2014.
9 // Modifications copyright (c) 2014, Oracle and/or its affiliates.
10
11 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
12
13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
15
16 // Use, modification and distribution is subject to the Boost Software License,
17 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
19
20 #ifndef BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
21 #define BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
22
23
24 #include <algorithm>
25
26 #include <boost/range.hpp>
27 #include <boost/type_traits/is_const.hpp>
28 #include <boost/type_traits/remove_reference.hpp>
29
30 #include <boost/geometry/algorithms/detail/interior_iterator.hpp>
31 #include <boost/geometry/algorithms/not_implemented.hpp>
32 #include <boost/geometry/core/closure.hpp>
33 #include <boost/geometry/core/exterior_ring.hpp>
34 #include <boost/geometry/core/interior_rings.hpp>
35 #include <boost/geometry/core/point_type.hpp>
36 #include <boost/geometry/core/tag_cast.hpp>
37 #include <boost/geometry/core/tags.hpp>
38
39 #include <boost/geometry/geometries/concepts/check.hpp>
40
41 #include <boost/geometry/geometries/segment.hpp>
42
43 #include <boost/geometry/util/add_const_if_c.hpp>
44 #include <boost/geometry/util/range.hpp>
45
46
47 namespace boost { namespace geometry
48 {
49
50 #ifndef DOXYGEN_NO_DETAIL
51 namespace detail { namespace for_each
52 {
53
54
55 struct fe_point_per_point
56 {
57 template <typename Point, typename Functor>
58 static inline void apply(Point& point, Functor& f)
59 {
60 f(point);
61 }
62 };
63
64
65 struct fe_point_per_segment
66 {
67 template <typename Point, typename Functor>
68 static inline void apply(Point& , Functor& /*f*/)
69 {
70 // TODO: if non-const, we should extract the points from the segment
71 // and call the functor on those two points
72 }
73 };
74
75
76 struct fe_range_per_point
77 {
78 template <typename Range, typename Functor>
79 static inline void apply(Range& range, Functor& f)
80 {
81 // The previous implementation called the std library:
82 // return (std::for_each(boost::begin(range), boost::end(range), f));
83 // But that is not accepted for capturing lambda's.
84 // It needs to do it like that to return the state of Functor f (f is passed by value in std::for_each).
85
86 // So we now loop manually.
87
88 for (typename boost::range_iterator<Range>::type
89 it = boost::begin(range); it != boost::end(range); ++it)
90 {
91 f(*it);
92 }
93 }
94 };
95
96
97 template <closure_selector Closure>
98 struct fe_range_per_segment_with_closure
99 {
100 template <typename Range, typename Functor>
101 static inline void apply(Range& range, Functor& f)
102 {
103 typedef typename add_const_if_c
104 <
105 is_const<Range>::value,
106 typename point_type<Range>::type
107 >::type point_type;
108
109 typedef typename boost::range_iterator<Range>::type iterator_type;
110
111 iterator_type it = boost::begin(range);
112 iterator_type previous = it++;
113 while(it != boost::end(range))
114 {
115 model::referring_segment<point_type> s(*previous, *it);
116 f(s);
117 previous = it++;
118 }
119 }
120 };
121
122
123 template <>
124 struct fe_range_per_segment_with_closure<open>
125 {
126 template <typename Range, typename Functor>
127 static inline void apply(Range& range, Functor& f)
128 {
129 fe_range_per_segment_with_closure<closed>::apply(range, f);
130
131 model::referring_segment
132 <
133 typename add_const_if_c
134 <
135 is_const<Range>::value,
136 typename point_type<Range>::type
137 >::type
138 > s(range::back(range), range::front(range));
139
140 f(s);
141 }
142 };
143
144
145 struct fe_range_per_segment
146 {
147 template <typename Range, typename Functor>
148 static inline void apply(Range& range, Functor& f)
149 {
150 fe_range_per_segment_with_closure
151 <
152 closure<Range>::value
153 >::apply(range, f);
154 }
155 };
156
157
158 struct fe_polygon_per_point
159 {
160 template <typename Polygon, typename Functor>
161 static inline void apply(Polygon& poly, Functor& f)
162 {
163 fe_range_per_point::apply(exterior_ring(poly), f);
164
165 typename interior_return_type<Polygon>::type
166 rings = interior_rings(poly);
167
168 for (typename detail::interior_iterator<Polygon>::type
169 it = boost::begin(rings); it != boost::end(rings); ++it)
170 {
171 fe_range_per_point::apply(*it, f);
172 }
173 }
174
175 };
176
177 struct fe_polygon_per_segment
178 {
179 template <typename Polygon, typename Functor>
180 static inline void apply(Polygon& poly, Functor& f)
181 {
182 fe_range_per_segment::apply(exterior_ring(poly), f);
183
184 typename interior_return_type<Polygon>::type
185 rings = interior_rings(poly);
186
187 for (typename detail::interior_iterator<Polygon>::type
188 it = boost::begin(rings); it != boost::end(rings); ++it)
189 {
190 fe_range_per_segment::apply(*it, f);
191 }
192 }
193
194 };
195
196 // Implementation of multi, for both point and segment,
197 // just calling the single version.
198 template <typename Policy>
199 struct for_each_multi
200 {
201 template <typename MultiGeometry, typename Functor>
202 static inline void apply(MultiGeometry& multi, Functor& f)
203 {
204 for (typename boost::range_iterator<MultiGeometry>::type
205 it = boost::begin(multi); it != boost::end(multi); ++it)
206 {
207 Policy::apply(*it, f);
208 }
209 }
210 };
211
212 }} // namespace detail::for_each
213 #endif // DOXYGEN_NO_DETAIL
214
215
216 #ifndef DOXYGEN_NO_DISPATCH
217 namespace dispatch
218 {
219
220 template
221 <
222 typename Geometry,
223 typename Tag = typename tag_cast<typename tag<Geometry>::type, multi_tag>::type
224 >
225 struct for_each_point: not_implemented<Tag>
226 {};
227
228
229 template <typename Point>
230 struct for_each_point<Point, point_tag>
231 : detail::for_each::fe_point_per_point
232 {};
233
234
235 template <typename Linestring>
236 struct for_each_point<Linestring, linestring_tag>
237 : detail::for_each::fe_range_per_point
238 {};
239
240
241 template <typename Ring>
242 struct for_each_point<Ring, ring_tag>
243 : detail::for_each::fe_range_per_point
244 {};
245
246
247 template <typename Polygon>
248 struct for_each_point<Polygon, polygon_tag>
249 : detail::for_each::fe_polygon_per_point
250 {};
251
252
253 template
254 <
255 typename Geometry,
256 typename Tag = typename tag_cast<typename tag<Geometry>::type, multi_tag>::type
257 >
258 struct for_each_segment: not_implemented<Tag>
259 {};
260
261 template <typename Point>
262 struct for_each_segment<Point, point_tag>
263 : detail::for_each::fe_point_per_segment
264 {};
265
266
267 template <typename Linestring>
268 struct for_each_segment<Linestring, linestring_tag>
269 : detail::for_each::fe_range_per_segment
270 {};
271
272
273 template <typename Ring>
274 struct for_each_segment<Ring, ring_tag>
275 : detail::for_each::fe_range_per_segment
276 {};
277
278
279 template <typename Polygon>
280 struct for_each_segment<Polygon, polygon_tag>
281 : detail::for_each::fe_polygon_per_segment
282 {};
283
284
285 template <typename MultiGeometry>
286 struct for_each_point<MultiGeometry, multi_tag>
287 : detail::for_each::for_each_multi
288 <
289 // Specify the dispatch of the single-version as policy
290 for_each_point
291 <
292 typename add_const_if_c
293 <
294 is_const<MultiGeometry>::value,
295 typename boost::range_value<MultiGeometry>::type
296 >::type
297 >
298 >
299 {};
300
301
302 template <typename MultiGeometry>
303 struct for_each_segment<MultiGeometry, multi_tag>
304 : detail::for_each::for_each_multi
305 <
306 // Specify the dispatch of the single-version as policy
307 for_each_segment
308 <
309 typename add_const_if_c
310 <
311 is_const<MultiGeometry>::value,
312 typename boost::range_value<MultiGeometry>::type
313 >::type
314 >
315 >
316 {};
317
318
319 } // namespace dispatch
320 #endif // DOXYGEN_NO_DISPATCH
321
322
323 /*!
324 \brief \brf_for_each{point}
325 \details \det_for_each{point}
326 \ingroup for_each
327 \param geometry \param_geometry
328 \param f \par_for_each_f{point}
329 \tparam Geometry \tparam_geometry
330 \tparam Functor \tparam_functor
331
332 \qbk{[include reference/algorithms/for_each_point.qbk]}
333 \qbk{[heading Example]}
334 \qbk{[for_each_point] [for_each_point_output]}
335 \qbk{[for_each_point_const] [for_each_point_const_output]}
336 */
337 template<typename Geometry, typename Functor>
338 inline Functor for_each_point(Geometry& geometry, Functor f)
339 {
340 concepts::check<Geometry>();
341
342 dispatch::for_each_point<Geometry>::apply(geometry, f);
343 return f;
344 }
345
346
347 /*!
348 \brief \brf_for_each{segment}
349 \details \det_for_each{segment}
350 \ingroup for_each
351 \param geometry \param_geometry
352 \param f \par_for_each_f{segment}
353 \tparam Geometry \tparam_geometry
354 \tparam Functor \tparam_functor
355
356 \qbk{[include reference/algorithms/for_each_segment.qbk]}
357 \qbk{[heading Example]}
358 \qbk{[for_each_segment_const] [for_each_segment_const_output]}
359 */
360 template<typename Geometry, typename Functor>
361 inline Functor for_each_segment(Geometry& geometry, Functor f)
362 {
363 concepts::check<Geometry>();
364
365 dispatch::for_each_segment<Geometry>::apply(geometry, f);
366 return f;
367 }
368
369
370 }} // namespace boost::geometry
371
372
373 #endif // BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP