]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
7c673cae
FG
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
27namespace boost { namespace geometry
28{
29
30
31#ifndef DOXYGEN_NO_DISPATCH
32namespace dispatch
33{
34
35
36// specializations for segments_begin
37
38
39template <typename Linestring>
40struct 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
54template <typename Ring>
55struct 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
69template <typename Polygon>
70struct 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
106template <typename MultiLinestring>
107struct 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
122template <typename MultiPolygon>
123struct 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
146namespace dispatch
147{
148
149
150// specializations for segments_end
151
152
153template <typename Linestring>
154struct 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
168template <typename Ring>
169struct 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
183template <typename Polygon>
184struct 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
214template <typename MultiLinestring>
215struct 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
229template <typename MultiPolygon>
230struct 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
249template <typename Geometry>
250class segment_iterator
251 : public detail::segment_iterator::iterator_type<Geometry>::type
252{
253private:
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
274public:
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
334template <typename Geometry>
335inline segment_iterator<Geometry const>
336segments_begin(Geometry const& geometry)
337{
338 return dispatch::segments_begin<Geometry const>::apply(geometry);
339}
340
341
342// MK:: need to add doc here
343template <typename Geometry>
344inline segment_iterator<Geometry const>
345segments_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