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