]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/include/boost/geometry/iterators/segment_iterator.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / iterators / segment_iterator.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2014, Oracle and/or its affiliates.
4
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
6
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
9
10 #ifndef BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP
11 #define BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP
12
13 #include <boost/mpl/assert.hpp>
14 #include <boost/type_traits/is_convertible.hpp>
15 #include <boost/range.hpp>
16
17 #include <boost/geometry/core/exterior_ring.hpp>
18 #include <boost/geometry/core/interior_rings.hpp>
19 #include <boost/geometry/core/tags.hpp>
20
21 #include <boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp>
22 #include <boost/geometry/iterators/detail/segment_iterator/iterator_type.hpp>
23
24 #include <boost/geometry/iterators/dispatch/segment_iterator.hpp>
25
26
27 namespace boost { namespace geometry
28 {
29
30
31 #ifndef DOXYGEN_NO_DISPATCH
32 namespace dispatch
33 {
34
35
36 // specializations for segments_begin
37
38
39 template <typename Linestring>
40 struct segments_begin<Linestring, linestring_tag>
41 {
42 typedef typename detail::segment_iterator::iterator_type
43 <
44 Linestring
45 >::type return_type;
46
47 static inline return_type apply(Linestring& linestring)
48 {
49 return return_type(linestring);
50 }
51 };
52
53
54 template <typename Ring>
55 struct segments_begin<Ring, ring_tag>
56 {
57 typedef typename detail::segment_iterator::iterator_type
58 <
59 Ring
60 >::type return_type;
61
62 static inline return_type apply(Ring& ring)
63 {
64 return return_type(ring);
65 }
66 };
67
68
69 template <typename Polygon>
70 struct segments_begin<Polygon, polygon_tag>
71 {
72 typedef typename detail::point_iterator::inner_range_type
73 <
74 Polygon
75 >::type inner_range;
76
77 typedef typename detail::segment_iterator::iterator_type
78 <
79 Polygon
80 >::type return_type;
81
82 static inline return_type apply(Polygon& polygon)
83 {
84 typedef typename return_type::second_iterator_type flatten_iterator;
85
86 return return_type
87 (segments_begin
88 <
89 inner_range
90 >::apply(geometry::exterior_ring(polygon)),
91 segments_end
92 <
93 inner_range
94 >::apply(geometry::exterior_ring(polygon)),
95 flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
96 boost::end(geometry::interior_rings(polygon))
97 ),
98 flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
99 boost::end(geometry::interior_rings(polygon))
100 )
101 );
102 }
103 };
104
105
106 template <typename MultiLinestring>
107 struct segments_begin<MultiLinestring, multi_linestring_tag>
108 {
109 typedef typename detail::segment_iterator::iterator_type
110 <
111 MultiLinestring
112 >::type return_type;
113
114 static inline return_type apply(MultiLinestring& multilinestring)
115 {
116 return return_type(boost::begin(multilinestring),
117 boost::end(multilinestring));
118 }
119 };
120
121
122 template <typename MultiPolygon>
123 struct segments_begin<MultiPolygon, multi_polygon_tag>
124 {
125 typedef typename detail::segment_iterator::iterator_type
126 <
127 MultiPolygon
128 >::type return_type;
129
130 static inline return_type apply(MultiPolygon& multipolygon)
131 {
132 return return_type(boost::begin(multipolygon),
133 boost::end(multipolygon));
134 }
135 };
136
137
138 } // namespace dispatch
139 #endif // DOXYGEN_NO_DISPATCH
140
141
142
143
144
145 #ifndef DOXYGEN_NO_DISPATCH
146 namespace dispatch
147 {
148
149
150 // specializations for segments_end
151
152
153 template <typename Linestring>
154 struct segments_end<Linestring, linestring_tag>
155 {
156 typedef typename detail::segment_iterator::iterator_type
157 <
158 Linestring
159 >::type return_type;
160
161 static inline return_type apply(Linestring& linestring)
162 {
163 return return_type(linestring, true);
164 }
165 };
166
167
168 template <typename Ring>
169 struct segments_end<Ring, ring_tag>
170 {
171 typedef typename detail::segment_iterator::iterator_type
172 <
173 Ring
174 >::type return_type;
175
176 static inline return_type apply(Ring& ring)
177 {
178 return return_type(ring, true);
179 }
180 };
181
182
183 template <typename Polygon>
184 struct segments_end<Polygon, polygon_tag>
185 {
186 typedef typename detail::point_iterator::inner_range_type
187 <
188 Polygon
189 >::type inner_range;
190
191 typedef typename detail::segment_iterator::iterator_type
192 <
193 Polygon
194 >::type return_type;
195
196 static inline return_type apply(Polygon& polygon)
197 {
198 typedef typename return_type::second_iterator_type flatten_iterator;
199
200 return return_type
201 (segments_end
202 <
203 inner_range
204 >::apply(geometry::exterior_ring(polygon)),
205 flatten_iterator(boost::begin(geometry::interior_rings(polygon)),
206 boost::end(geometry::interior_rings(polygon))
207 ),
208 flatten_iterator( boost::end(geometry::interior_rings(polygon)) )
209 );
210 }
211 };
212
213
214 template <typename MultiLinestring>
215 struct segments_end<MultiLinestring, multi_linestring_tag>
216 {
217 typedef typename detail::segment_iterator::iterator_type
218 <
219 MultiLinestring
220 >::type return_type;
221
222 static inline return_type apply(MultiLinestring& multilinestring)
223 {
224 return return_type(boost::end(multilinestring));
225 }
226 };
227
228
229 template <typename MultiPolygon>
230 struct segments_end<MultiPolygon, multi_polygon_tag>
231 {
232 typedef typename detail::segment_iterator::iterator_type
233 <
234 MultiPolygon
235 >::type return_type;
236
237 static inline return_type apply(MultiPolygon& multipolygon)
238 {
239 return return_type(boost::end(multipolygon));
240 }
241 };
242
243
244 } // namespace dispatch
245 #endif // DOXYGEN_NO_DISPATCH
246
247
248 // MK:: need to add doc here
249 template <typename Geometry>
250 class segment_iterator
251 : public detail::segment_iterator::iterator_type<Geometry>::type
252 {
253 private:
254 typedef typename detail::segment_iterator::iterator_type
255 <
256 Geometry
257 >::type base;
258
259 inline base const* base_ptr() const
260 {
261 return this;
262 }
263
264 template <typename OtherGeometry> friend class segment_iterator;
265
266 template <typename G>
267 friend inline segment_iterator<G const> segments_begin(G const&);
268
269 template <typename G>
270 friend inline segment_iterator<G const> segments_end(G const&);
271
272 inline segment_iterator(base const& base_it) : base(base_it) {}
273
274 public:
275 // The following typedef is needed for this iterator to be
276 // bidirectional.
277 // Normally we would not have to define this. However, due to the
278 // fact that the value type of the iterator is not a reference,
279 // the iterator_facade framework (used to define the base class of
280 // this iterator) degrades automatically the iterator's category
281 // to input iterator. With the following typedef we recover the
282 // correct iterator category.
283 typedef std::bidirectional_iterator_tag iterator_category;
284
285 inline segment_iterator() {}
286
287 template <typename OtherGeometry>
288 inline segment_iterator(segment_iterator<OtherGeometry> const& other)
289 : base(*other.base_ptr())
290 {
291 static const bool is_conv
292 = boost::is_convertible<
293 typename detail::segment_iterator::iterator_type
294 <
295 OtherGeometry
296 >::type,
297 typename detail::segment_iterator::iterator_type<Geometry>::type
298 >::value;
299
300 BOOST_MPL_ASSERT_MSG((is_conv),
301 NOT_CONVERTIBLE,
302 (segment_iterator<OtherGeometry>));
303 }
304
305 inline segment_iterator& operator++() // prefix
306 {
307 base::operator++();
308 return *this;
309 }
310
311 inline segment_iterator& operator--() // prefix
312 {
313 base::operator--();
314 return *this;
315 }
316
317 inline segment_iterator operator++(int) // postfix
318 {
319 segment_iterator copy(*this);
320 base::operator++();
321 return copy;
322 }
323
324 inline segment_iterator operator--(int) // postfix
325 {
326 segment_iterator copy(*this);
327 base::operator--();
328 return copy;
329 }
330 };
331
332
333 // MK:: need to add doc here
334 template <typename Geometry>
335 inline segment_iterator<Geometry const>
336 segments_begin(Geometry const& geometry)
337 {
338 return dispatch::segments_begin<Geometry const>::apply(geometry);
339 }
340
341
342 // MK:: need to add doc here
343 template <typename Geometry>
344 inline segment_iterator<Geometry const>
345 segments_end(Geometry const& geometry)
346 {
347 return dispatch::segments_end<Geometry const>::apply(geometry);
348 }
349
350
351 }} // namespace boost::geometry
352
353 #endif // BOOST_GEOMETRY_ITERATORS_SEGMENT_ITERATOR_HPP