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