]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/geometries/adapted/boost_polygon/ring_proxy.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / geometry / geometries / adapted / boost_polygon / ring_proxy.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
4
5 // Use, modification and distribution is subject to the Boost Software License,
6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8
9 #ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP
10 #define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP
11
12 // Adapts Geometries from Boost.Polygon for usage in Boost.Geometry
13 // boost::polygon::polygon_with_holes_data -> boost::geometry::polygon
14 // pair{begin_points, end_points} -> ring_proxy
15
16 #include <boost/polygon/polygon.hpp>
17 #include <boost/range.hpp>
18
19
20
21 namespace boost { namespace geometry
22 {
23
24 namespace adapt { namespace bp
25 {
26
27 namespace detail
28 {
29
30 template <bool Mutable>
31 struct modify
32 {};
33
34 template <>
35 struct modify<true>
36 {
37 template <typename Ring, typename Point>
38 static inline void push_back(Ring& ring, Point const& point)
39 {
40 // Boost.Polygon's polygons are not appendable. So create a temporary vector,
41 // add a record and set it to the original. Of course: this is not efficient.
42 // But there seems no other way (without using a wrapper)
43 std::vector<Point> temporary_vector
44 (
45 boost::polygon::begin_points(ring),
46 boost::polygon::end_points(ring)
47 );
48 temporary_vector.push_back(point);
49 boost::polygon::set_points(ring, temporary_vector.begin(), temporary_vector.end());
50 }
51
52 };
53
54 template <>
55 struct modify<false>
56 {
57 template <typename Ring, typename Point>
58 static inline void push_back(Ring& /*ring*/, Point const& /*point*/)
59 {
60 }
61
62 };
63
64
65 }
66
67
68 // Polygon should implement the boost::polygon::polygon_with_holes_concept
69 // Specify constness in the template parameter if necessary
70 template<typename Polygon>
71 class ring_proxy
72 {
73 public :
74 typedef typename boost::polygon::polygon_traits
75 <
76 typename boost::remove_const<Polygon>::type
77 >::iterator_type iterator_type;
78
79 typedef typename boost::polygon::polygon_with_holes_traits
80 <
81 typename boost::remove_const<Polygon>::type
82 >::iterator_holes_type hole_iterator_type;
83
84 static const bool is_mutable = !boost::is_const<Polygon>::type::value;
85
86 inline ring_proxy(Polygon& p)
87 : m_polygon_pointer(&p)
88 , m_do_hole(false)
89 {}
90
91 // Constructor used from hole_iterator
92 inline ring_proxy(Polygon& p, hole_iterator_type hole_it)
93 : m_polygon_pointer(&p)
94 , m_do_hole(true)
95 , m_hole_it(hole_it)
96 {}
97
98 // Default constructor, for mutable polygons / appending (interior) rings
99 inline ring_proxy()
100 : m_polygon_pointer(&m_polygon_for_default_constructor)
101 , m_do_hole(false)
102 {}
103
104
105 iterator_type begin() const
106 {
107 return m_do_hole
108 ? boost::polygon::begin_points(*m_hole_it)
109 : boost::polygon::begin_points(*m_polygon_pointer)
110 ;
111 }
112
113 iterator_type begin()
114 {
115 return m_do_hole
116 ? boost::polygon::begin_points(*m_hole_it)
117 : boost::polygon::begin_points(*m_polygon_pointer)
118 ;
119 }
120
121 iterator_type end() const
122 {
123 return m_do_hole
124 ? boost::polygon::end_points(*m_hole_it)
125 : boost::polygon::end_points(*m_polygon_pointer)
126 ;
127 }
128
129 iterator_type end()
130 {
131 return m_do_hole
132 ? boost::polygon::end_points(*m_hole_it)
133 : boost::polygon::end_points(*m_polygon_pointer)
134 ;
135 }
136
137 // Mutable
138 void clear()
139 {
140 Polygon p;
141 if (m_do_hole)
142 {
143 // Does NOT work see comment above
144 }
145 else
146 {
147 boost::polygon::set_points(*m_polygon_pointer,
148 boost::polygon::begin_points(p),
149 boost::polygon::end_points(p));
150 }
151 }
152
153 void resize(std::size_t /*new_size*/)
154 {
155 if (m_do_hole)
156 {
157 // Does NOT work see comment above
158 }
159 else
160 {
161 // TODO: implement this by resizing the container
162 }
163 }
164
165
166
167 template <typename Point>
168 void push_back(Point const& point)
169 {
170 if (m_do_hole)
171 {
172 //detail::modify<is_mutable>::push_back(*m_hole_it, point);
173 //std::cout << "HOLE: " << typeid(*m_hole_it).name() << std::endl;
174 //std::cout << "HOLE: " << typeid(m_hole_it).name() << std::endl;
175 //std::cout << "HOLE: " << typeid(hole_iterator_type).name() << std::endl;
176
177 // Note, ths does NOT work because hole_iterator_type is defined
178 // as a const_iterator by Boost.Polygon
179
180 }
181 else
182 {
183 detail::modify<is_mutable>::push_back(*m_polygon_pointer, point);
184 }
185 }
186
187 private :
188 Polygon* m_polygon_pointer;
189 bool m_do_hole;
190 hole_iterator_type m_hole_it;
191
192 Polygon m_polygon_for_default_constructor;
193 };
194
195
196
197
198 // Support geometry::adapt::bp::ring_proxy for Boost.Range ADP
199 template<typename Polygon>
200 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
201 range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy)
202 {
203 return proxy.begin();
204 }
205
206 template<typename Polygon>
207 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type
208 range_begin(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy)
209 {
210 return proxy.begin();
211 }
212
213 template<typename Polygon>
214 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon>::iterator_type
215 range_end(boost::geometry::adapt::bp::ring_proxy<Polygon>& proxy)
216 {
217 return proxy.end();
218 }
219
220 template<typename Polygon>
221 inline typename boost::geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type
222 range_end(boost::geometry::adapt::bp::ring_proxy<Polygon const> const& proxy)
223 {
224 return proxy.end();
225 }
226
227
228
229
230 }} // namespace adapt::bp
231
232
233 namespace traits
234 {
235
236 template <typename Polygon>
237 struct tag<adapt::bp::ring_proxy<Polygon> >
238 {
239 typedef ring_tag type;
240 };
241
242
243 template <typename Polygon>
244 struct rvalue_type<adapt::bp::ring_proxy<Polygon> >
245 {
246 typedef adapt::bp::ring_proxy<Polygon> type;
247 };
248
249 template <typename Polygon>
250 struct clear<adapt::bp::ring_proxy<Polygon> >
251 {
252 static inline void apply(adapt::bp::ring_proxy<Polygon> proxy)
253 {
254 proxy.clear();
255 }
256 };
257
258
259 template <typename Polygon>
260 struct resize<adapt::bp::ring_proxy<Polygon> >
261 {
262 static inline void apply(adapt::bp::ring_proxy<Polygon> proxy, std::size_t new_size)
263 {
264 proxy.resize(new_size);
265 }
266 };
267
268 template <typename Polygon>
269 struct push_back<adapt::bp::ring_proxy<Polygon> >
270 {
271 static inline void apply(adapt::bp::ring_proxy<Polygon> proxy,
272 typename boost::polygon::polygon_traits<Polygon>::point_type const& point)
273 {
274 proxy.push_back(point);
275 }
276 };
277
278
279 } // namespace traits
280
281 }} // namespace boost::geometry
282
283 // Specialize ring_proxy for Boost.Range
284 namespace boost
285 {
286 template<typename Polygon>
287 struct range_mutable_iterator<geometry::adapt::bp::ring_proxy<Polygon> >
288 {
289 typedef typename geometry::adapt::bp::ring_proxy<Polygon>::iterator_type type;
290 };
291
292 template<typename Polygon>
293 struct range_const_iterator<geometry::adapt::bp::ring_proxy<Polygon> >
294 {
295 typedef typename geometry::adapt::bp::ring_proxy<Polygon const>::iterator_type type;
296 };
297
298 } // namespace boost
299
300
301 #endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_BOOST_POLYGON_RING_PROXY_HPP