1 | /* |
2 | Copyright 2008 Intel Corporation |
3 | |
4 | Use, modification and distribution are subject to the Boost Software License, |
5 | Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
6 | http://www.boost.org/LICENSE_1_0.txt). |
7 | */ |
8 | #ifndef BOOST_POLYGON_POLYGON_SET_CONCEPT_HPP |
9 | #define BOOST_POLYGON_POLYGON_SET_CONCEPT_HPP |
10 | #include "polygon_set_data.hpp" |
11 | #include "detail/polygon_simplify.hpp" |
12 | namespace boost { namespace polygon{ |
13 | |
14 | template <typename T, typename T2> |
15 | struct is_either_polygon_set_type { |
16 | typedef typename gtl_or<typename is_polygon_set_type<T>::type, typename is_polygon_set_type<T2>::type >::type type; |
17 | }; |
18 | |
19 | template <typename T> |
20 | struct is_any_polygon_set_type { |
21 | typedef typename gtl_or<typename is_polygon_45_or_90_set_type<T>::type, typename is_polygon_set_type<T>::type >::type type; |
22 | }; |
23 | |
24 | template <typename polygon_set_type> |
25 | typename enable_if< typename is_any_polygon_set_type<polygon_set_type>::type, |
26 | typename polygon_set_traits<polygon_set_type>::iterator_type>::type |
27 | begin_polygon_set_data(const polygon_set_type& polygon_set) { |
28 | return polygon_set_traits<polygon_set_type>::begin(polygon_set); |
29 | } |
30 | |
31 | template <typename polygon_set_type> |
32 | typename enable_if< typename is_any_polygon_set_type<polygon_set_type>::type, |
33 | typename polygon_set_traits<polygon_set_type>::iterator_type>::type |
34 | end_polygon_set_data(const polygon_set_type& polygon_set) { |
35 | return polygon_set_traits<polygon_set_type>::end(polygon_set); |
36 | } |
37 | |
38 | template <typename polygon_set_type> |
39 | typename enable_if< typename is_polygon_set_type<polygon_set_type>::type, |
40 | bool>::type |
41 | clean(const polygon_set_type& polygon_set) { |
42 | return polygon_set_traits<polygon_set_type>::clean(polygon_set); |
43 | } |
44 | |
45 | //assign |
46 | template <typename polygon_set_type_1, typename polygon_set_type_2> |
47 | typename enable_if< typename gtl_and< |
48 | typename is_mutable_polygon_set_type<polygon_set_type_1>::type, |
49 | typename is_any_polygon_set_type<polygon_set_type_2>::type>::type, |
50 | polygon_set_type_1>::type & |
51 | assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) { |
52 | if(clean(rvalue)) |
53 | polygon_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_polygon_set_data(rvalue), end_polygon_set_data(rvalue)); |
54 | else { |
55 | polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps; |
56 | ps.insert(begin_polygon_set_data(rvalue), end_polygon_set_data(rvalue)); |
57 | ps.clean(); |
58 | polygon_set_mutable_traits<polygon_set_type_1>::set(lvalue, ps.begin(), ps.end()); |
59 | } |
60 | return lvalue; |
61 | } |
62 | |
63 | //get trapezoids |
64 | template <typename output_container_type, typename polygon_set_type> |
65 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
66 | void>::type |
67 | get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set) { |
68 | polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; |
69 | assign(ps, polygon_set); |
70 | ps.get_trapezoids(output); |
71 | } |
72 | |
73 | //get trapezoids |
74 | template <typename output_container_type, typename polygon_set_type> |
75 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
76 | void>::type |
77 | get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set, |
78 | orientation_2d orient) { |
79 | polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; |
80 | assign(ps, polygon_set); |
81 | ps.get_trapezoids(output, orient); |
82 | } |
83 | |
84 | //equivalence |
85 | template <typename polygon_set_type_1, typename polygon_set_type_2> |
86 | typename enable_if< typename gtl_and_3 < |
87 | typename is_any_polygon_set_type<polygon_set_type_1>::type, |
88 | typename is_any_polygon_set_type<polygon_set_type_2>::type, |
89 | typename is_either_polygon_set_type<polygon_set_type_1, polygon_set_type_2>::type>::type, |
90 | bool>::type |
91 | equivalence(const polygon_set_type_1& lvalue, |
92 | const polygon_set_type_2& rvalue) { |
93 | polygon_set_data<typename polygon_set_traits<polygon_set_type_1>::coordinate_type> ps1; |
94 | assign(ps1, lvalue); |
95 | polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps2; |
96 | assign(ps2, rvalue); |
97 | return ps1 == ps2; |
98 | } |
99 | |
100 | //clear |
101 | template <typename polygon_set_type> |
102 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
103 | void>::type |
104 | clear(polygon_set_type& polygon_set) { |
105 | polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; |
106 | assign(polygon_set, ps); |
107 | } |
108 | |
109 | //empty |
110 | template <typename polygon_set_type> |
111 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
112 | bool>::type |
113 | empty(const polygon_set_type& polygon_set) { |
114 | if(clean(polygon_set)) return begin_polygon_set_data(polygon_set) == end_polygon_set_data(polygon_set); |
115 | polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; |
116 | assign(ps, polygon_set); |
117 | ps.clean(); |
118 | return ps.empty(); |
119 | } |
120 | |
121 | //extents |
122 | template <typename polygon_set_type, typename rectangle_type> |
123 | typename enable_if< typename gtl_and< |
124 | typename is_mutable_polygon_set_type<polygon_set_type>::type, |
125 | typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, |
126 | bool>::type |
127 | extents(rectangle_type& extents_rectangle, |
128 | const polygon_set_type& polygon_set) { |
129 | clean(polygon_set); |
130 | polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; |
131 | assign(ps, polygon_set); |
132 | return ps.extents(extents_rectangle); |
133 | } |
134 | |
135 | //area |
136 | template <typename polygon_set_type> |
137 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
138 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type>::type |
139 | area(const polygon_set_type& polygon_set) { |
140 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; |
141 | typedef polygon_with_holes_data<Unit> p_type; |
142 | typedef typename coordinate_traits<Unit>::area_type area_type; |
143 | std::vector<p_type> polys; |
144 | assign(polys, polygon_set); |
145 | area_type retval = (area_type)0; |
146 | for(std::size_t i = 0; i < polys.size(); ++i) { |
147 | retval += area(polys[i]); |
148 | } |
149 | return retval; |
150 | } |
151 | |
152 | template <typename polygon_set_type> |
153 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
154 | std::size_t>::type |
155 | simplify(polygon_set_type& polygon_set, typename coordinate_traits< |
156 | typename polygon_set_traits<polygon_set_type>::coordinate_type |
157 | >::coordinate_distance threshold) { |
158 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; |
159 | typedef polygon_with_holes_data<Unit> p_type; |
160 | std::vector<p_type> polys; |
161 | assign(polys, polygon_set); |
162 | std::size_t retval = 0; |
163 | for(std::size_t i = 0; i < polys.size(); ++i) { |
164 | retval += detail::simplify_detail::simplify(polys[i].self_.coords_, |
165 | polys[i].self_.coords_, threshold); |
166 | for(typename std::list<polygon_data<Unit> >::iterator itrh = |
167 | polys[i].holes_.begin(); itrh != (polys[i].holes_.end()); ++itrh) { |
168 | retval += detail::simplify_detail::simplify((*itrh).coords_, |
169 | (*itrh).coords_, threshold); |
170 | } |
171 | } |
172 | assign(polygon_set, polys); |
173 | return retval; |
174 | } |
175 | |
176 | template <typename polygon_set_type, typename coord_type> |
177 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
178 | polygon_set_type>::type & |
179 | resize(polygon_set_type& polygon_set, coord_type resizing, bool corner_fill_arcs = false, int num_circle_segments = 0) { |
180 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; |
181 | clean(polygon_set); |
182 | polygon_set_data<Unit> ps; |
183 | assign(ps, polygon_set); |
184 | ps.resize(resizing, corner_fill_arcs,num_circle_segments); |
185 | assign(polygon_set, ps); |
186 | return polygon_set; |
187 | } |
188 | |
189 | template <typename polygon_set_type> |
190 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
191 | polygon_set_type>::type & |
192 | bloat(polygon_set_type& polygon_set, |
193 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { |
194 | return resize(polygon_set, bloating); |
195 | } |
196 | |
197 | template <typename polygon_set_type> |
198 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
199 | polygon_set_type>::type & |
200 | shrink(polygon_set_type& polygon_set, |
201 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) { |
202 | return resize(polygon_set, -(typename polygon_set_traits<polygon_set_type>::coordinate_type)shrinking); |
203 | } |
204 | |
205 | //interact |
206 | template <typename polygon_set_type_1, typename polygon_set_type_2> |
207 | typename enable_if< typename gtl_and_3 < |
208 | typename is_any_polygon_set_type<polygon_set_type_1>::type, |
209 | typename is_any_polygon_set_type<polygon_set_type_2>::type, |
210 | typename is_either_polygon_set_type<polygon_set_type_1, polygon_set_type_2>::type>::type, |
211 | polygon_set_type_1>::type& |
212 | interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) { |
213 | polygon_set_data<typename polygon_set_traits<polygon_set_type_1>::coordinate_type> ps1; |
214 | assign(ps1, polygon_set_1); |
215 | polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps2; |
216 | assign(ps2, polygon_set_2); |
217 | ps1.interact(ps2); |
218 | assign(polygon_set_1, ps1); |
219 | return polygon_set_1; |
220 | } |
221 | |
222 | template <typename polygon_set_type> |
223 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
224 | polygon_set_type>::type & |
225 | scale_up(polygon_set_type& polygon_set, |
226 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) { |
227 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; |
228 | clean(polygon_set); |
229 | polygon_set_data<Unit> ps; |
230 | assign(ps, polygon_set); |
231 | ps.scale_up(factor); |
232 | assign(polygon_set, ps); |
233 | return polygon_set; |
234 | } |
235 | |
236 | template <typename polygon_set_type> |
237 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
238 | polygon_set_type>::type & |
239 | scale_down(polygon_set_type& polygon_set, |
240 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) { |
241 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; |
242 | clean(polygon_set); |
243 | polygon_set_data<Unit> ps; |
244 | assign(ps, polygon_set); |
245 | ps.scale_down(factor); |
246 | assign(polygon_set, ps); |
247 | return polygon_set; |
248 | } |
249 | |
250 | //transform |
251 | template <typename polygon_set_type, typename transformation_type> |
252 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
253 | polygon_set_type>::type & |
254 | transform(polygon_set_type& polygon_set, |
255 | const transformation_type& transformation) { |
256 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; |
257 | clean(polygon_set); |
258 | polygon_set_data<Unit> ps; |
259 | assign(ps, polygon_set); |
260 | ps.transform(transformation); |
261 | assign(polygon_set, ps); |
262 | return polygon_set; |
263 | } |
264 | |
265 | //keep |
266 | template <typename polygon_set_type> |
267 | typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, |
268 | polygon_set_type>::type & |
269 | keep(polygon_set_type& polygon_set, |
270 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type min_area, |
271 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type max_area, |
272 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width, |
273 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width, |
274 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height, |
275 | typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) { |
276 | typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; |
277 | typedef typename coordinate_traits<Unit>::unsigned_area_type uat; |
278 | std::list<polygon_with_holes_data<Unit> > polys; |
279 | assign(polys, polygon_set); |
280 | typename std::list<polygon_with_holes_data<Unit> >::iterator itr_nxt; |
281 | for(typename std::list<polygon_with_holes_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){ |
282 | itr_nxt = itr; |
283 | ++itr_nxt; |
284 | rectangle_data<Unit> bbox; |
285 | extents(bbox, *itr); |
286 | uat pwidth = delta(bbox, HORIZONTAL); |
287 | if(pwidth > min_width && pwidth <= max_width){ |
288 | uat pheight = delta(bbox, VERTICAL); |
289 | if(pheight > min_height && pheight <= max_height){ |
290 | typename coordinate_traits<Unit>::area_type parea = area(*itr); |
291 | if(parea <= max_area && parea >= min_area) { |
292 | continue; |
293 | } |
294 | } |
295 | } |
296 | polys.erase(itr); |
297 | } |
298 | assign(polygon_set, polys); |
299 | return polygon_set; |
300 | } |
301 | |
302 | namespace operators { |
303 | |
304 | struct yes_ps_ob : gtl_yes {}; |
305 | |
306 | template <typename geometry_type_1, typename geometry_type_2> |
307 | typename enable_if< typename gtl_and_4 < yes_ps_ob, typename is_any_polygon_set_type<geometry_type_1>::type, |
308 | typename is_any_polygon_set_type<geometry_type_2>::type, |
309 | typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, |
310 | polygon_set_view<geometry_type_1, geometry_type_2, 0> >::type |
311 | operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
312 | return polygon_set_view<geometry_type_1, geometry_type_2, 0> |
313 | (lvalue, rvalue); |
314 | } |
315 | |
316 | struct yes_ps_op : gtl_yes {}; |
317 | |
318 | template <typename geometry_type_1, typename geometry_type_2> |
319 | typename enable_if< typename gtl_and_4 < yes_ps_op, |
320 | typename gtl_if<typename is_any_polygon_set_type<geometry_type_1>::type>::type, |
321 | typename gtl_if<typename is_any_polygon_set_type<geometry_type_2>::type>::type, |
322 | typename gtl_if<typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type> |
323 | ::type, polygon_set_view<geometry_type_1, geometry_type_2, 0> >::type |
324 | operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
325 | return polygon_set_view<geometry_type_1, geometry_type_2, 0> |
326 | (lvalue, rvalue); |
327 | } |
328 | |
329 | struct yes_ps_os : gtl_yes {}; |
330 | |
331 | template <typename geometry_type_1, typename geometry_type_2> |
332 | typename enable_if< typename gtl_and_4 < yes_ps_os, |
333 | typename is_any_polygon_set_type<geometry_type_1>::type, |
334 | typename is_any_polygon_set_type<geometry_type_2>::type, |
335 | typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, |
336 | polygon_set_view<geometry_type_1, geometry_type_2, 1> >::type |
337 | operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
338 | return polygon_set_view<geometry_type_1, geometry_type_2, 1> |
339 | (lvalue, rvalue); |
340 | } |
341 | |
342 | struct yes_ps_oa : gtl_yes {}; |
343 | |
344 | template <typename geometry_type_1, typename geometry_type_2> |
345 | typename enable_if< typename gtl_and_4 < yes_ps_oa, |
346 | typename is_any_polygon_set_type<geometry_type_1>::type, |
347 | typename is_any_polygon_set_type<geometry_type_2>::type, |
348 | typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, |
349 | polygon_set_view<geometry_type_1, geometry_type_2, 1> >::type |
350 | operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
351 | return polygon_set_view<geometry_type_1, geometry_type_2, 1> |
352 | (lvalue, rvalue); |
353 | } |
354 | |
355 | struct yes_ps_ox : gtl_yes {}; |
356 | |
357 | template <typename geometry_type_1, typename geometry_type_2> |
358 | typename enable_if< typename gtl_and_4 < yes_ps_ox, |
359 | typename is_any_polygon_set_type<geometry_type_1>::type, |
360 | typename is_any_polygon_set_type<geometry_type_2>::type, |
361 | typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, |
362 | polygon_set_view<geometry_type_1, geometry_type_2, 2> >::type |
363 | operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
364 | return polygon_set_view<geometry_type_1, geometry_type_2, 2> |
365 | (lvalue, rvalue); |
366 | } |
367 | |
368 | struct yes_ps_om : gtl_yes {}; |
369 | |
370 | template <typename geometry_type_1, typename geometry_type_2> |
371 | typename enable_if< typename gtl_and_4 < yes_ps_om, |
372 | typename gtl_if<typename is_any_polygon_set_type<geometry_type_1>::type>::type, |
373 | typename gtl_if<typename is_any_polygon_set_type<geometry_type_2>::type>::type, |
374 | typename gtl_if<typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type> |
375 | ::type, polygon_set_view<geometry_type_1, geometry_type_2, 3> >::type |
376 | operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
377 | return polygon_set_view<geometry_type_1, geometry_type_2, 3> |
378 | (lvalue, rvalue); |
379 | } |
380 | |
381 | struct yes_ps_ope : gtl_yes {}; |
382 | |
383 | template <typename geometry_type_1, typename geometry_type_2> |
384 | typename enable_if< typename gtl_and_4< yes_ps_ope, gtl_yes, typename is_mutable_polygon_set_type<geometry_type_1>::type, |
385 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, |
386 | geometry_type_1>::type & |
387 | operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
388 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue); |
389 | } |
390 | |
391 | struct yes_ps_obe : gtl_yes {}; |
392 | |
393 | template <typename geometry_type_1, typename geometry_type_2> |
394 | typename enable_if< typename gtl_and_3< yes_ps_obe, typename is_mutable_polygon_set_type<geometry_type_1>::type, |
395 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, |
396 | geometry_type_1>::type & |
397 | operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
398 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue); |
399 | } |
400 | |
401 | struct yes_ps_ose : gtl_yes {}; |
402 | |
403 | template <typename geometry_type_1, typename geometry_type_2> |
404 | typename enable_if< typename gtl_and_3< yes_ps_ose, typename is_mutable_polygon_set_type<geometry_type_1>::type, |
405 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, |
406 | geometry_type_1>::type & |
407 | operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
408 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue); |
409 | } |
410 | |
411 | struct yes_ps_oae : gtl_yes {}; |
412 | |
413 | template <typename geometry_type_1, typename geometry_type_2> |
414 | typename enable_if< |
415 | typename gtl_and_3< yes_ps_oae, typename is_mutable_polygon_set_type<geometry_type_1>::type, |
416 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, |
417 | geometry_type_1>::type & |
418 | operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
419 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue); |
420 | } |
421 | |
422 | struct yes_ps_oxe : gtl_yes {}; |
423 | |
424 | template <typename geometry_type_1, typename geometry_type_2> |
425 | typename enable_if< typename gtl_and_3< yes_ps_oxe, typename is_mutable_polygon_set_type<geometry_type_1>::type, |
426 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, |
427 | geometry_type_1>::type & |
428 | operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
429 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 2>(lvalue, rvalue); |
430 | } |
431 | |
432 | struct yes_ps_ome : gtl_yes {}; |
433 | |
434 | template <typename geometry_type_1, typename geometry_type_2> |
435 | typename enable_if< |
436 | typename gtl_and_3< yes_ps_ome, typename is_mutable_polygon_set_type<geometry_type_1>::type, |
437 | typename is_any_polygon_set_type<geometry_type_2>::type>::type, |
438 | geometry_type_1>::type & |
439 | operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { |
440 | return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 3>(lvalue, rvalue); |
441 | } |
442 | |
443 | // TODO: Dafna, test these four resizing operators |
444 | struct y_ps_rpe : gtl_yes {}; |
445 | |
446 | template <typename geometry_type_1, typename coordinate_type_1> |
447 | typename enable_if< typename gtl_and_3< y_ps_rpe, typename is_mutable_polygon_set_type<geometry_type_1>::type, |
448 | typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, |
449 | coordinate_concept>::type>::type, |
450 | geometry_type_1>::type & |
451 | operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { |
452 | return resize(lvalue, rvalue); |
453 | } |
454 | |
455 | struct y_ps_rme : gtl_yes {}; |
456 | |
457 | template <typename geometry_type_1, typename coordinate_type_1> |
458 | typename enable_if< typename gtl_and_3<y_ps_rme, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type, |
459 | typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, |
460 | coordinate_concept>::type>::type, |
461 | geometry_type_1>::type & |
462 | operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { |
463 | return resize(lvalue, -rvalue); |
464 | } |
465 | |
466 | struct y_ps_rp : gtl_yes {}; |
467 | |
468 | template <typename geometry_type_1, typename coordinate_type_1> |
469 | typename enable_if< typename gtl_and_3<y_ps_rp, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type, |
470 | typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, |
471 | coordinate_concept>::type> |
472 | ::type, geometry_type_1>::type |
473 | operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { |
474 | geometry_type_1 retval(lvalue); |
475 | retval += rvalue; |
476 | return retval; |
477 | } |
478 | |
479 | struct y_ps_rm : gtl_yes {}; |
480 | |
481 | template <typename geometry_type_1, typename coordinate_type_1> |
482 | typename enable_if< typename gtl_and_3<y_ps_rm, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type, |
483 | typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, |
484 | coordinate_concept>::type> |
485 | ::type, geometry_type_1>::type |
486 | operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { |
487 | geometry_type_1 retval(lvalue); |
488 | retval -= rvalue; |
489 | return retval; |
490 | } |
491 | |
492 | |
493 | } //end operators namespace |
494 | |
495 | template <typename T> |
496 | struct view_of<polygon_45_set_concept, T> { |
497 | typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type; |
498 | T* tp; |
499 | std::vector<polygon_45_with_holes_data<coordinate_type> > polys; |
500 | view_of(const T& obj) : tp(), polys() { |
501 | std::vector<polygon_with_holes_data<coordinate_type> > gpolys; |
502 | assign(gpolys, obj); |
503 | for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin(); |
504 | itr != gpolys.end(); ++itr) { |
505 | polys.push_back(polygon_45_with_holes_data<coordinate_type>()); |
506 | assign(polys.back(), view_as<polygon_45_with_holes_concept>(*itr)); |
507 | } |
508 | } |
509 | view_of(T& obj) : tp(&obj), polys() { |
510 | std::vector<polygon_with_holes_data<coordinate_type> > gpolys; |
511 | assign(gpolys, obj); |
512 | for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin(); |
513 | itr != gpolys.end(); ++itr) { |
514 | polys.push_back(polygon_45_with_holes_data<coordinate_type>()); |
515 | assign(polys.back(), view_as<polygon_45_with_holes_concept>(*itr)); |
516 | } |
517 | } |
518 | |
519 | typedef typename std::vector<polygon_45_with_holes_data<coordinate_type> >::const_iterator iterator_type; |
520 | typedef view_of operator_arg_type; |
521 | |
522 | inline iterator_type begin() const { |
523 | return polys.begin(); |
524 | } |
525 | |
526 | inline iterator_type end() const { |
527 | return polys.end(); |
528 | } |
529 | |
530 | inline orientation_2d orient() const { return HORIZONTAL; } |
531 | |
532 | inline bool clean() const { return false; } |
533 | |
534 | inline bool sorted() const { return false; } |
535 | |
536 | inline T& get() { return *tp; } |
537 | }; |
538 | |
539 | template <typename T> |
540 | struct polygon_45_set_traits<view_of<polygon_45_set_concept, T> > { |
541 | typedef typename view_of<polygon_45_set_concept, T>::coordinate_type coordinate_type; |
542 | typedef typename view_of<polygon_45_set_concept, T>::iterator_type iterator_type; |
543 | typedef view_of<polygon_45_set_concept, T> operator_arg_type; |
544 | |
545 | static inline iterator_type begin(const view_of<polygon_45_set_concept, T>& polygon_set) { |
546 | return polygon_set.begin(); |
547 | } |
548 | |
549 | static inline iterator_type end(const view_of<polygon_45_set_concept, T>& polygon_set) { |
550 | return polygon_set.end(); |
551 | } |
552 | |
553 | static inline orientation_2d orient(const view_of<polygon_45_set_concept, T>& polygon_set) { |
554 | return polygon_set.orient(); } |
555 | |
556 | static inline bool clean(const view_of<polygon_45_set_concept, T>& polygon_set) { |
557 | return polygon_set.clean(); } |
558 | |
559 | static inline bool sorted(const view_of<polygon_45_set_concept, T>& polygon_set) { |
560 | return polygon_set.sorted(); } |
561 | |
562 | }; |
563 | |
564 | template <typename T> |
565 | struct geometry_concept<view_of<polygon_45_set_concept, T> > { |
566 | typedef polygon_45_set_concept type; |
567 | }; |
568 | |
569 | template <typename T> |
570 | struct get_coordinate_type<view_of<polygon_45_set_concept, T>, polygon_45_set_concept> { |
571 | typedef typename view_of<polygon_45_set_concept, T>::coordinate_type type; |
572 | }; |
573 | template <typename T> |
574 | struct get_iterator_type_2<view_of<polygon_45_set_concept, T>, polygon_45_set_concept> { |
575 | typedef typename view_of<polygon_45_set_concept, T>::iterator_type type; |
576 | static type begin(const view_of<polygon_45_set_concept, T>& t) { return t.begin(); } |
577 | static type end(const view_of<polygon_45_set_concept, T>& t) { return t.end(); } |
578 | }; |
579 | } |
580 | } |
581 | #endif |
582 | |