]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/polygon/detail/iterator_geometry_to_set.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / polygon / detail / iterator_geometry_to_set.hpp
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_ITERATOR_GEOMETRY_TO_SET_HPP
9 #define BOOST_POLYGON_ITERATOR_GEOMETRY_TO_SET_HPP
10 namespace boost { namespace polygon{
11 template <typename concept_type, typename geometry_type>
12 class iterator_geometry_to_set {};
13
14 template <typename rectangle_type>
15 class iterator_geometry_to_set<rectangle_concept, rectangle_type> {
16 public:
17 typedef typename rectangle_traits<rectangle_type>::coordinate_type coordinate_type;
18 typedef std::forward_iterator_tag iterator_category;
19 typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > value_type;
20 typedef std::ptrdiff_t difference_type;
21 typedef const value_type* pointer; //immutable
22 typedef const value_type& reference; //immutable
23 private:
24 rectangle_data<coordinate_type> rectangle_;
25 mutable value_type vertex_;
26 unsigned int corner_;
27 orientation_2d orient_;
28 bool is_hole_;
29 public:
30 iterator_geometry_to_set() : rectangle_(), vertex_(), corner_(4), orient_(), is_hole_() {}
31 iterator_geometry_to_set(const rectangle_type& rectangle, direction_1d dir,
32 orientation_2d orient = HORIZONTAL, bool is_hole = false, bool = false, direction_1d = CLOCKWISE) :
33 rectangle_(), vertex_(), corner_(0), orient_(orient), is_hole_(is_hole) {
34 assign(rectangle_, rectangle);
35 if(dir == HIGH) corner_ = 4;
36 }
37 inline iterator_geometry_to_set& operator++() {
38 ++corner_;
39 return *this;
40 }
41 inline const iterator_geometry_to_set operator++(int) {
42 iterator_geometry_to_set tmp(*this);
43 ++(*this);
44 return tmp;
45 }
46 inline bool operator==(const iterator_geometry_to_set& that) const {
47 return corner_ == that.corner_;
48 }
49 inline bool operator!=(const iterator_geometry_to_set& that) const {
50 return !(*this == that);
51 }
52 inline reference operator*() const {
53 if(corner_ == 0) {
54 vertex_.first = get(get(rectangle_, orient_.get_perpendicular()), LOW);
55 vertex_.second.first = get(get(rectangle_, orient_), LOW);
56 vertex_.second.second = 1;
57 if(is_hole_) vertex_.second.second *= -1;
58 } else if(corner_ == 1) {
59 vertex_.second.first = get(get(rectangle_, orient_), HIGH);
60 vertex_.second.second = -1;
61 if(is_hole_) vertex_.second.second *= -1;
62 } else if(corner_ == 2) {
63 vertex_.first = get(get(rectangle_, orient_.get_perpendicular()), HIGH);
64 vertex_.second.first = get(get(rectangle_, orient_), LOW);
65 } else {
66 vertex_.second.first = get(get(rectangle_, orient_), HIGH);
67 vertex_.second.second = 1;
68 if(is_hole_) vertex_.second.second *= -1;
69 }
70 return vertex_;
71 }
72 };
73
74 template <typename polygon_type>
75 class iterator_geometry_to_set<polygon_90_concept, polygon_type> {
76 public:
77 typedef typename polygon_traits<polygon_type>::coordinate_type coordinate_type;
78 typedef std::forward_iterator_tag iterator_category;
79 typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > value_type;
80 typedef std::ptrdiff_t difference_type;
81 typedef const value_type* pointer; //immutable
82 typedef const value_type& reference; //immutable
83 typedef typename polygon_traits<polygon_type>::iterator_type coord_iterator_type;
84 private:
85 value_type vertex_;
86 typename polygon_traits<polygon_type>::iterator_type itrb, itre;
87 bool last_vertex_;
88 bool is_hole_;
89 int multiplier_;
90 point_data<coordinate_type> first_pt, second_pt, pts[3];
91 bool use_wrap;
92 orientation_2d orient_;
93 int polygon_index;
94 public:
95 iterator_geometry_to_set() : vertex_(), itrb(), itre(), last_vertex_(), is_hole_(), multiplier_(), first_pt(), second_pt(), pts(), use_wrap(), orient_(), polygon_index(-1) {}
96 iterator_geometry_to_set(const polygon_type& polygon, direction_1d dir, orientation_2d orient = HORIZONTAL, bool is_hole = false, bool winding_override = false, direction_1d w = CLOCKWISE) :
97 vertex_(), itrb(), itre(), last_vertex_(),
98 is_hole_(is_hole), multiplier_(), first_pt(), second_pt(), pts(), use_wrap(),
99 orient_(orient), polygon_index(0) {
100 itrb = begin_points(polygon);
101 itre = end_points(polygon);
102 use_wrap = false;
103 if(itrb == itre || dir == HIGH || ::boost::polygon::size(polygon) < 4) {
104 polygon_index = -1;
105 } else {
106 direction_1d wdir = w;
107 if(!winding_override)
108 wdir = winding(polygon);
109 multiplier_ = wdir == LOW ? -1 : 1;
110 if(is_hole_) multiplier_ *= -1;
111 first_pt = pts[0] = *itrb;
112 ++itrb;
113 second_pt = pts[1] = *itrb;
114 ++itrb;
115 pts[2] = *itrb;
116 evaluate_();
117 }
118 }
119 iterator_geometry_to_set(const iterator_geometry_to_set& that) :
120 vertex_(), itrb(), itre(), last_vertex_(), is_hole_(), multiplier_(), first_pt(),
121 second_pt(), pts(), use_wrap(), orient_(), polygon_index(-1) {
122 vertex_ = that.vertex_;
123 itrb = that.itrb;
124 itre = that.itre;
125 last_vertex_ = that.last_vertex_;
126 is_hole_ = that.is_hole_;
127 multiplier_ = that.multiplier_;
128 first_pt = that.first_pt;
129 second_pt = that.second_pt;
130 pts[0] = that.pts[0];
131 pts[1] = that.pts[1];
132 pts[2] = that.pts[2];
133 use_wrap = that.use_wrap;
134 orient_ = that.orient_;
135 polygon_index = that.polygon_index;
136 }
137 inline iterator_geometry_to_set& operator++() {
138 ++polygon_index;
139 if(itrb == itre) {
140 if(first_pt == pts[1]) polygon_index = -1;
141 else {
142 pts[0] = pts[1];
143 pts[1] = pts[2];
144 if(first_pt == pts[2]) {
145 pts[2] = second_pt;
146 } else {
147 pts[2] = first_pt;
148 }
149 }
150 } else {
151 ++itrb;
152 pts[0] = pts[1];
153 pts[1] = pts[2];
154 if(itrb == itre) {
155 if(first_pt == pts[2]) {
156 pts[2] = second_pt;
157 } else {
158 pts[2] = first_pt;
159 }
160 } else {
161 pts[2] = *itrb;
162 }
163 }
164 evaluate_();
165 return *this;
166 }
167 inline const iterator_geometry_to_set operator++(int) {
168 iterator_geometry_to_set tmp(*this);
169 ++(*this);
170 return tmp;
171 }
172 inline bool operator==(const iterator_geometry_to_set& that) const {
173 return polygon_index == that.polygon_index;
174 }
175 inline bool operator!=(const iterator_geometry_to_set& that) const {
176 return !(*this == that);
177 }
178 inline reference operator*() const {
179 return vertex_;
180 }
181
182 inline void evaluate_() {
183 vertex_.first = pts[1].get(orient_.get_perpendicular());
184 vertex_.second.first =pts[1].get(orient_);
185 if(pts[1] == pts[2]) {
186 vertex_.second.second = 0;
187 } else if(pts[0].get(HORIZONTAL) != pts[1].get(HORIZONTAL)) {
188 vertex_.second.second = -1;
189 } else if(pts[0].get(VERTICAL) != pts[1].get(VERTICAL)) {
190 vertex_.second.second = 1;
191 } else {
192 vertex_.second.second = 0;
193 }
194 vertex_.second.second *= multiplier_;
195 }
196 };
197
198 template <typename polygon_with_holes_type>
199 class iterator_geometry_to_set<polygon_90_with_holes_concept, polygon_with_holes_type> {
200 public:
201 typedef typename polygon_90_traits<polygon_with_holes_type>::coordinate_type coordinate_type;
202 typedef std::forward_iterator_tag iterator_category;
203 typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > value_type;
204 typedef std::ptrdiff_t difference_type;
205 typedef const value_type* pointer; //immutable
206 typedef const value_type& reference; //immutable
207 private:
208 iterator_geometry_to_set<polygon_90_concept, polygon_with_holes_type> itrb, itre;
209 iterator_geometry_to_set<polygon_90_concept, typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type> itrhib, itrhie;
210 typename polygon_with_holes_traits<polygon_with_holes_type>::iterator_holes_type itrhb, itrhe;
211 orientation_2d orient_;
212 bool is_hole_;
213 bool started_holes;
214 public:
215 iterator_geometry_to_set() : itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(), is_hole_(), started_holes() {}
216 iterator_geometry_to_set(const polygon_with_holes_type& polygon, direction_1d dir,
217 orientation_2d orient = HORIZONTAL, bool is_hole = false, bool = false, direction_1d = CLOCKWISE) :
218 itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(orient), is_hole_(is_hole), started_holes() {
219 itre = iterator_geometry_to_set<polygon_90_concept, polygon_with_holes_type>(polygon, HIGH, orient, is_hole_);
220 itrhe = end_holes(polygon);
221 if(dir == HIGH) {
222 itrb = itre;
223 itrhb = itrhe;
224 started_holes = true;
225 } else {
226 itrb = iterator_geometry_to_set<polygon_90_concept, polygon_with_holes_type>(polygon, LOW, orient, is_hole_);
227 itrhb = begin_holes(polygon);
228 started_holes = false;
229 }
230 }
231 iterator_geometry_to_set(const iterator_geometry_to_set& that) :
232 itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(), is_hole_(), started_holes() {
233 itrb = that.itrb;
234 itre = that.itre;
235 if(that.itrhib != that.itrhie) {
236 itrhib = that.itrhib;
237 itrhie = that.itrhie;
238 }
239 itrhb = that.itrhb;
240 itrhe = that.itrhe;
241 orient_ = that.orient_;
242 is_hole_ = that.is_hole_;
243 started_holes = that.started_holes;
244 }
245 inline iterator_geometry_to_set& operator++() {
246 //this code can be folded with flow control factoring
247 if(itrb == itre) {
248 if(itrhib == itrhie) {
249 if(itrhb != itrhe) {
250 itrhib = iterator_geometry_to_set<polygon_90_concept,
251 typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_);
252 itrhie = iterator_geometry_to_set<polygon_90_concept,
253 typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_);
254 ++itrhb;
255 } else {
256 //in this case we have no holes so we just need the iterhib == itrhie, which
257 //is always true if they were default initialized in the initial case or
258 //both point to end of the previous hole processed
259 //no need to explicitly reset them, and it causes an stl debug assertion to use
260 //the default constructed iterator this way
261 //itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept,
262 // typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>();
263 }
264 } else {
265 ++itrhib;
266 if(itrhib == itrhie) {
267 if(itrhb != itrhe) {
268 itrhib = iterator_geometry_to_set<polygon_90_concept,
269 typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_);
270 itrhie = iterator_geometry_to_set<polygon_90_concept,
271 typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_);
272 ++itrhb;
273 } else {
274 //this is the same case as above
275 //itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept,
276 // typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>();
277 }
278 }
279 }
280 } else {
281 ++itrb;
282 if(itrb == itre) {
283 if(itrhb != itrhe) {
284 itrhib = iterator_geometry_to_set<polygon_90_concept,
285 typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_);
286 itrhie = iterator_geometry_to_set<polygon_90_concept,
287 typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_);
288 ++itrhb;
289 }
290 }
291 }
292 return *this;
293 }
294 inline const iterator_geometry_to_set operator++(int) {
295 iterator_geometry_to_set tmp(*this);
296 ++(*this);
297 return tmp;
298 }
299 inline bool operator==(const iterator_geometry_to_set& that) const {
300 return itrb == that.itrb && itrhb == that.itrhb && itrhib == that.itrhib;
301 }
302 inline bool operator!=(const iterator_geometry_to_set& that) const {
303 return !(*this == that);
304 }
305 inline reference operator*() const {
306 if(itrb != itre) return *itrb;
307 return *itrhib;
308 }
309 };
310
311
312 }
313 }
314 #endif