1 // Copyright (c) 2003
2 // Utrecht University (The Netherlands),
3 // ETH Zurich (Switzerland),
4 // INRIA Sophia-Antipolis (France),
5 // Max-Planck-Institute Saarbruecken (Germany),
6 // and Tel-Aviv University (Israel). All rights reserved.
7 //
8 // This file is part of CGAL (www.cgal.org)
9 //
10 // $URL: https://github.com/CGAL/cgal/blob/v5.3/STL_Extension/include/CGAL/iterator.h $
11 // $Id: iterator.h 758ae80 2020-07-30T17:33:00+02:00 Dmitry Anisimov
12 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
13 //
14 //
15 // Author(s) : Michael Hoffmann <hoffmann@inf.ethz.ch>
16 // Lutz Kettner <kettner@mpi-sb.mpg.de>
17 // Sylvain Pion
18
19 #ifndef CGAL_ITERATOR_H
20 #define CGAL_ITERATOR_H 1
21
22 #include <CGAL/disable_warnings.h>
23
24 #include <CGAL/assertions.h>
25 #include <CGAL/circulator.h>
26 #include <CGAL/Iterator_range.h>
27 #include <CGAL/tuple.h>
28 #include <CGAL/use.h>
29
30 #include <boost/variant.hpp>
31 #include <boost/optional.hpp>
32 #include <boost/config.hpp>
33
34 #include <vector>
35 #include <map>
36 #include <utility>
37
38 namespace CGAL {
39
40 template<typename I>
41 class Prevent_deref
42 : public boost::iterator_adaptor<
43 Prevent_deref<I>
44 , I // base
45 , I // value
46 >
47 {
48 public:
49 typedef boost::iterator_adaptor<
50 Prevent_deref<I>
51 , I // base
52 , I // value
53 > Base;
54 typedef typename Base::reference reference;
55 typedef typename std::pair<I, I> range;
56
Prevent_deref()57 Prevent_deref() : Base() {}
Prevent_deref(const I & i)58 Prevent_deref(const I& i) : Base(i) {}
59 private:
60 friend class boost::iterator_core_access;
dereference()61 reference dereference() const { return const_cast<typename boost::remove_reference<reference>::type&>(this->base_reference()); }
62 };
63
64 template<typename I>
make_prevent_deref_range(const Iterator_range<I> & range)65 Iterator_range<Prevent_deref<I> > make_prevent_deref_range(const Iterator_range<I>& range)
66 {
67 return Iterator_range<Prevent_deref<I> >(make_prevent_deref(range.first), make_prevent_deref(range.second));
68 }
69
70 template<typename I>
make_prevent_deref(const I & i)71 Prevent_deref<I> make_prevent_deref(const I& i)
72 {
73 return Prevent_deref<I>(i);
74 }
75
76 template<typename I>
make_prevent_deref_range(const I & begin,const I & end)77 Iterator_range<Prevent_deref<I> > make_prevent_deref_range(const I& begin, const I& end)
78 {
79 return Iterator_range<Prevent_deref<I> >(make_prevent_deref(begin), make_prevent_deref(end));
80 }
81
82 namespace cpp98 {
83
84 template<typename Category, typename Tp, typename Distance = std::ptrdiff_t,
85 typename Pointer = Tp*, typename Reference = Tp&>
86 struct iterator
87 {
88 /// One of the iterator_tags tag types.
89 typedef Category iterator_category;
90 /// The type "pointed to" by the iterator.
91 typedef Tp value_type;
92 /// Distance between iterators is represented as this type.
93 typedef Distance difference_type;
94 /// This type represents a pointer-to-value_type.
95 typedef Pointer pointer;
96 /// This type represents a reference-to-value_type.
97 typedef Reference reference;
98 };
99
100 } // end namespace cpp98
101
102 // +----------------------------------------------------------------+
103 // | Emptyset_iterator
104 // +----------------------------------------------------------------+
105 // | sends everything to /dev/null
106 // +----------------------------------------------------------------+
107
108 struct Emptyset_iterator
109 : public CGAL::cpp98::iterator< std::output_iterator_tag, void, void, void, void >
110 {
111 template< class T >
112 Emptyset_iterator& operator=(const T&) { return *this; }
113
114 Emptyset_iterator& operator++() { return *this; }
115 Emptyset_iterator& operator++(int) { return *this; }
116
117 Emptyset_iterator& operator*() { return *this; }
118 };
119
120 // +---------------------------------------------------------------------+
121 // | Insert_iterator
122 // +---------------------------------------------------------------------+
123 // | Insert output iterator, which calls insert(value) on the container.
124 // | Similar to std::insert_iterator<> except it doesn't pass an iterator.
125 // +---------------------------------------------------------------------+
126
127 template < class Container >
128 class Insert_iterator
129 : public CGAL::cpp98::iterator< std::output_iterator_tag, void, void, void, void >
130 {
131 protected:
132 Container *container;
133 public:
134 typedef Container container_type;
135
Insert_iterator(Container & c)136 explicit Insert_iterator(Container &c)
137 : container(&c) {}
138
139 Insert_iterator&
140 operator=(typename Container::const_reference value)
141 {
142 container->insert(value);
143 return *this;
144 }
145
146 Insert_iterator&
147 operator*() { return *this; }
148
149 Insert_iterator&
150 operator++() { return *this; }
151
152 Insert_iterator
153 operator++(int) { return *this; }
154 };
155
156 template < class Container >
157 inline Insert_iterator<Container>
inserter(Container & x)158 inserter(Container &x)
159 { return Insert_iterator<Container>(x); }
160
161 // +----------------------------------------------------------------+
162 // | Oneset_iterator
163 // +----------------------------------------------------------------+
164 // | stores a pointer to an object of type T
165 // | which will be affected by operator*().
166 // +----------------------------------------------------------------+
167
168 template < class T >
169 class Oneset_iterator
170 : public CGAL::cpp98::iterator< std::bidirectional_iterator_tag,
171 void, void, void, void >
172 {
173 T* t;
174
175 public:
176 // types
177 typedef Oneset_iterator<T> Self;
178
179 public:
Oneset_iterator(T & t)180 Oneset_iterator(T& t) : t(&t) {}
181
182 T& operator*() { return *t; }
183 const T& operator*() const { return *t; }
184 T* operator->() { return t; }
185 const T* operator->() const { return t; }
186
187 Self& operator++() { return *this; }
188 Self& operator++(int) { return *this; }
189
190 Self& operator--() { return *this; }
191 Self& operator--(int) { return *this; }
192 };
193
194 // +----------------------------------------------------------------+
195 // | Const_oneset_iterator
196 // +----------------------------------------------------------------+
197 // | stores an object of type T
198 // | which will be affected by operator*().
199 // +----------------------------------------------------------------+
200
201 template < typename T >
202 class Const_oneset_iterator {
203 public:
204
205 // types
206 typedef std::random_access_iterator_tag iterator_category;
207 typedef std::ptrdiff_t difference_type;
208 typedef T value_type;
209 typedef value_type* pointer;
210 typedef value_type& reference;
211
212 typedef Const_oneset_iterator<T> Self;
213 typedef difference_type Diff;
214 typedef value_type Val;
215 typedef pointer Ptr;
216 typedef reference Ref;
217
218 // construction
219 Const_oneset_iterator( const T& t = T(), Diff n = 0)
value(t)220 : value( t), index( n)
221 { }
222
223 // access
224 Ref operator * ( ) { return value; }
225 const value_type& operator * ( ) const { return value; }
226 Ptr operator -> ( ) { return &value; }
227 const value_type* operator -> ( ) const { return &value; }
228
229 // equality operator
230 bool operator == ( const Self& x) const { return ( index==x.index); }
231 bool operator != ( const Self& x) const { return ( index!=x.index); }
232
233 // forward operations
234 // ------------------
235 Self& operator ++ ( ) { ++index; return *this; }
236 Self operator ++ ( int) { Self tmp = *this; ++index; return tmp; }
237
238 // bidirectional operations
239 // ------------------------
240 Self& operator -- ( ) { --index; return *this; }
241 Self operator -- ( int) { Self tmp = *this; --index; return tmp; }
242
243 // random access operations
244 // ------------------------
245 // access
246 Ref operator [] ( Diff ) { return value;}
247 const value_type& operator [] ( Diff ) const { return value;}
248
249 // less operator
250 bool operator < ( const Self& x) const { return ( index < x.index);}
251
252 // arithmetic operations
253 Self& operator += ( Diff n) { index += n; return *this; }
254 Self& operator -= ( Diff n) { index -= n; return *this; }
255
256 Self operator + ( Diff n) const { Self tmp = *this; return tmp+=n; }
257 Self operator - ( Diff n) const { Self tmp = *this; return tmp-=n; }
258
259 Diff operator - ( const Self& x) const { return index - x.index; }
260
261 private:
262
263 // data members
264 Val value;
265 Diff index;
266 };
267
268 // +----------------------------------------------------------------+
269 // | Counting_output_iterator
270 // +----------------------------------------------------------------+
271 // | stores a pointer to an int,
272 // | which will be incremented by operator=().
273 // +----------------------------------------------------------------+
274
275 // Undocumented, because there is some hope to merge it into Counting_iterator
276 class Counting_output_iterator
277 : public CGAL::cpp98::iterator< std::output_iterator_tag, void, void, void, void >
278 {
279 std::size_t *c;
280 public:
Counting_output_iterator(std::size_t * cc)281 Counting_output_iterator(std::size_t *cc) : c(cc) { *c = 0; }
282
283 Counting_output_iterator& operator++() { return *this; }
284 Counting_output_iterator& operator++(int) { return *this; }
285
286 Counting_output_iterator& operator*() { return *this; }
287
288 template <typename T>
289 void operator=(const T&) { ++*c; }
290
current_counter()291 std::size_t current_counter() const { return *c; }
292 };
293
294 template < class I,
295 class Val = typename std::iterator_traits<I>::value_type >
296 class Counting_iterator {
297 protected:
298 I nt; // The internal iterator.
299 std::size_t d_i; // The internal counter.
300 public:
301 typedef I Iterator;
302 typedef Counting_iterator<I,Val> Self;
303
304 typedef std::input_iterator_tag iterator_category;
305 typedef Val value_type;
306 typedef std::ptrdiff_t difference_type;
307 typedef const value_type& reference;
308 typedef const value_type* pointer;
309
310 // CREATION
311 // --------
312
d_i(i)313 Counting_iterator( std::size_t i = 0) : d_i(i) {}
nt(j)314 Counting_iterator( Iterator j, std::size_t i = 0) : nt(j), d_i(i) {}
315
316 // OPERATIONS Forward Category
317 // ---------------------------
318
current_iterator()319 Iterator current_iterator() const { return nt;}
current_counter()320 std::size_t current_counter() const { return d_i;}
321
322 bool operator==( const Self& i) const { return ( d_i == i.d_i); }
323 bool operator!=( const Self& i) const { return !(*this == i); }
324 reference operator*() const { return *nt; }
325 pointer operator->() const { return nt.operator->(); }
326 Self& operator++() {
327 ++nt;
328 ++d_i;
329 return *this;
330 }
331 Self operator++(int) {
332 Self tmp = *this;
333 ++*this;
334 return tmp;
335 }
336 };
337
338 template < class I, int N,
339 class Ref = typename std::iterator_traits<I>::reference,
340 class Ptr = typename std::iterator_traits<I>::pointer,
341 class Val = typename std::iterator_traits<I>::value_type,
342 class Dist = typename std::iterator_traits<I>::difference_type,
343 class Ctg = typename std::iterator_traits<I>::iterator_category >
344 class N_step_adaptor {
345 protected:
346 I nt; // The internal iterator.
347 bool empty;
348 public:
349 typedef I Iterator;
350 typedef N_step_adaptor<I,N> Self;
351 typedef std::iterator_traits<I> ITI;
352 typedef typename ITI::reference reference;
353 typedef typename ITI::pointer pointer;
354 typedef typename ITI::value_type value_type;
355 typedef typename ITI::difference_type difference_type;
356 typedef typename ITI::iterator_category iterator_category;
357 // Special for circulators.
358 typedef I_Circulator_size_traits<iterator_category,I> C_S_Traits;
359 typedef typename C_S_Traits::size_type size_type;
360
361 // CREATION
362 // --------
363
N_step_adaptor()364 N_step_adaptor(): empty(true) {}
N_step_adaptor(Iterator j)365 N_step_adaptor( Iterator j) : nt(j), empty(false) {}
366
367 template <class II>
N_step_adaptor(const N_step_adaptor<II,N> & j)368 N_step_adaptor( const N_step_adaptor<II,N>& j)
369 : nt( j.current_iterator()), empty(j.empty) {}
370
371 // OPERATIONS Forward Category
372 // ---------------------------
373
374 // Circulator stuff.
375 typedef I Circulator;
current_circulator()376 Circulator current_circulator() const { return nt;}
377
current_iterator()378 Iterator current_iterator() const { return nt;}
379 bool operator==( std::nullptr_t p) const {
380 CGAL_USE(p);
381 CGAL_assertion( p == 0);
382 return empty;
383 }
384 bool operator!=( std::nullptr_t p) const { return !(*this == p); }
385 bool operator==( const Self& i) const { return (empty && i.empty) ||( nt == i.nt); }
386 bool operator!=( const Self& i) const { return !(*this == i); }
387 reference operator*() const { return *nt; }
388 pointer operator->() const { return nt.operator->(); }
389 Self& operator++() {
390 std::advance( nt, N);
391 return *this;
392 }
393 Self operator++(int) {
394 Self tmp = *this;
395 ++*this;
396 return tmp;
397 }
398
399 // OPERATIONS Bidirectional Category
400 // ---------------------------------
401
402 Self& operator--() {
403 std::advance( nt, -N);
404 return *this;
405 }
406 Self operator--(int) {
407 Self tmp = *this;
408 --*this;
409 return tmp;
410 }
411
412 // OPERATIONS Random Access Category
413 // ---------------------------------
414
min_circulator()415 Self min_circulator() const { return Self( nt.min_circulator()); }
416 Self& operator+=( difference_type n) {
417 nt += difference_type(N * n);
418 return *this;
419 }
420 Self operator+( difference_type n) const {
421 Self tmp = *this;
422 tmp.nt += difference_type(N * n);
423 return tmp;
424 }
425 Self& operator-=( difference_type n) {
426 return operator+=( -n);
427 }
428 Self operator-( difference_type n) const {
429 Self tmp = *this;
430 return tmp += -n;
431 }
432 difference_type operator-( const Self& i) const { return (nt-i.nt)/N;}
433 reference operator[]( difference_type n) const {
434 Self tmp = *this;
435 tmp += n;
436 return tmp.operator*();
437 }
438 bool operator<( const Self& i) const { return ( nt < i.nt); }
439 bool operator>( const Self& i) const { return i < *this; }
440 bool operator<=( const Self& i) const { return !(i < *this); }
441 bool operator>=( const Self& i) const { return !(*this < i); }
442 };
443
444 // Microsoft 1300 cannot handle the default template parameters. Hence, ...
445 template < class I, int N, class Ref, class Ptr,
446 class Val, class Dist, class Ctg >
447 inline
448 N_step_adaptor<I,N,Ref,Ptr,Val,Dist,Ctg>
449 operator+(typename N_step_adaptor<I,N,Ref,Ptr,Val,Dist,Ctg>::difference_type n,
450 N_step_adaptor<I,N,Ref,Ptr,Val,Dist,Ctg> i)
451 { return i += n; }
452
453 template < class I, int N>
454 class N_step_adaptor_derived : public I {
455 public:
456 typedef I Iterator;
457 typedef I Circulator;
458 typedef N_step_adaptor_derived<I,N> Self;
459 typedef typename I::iterator_category iterator_category;
460 typedef typename I::value_type value_type;
461 typedef typename I::difference_type difference_type;
462 typedef typename I::reference reference;
463 typedef typename I::pointer pointer;
464 // Special for circulators.
465 typedef I_Circulator_size_traits<iterator_category,I> C_S_Traits;
466 typedef typename C_S_Traits::size_type size_type;
467
468 // CREATION
469 // --------
470
N_step_adaptor_derived()471 N_step_adaptor_derived() {}
N_step_adaptor_derived(Iterator j)472 N_step_adaptor_derived( Iterator j) : I(j) {}
473
474 template <class II>
N_step_adaptor_derived(const N_step_adaptor_derived<II,N> & j)475 N_step_adaptor_derived( const N_step_adaptor_derived<II,N>& j)
476 : I( j.current_iterator()) {}
477
478 // OPERATIONS Forward Category
479 // ---------------------------
480
current_circulator()481 Circulator current_circulator() const { return *this;}
current_iterator()482 Iterator current_iterator() const { return *this;}
483
484 Self& operator++() {
485 std::advance( (I&)*this, N);
486 return *this;
487 }
488 Self operator++(int) {
489 Self tmp = *this;
490 ++*this;
491 return tmp;
492 }
493
494 // OPERATIONS Bidirectional Category
495 // ---------------------------------
496
497 Self& operator--() {
498 std::advance( (I&)*this, -N);
499 return *this;
500 }
501 Self operator--(int) {
502 Self tmp = *this;
503 --*this;
504 return tmp;
505 }
506
507 // OPERATIONS Random Access Category
508 // ---------------------------------
509
min_circulator()510 Self min_circulator() const { return Self( I::min_circulator()); }
511 Self& operator+=( difference_type n) {
512 I::operator+=( difference_type(N * n));
513 return *this;
514 }
515 Self operator+( difference_type n) const {
516 Self tmp = *this;
517 tmp += n;
518 return tmp;
519 }
520 Self& operator-=( difference_type n) {
521 return operator+=( -n);
522 }
523 Self operator-( difference_type n) const {
524 Self tmp = *this;
525 return tmp += -n;
526 }
527 difference_type operator-( const Self& i) const {
528 return (I::operator-(i)) / N;
529 }
530 reference operator[]( difference_type n) const {
531 Self tmp = *this;
532 tmp += n;
533 return tmp.operator*();
534 }
535 };
536
537 template < class I, int N >
538 inline
539 N_step_adaptor_derived<I,N>
540 operator+( typename N_step_adaptor_derived<I,N>::difference_type n,
541 N_step_adaptor_derived<I,N> i)
542 { return i += n; }
543
544 template < class I, class P > struct Filter_iterator;
545
546 template < class I, class P >
547 bool operator==(const Filter_iterator<I,P>&, const Filter_iterator<I,P>&);
548 template < class I, class P >
549 bool operator<(const Filter_iterator<I,P>&, const Filter_iterator<I,P>&);
550
551 template < class I, class P >
552 struct Filter_iterator {
553 typedef I Iterator;
554 typedef P Predicate;
555 typedef Filter_iterator<I,P> Self;
556 typedef std::iterator_traits<I> ITI;
557 typedef typename ITI::reference reference;
558 typedef typename ITI::pointer pointer;
559 typedef typename ITI::value_type value_type;
560 typedef typename ITI::difference_type difference_type;
561 typedef typename ITI::iterator_category iterator_category;
562 // Special for circulators.
563 typedef I_Circulator_size_traits<iterator_category,I> C_S_Traits;
564 typedef typename C_S_Traits::size_type size_type;
565
566 protected:
567 Iterator e_; // past-the-end position.
568 Iterator c_; // current position.
569 Predicate p_; // Leave out x <==> p_(x).
570 public:
571
Filter_iteratorFilter_iterator572 Filter_iterator() {}
573
Filter_iteratorFilter_iterator574 Filter_iterator(Iterator e, const Predicate& p)
575 : e_(e), c_(e), p_(p) {}
576
Filter_iteratorFilter_iterator577 Filter_iterator(Iterator e, const Predicate& p, Iterator c)
578 : e_(e), c_(c), p_(p)
579 {
580 while (c_ != e_ && p_(c_))
581 ++c_;
582 }
583
584 Self& operator++() {
585 do { ++c_; } while (c_ != e_ && p_(c_));
586 return *this;
587 }
588
589 Self& operator--() {
590 do {
591 --c_;
592 } while (p_(c_));
593 return *this;
594 }
595
596 Self operator++(int) {
597 Self tmp(*this);
598 ++(*this);
599 return tmp;
600 }
601
602 Self operator--(int) {
603 Self tmp(*this);
604 --(*this);
605 return tmp;
606 }
607
608 reference operator*() const { return *c_; }
609 pointer operator->() const { return &*c_; }
predicateFilter_iterator610 const Predicate& predicate() const { return p_; }
baseFilter_iterator611 Iterator base() const { return c_; }
612
endFilter_iterator613 Iterator end() const { return e_; }
is_endFilter_iterator614 bool is_end() const { return (c_ == e_); }
615
616 friend bool operator== <>(const Self&, const Self&);
617 friend bool operator< <>(const Self&, const Self&);
618 };
619
620 template < class I, class P >
621 inline Filter_iterator< I, P >
filter_iterator(I e,const P & p)622 filter_iterator(I e, const P& p)
623 { return Filter_iterator< I, P >(e, p); }
624
625 template < class I, class P >
626 inline Filter_iterator< I, P >
filter_iterator(I e,const P & p,I c)627 filter_iterator(I e, const P& p, I c)
628 { return Filter_iterator< I, P >(e, p, c); }
629
630 template < class I, class P >
631 inline
632 bool operator==(const Filter_iterator<I,P>& it1,
633 const Filter_iterator<I,P>& it2)
634 {
635 CGAL_precondition(it1.e_ == it2.e_);
636 return it1.base() == it2.base();
637 }
638
639 template < class I, class P >
640 inline
641 bool operator<(const Filter_iterator<I,P>& it1,
642 const Filter_iterator<I,P>& it2)
643 {
644 return it1.base() < it2.base();
645 }
646
647 template < class I, class P >
648 inline
649 bool operator!=(const Filter_iterator<I,P>& it1,
650 const Filter_iterator<I,P>& it2)
651 { return !(it1 == it2); }
652
653 template <class I1,class Op>
654 class Join_input_iterator_1
655 {
656 typedef Join_input_iterator_1<I1,Op> Self;
657
658 typedef typename std::iterator_traits<I1>::value_type arg_type;
659
660 public:
661 typedef typename std::iterator_traits<I1>::iterator_category iterator_category;
662 typedef std::decay_t<decltype(std::declval<Op>()(std::declval<arg_type>()))>
663 value_type;
664 typedef typename std::iterator_traits<I1>::difference_type difference_type;
665 typedef value_type const* pointer;
666 typedef value_type const& reference;
667
668 protected:
669 I1 i1;
670 Op op;
671 mutable value_type val; // Note: mutable is needed because we want to
672 // return a reference in operator*() and
673 // operator[](int) below.
674
675 public:
Join_input_iterator_1()676 Join_input_iterator_1() {}
Join_input_iterator_1(const Join_input_iterator_1 & it)677 Join_input_iterator_1(const Join_input_iterator_1& it)
678 : i1(it.i1), op(it.op) {}
679 Join_input_iterator_1(I1 i,const Op& o=Op())
i1(i)680 : i1(i), op(o) {}
681
current_iterator1()682 I1 current_iterator1() const { return i1; }
683
684 bool operator==(const Self& i) const {
685 return i1 == i.i1;
686 }
687 bool operator!=(const Self& i) const { return !(*this == i); }
688 bool operator< (const Self& i) const {
689 return i1 < i.i1;
690 }
691
692 Join_input_iterator_1& operator=(const Join_input_iterator_1& it)
693 {
694 i1 = it.i1;
695 op = it.op;
696 return *this;
697 }
698
699 const value_type& operator*() const {
700 val = op(*i1);
701 return val;
702 }
703
704 Self& operator++( ) {
705 ++i1;
706 return *this;
707 }
708 Self operator++(int) { Self tmp = *this; ++(*this); return tmp; }
709 Self& operator--( ) {
710 --i1;
711 return *this;
712 }
713 Self operator--(int) { Self tmp = *this; --(*this); return tmp; }
714
715 const value_type& operator[](difference_type i) const {
716 val = op(i1[i]);
717 return val;
718 }
719
720 Self& operator+=(difference_type n) {
721 i1 += n;
722 return *this;
723 }
724 Self& operator-=(difference_type n) {
725 i1 -= n;
726 return *this;
727 }
728 Self operator+ (difference_type n) const {
729 Self tmp = *this;
730 return tmp += n;
731 }
732 Self operator- (difference_type n) const {
733 Self tmp = *this;
734 return tmp -= n;
735 }
736 difference_type operator-(const Self& i) const { return i1 - i.i1; }
737 };
738
739 template <class I1,class I2,class Op>
740 class Join_input_iterator_2
741 {
742 typedef Join_input_iterator_2<I1,I2,Op> Self;
743
744 typedef typename std::iterator_traits<I1>::value_type arg_type_1;
745 typedef typename std::iterator_traits<I2>::value_type arg_type_2;
746
747 public:
748 typedef typename std::iterator_traits<I1>::iterator_category iterator_category;
749 typedef decltype(std::declval<Op>()(std::declval<arg_type_1>(), std::declval<arg_type_2>()))
750 value_type;
751 typedef typename std::iterator_traits<I1>::difference_type difference_type;
752 typedef value_type* pointer;
753 typedef value_type& reference;
754
755 protected:
756 I1 i1;
757 I2 i2;
758 Op op;
759 mutable value_type val; // Note: mutable is needed because we want to
760 // return a reference in operator*() and
761 // operator[](int) below.
762
763 public:
Join_input_iterator_2()764 Join_input_iterator_2() {}
Join_input_iterator_2(const Join_input_iterator_2 & it)765 Join_input_iterator_2(const Join_input_iterator_2& it)
766 : i1(it.i1), i2(it.i2), op(it.op) {}
767 Join_input_iterator_2(I1 i1,I2 i2,const Op& op=Op())
i1(i1)768 : i1(i1), i2(i2), op(op) {}
769
current_iterator1()770 I1 current_iterator1() const { return i1; }
current_iterator2()771 I2 current_iterator2() const { return i2; }
772
773 bool operator==(const Self& i) const {
774 return i1 == i.i1 && i2 == i.i2;
775 }
776 bool operator!=(const Self& i) const { return !(*this == i); }
777 bool operator< (const Self& i) const {
778 return i1 < i.i1 && i2 < i.i2;
779 }
780
781 Join_input_iterator_2& operator=(const Join_input_iterator_2& it)
782 {
783 i1 = it.i1;
784 i2 = it.i2;
785 op = it.op;
786 return *this;
787 }
788
789 const value_type& operator*() const {
790 val = op(*i1,*i2);
791 return val;
792 }
793
794 Self& operator++( ) {
795 ++i1;
796 ++i2;
797 return *this;
798 }
799 Self operator++(int) { Self tmp = *this; ++(*this); return tmp; }
800 Self& operator--( ) {
801 --i1;
802 --i2;
803 return *this;
804 }
805 Self operator--(int) { Self tmp = *this; --(*this); return tmp; }
806
807 const value_type& operator[](difference_type i) const {
808 val = op(i1[i],i2[i]);
809 return val;
810 }
811
812 Self& operator+=(difference_type n) {
813 i1 += n;
814 i2 += n;
815 return *this;
816 }
817 Self& operator-=(difference_type n) {
818 i1 -= n;
819 i2 -= n;
820 return *this;
821 }
822 Self operator+ (difference_type n) const {
823 Self tmp = *this;
824 return tmp += n;
825 }
826 Self operator- (difference_type n) const {
827 Self tmp = *this;
828 return tmp -= n;
829 }
830 difference_type operator-(const Self& i) const { return i1 - i.i1; }
831 };
832
833 template <class I1,class I2,class I3,class Op>
834 class Join_input_iterator_3
835 {
836 typedef Join_input_iterator_3<I1,I2,I3,Op> Self;
837
838 typedef typename std::iterator_traits<I1>::value_type arg_type_1;
839 typedef typename std::iterator_traits<I2>::value_type arg_type_2;
840 typedef typename std::iterator_traits<I3>::value_type arg_type_3;
841
842 public:
843 typedef typename std::iterator_traits<I1>::iterator_category iterator_category;
844 typedef decltype(std::declval<Op>()(std::declval<arg_type_1>(), std::declval<arg_type_2>(), std::declval<arg_type_3>()))
845 value_type;
846 typedef typename std::iterator_traits<I1>::difference_type difference_type;
847 typedef value_type* pointer;
848 typedef value_type& reference;
849
850 protected:
851 I1 i1;
852 I2 i2;
853 I3 i3;
854 Op op;
855 mutable value_type val; // Note: mutable is needed because we want to
856 // return a reference in operator*() and
857 // operator[](int) below.
858
859 public:
Join_input_iterator_3()860 Join_input_iterator_3() {}
Join_input_iterator_3(const Join_input_iterator_3 & it)861 Join_input_iterator_3(const Join_input_iterator_3& it)
862 : i1(it.i1), i2(it.i2), i3(it.i3), op(it.op) {}
863 Join_input_iterator_3(I1 i1,I2 i2,I3 i3,const Op& op=Op())
i1(i1)864 : i1(i1), i2(i2), i3(i3), op(op) {}
865
current_iterator1()866 I1 current_iterator1() const { return i1; }
current_iterator2()867 I2 current_iterator2() const { return i2; }
current_iterator3()868 I2 current_iterator3() const { return i3; }
869
870 bool operator==(const Self& i) const {
871 return i1 == i.i1 && i2 == i.i2 && i3 == i.i3;
872 }
873 bool operator!=(const Self& i) const { return !(*this == i); }
874 bool operator< (const Self& i) const {
875 return i1 < i.i1 && i2 < i.i2 && i3 < i.i3;
876 }
877
878 Join_input_iterator_3& operator=(const Join_input_iterator_3& it)
879 {
880 i1 = it.i1;
881 i2 = it.i2;
882 i3 = it.i3;
883 op = it.op;
884 return *this;
885 }
886
887 const value_type& operator*() const {
888 val = op(*i1,*i2,*i3);
889 return val;
890 }
891
892 Self& operator++( ) {
893 ++i1;
894 ++i2;
895 ++i3;
896 return *this;
897 }
898 Self operator++(int) { Self tmp = *this; ++(*this); return tmp; }
899 Self& operator--( ) {
900 --i1;
901 --i2;
902 --i3;
903 return *this;
904 }
905 Self operator--(int) { Self tmp = *this; --(*this); return tmp; }
906
907 const value_type& operator[](difference_type i) const {
908 val = op(i1[i],i2[i],i3[i]);
909 return val;
910 }
911
912 Self& operator+=(difference_type n) {
913 i1 += n;
914 i2 += n;
915 i3 += n;
916 return *this;
917 }
918 Self& operator-=(difference_type n) {
919 i1 -= n;
920 i2 -= n;
921 i3 -= n;
922 return *this;
923 }
924 Self operator+ (difference_type n) const {
925 Self tmp = *this;
926 return tmp += n;
927 }
928 Self operator- (difference_type n) const {
929 Self tmp = *this;
930 return tmp -= n;
931 }
932 difference_type operator-(const Self& i) const { return i1 - i.i1; }
933 };
934
935 template < class IC>
936 class Inverse_index {
937
938 // DEFINITION
939 //
940 // The class Inverse_index<IC,T> constructs an inverse index for a
941 // given range [i,j) of two iterators or circulators of type `IC' with the
942 // value type `T'. The first element I in the
943 // range [i,j) has the index 0. Consecutive elements are numbered
944 // incrementally. The inverse index provides a query for a given iterator
945 // or circulator k to retrieve its index number. For random access
946 // iterators or circulators, it is done in constant time by subtracting i.
947 // For other iterator categories, an STL `map' is used, which results in a
948 // log j-i query time. A comparison operator `operator<' is needed for
949 // `T*'.
950 //
951 // CREATION
952
953 protected:
954 typedef std::map< const void*, std::size_t > Index;
955 Index idx;
956 IC start;
957 typedef typename Index::iterator Index_iterator;
958 typedef typename Index::const_iterator Index_const_iterator;
959 typedef typename Index::value_type Item;
960
961 protected:
962 void ini_idx( IC i, const IC& j, std::input_iterator_tag);
ini_idx(const IC & i,const IC & j,std::forward_iterator_tag)963 void ini_idx( const IC& i, const IC& j, std::forward_iterator_tag){
964 ini_idx( i, j, std::input_iterator_tag());
965 }
ini_idx(const IC & i,const IC & j,std::bidirectional_iterator_tag)966 void ini_idx(const IC& i,const IC& j, std::bidirectional_iterator_tag){
967 ini_idx( i, j, std::input_iterator_tag());
968 }
ini_idx(const IC & i,const IC & j,Forward_circulator_tag)969 void ini_idx( const IC& i, const IC& j, Forward_circulator_tag) {
970 ini_idx( i, j, std::input_iterator_tag());
971 }
ini_idx(const IC & i,const IC & j,Bidirectional_circulator_tag)972 void ini_idx( const IC& i, const IC& j, Bidirectional_circulator_tag){
973 ini_idx( i, j, std::input_iterator_tag());
974 }
ini_idx(const IC &,const IC &,std::random_access_iterator_tag)975 void ini_idx( const IC&, const IC&, std::random_access_iterator_tag){}
ini_idx(const IC &,const IC &,Random_access_circulator_tag)976 void ini_idx( const IC&, const IC&, Random_access_circulator_tag){}
977
978 public:
init_index(const IC & i,const IC & j)979 void init_index( const IC& i, const IC& j) {
980 typedef typename std::iterator_traits<IC>::iterator_category ICC;
981 ini_idx( i, j, ICC());
982 }
983
984 protected:
push_back(const IC & k,std::input_iterator_tag)985 void push_back( const IC& k, std::input_iterator_tag) {
986 std::size_t d = idx.size();
987 idx[ &*k] = d;
988 }
push_back(const IC & k,std::forward_iterator_tag)989 void push_back( const IC& k, std::forward_iterator_tag){
990 push_back( k, std::input_iterator_tag());
991 }
push_back(const IC & k,std::bidirectional_iterator_tag)992 void push_back( const IC& k, std::bidirectional_iterator_tag){
993 push_back( k, std::input_iterator_tag());
994 }
push_back(const IC & k,Forward_circulator_tag)995 void push_back( const IC& k, Forward_circulator_tag){
996 push_back( k, std::input_iterator_tag());
997 }
push_back(const IC & k,Bidirectional_circulator_tag)998 void push_back( const IC& k, Bidirectional_circulator_tag){
999 push_back( k, std::input_iterator_tag());
1000 }
push_back(const IC &,std::random_access_iterator_tag)1001 void push_back( const IC&, std::random_access_iterator_tag){}
push_back(const IC &,Random_access_circulator_tag)1002 void push_back( const IC&, Random_access_circulator_tag){}
1003
1004 public:
push_back(const IC & k)1005 void push_back( const IC& k) {
1006 // adds k at the end of the indices.
1007 typedef typename std::iterator_traits<IC>::iterator_category ICC;
1008 push_back( k, ICC());
1009 }
1010
find(const IC & k,std::random_access_iterator_tag)1011 std::size_t find( const IC& k, std::random_access_iterator_tag) const {
1012 return std::size_t(k - start);
1013 }
find(const IC & k,Random_access_circulator_tag)1014 std::size_t find( const IC& k, Random_access_circulator_tag) const {
1015 return std::size_t(k - start);
1016 }
find(const IC & k,std::input_iterator_tag)1017 std::size_t find( const IC& k, std::input_iterator_tag) const {
1018 // returns inverse index of k.
1019 Index_const_iterator i = idx.find( &*k);
1020 CGAL_assertion( i != idx.end());
1021 return (*i).second;
1022 }
find(const IC & k,std::forward_iterator_tag)1023 std::size_t find( const IC& k, std::forward_iterator_tag) const {
1024 return find( k, std::input_iterator_tag());
1025 }
find(const IC & k,std::bidirectional_iterator_tag)1026 std::size_t find( const IC& k, std::bidirectional_iterator_tag) const {
1027 return find( k, std::input_iterator_tag());
1028 }
find(const IC & k,Forward_circulator_tag)1029 std::size_t find( const IC& k, Forward_circulator_tag) const {
1030 return find( k, std::input_iterator_tag());
1031 }
find(const IC & k,Bidirectional_circulator_tag)1032 std::size_t find( const IC& k, Bidirectional_circulator_tag) const {
1033 return find( k, std::input_iterator_tag());
1034 }
1035
1036 typedef IC iterator;
1037 typedef IC Circulator;
1038 typedef std::size_t size_type;
1039
Inverse_index()1040 Inverse_index() : start(IC()) {}
1041 // invalid index.
1042
Inverse_index(const IC & i)1043 Inverse_index( const IC& i) : start(i) {};
1044 // empty inverse index initialized to start at i.
1045
Inverse_index(const IC & i,const IC & j)1046 Inverse_index( const IC& i, const IC& j) : start(i) {
1047 // inverse index initialized with range [i,j).
1048 init_index( i, j);
1049 }
1050
1051 // OPERATIONS
1052
1053 std::size_t operator[]( const IC& k) const {
1054 // returns inverse index of k.
1055 typedef typename std::iterator_traits<IC>::iterator_category
1056 category;
1057 return find( k, category());
1058 }
1059 };
1060
1061 template < class IC>
1062 void
ini_idx(IC i,const IC & j,std::input_iterator_tag)1063 Inverse_index< IC>::ini_idx( IC i, const IC& j, std::input_iterator_tag) {
1064 std::size_t n = 0;
1065 Index_iterator hint = idx.begin();
1066 if ( ! is_empty_range( i, j)) {
1067 do {
1068 hint = idx.insert( hint, Item( &*i, n));
1069 n++;
1070 } while ((++i) != (j));
1071 }
1072 }
1073
1074 template < class IC>
1075 class Random_access_adaptor {
1076
1077 // DEFINITION
1078 //
1079 // The class Random_access_adaptor<IC> provides a random access
1080 // for data structures. Either the data structure supports random access
1081 // iterators or circulators where this class maps function calls to the
1082 // iterator or circulator, or a STL `vector' is used to provide the random
1083 // access. The iterator or circulator of the data structure are of type
1084 // `IC'.
1085 //
1086 // CREATION
1087
1088 protected:
1089 typedef std::vector< IC> Index;
1090 Index index;
1091 IC start;
1092
1093 public:
1094 typedef typename Index::size_type size_type;
1095
1096 void init_index( IC i, const IC& j, std::forward_iterator_tag);
init_index(const IC & i,const IC & j,std::bidirectional_iterator_tag)1097 void init_index( const IC& i, const IC& j,
1098 std::bidirectional_iterator_tag){
1099 init_index( i, j, std::forward_iterator_tag());
1100 }
init_index(const IC & i,const IC &,std::random_access_iterator_tag)1101 void init_index( const IC& i, const IC&,
1102 std::random_access_iterator_tag){
1103 start = i;
1104 }
init_index(const IC & i,const IC & j)1105 void init_index( const IC& i, const IC& j) {
1106 typedef typename std::iterator_traits<IC>::iterator_category ICC;
1107 init_index( i, j, ICC());
1108 }
1109
1110
reserve(size_type r,std::forward_iterator_tag)1111 void reserve( size_type r, std::forward_iterator_tag) {
1112 index.reserve( r);
1113 }
reserve(size_type r,std::bidirectional_iterator_tag)1114 void reserve( size_type r, std::bidirectional_iterator_tag){
1115 reserve( r, std::forward_iterator_tag());
1116 }
reserve(size_type,std::random_access_iterator_tag)1117 void reserve( size_type, std::random_access_iterator_tag){}
1118
1119
push_back(const IC & k,std::forward_iterator_tag)1120 void push_back( const IC& k, std::forward_iterator_tag) {
1121 index.push_back(k);
1122 }
push_back(const IC & k,std::bidirectional_iterator_tag)1123 void push_back( const IC& k, std::bidirectional_iterator_tag){
1124 push_back( k, std::forward_iterator_tag());
1125 }
push_back(const IC &,std::random_access_iterator_tag)1126 void push_back( const IC&, std::random_access_iterator_tag){}
1127
1128
find(size_type n,std::forward_iterator_tag)1129 const IC& find( size_type n, std::forward_iterator_tag) const {
1130 // returns inverse index of k.
1131 CGAL_assertion( n < index.size());
1132 return index[n];
1133 }
find(size_type n,std::bidirectional_iterator_tag)1134 const IC& find( size_type n, std::bidirectional_iterator_tag) const {
1135 return find( n, std::forward_iterator_tag());
1136 }
find(size_type n,std::random_access_iterator_tag)1137 IC find( size_type n, std::random_access_iterator_tag) const {
1138 return start + n;
1139 }
1140
1141 typedef IC iterator;
1142 typedef IC Circulator;
1143
Random_access_adaptor()1144 Random_access_adaptor() : start(IC()) {}
1145 // invalid index.
1146
Random_access_adaptor(const IC & i)1147 Random_access_adaptor( const IC& i) : start(i) {}
1148 // empty random access index initialized to start at i.
1149
Random_access_adaptor(const IC & i,const IC & j)1150 Random_access_adaptor( const IC& i, const IC& j) : start(i) {
1151 // random access index initialized with range [i,j).
1152 init_index( i, j);
1153 }
1154
reserve(size_type r)1155 void reserve( size_type r) {
1156 // reserve r entries, if a `vector' is used internally.
1157 typedef typename std::iterator_traits<IC>::iterator_category ICC;
1158 reserve( r, ICC());
1159 }
1160
1161 // OPERATIONS
1162
find(size_type n)1163 IC find( size_type n) const {
1164 // returns inverse index of k.
1165 typedef typename std::iterator_traits<IC>::iterator_category ICC;
1166 return find( n, ICC());
1167 }
1168
1169 IC operator[]( size_type n) const { return find(n); }
1170
push_back(const IC & k)1171 void push_back( const IC& k) {
1172 // adds k at the end of the indices.
1173 typedef typename std::iterator_traits<IC>::iterator_category ICC;
1174 push_back( k, ICC());
1175 }
1176 };
1177
1178 template < class IC>
1179 void
init_index(IC i,const IC & j,std::forward_iterator_tag)1180 Random_access_adaptor< IC>::init_index( IC i, const IC& j,
1181 std::forward_iterator_tag) {
1182 if ( ! is_empty_range( i, j)) {
1183 do {
1184 index.push_back( i);
1185 } while ((++i) != (j));
1186 }
1187 }
1188
1189 template < class IC, class T >
1190 class Random_access_value_adaptor : public Random_access_adaptor<IC> {
1191 public:
1192 typedef typename Random_access_adaptor<IC>::size_type size_type;
1193
Random_access_value_adaptor()1194 Random_access_value_adaptor() {}
1195 // invalid index.
1196
Random_access_value_adaptor(const IC & i)1197 Random_access_value_adaptor( const IC& i)
1198 : Random_access_adaptor<IC>(i) {}
1199 // empty random access index initialized to start at i.
1200
Random_access_value_adaptor(const IC & i,const IC & j)1201 Random_access_value_adaptor( const IC& i, const IC& j)
1202 : Random_access_adaptor<IC>(i,j) {}
1203 // random access index initialized with range [i,j).
1204
1205 // OPERATIONS
1206
1207 T& operator[]( size_type n) const {
1208 // returns inverse index of k.
1209 return *(Random_access_adaptor<IC>::operator[](n));
1210 }
1211 };
1212
1213 template<typename _Iterator, typename Predicate>
1214 class Filter_output_iterator
1215 : public CGAL::cpp98::iterator<std::output_iterator_tag, void, void, void, void>
1216 {
1217 protected:
1218 _Iterator iterator;
1219 Predicate predicate;
1220
1221 public:
1222 typedef _Iterator iterator_type;
1223
Filter_output_iterator(_Iterator & __x,const Predicate & pred)1224 explicit Filter_output_iterator(_Iterator& __x, const Predicate& pred)
1225 : iterator(__x), predicate(pred)
1226 {}
1227
1228 template <typename T>
1229 Filter_output_iterator&
1230 operator=(const T& t)
1231 {
1232 if(! predicate(t))
1233 *iterator = t;
1234 return *this;
1235 }
1236
1237 Filter_output_iterator&
1238 operator*()
1239 { return *this; }
1240
1241 Filter_output_iterator&
1242 operator++()
1243 {
1244 ++iterator;
1245 return *this;
1246 }
1247
1248 Filter_output_iterator
1249 operator++(int)
1250 {
1251 Filter_output_iterator res(*this);
1252 ++iterator;
1253 return res;
1254 }
1255 };
1256
1257 template < class I, class P >
1258 inline Filter_output_iterator< I, P >
filter_output_iterator(I e,const P & p)1259 filter_output_iterator(I e, const P& p)
1260 { return Filter_output_iterator< I, P >(e, p); }
1261
1262 namespace internal {
1263
1264 template<typename OutputIterator>
1265 struct Output_visitor : boost::static_visitor<OutputIterator&> {
Output_visitorOutput_visitor1266 Output_visitor(OutputIterator* it) : out(it) {}
1267 OutputIterator* out;
1268
1269 template<typename T>
operatorOutput_visitor1270 OutputIterator& operator()(const T& t) {
1271 *(*out)++ = t;
1272 return *out;
1273 }
1274 };
1275
1276 } // internal
1277
1278
1279
1280 namespace internal {
1281
1282 template < typename D, typename V = std::tuple<>, typename O = std::tuple<> >
1283 struct Derivator
1284 {
1285 typedef Derivator<D, V, O> Self;
1286 Self& operator=(const Self&) = delete;
1287 template <class Tuple>
tuple_dispatchDerivator1288 void tuple_dispatch(const Tuple&)
1289 {}
1290 };
1291
1292 template < typename D, typename V1, typename O1, typename... V, typename... O>
1293 struct Derivator<D, std::tuple<V1, V...>, std::tuple<O1, O...> >
1294 : public Derivator<D, std::tuple<V...>, std::tuple<O...> >
1295 {
1296 typedef Derivator<D, std::tuple<V1, V...>, std::tuple<O1, O...> > Self;
1297 typedef Derivator<D, std::tuple<V...>, std::tuple<O...> > Base;
1298
1299 Self& operator=(const Self&) = delete;
1300
1301 using Base::operator=;
1302
1303 D& operator=(const V1& v)
1304 {
1305 * std::get< D::size - sizeof...(V) - 1 >(static_cast<typename D::Iterator_tuple&>(static_cast<D&>(*this))) ++ = v;
1306 return static_cast<D&>(*this);
1307 }
1308
1309 template <class Tuple>
1310 void tuple_dispatch(const Tuple& t)
1311 {
1312 * std::get< D::size - sizeof...(V) - 1 >(static_cast<typename D::Iterator_tuple&>(static_cast<D&>(*this))) ++ =
1313 std::get< D::size - sizeof...(V) - 1 >(t);
1314 static_cast<Base&>(*this).tuple_dispatch(t);
1315 }
1316 };
1317
1318 } // internal
1319
1320 namespace tuple_internal {
1321 template <typename ...Args, std::size_t ...Is>
1322 auto to_tuple(std::tuple<Args...> &t, std::index_sequence<Is...>)
1323 {
1324 return std::tuple<Args&...>(std::get<Is>(t)...);
1325 }
1326
1327 }//end namespace tuple_internal
1328
1329 // OutputIterator which accepts several types in *o++= and dispatches,
1330 // wraps several other output iterators, and dispatches accordingly.
1331 template < typename V, typename O >
1332 class Dispatch_output_iterator;
1333
1334 template < typename... V, typename... O >
1335 class Dispatch_output_iterator < std::tuple<V...>, std::tuple<O...> >
1336 : private internal::Derivator<Dispatch_output_iterator< std::tuple<V...>, std::tuple<O...> >, std::tuple<V...>, std::tuple<O...> >
1337 , public std::tuple<O...>
1338 {
1339 CGAL_static_assertion_msg(sizeof...(V) == sizeof...(O),
1340 "The number of explicit template parameters has to match the number of arguments");
1341
1342 static const int size = sizeof...(V);
1343
1344 template <typename D, typename V_, typename O_>
1345 friend struct internal::Derivator;
1346
1347 public:
1348
1349 typedef std::tuple<O...> Iterator_tuple;
1350 typedef std::tuple<V...> Value_type_tuple;
1351
1352 typedef std::output_iterator_tag iterator_category;
1353 typedef void value_type;
1354 typedef void difference_type;
1355 typedef void pointer;
1356 typedef void reference;
1357
1358 private:
1359
1360 typedef Dispatch_output_iterator Self;
1361 typedef internal::Derivator<Self, Value_type_tuple, Iterator_tuple > Base;
1362
1363 public:
1364
1365 using Base::operator=;
1366 using Base::tuple_dispatch;
1367
1368 Dispatch_output_iterator(O... o) : std::tuple<O...>(o...) {}
1369
1370
1371 Dispatch_output_iterator(const Dispatch_output_iterator&)=default;
1372
1373 Self& operator=(const Self& s)
1374 {
1375 static_cast<Iterator_tuple&>(*this) = static_cast<const Iterator_tuple&>(s);
1376 return *this;
1377 }
1378
1379 template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
1380 Self& operator=(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) >& t) {
1381 internal::Output_visitor<Self> visitor(this);
1382 #if BOOST_VERSION==105800
1383 t.apply_visitor(visitor);
1384 #else
1385 boost::apply_visitor(visitor, t);
1386 #endif
1387 return *this;
1388 }
1389
1390 template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
1391 Self& operator=(const boost::optional< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) > >& t) {
1392 internal::Output_visitor<Self> visitor(this);
1393 #if BOOST_VERSION==105800
1394 if(t) t->apply_visitor(visitor);
1395 #else
1396 if(t) boost::apply_visitor(visitor, *t);
1397 #endif
1398 return *this;
1399 }
1400
1401 Self& operator++() { return *this; }
1402 Self& operator++(int) { return *this; }
1403 Self& operator*() { return *this; }
1404
1405 const Iterator_tuple& get_iterator_tuple() const { return *this; }
1406
1407 Self& operator=(const std::tuple<V...>& t)
1408 {
1409 tuple_dispatch(t);
1410 return *this;
1411 }
1412
1413 operator std::tuple<O&...>()
1414 {
1415 return tuple_internal::to_tuple(*this, std::index_sequence_for<O...>{});
1416 }
1417
1418 operator std::tuple<const O&...>()const
1419 {
1420 return tuple_internal::to_tuple(*this, std::index_sequence_for<O...>{});
1421 }
1422 };
1423
1424 template < typename... V, typename... O>
1425 Dispatch_output_iterator<std::tuple<V...>, std::tuple<O...> >
1426 dispatch_output(O... o)
1427 {
1428 return Dispatch_output_iterator<std::tuple<V...>, std::tuple<O...> > (o...);
1429 }
1430
1431
1432 // Same as Dispatch_output_iterator, but has a dummy *o++= for all other types
1433 // that drops the data (same as Emptyset_iterator).
1434
1435 template < typename V, typename O >
1436 class Dispatch_or_drop_output_iterator;
1437
1438 template < typename... V, typename... O >
1439 class Dispatch_or_drop_output_iterator < std::tuple<V...>, std::tuple<O...> >
1440 : public Dispatch_output_iterator< std::tuple<V...>, std::tuple<O...> >
1441 {
1442 typedef Dispatch_or_drop_output_iterator Self;
1443 typedef Dispatch_output_iterator< std::tuple<V...>, std::tuple<O...> > Base;
1444
1445 template <typename D, typename V_, typename O_>
1446 friend struct internal::Derivator;
1447
1448 public:
1449
1450 Dispatch_or_drop_output_iterator(O... o) : Base(o...) {}
1451
1452 Dispatch_or_drop_output_iterator(const Dispatch_or_drop_output_iterator&)=default;
1453 Dispatch_or_drop_output_iterator& operator=(const Dispatch_or_drop_output_iterator&)=default;
1454
1455 using Base::operator=;
1456
1457 Self& operator*() { return *this; }
1458 Self& operator++() { return *this; }
1459 Self& operator++(int) { return *this; }
1460
1461 template <class T>
1462 Self& operator=(const T&) { return *this; }
1463
1464 };
1465
1466
1467 template < typename... V, typename... O>
1468 inline
1469 Dispatch_or_drop_output_iterator<std::tuple<V...>, std::tuple<O...> >
1470 dispatch_or_drop_output(O... o)
1471 {
1472 return Dispatch_or_drop_output_iterator<std::tuple<V...>, std::tuple<O...> >(o...);
1473 }
1474
1475
1476 // Trick to select iterator or const_iterator depending on the range constness
1477 template <typename RangeRef>
1478 struct Range_iterator_type;
1479 template <typename RangeRef>
1480 struct Range_iterator_type<RangeRef&> { typedef typename RangeRef::iterator type; };
1481 template <typename RangeRef>
1482 struct Range_iterator_type<const RangeRef&> { typedef typename RangeRef::const_iterator type; };
1483
1484 } //namespace CGAL
1485
1486 #include <CGAL/enable_warnings.h>
1487
1488 #endif // CGAL_ITERATOR_H
1489