Chris@16
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@16
|
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
Chris@16
|
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
Chris@16
|
6
|
Chris@16
|
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
Chris@16
|
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
Chris@16
|
9
|
Chris@16
|
10 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
12 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
13
|
Chris@16
|
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
|
Chris@16
|
15 #define BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
|
Chris@16
|
16
|
Chris@16
|
17
|
Chris@16
|
18 #include <algorithm>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/range.hpp>
|
Chris@16
|
21 #include <boost/type_traits/is_const.hpp>
|
Chris@16
|
22 #include <boost/typeof/typeof.hpp>
|
Chris@16
|
23
|
Chris@16
|
24 #include <boost/geometry/algorithms/not_implemented.hpp>
|
Chris@16
|
25 #include <boost/geometry/core/exterior_ring.hpp>
|
Chris@16
|
26 #include <boost/geometry/core/interior_rings.hpp>
|
Chris@16
|
27 #include <boost/geometry/core/tag_cast.hpp>
|
Chris@16
|
28
|
Chris@16
|
29 #include <boost/geometry/geometries/concepts/check.hpp>
|
Chris@16
|
30
|
Chris@16
|
31 #include <boost/geometry/geometries/segment.hpp>
|
Chris@16
|
32
|
Chris@16
|
33 #include <boost/geometry/util/add_const_if_c.hpp>
|
Chris@16
|
34
|
Chris@16
|
35
|
Chris@16
|
36 namespace boost { namespace geometry
|
Chris@16
|
37 {
|
Chris@16
|
38
|
Chris@16
|
39 #ifndef DOXYGEN_NO_DETAIL
|
Chris@16
|
40 namespace detail { namespace for_each
|
Chris@16
|
41 {
|
Chris@16
|
42
|
Chris@16
|
43
|
Chris@16
|
44 struct fe_point_per_point
|
Chris@16
|
45 {
|
Chris@16
|
46 template <typename Point, typename Functor>
|
Chris@16
|
47 static inline void apply(Point& point, Functor& f)
|
Chris@16
|
48 {
|
Chris@16
|
49 f(point);
|
Chris@16
|
50 }
|
Chris@16
|
51 };
|
Chris@16
|
52
|
Chris@16
|
53
|
Chris@16
|
54 struct fe_point_per_segment
|
Chris@16
|
55 {
|
Chris@16
|
56 template <typename Point, typename Functor>
|
Chris@16
|
57 static inline void apply(Point& , Functor& f)
|
Chris@16
|
58 {
|
Chris@16
|
59 // TODO: if non-const, we should extract the points from the segment
|
Chris@16
|
60 // and call the functor on those two points
|
Chris@16
|
61 }
|
Chris@16
|
62 };
|
Chris@16
|
63
|
Chris@16
|
64
|
Chris@16
|
65 struct fe_range_per_point
|
Chris@16
|
66 {
|
Chris@16
|
67 template <typename Range, typename Functor>
|
Chris@16
|
68 static inline void apply(Range& range, Functor& f)
|
Chris@16
|
69 {
|
Chris@16
|
70 // The previous implementation called the std library:
|
Chris@16
|
71 // return (std::for_each(boost::begin(range), boost::end(range), f));
|
Chris@16
|
72 // But that is not accepted for capturing lambda's.
|
Chris@16
|
73 // It needs to do it like that to return the state of Functor f (f is passed by value in std::for_each).
|
Chris@16
|
74
|
Chris@16
|
75 // So we now loop manually.
|
Chris@16
|
76
|
Chris@16
|
77 for (typename boost::range_iterator<Range>::type it = boost::begin(range); it != boost::end(range); ++it)
|
Chris@16
|
78 {
|
Chris@16
|
79 f(*it);
|
Chris@16
|
80 }
|
Chris@16
|
81 }
|
Chris@16
|
82 };
|
Chris@16
|
83
|
Chris@16
|
84
|
Chris@16
|
85 struct fe_range_per_segment
|
Chris@16
|
86 {
|
Chris@16
|
87 template <typename Range, typename Functor>
|
Chris@16
|
88 static inline void apply(Range& range, Functor& f)
|
Chris@16
|
89 {
|
Chris@16
|
90 typedef typename add_const_if_c
|
Chris@16
|
91 <
|
Chris@16
|
92 is_const<Range>::value,
|
Chris@16
|
93 typename point_type<Range>::type
|
Chris@16
|
94 >::type point_type;
|
Chris@16
|
95
|
Chris@16
|
96 BOOST_AUTO_TPL(it, boost::begin(range));
|
Chris@16
|
97 BOOST_AUTO_TPL(previous, it++);
|
Chris@16
|
98 while(it != boost::end(range))
|
Chris@16
|
99 {
|
Chris@16
|
100 model::referring_segment<point_type> s(*previous, *it);
|
Chris@16
|
101 f(s);
|
Chris@16
|
102 previous = it++;
|
Chris@16
|
103 }
|
Chris@16
|
104 }
|
Chris@16
|
105 };
|
Chris@16
|
106
|
Chris@16
|
107
|
Chris@16
|
108 struct fe_polygon_per_point
|
Chris@16
|
109 {
|
Chris@16
|
110 template <typename Polygon, typename Functor>
|
Chris@16
|
111 static inline void apply(Polygon& poly, Functor& f)
|
Chris@16
|
112 {
|
Chris@16
|
113 fe_range_per_point::apply(exterior_ring(poly), f);
|
Chris@16
|
114
|
Chris@16
|
115 typename interior_return_type<Polygon>::type rings
|
Chris@16
|
116 = interior_rings(poly);
|
Chris@16
|
117 for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
Chris@16
|
118 {
|
Chris@16
|
119 fe_range_per_point::apply(*it, f);
|
Chris@16
|
120 }
|
Chris@16
|
121 }
|
Chris@16
|
122
|
Chris@16
|
123 };
|
Chris@16
|
124
|
Chris@16
|
125
|
Chris@16
|
126 struct fe_polygon_per_segment
|
Chris@16
|
127 {
|
Chris@16
|
128 template <typename Polygon, typename Functor>
|
Chris@16
|
129 static inline void apply(Polygon& poly, Functor& f)
|
Chris@16
|
130 {
|
Chris@16
|
131 fe_range_per_segment::apply(exterior_ring(poly), f);
|
Chris@16
|
132
|
Chris@16
|
133 typename interior_return_type<Polygon>::type rings
|
Chris@16
|
134 = interior_rings(poly);
|
Chris@16
|
135 for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
|
Chris@16
|
136 {
|
Chris@16
|
137 fe_range_per_segment::apply(*it, f);
|
Chris@16
|
138 }
|
Chris@16
|
139 }
|
Chris@16
|
140
|
Chris@16
|
141 };
|
Chris@16
|
142
|
Chris@16
|
143
|
Chris@16
|
144 }} // namespace detail::for_each
|
Chris@16
|
145 #endif // DOXYGEN_NO_DETAIL
|
Chris@16
|
146
|
Chris@16
|
147
|
Chris@16
|
148 #ifndef DOXYGEN_NO_DISPATCH
|
Chris@16
|
149 namespace dispatch
|
Chris@16
|
150 {
|
Chris@16
|
151
|
Chris@16
|
152 template
|
Chris@16
|
153 <
|
Chris@16
|
154 typename Geometry,
|
Chris@16
|
155 typename Tag = typename tag_cast<typename tag<Geometry>::type, multi_tag>::type
|
Chris@16
|
156 >
|
Chris@16
|
157 struct for_each_point: not_implemented<Tag>
|
Chris@16
|
158 {};
|
Chris@16
|
159
|
Chris@16
|
160
|
Chris@16
|
161 template <typename Point>
|
Chris@16
|
162 struct for_each_point<Point, point_tag>
|
Chris@16
|
163 : detail::for_each::fe_point_per_point
|
Chris@16
|
164 {};
|
Chris@16
|
165
|
Chris@16
|
166
|
Chris@16
|
167 template <typename Linestring>
|
Chris@16
|
168 struct for_each_point<Linestring, linestring_tag>
|
Chris@16
|
169 : detail::for_each::fe_range_per_point
|
Chris@16
|
170 {};
|
Chris@16
|
171
|
Chris@16
|
172
|
Chris@16
|
173 template <typename Ring>
|
Chris@16
|
174 struct for_each_point<Ring, ring_tag>
|
Chris@16
|
175 : detail::for_each::fe_range_per_point
|
Chris@16
|
176 {};
|
Chris@16
|
177
|
Chris@16
|
178
|
Chris@16
|
179 template <typename Polygon>
|
Chris@16
|
180 struct for_each_point<Polygon, polygon_tag>
|
Chris@16
|
181 : detail::for_each::fe_polygon_per_point
|
Chris@16
|
182 {};
|
Chris@16
|
183
|
Chris@16
|
184
|
Chris@16
|
185 template
|
Chris@16
|
186 <
|
Chris@16
|
187 typename Geometry,
|
Chris@16
|
188 typename Tag = typename tag_cast<typename tag<Geometry>::type, multi_tag>::type
|
Chris@16
|
189 >
|
Chris@16
|
190 struct for_each_segment: not_implemented<Tag>
|
Chris@16
|
191 {};
|
Chris@16
|
192
|
Chris@16
|
193 template <typename Point>
|
Chris@16
|
194 struct for_each_segment<Point, point_tag>
|
Chris@16
|
195 : detail::for_each::fe_point_per_segment
|
Chris@16
|
196 {};
|
Chris@16
|
197
|
Chris@16
|
198
|
Chris@16
|
199 template <typename Linestring>
|
Chris@16
|
200 struct for_each_segment<Linestring, linestring_tag>
|
Chris@16
|
201 : detail::for_each::fe_range_per_segment
|
Chris@16
|
202 {};
|
Chris@16
|
203
|
Chris@16
|
204
|
Chris@16
|
205 template <typename Ring>
|
Chris@16
|
206 struct for_each_segment<Ring, ring_tag>
|
Chris@16
|
207 : detail::for_each::fe_range_per_segment
|
Chris@16
|
208 {};
|
Chris@16
|
209
|
Chris@16
|
210
|
Chris@16
|
211 template <typename Polygon>
|
Chris@16
|
212 struct for_each_segment<Polygon, polygon_tag>
|
Chris@16
|
213 : detail::for_each::fe_polygon_per_segment
|
Chris@16
|
214 {};
|
Chris@16
|
215
|
Chris@16
|
216
|
Chris@16
|
217 } // namespace dispatch
|
Chris@16
|
218 #endif // DOXYGEN_NO_DISPATCH
|
Chris@16
|
219
|
Chris@16
|
220
|
Chris@16
|
221 /*!
|
Chris@16
|
222 \brief \brf_for_each{point}
|
Chris@16
|
223 \details \det_for_each{point}
|
Chris@16
|
224 \ingroup for_each
|
Chris@16
|
225 \param geometry \param_geometry
|
Chris@16
|
226 \param f \par_for_each_f{point}
|
Chris@16
|
227 \tparam Geometry \tparam_geometry
|
Chris@16
|
228 \tparam Functor \tparam_functor
|
Chris@16
|
229
|
Chris@16
|
230 \qbk{[include reference/algorithms/for_each_point.qbk]}
|
Chris@16
|
231 \qbk{[heading Example]}
|
Chris@16
|
232 \qbk{[for_each_point] [for_each_point_output]}
|
Chris@16
|
233 \qbk{[for_each_point_const] [for_each_point_const_output]}
|
Chris@16
|
234 */
|
Chris@16
|
235 template<typename Geometry, typename Functor>
|
Chris@16
|
236 inline Functor for_each_point(Geometry& geometry, Functor f)
|
Chris@16
|
237 {
|
Chris@16
|
238 concept::check<Geometry>();
|
Chris@16
|
239
|
Chris@16
|
240 dispatch::for_each_point<Geometry>::apply(geometry, f);
|
Chris@16
|
241 return f;
|
Chris@16
|
242 }
|
Chris@16
|
243
|
Chris@16
|
244
|
Chris@16
|
245 /*!
|
Chris@16
|
246 \brief \brf_for_each{segment}
|
Chris@16
|
247 \details \det_for_each{segment}
|
Chris@16
|
248 \ingroup for_each
|
Chris@16
|
249 \param geometry \param_geometry
|
Chris@16
|
250 \param f \par_for_each_f{segment}
|
Chris@16
|
251 \tparam Geometry \tparam_geometry
|
Chris@16
|
252 \tparam Functor \tparam_functor
|
Chris@16
|
253
|
Chris@16
|
254 \qbk{[include reference/algorithms/for_each_segment.qbk]}
|
Chris@16
|
255 \qbk{[heading Example]}
|
Chris@16
|
256 \qbk{[for_each_segment_const] [for_each_segment_const_output]}
|
Chris@16
|
257 */
|
Chris@16
|
258 template<typename Geometry, typename Functor>
|
Chris@16
|
259 inline Functor for_each_segment(Geometry& geometry, Functor f)
|
Chris@16
|
260 {
|
Chris@16
|
261 concept::check<Geometry>();
|
Chris@16
|
262
|
Chris@16
|
263 dispatch::for_each_segment<Geometry>::apply(geometry, f);
|
Chris@16
|
264 return f;
|
Chris@16
|
265 }
|
Chris@16
|
266
|
Chris@16
|
267
|
Chris@16
|
268 }} // namespace boost::geometry
|
Chris@16
|
269
|
Chris@16
|
270
|
Chris@16
|
271 #endif // BOOST_GEOMETRY_ALGORITHMS_FOR_EACH_HPP
|