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_90_SET_TRAITS_HPP |
9 | #define BOOST_POLYGON_POLYGON_90_SET_TRAITS_HPP |
10 | namespace boost { namespace polygon{ |
11 | |
12 | struct polygon_90_set_concept {}; |
13 | |
14 | template <typename T, typename T2> |
15 | struct traits_by_concept {}; |
16 | template <typename T> |
17 | struct traits_by_concept<T, coordinate_concept> { typedef coordinate_traits<T> type; }; |
18 | template <typename T> |
19 | struct traits_by_concept<T, interval_concept> { typedef interval_traits<T> type; }; |
20 | template <typename T> |
21 | struct traits_by_concept<T, point_concept> { typedef point_traits<T> type; }; |
22 | template <typename T> |
23 | struct traits_by_concept<T, rectangle_concept> { typedef rectangle_traits<T> type; }; |
24 | template <typename T> |
25 | struct traits_by_concept<T, segment_concept> { typedef segment_traits<T> type; }; |
26 | template <typename T> |
27 | struct traits_by_concept<T, polygon_90_concept> { typedef polygon_traits<T> type; }; |
28 | template <typename T> |
29 | struct traits_by_concept<T, polygon_90_with_holes_concept> { typedef polygon_traits<T> type; }; |
30 | template <typename T> |
31 | struct traits_by_concept<T, polygon_45_concept> { typedef polygon_traits<T> type; }; |
32 | template <typename T> |
33 | struct traits_by_concept<T, polygon_45_with_holes_concept> { typedef polygon_traits<T> type; }; |
34 | template <typename T> |
35 | struct traits_by_concept<T, polygon_concept> { typedef polygon_traits<T> type; }; |
36 | template <typename T> |
37 | struct traits_by_concept<T, polygon_with_holes_concept> { typedef polygon_traits<T> type; }; |
38 | |
39 | struct polygon_45_set_concept; |
40 | struct polygon_set_concept; |
41 | template <typename T> |
42 | struct polygon_90_set_traits; |
43 | template <typename T> |
44 | struct polygon_45_set_traits; |
45 | template <typename T> |
46 | struct polygon_set_traits; |
47 | template <typename T> |
48 | struct traits_by_concept<T, polygon_90_set_concept> { typedef polygon_90_set_traits<T> type; }; |
49 | template <typename T> |
50 | struct traits_by_concept<T, polygon_45_set_concept> { typedef polygon_45_set_traits<T> type; }; |
51 | template <typename T> |
52 | struct traits_by_concept<T, polygon_set_concept> { typedef polygon_set_traits<T> type; }; |
53 | |
54 | template <typename T, typename T2> |
55 | struct get_coordinate_type { |
56 | typedef typename traits_by_concept<T, T2>::type traits_type; |
57 | typedef typename traits_type::coordinate_type type; |
58 | }; |
59 | //want to prevent recursive template definition syntax errors, so duplicate get_coordinate_type |
60 | template <typename T, typename T2> |
61 | struct get_coordinate_type_2 { |
62 | typedef typename traits_by_concept<T, T2>::type traits_type; |
63 | typedef typename traits_type::coordinate_type type; |
64 | }; |
65 | template <typename T> |
66 | struct get_coordinate_type<T, undefined_concept> { |
67 | typedef typename get_coordinate_type_2<typename std::iterator_traits |
68 | <typename T::iterator>::value_type, |
69 | typename geometry_concept<typename std::iterator_traits |
70 | <typename T::iterator>::value_type>::type>::type type; }; |
71 | |
72 | template <typename T, typename T2> |
73 | struct get_iterator_type_2 { |
74 | typedef const T* type; |
75 | static type begin(const T& t) { return &t; } |
76 | static type end(const T& t) { const T* tp = &t; ++tp; return tp; } |
77 | }; |
78 | template <typename T> |
79 | struct get_iterator_type { |
80 | typedef get_iterator_type_2<T, typename geometry_concept<T>::type> indirect_type; |
81 | typedef typename indirect_type::type type; |
82 | static type begin(const T& t) { return indirect_type::begin(t); } |
83 | static type end(const T& t) { return indirect_type::end(t); } |
84 | }; |
85 | template <typename T> |
86 | struct get_iterator_type_2<T, undefined_concept> { |
87 | typedef typename T::const_iterator type; |
88 | static type begin(const T& t) { return t.begin(); } |
89 | static type end(const T& t) { return t.end(); } |
90 | }; |
91 | |
92 | // //helpers for allowing polygon 45 and containers of polygon 45 to behave interchangably in polygon_45_set_traits |
93 | // template <typename T, typename T2> |
94 | // struct get_coordinate_type_45 {}; |
95 | // template <typename T, typename T2> |
96 | // struct get_coordinate_type_2_45 {}; |
97 | // template <typename T> |
98 | // struct get_coordinate_type_45<T, void> { |
99 | // typedef typename get_coordinate_type_2_45< typename T::value_type, typename geometry_concept<typename T::value_type>::type >::type type; }; |
100 | // template <typename T> |
101 | // struct get_coordinate_type_45<T, polygon_45_concept> { typedef typename polygon_traits<T>::coordinate_type type; }; |
102 | // template <typename T> |
103 | // struct get_coordinate_type_45<T, polygon_45_with_holes_concept> { typedef typename polygon_traits<T>::coordinate_type type; }; |
104 | // template <typename T> |
105 | // struct get_coordinate_type_2_45<T, polygon_45_concept> { typedef typename polygon_traits<T>::coordinate_type type; }; |
106 | // template <typename T> |
107 | // struct get_coordinate_type_2_45<T, polygon_45_with_holes_concept> { typedef typename polygon_traits<T>::coordinate_type type; }; |
108 | // template <typename T, typename T2> |
109 | // struct get_iterator_type_45 {}; |
110 | // template <typename T> |
111 | // struct get_iterator_type_45<T, void> { |
112 | // typedef typename T::const_iterator type; |
113 | // static type begin(const T& t) { return t.begin(); } |
114 | // static type end(const T& t) { return t.end(); } |
115 | // }; |
116 | // template <typename T> |
117 | // struct get_iterator_type_45<T, polygon_45_concept> { |
118 | // typedef const T* type; |
119 | // static type begin(const T& t) { return &t; } |
120 | // static type end(const T& t) { const T* tp = &t; ++tp; return tp; } |
121 | // }; |
122 | // template <typename T> |
123 | // struct get_iterator_type_45<T, polygon_45_with_holes_concept> { |
124 | // typedef const T* type; |
125 | // static type begin(const T& t) { return &t; } |
126 | // static type end(const T& t) { const T* tp = &t; ++tp; return tp; } |
127 | // }; |
128 | // template <typename T> |
129 | // struct get_iterator_type_45<T, polygon_90_set_concept> { |
130 | // typedef const T* type; |
131 | // static type begin(const T& t) { return &t; } |
132 | // static type end(const T& t) { const T* tp = &t; ++tp; return tp; } |
133 | // }; |
134 | |
135 | template <typename T> |
136 | struct polygon_90_set_traits { |
137 | typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type; |
138 | typedef get_iterator_type<T> indirection_type; |
139 | typedef typename get_iterator_type<T>::type iterator_type; |
140 | typedef T operator_arg_type; |
141 | |
142 | static inline iterator_type begin(const T& polygon_set) { |
143 | return indirection_type::begin(polygon_set); |
144 | } |
145 | |
146 | static inline iterator_type end(const T& polygon_set) { |
147 | return indirection_type::end(polygon_set); |
148 | } |
149 | |
150 | static inline orientation_2d orient(const T&) { return HORIZONTAL; } |
151 | |
152 | static inline bool clean(const T&) { return false; } |
153 | |
154 | static inline bool sorted(const T&) { return false; } |
155 | }; |
156 | |
157 | template <typename T> |
158 | struct is_manhattan_polygonal_concept { typedef gtl_no type; }; |
159 | template <> |
160 | struct is_manhattan_polygonal_concept<rectangle_concept> { typedef gtl_yes type; }; |
161 | template <> |
162 | struct is_manhattan_polygonal_concept<polygon_90_concept> { typedef gtl_yes type; }; |
163 | template <> |
164 | struct is_manhattan_polygonal_concept<polygon_90_with_holes_concept> { typedef gtl_yes type; }; |
165 | template <> |
166 | struct is_manhattan_polygonal_concept<polygon_90_set_concept> { typedef gtl_yes type; }; |
167 | |
168 | template <typename T> |
169 | struct is_polygon_90_set_type { |
170 | typedef typename is_manhattan_polygonal_concept<typename geometry_concept<T>::type>::type type; |
171 | }; |
172 | template <typename T> |
173 | struct is_polygon_90_set_type<std::list<T> > { |
174 | typedef typename gtl_or< |
175 | typename is_manhattan_polygonal_concept<typename geometry_concept<std::list<T> >::type>::type, |
176 | typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type; |
177 | }; |
178 | template <typename T> |
179 | struct is_polygon_90_set_type<std::vector<T> > { |
180 | typedef typename gtl_or< |
181 | typename is_manhattan_polygonal_concept<typename geometry_concept<std::vector<T> >::type>::type, |
182 | typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type; |
183 | }; |
184 | |
185 | template <typename T> |
186 | struct is_mutable_polygon_90_set_type { |
187 | typedef typename gtl_same_type<polygon_90_set_concept, typename geometry_concept<T>::type>::type type; |
188 | }; |
189 | template <typename T> |
190 | struct is_mutable_polygon_90_set_type<std::list<T> > { |
191 | typedef typename gtl_or< |
192 | typename gtl_same_type<polygon_90_set_concept, typename geometry_concept<std::list<T> >::type>::type, |
193 | typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type; |
194 | }; |
195 | template <typename T> |
196 | struct is_mutable_polygon_90_set_type<std::vector<T> > { |
197 | typedef typename gtl_or< |
198 | typename gtl_same_type<polygon_90_set_concept, typename geometry_concept<std::vector<T> >::type>::type, |
199 | typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type; |
200 | }; |
201 | |
202 | // //specialization for rectangle, polygon_90 and polygon_90_with_holes types |
203 | // template <typename T> |
204 | // struct polygon_90_set_traits |
205 | // typedef typename geometry_concept<T>::type concept_type; |
206 | // typedef typename get_coordinate_type<T, concept_type>::type coordinate_type; |
207 | // typedef iterator_geometry_to_set<concept_type, T> iterator_type; |
208 | // typedef T operator_arg_type; |
209 | |
210 | // static inline iterator_type begin(const T& polygon_set) { |
211 | // return iterator_geometry_to_set<concept_type, T>(polygon_set, LOW, HORIZONTAL); |
212 | // } |
213 | |
214 | // static inline iterator_type end(const T& polygon_set) { |
215 | // return iterator_geometry_to_set<concept_type, T>(polygon_set, HIGH, HORIZONTAL); |
216 | // } |
217 | |
218 | // static inline orientation_2d orient(const T& polygon_set) { return HORIZONTAL; } |
219 | |
220 | // static inline bool clean(const T& polygon_set) { return false; } |
221 | |
222 | // static inline bool sorted(const T& polygon_set) { return false; } |
223 | |
224 | // }; |
225 | |
226 | // //specialization for containers of recangle, polygon_90, polygon_90_with_holes |
227 | // template <typename T> |
228 | // struct polygon_90_set_traits<T, typename is_manhattan_polygonal_concept<typename std::iterator_traits<typename T::iterator>::value_type>::type> { |
229 | // typedef typename std::iterator_traits<typename T::iterator>::value_type geometry_type; |
230 | // typedef typename geometry_concept<geometry_type>::type concept_type; |
231 | // typedef typename get_coordinate_type<geometry_type, concept_type>::type coordinate_type; |
232 | // typedef iterator_geometry_range_to_set<concept_type, typename T::const_iterator> iterator_type; |
233 | // typedef T operator_arg_type; |
234 | |
235 | // static inline iterator_type begin(const T& polygon_set) { |
236 | // return iterator_type(polygon_set.begin(), HORIZONTAL); |
237 | // } |
238 | |
239 | // static inline iterator_type end(const T& polygon_set) { |
240 | // return iterator_type(polygon_set.end(), HORIZONTAL); |
241 | // } |
242 | |
243 | // static inline orientation_2d orient(const T& polygon_set) { return HORIZONTAL; } |
244 | |
245 | // static inline bool clean(const T& polygon_set) { return false; } |
246 | |
247 | // static inline bool sorted(const T& polygon_set) { return false; } |
248 | |
249 | // }; |
250 | |
251 | //get dispatch functions |
252 | template <typename output_container_type, typename pst> |
253 | void get_90_dispatch(output_container_type& output, const pst& ps, |
254 | orientation_2d orient, rectangle_concept ) { |
255 | form_rectangles(output, ps.begin(), ps.end(), orient, rectangle_concept()); |
256 | } |
257 | |
258 | template <typename output_container_type, typename pst> |
259 | void get_90_dispatch(output_container_type& output, const pst& ps, |
260 | orientation_2d orient, polygon_90_concept tag) { |
261 | get_polygons(output, ps.begin(), ps.end(), orient, true, tag); |
262 | } |
263 | |
264 | template <typename output_container_type, typename pst> |
265 | void get_90_dispatch(output_container_type& output, const pst& ps, |
266 | orientation_2d orient, polygon_90_with_holes_concept tag) { |
267 | get_polygons(output, ps.begin(), ps.end(), orient, false, tag); |
268 | } |
269 | |
270 | //by default works with containers of rectangle, polygon or polygon with holes |
271 | //must be specialized to work with anything else |
272 | template <typename T> |
273 | struct polygon_90_set_mutable_traits {}; |
274 | template <typename T> |
275 | struct polygon_90_set_mutable_traits<std::list<T> > { |
276 | typedef typename geometry_concept<T>::type concept_type; |
277 | template <typename input_iterator_type> |
278 | static inline void set(std::list<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end, orientation_2d orient) { |
279 | polygon_set.clear(); |
280 | polygon_90_set_data<typename polygon_90_set_traits<std::list<T> >::coordinate_type> ps(orient); |
281 | ps.reserve(std::distance(input_begin, input_end)); |
282 | ps.insert(input_begin, input_end, orient); |
283 | ps.clean(); |
284 | get_90_dispatch(polygon_set, ps, orient, concept_type()); |
285 | } |
286 | }; |
287 | template <typename T> |
288 | struct polygon_90_set_mutable_traits<std::vector<T> > { |
289 | typedef typename geometry_concept<T>::type concept_type; |
290 | template <typename input_iterator_type> |
291 | static inline void set(std::vector<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end, orientation_2d orient) { |
292 | polygon_set.clear(); |
293 | size_t num_ele = std::distance(input_begin, input_end); |
294 | polygon_set.reserve(num_ele); |
295 | polygon_90_set_data<typename polygon_90_set_traits<std::list<T> >::coordinate_type> ps(orient); |
296 | ps.reserve(num_ele); |
297 | ps.insert(input_begin, input_end, orient); |
298 | ps.clean(); |
299 | get_90_dispatch(polygon_set, ps, orient, concept_type()); |
300 | } |
301 | }; |
302 | |
303 | template <typename T> |
304 | struct polygon_90_set_mutable_traits<polygon_90_set_data<T> > { |
305 | |
306 | template <typename input_iterator_type> |
307 | static inline void set(polygon_90_set_data<T>& polygon_set, |
308 | input_iterator_type input_begin, input_iterator_type input_end, |
309 | orientation_2d orient) { |
310 | polygon_set.clear(); |
311 | polygon_set.reserve(std::distance(input_begin, input_end)); |
312 | polygon_set.insert(input_begin, input_end, orient); |
313 | } |
314 | |
315 | }; |
316 | |
317 | template <typename T> |
318 | struct polygon_90_set_traits<polygon_90_set_data<T> > { |
319 | typedef typename polygon_90_set_data<T>::coordinate_type coordinate_type; |
320 | typedef typename polygon_90_set_data<T>::iterator_type iterator_type; |
321 | typedef typename polygon_90_set_data<T>::operator_arg_type operator_arg_type; |
322 | |
323 | static inline iterator_type begin(const polygon_90_set_data<T>& polygon_set) { |
324 | return polygon_set.begin(); |
325 | } |
326 | |
327 | static inline iterator_type end(const polygon_90_set_data<T>& polygon_set) { |
328 | return polygon_set.end(); |
329 | } |
330 | |
331 | static inline orientation_2d orient(const polygon_90_set_data<T>& polygon_set) { return polygon_set.orient(); } |
332 | |
333 | static inline bool clean(const polygon_90_set_data<T>& polygon_set) { polygon_set.clean(); return true; } |
334 | |
335 | static inline bool sorted(const polygon_90_set_data<T>& polygon_set) { polygon_set.sort(); return true; } |
336 | |
337 | }; |
338 | |
339 | template <typename T> |
340 | struct is_polygon_90_set_concept { }; |
341 | template <> |
342 | struct is_polygon_90_set_concept<polygon_90_set_concept> { typedef gtl_yes type; }; |
343 | template <> |
344 | struct is_polygon_90_set_concept<rectangle_concept> { typedef gtl_yes type; }; |
345 | template <> |
346 | struct is_polygon_90_set_concept<polygon_90_concept> { typedef gtl_yes type; }; |
347 | template <> |
348 | struct is_polygon_90_set_concept<polygon_90_with_holes_concept> { typedef gtl_yes type; }; |
349 | |
350 | template <typename T> |
351 | struct is_mutable_polygon_90_set_concept { typedef gtl_no type; }; |
352 | template <> |
353 | struct is_mutable_polygon_90_set_concept<polygon_90_set_concept> { typedef gtl_yes type; }; |
354 | |
355 | template <typename T> |
356 | struct geometry_concept<polygon_90_set_data<T> > { typedef polygon_90_set_concept type; }; |
357 | |
358 | //template <typename T> |
359 | //typename enable_if<typename is_polygon_90_set_type<T>::type, void>::type |
360 | //print_is_polygon_90_set_concept(const T& t) { std::cout << "is polygon 90 set concept\n"; } |
361 | //template <typename T> |
362 | //typename enable_if<typename is_mutable_polygon_90_set_type<T>::type, void>::type |
363 | //print_is_mutable_polygon_90_set_concept(const T& t) { std::cout << "is mutable polygon 90 set concept\n"; } |
364 | } |
365 | } |
366 | #endif |
367 | |