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