1 // Copyright (c) 1997  INRIA Sophia-Antipolis (France).
2 // All rights reserved.
3 //
4 // This file is part of CGAL (www.cgal.org).
5 //
6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/TDS_2/include/CGAL/Triangulation_ds_circulators_2.h $
7 // $Id: Triangulation_ds_circulators_2.h 74d8922 2020-04-20T15:25:40+02:00 Guillaume Damiand
8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 //
11 // Author(s)     : Mariette Yvinec
12 //                 Menelaos Karavelas <mkaravel@cse.nd.edu>
13 
14 #ifndef CGAL_TRIANGULATION_DS_CIRCULATORS_2_H
15 #define CGAL_TRIANGULATION_DS_CIRCULATORS_2_H
16 
17 #include <CGAL/license/TDS_2.h>
18 
19 
20 #include <utility>
21 #include <iterator>
22 #include <CGAL/circulator.h>
23 #include <CGAL/triangulation_assertions.h>
24 #include <CGAL/Triangulation_utils_2.h>
25 
26 namespace CGAL {
27 
28 template < class Tds>
29 class Triangulation_ds_face_circulator_2
30   : public Bidirectional_circulator_base< typename Tds::Face,
31                                  std::ptrdiff_t,
32                                  std::size_t>,
33     public Triangulation_cw_ccw_2
34 
35 {
36 private:
37   typedef
38   Bidirectional_circulator_base< typename Tds::Face,
39                                  std::ptrdiff_t,
40                                  std::size_t>  Base_circulator;
41 
42 public:
43   typedef Triangulation_ds_face_circulator_2<Tds> Face_circulator;
44   typedef typename Tds::Face                      Face;
45   typedef typename Tds::Vertex                    Vertex;
46   typedef typename Tds::Face_handle               Face_handle;
47   typedef typename Tds::Vertex_handle             Vertex_handle;
48 
49 
50 private:
51   Vertex_handle _v;
52   Face_handle    pos;
53 
54 public:
Triangulation_ds_face_circulator_2()55   Triangulation_ds_face_circulator_2()
56     : _v(), pos()
57   {}
58 
59   Triangulation_ds_face_circulator_2(Vertex_handle v,
60                                      Face_handle f = Face_handle());
61 
62   Face_circulator& operator++();
63   Face_circulator operator++(int);
64   Face_circulator& operator--();
65   Face_circulator operator--(int);
66 
67   bool operator==(const Face_circulator &fc) const;
68   bool operator!=(const Face_circulator &fc) const;
69 
70   bool operator==(const Face_handle &fh) const { return pos == fh; }
71   bool operator!=(const Face_handle &fh) const { return pos != fh; }
72 
73   bool is_empty() const;
74   bool operator==(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const;
75   bool operator!=(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const;
76 
77   Face&
78   operator*() const
79   {
80     CGAL_triangulation_precondition(pos != Face_handle() &&
81                                  _v != Vertex_handle());
82     return *pos;
83   }
84 
85   Face*
86   operator->() const
87   {
88     CGAL_triangulation_precondition(pos != Face_handle() &&
89                                  _v != Vertex_handle());
90     return &*pos;
91   }
92 
base()93   Face_handle base()  const {return pos;}
Face_handle()94   operator Face_handle()  const {return pos;}
95 };
96 
97 template < class Tds_ >
98 bool
99 operator==(typename Tds_::Face_handle fh,
100            Triangulation_ds_face_circulator_2<Tds_> fc)
101 {
102   return (fc==fh);
103 }
104 
105 template < class Tds_ >
106 bool
107 operator!=(typename Tds_::Face_handle fh,
108            Triangulation_ds_face_circulator_2<Tds_> fc)
109 {
110   return (fc!=fh);
111 }
112 
113 
114 template < class Tds >
115 class Triangulation_ds_vertex_circulator_2 :
116   public Bidirectional_circulator_base< typename Tds::Vertex,
117                                        std::ptrdiff_t,
118                                        std::size_t>,
119   public  Triangulation_cw_ccw_2
120 {
121 public:
122   typedef Triangulation_ds_vertex_circulator_2<Tds> Vertex_circulator;
123   typedef typename Tds::Face                      Face;
124   typedef typename Tds::Vertex                    Vertex;
125   typedef typename Tds::Face_handle               Face_handle;
126   typedef typename Tds::Vertex_handle             Vertex_handle;
127 
128 private:
129   Vertex_handle _v;
130   Face_handle   pos;
131   int _ri;
132 
133 public:
Triangulation_ds_vertex_circulator_2()134   Triangulation_ds_vertex_circulator_2()
135     :  _v(), pos()
136   {}
137 
138   Triangulation_ds_vertex_circulator_2(Vertex_handle v,
139                                        Face_handle f = Face_handle());
140 
141   Vertex_circulator& operator++();
142   Vertex_circulator  operator++(int);
143   Vertex_circulator& operator--();
144   Vertex_circulator  operator--(int);
145 
146   bool operator==(const Vertex_circulator &vc) const;
147   bool operator!=(const Vertex_circulator &vc) const;
148 
149   bool operator==(const Vertex_handle &vh) const
150   { return pos->vertex(_ri) == vh; }
151   bool operator!=(const Vertex_handle &vh) const
152   { return pos->vertex(_ri) != vh; }
153 
154   bool is_empty() const;
155   bool operator==(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const;
156   bool operator!=(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const;
157 
158   Vertex&
159   operator*() const
160   {
161     CGAL_triangulation_precondition(pos != Face_handle() &&
162                                  _v != Vertex_handle());
163     return *(pos->vertex(_ri));
164   }
165 
166   Vertex*
167   operator->() const
168   {
169     CGAL_triangulation_precondition(pos != Face_handle() &&
170                                  _v != Vertex_handle());
171     return &*(pos->vertex(_ri));
172   }
173 
base()174    Vertex_handle base() const {return pos->vertex(_ri);}
Vertex_handle()175    operator Vertex_handle() const {return pos->vertex(_ri);}
176 };
177 
178 template < class Tds_ >
179 inline
180 bool
181 operator==(typename Tds_::Vertex_handle vh,
182            Triangulation_ds_vertex_circulator_2<Tds_> vc)
183 {
184   return (vc==vh);
185 }
186 
187 template < class Tds_ >
188 inline
189 bool
190 operator!=(typename Tds_::Vertex_handle vh,
191            Triangulation_ds_vertex_circulator_2<Tds_> vc)
192 {
193   return !(vc==vh);
194 }
195 
196 
197 template < class Tds >
198 class Triangulation_ds_edge_circulator_2 :
199   public Bidirectional_circulator_base < typename Tds::Edge,
200                                          std::ptrdiff_t,
201                                          std::size_t>,
202   public Triangulation_cw_ccw_2
203 {
204 public:
205   typedef Triangulation_ds_edge_circulator_2<Tds>  Edge_circulator;
206   typedef typename Tds::Face                       Face;
207   typedef typename Tds::Vertex                     Vertex;
208   typedef typename Tds::Edge                       Edge;
209   typedef typename Tds::Face_handle                Face_handle;
210   typedef typename Tds::Vertex_handle              Vertex_handle;
211 
212 private:
213   int _ri;
214   Vertex_handle _v;
215   Face_handle  pos;
216   mutable Edge edge;
217 
218 public:
Triangulation_ds_edge_circulator_2()219   Triangulation_ds_edge_circulator_2()
220     : _ri(0), _v(), pos()
221   {}
222 
223   Triangulation_ds_edge_circulator_2( Vertex_handle v,
224                                       Face_handle f = Face_handle());
225 
226   Edge_circulator& operator++();
227   Edge_circulator operator++(int);
228   Edge_circulator& operator--();
229   Edge_circulator operator--(int);
230 
231   bool operator==(const Edge_circulator &vc) const;
232   bool operator!=(const Edge_circulator &vc) const;
233   bool is_empty() const;
234   bool operator==(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const;
235   bool operator!=(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const;
236 
237   Edge*  operator->() const {
238     edge.first=pos;
239     edge.second= _ri;
240     return &edge;
241   }
242 
243   Edge& operator*() const {
244     edge.first=pos;
245     edge.second= _ri;
246     return edge;
247   }
248 
249 };
250 
251 
252 template < class Tds >
253 Triangulation_ds_face_circulator_2<Tds> ::
Triangulation_ds_face_circulator_2(Vertex_handle v,Face_handle f)254 Triangulation_ds_face_circulator_2(Vertex_handle v, Face_handle f)
255   : _v(v), pos(f)
256 {
257   if (_v == Vertex_handle()) pos = Face_handle();
258   else if ( pos == Face_handle()) pos = v->face();
259 
260   if (pos ==  Face_handle()|| pos->dimension() < 2) {
261     _v =  Vertex_handle() ; pos = Face_handle(); return;}
262   else CGAL_triangulation_precondition( pos->has_vertex(v));
263 }
264 
265 
266 template < class Tds >
267 Triangulation_ds_face_circulator_2<Tds>&
268 Triangulation_ds_face_circulator_2<Tds> ::
269 operator++()
270 {
271   CGAL_triangulation_precondition( pos != Face_handle() &&
272                                  _v != Vertex_handle());
273   int i = pos->index(_v);
274   pos = pos->neighbor(ccw(i));
275   return *this;
276 }
277 
278 template < class Tds >
279 Triangulation_ds_face_circulator_2<Tds>
280 Triangulation_ds_face_circulator_2<Tds> ::
281 operator++(int)
282 {
283   CGAL_triangulation_precondition(pos != Face_handle() &&
284                                  _v != Vertex_handle());
285   Face_circulator tmp(*this);
286   ++(*this);
287   return tmp;
288 }
289 
290 template < class Tds >
291 Triangulation_ds_face_circulator_2<Tds>&
292 Triangulation_ds_face_circulator_2<Tds> ::
293 operator--()
294 {
295    CGAL_triangulation_precondition(pos != Face_handle() &&
296                                  _v != Vertex_handle());
297    int i = pos->index(_v);
298    pos = pos->neighbor(cw(i));
299    return *this;
300 }
301 
302 template < class Tds >
303 Triangulation_ds_face_circulator_2<Tds>
304 Triangulation_ds_face_circulator_2<Tds> ::
305 operator--(int)
306 {
307   CGAL_triangulation_precondition(pos != Face_handle() &&
308                                  _v != Vertex_handle());
309   Face_circulator tmp(*this);
310   --(*this);
311   return tmp;
312 }
313 
314 template < class Tds >
315 inline bool
316 Triangulation_ds_face_circulator_2<Tds> ::
317 operator==(const Face_circulator &fc) const
318 {
319   return (_v == fc._v) &&  (pos == fc.pos);
320 }
321 
322 template < class Tds >
323 inline bool
324 Triangulation_ds_face_circulator_2<Tds> ::
325 operator!=(const Face_circulator &fc) const
326 {
327 return ! (*this == fc);
328 }
329 
330 template < class Tds >
331 inline bool
332 Triangulation_ds_face_circulator_2<Tds> ::
is_empty()333 is_empty() const
334 {
335 return (_v == Vertex_handle() ||  pos == Face_handle() );
336 }
337 
338 template < class Tds >
339 inline bool
340 Triangulation_ds_face_circulator_2<Tds> ::
341 operator==(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const
342 {
343   //CGAL_triangulation_assertion( n == nullptr);
344   return (_v == Vertex_handle() ||  pos == Face_handle() );
345 }
346 
347 template < class Tds >
348 inline bool
349 Triangulation_ds_face_circulator_2<Tds> ::
350 operator!=(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const
351 {
352   //CGAL_triangulation_assertion( n == nullptr);
353   return ! (*this == nullptr);
354 }
355 
356 template < class Tds >
357 Triangulation_ds_vertex_circulator_2<Tds> ::
Triangulation_ds_vertex_circulator_2(Vertex_handle v,Face_handle f)358 Triangulation_ds_vertex_circulator_2 (Vertex_handle v,
359                                       Face_handle f)
360   : _v( v ), pos(f)
361 {
362   if (_v == Vertex_handle()) { pos = Face_handle();}
363   else if (pos == Face_handle()) {pos = v->face();}
364 
365   if (pos == Face_handle() || pos->dimension() < 1){
366     _v = Vertex_handle(); pos = Face_handle(); return;}
367   int i = pos->index(_v);
368   if (pos->dimension() == 2) {_ri = ccw(i);}
369   else {CGAL_assertion(i>=0 && i<=1);_ri = (i == 0) ? 1 : 0;}
370   return;
371 }
372 
373 
374 template < class Tds >
375 Triangulation_ds_vertex_circulator_2<Tds>&
376 Triangulation_ds_vertex_circulator_2<Tds> ::
377 operator++()
378 {
379   CGAL_triangulation_precondition(pos != Face_handle() &&
380                                   _v != Vertex_handle());
381   int i = pos->index(_v);
382 
383   if (pos->dimension() == 1) {
384     CGAL_assertion(i>=0 && i<=1);
385     pos = pos->neighbor((i == 0) ? 1 : 0);
386     _ri = 1 - pos->index(_v);
387   }
388   else{
389     pos = pos->neighbor(ccw(i));
390     i = pos->index(_v);
391     _ri = ccw(i);
392   }
393   return *this;
394 }
395 
396 template < class Tds >
397 Triangulation_ds_vertex_circulator_2<Tds>
398 Triangulation_ds_vertex_circulator_2<Tds> ::
399 operator++(int)
400 {
401   Vertex_circulator tmp(*this);
402   ++(*this);
403   return tmp;
404 }
405 
406 template < class Tds >
407 Triangulation_ds_vertex_circulator_2<Tds>&
408 Triangulation_ds_vertex_circulator_2<Tds> ::
409 operator--()
410 {
411   CGAL_triangulation_precondition(pos != Face_handle() &&
412                                   _v != Vertex_handle());
413   int i = pos->index(_v);
414 
415   if (pos->dimension() == 1) {
416     CGAL_assertion(i>=0 && i<=1);
417     pos = pos->neighbor((i == 0) ? 1 : 0);
418     _ri = 1 - pos->index(_v);
419   }
420   else{
421     pos = pos->neighbor(cw(i));
422     i = pos->index(_v);
423     _ri = ccw(i);
424   }
425   return *this;
426 }
427 
428 template < class Tds >
429 Triangulation_ds_vertex_circulator_2<Tds>
430 Triangulation_ds_vertex_circulator_2<Tds> ::
431 operator--(int)
432 {
433   Vertex_circulator tmp(*this);
434   --(*this);
435   return tmp;
436 }
437 
438 template < class Tds >
439 inline bool
440 Triangulation_ds_vertex_circulator_2<Tds> ::
441 operator==(const Vertex_circulator &vc) const
442 {
443   return (_v == vc._v) &&  (_ri == vc._ri) && (pos == vc.pos);
444 }
445 
446 template < class Tds >
447 inline bool
448 Triangulation_ds_vertex_circulator_2<Tds> ::
449 operator!=(const Vertex_circulator &vc) const
450 {
451   return ! (*this == vc);
452 }
453 
454 template < class Tds >
455 inline bool
456 Triangulation_ds_vertex_circulator_2<Tds> ::
is_empty()457 is_empty() const
458 {
459   return (_v == Vertex_handle() || pos == Face_handle());
460 }
461 
462 template < class Tds >
463 inline bool
464 Triangulation_ds_vertex_circulator_2<Tds> ::
465 operator==(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const
466 {
467   //CGAL_triangulation_assertion( n == nullptr);
468   return (_v == Vertex_handle() || pos == Face_handle());
469 }
470 
471 template < class Tds >
472 inline bool
473 Triangulation_ds_vertex_circulator_2<Tds> ::
474 operator!=(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const
475 {
476   //CGAL_triangulation_assertion( n == nullptr);
477   return !(*this == nullptr);
478 }
479 
480 
481 template < class Tds >
482 Triangulation_ds_edge_circulator_2<Tds> ::
Triangulation_ds_edge_circulator_2(Vertex_handle v,Face_handle f)483 Triangulation_ds_edge_circulator_2(Vertex_handle v, Face_handle f)
484     : _v(v), pos(f)
485 {
486   if (_v == Vertex_handle()) { pos = Face_handle();}
487   else if (pos==Face_handle()) {pos = v->face();}
488 
489   if (pos == Face_handle() || pos->dimension() < 1){
490     _ri = 0; _v = Vertex_handle(); pos = Face_handle();return;}
491   int i = pos->index(_v);
492   if (pos->dimension() == 2) {_ri = ccw(i);}
493   else {_ri = 2;}
494   return;
495 }
496 
497 template < class Tds >
498 Triangulation_ds_edge_circulator_2<Tds>&
499 Triangulation_ds_edge_circulator_2<Tds> ::
500 operator++()
501 {
502   CGAL_triangulation_precondition(pos != Face_handle() &&
503                                   _v != Vertex_handle());
504   int i = pos->index(_v);
505   if (pos->dimension() == 1) {
506     CGAL_assertion(i>=0 && i<=1);
507     pos = pos->neighbor(i == 0 ? 1 : 0);
508     return *this;
509   }
510   else{
511     pos = pos->neighbor(ccw(i));
512     i = pos->index(_v);
513     _ri = ccw(i);
514   }
515   return *this;
516 }
517 
518 template < class Tds >
519 Triangulation_ds_edge_circulator_2<Tds>
520 Triangulation_ds_edge_circulator_2<Tds> ::
521 operator++(int)
522 {
523   Edge_circulator tmp(*this);
524   ++(*this);
525   return tmp;
526 }
527 
528 template < class Tds >
529 Triangulation_ds_edge_circulator_2<Tds>&
530 Triangulation_ds_edge_circulator_2<Tds> ::
531 operator--()
532 {
533   CGAL_triangulation_precondition(pos != Face_handle() &&
534                                   _v != Vertex_handle());
535   int i = pos->index(_v);
536 
537   if (pos->dimension() == 1) {
538     CGAL_assertion(i>=0 && i<=1);
539     pos = pos->neighbor((i == 0) ? 1 : 0);
540     return *this;
541   }
542   else{
543     pos = pos->neighbor(cw(i));
544     i = pos->index(_v);
545     _ri = ccw(i);
546   }
547   return *this;
548 }
549 
550 template < class Tds >
551 Triangulation_ds_edge_circulator_2<Tds>
552 Triangulation_ds_edge_circulator_2<Tds> ::
553 operator--(int)
554 {
555   Edge_circulator tmp(*this);
556   --(*this);
557   return tmp;
558 }
559 
560 template < class Tds >
561 inline bool
562 Triangulation_ds_edge_circulator_2<Tds> ::
563 operator==(const Edge_circulator &vc) const
564 {
565   return (_v == vc._v) &&  (_ri == vc._ri) && (pos == vc.pos);
566 }
567 
568 template < class Tds >
569 inline bool
570 Triangulation_ds_edge_circulator_2<Tds> ::
571 operator!=(const Edge_circulator &vc) const
572 {
573   return ! (*this == vc);
574 }
575 
576 template < class Tds >
577 inline bool
578 Triangulation_ds_edge_circulator_2<Tds> ::
is_empty()579 is_empty() const
580 {
581   return (_v == Vertex_handle() || pos == Face_handle());
582 }
583 
584 template < class Tds >
585 inline bool
586 Triangulation_ds_edge_circulator_2<Tds> ::
587 operator==(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const
588 {
589   //CGAL_triangulation_assertion( n == nullptr);
590   return (_v == Vertex_handle() || pos == Face_handle());
591 }
592 
593 template < class Tds >
594 inline bool
595 Triangulation_ds_edge_circulator_2<Tds> ::
596 operator!=(std::nullptr_t /*CGAL_triangulation_assertion_code(n)*/) const
597 {
598   //CGAL_triangulation_assertion( n == nullptr);
599   return !(*this == nullptr);
600 }
601 
602 
603 } //namespace CGAL
604 
605 #endif //CGAL_TRIANGULATION_DS_CIRCULATORS_2_H
606