@@ -74,6 +74,7 @@ namespace chen
7474 virtual Reference operator *() const = 0 ;
7575 virtual void operator ++() = 0 ;
7676 virtual bool operator ==(const base &o) const = 0 ;
77+ virtual Distance distance () const = 0;
7778 };
7879
7980 /* *
@@ -90,6 +91,12 @@ namespace chen
9091 virtual Reference operator *() const = 0 ;
9192 virtual void operator ++() = 0 ;
9293 virtual bool operator ==(const base &o) const = 0 ;
94+ virtual Distance distance () const
95+ {
96+ // only valid in input iterator
97+ // use std::distance in other iterators
98+ return 0 ;
99+ }
93100
94101 public:
95102 virtual void operator --() = 0 ;
@@ -109,6 +116,12 @@ namespace chen
109116 virtual Reference operator *() const = 0 ;
110117 virtual void operator ++() = 0 ;
111118 virtual bool operator ==(const base &o) const = 0 ;
119+ virtual Distance distance () const
120+ {
121+ // only valid in input iterator
122+ // use std::distance in other iterators
123+ return 0 ;
124+ }
112125
113126 public:
114127 virtual void operator --() = 0 ;
@@ -157,6 +170,7 @@ namespace chen
157170 virtual void operator ++() override
158171 {
159172 ++this ->_it ;
173+ ++this ->_distance ;
160174 }
161175
162176 virtual bool operator ==(const super_class &o) const override
@@ -165,8 +179,14 @@ namespace chen
165179 return this ->_it == tmp._it ;
166180 }
167181
182+ virtual Distance distance () const override
183+ {
184+ return this ->_distance ;
185+ }
186+
168187 protected:
169188 Iterator _it;
189+ Distance _distance = 0 ;
170190 };
171191
172192 /* *
@@ -371,6 +391,14 @@ namespace chen
371391 return !(*this == o);
372392 }
373393
394+ Distance distance () const
395+ {
396+ // since input iterator is single-pass, we can't use std::distance on it
397+ // however, in some cases we want to know input iterator's position, so I add this method
398+ // @caution don't use this method if your category is not input iterator
399+ return this ->_ptr ->distance ();
400+ }
401+
374402 /* *
375403 * Bidirectional iterator
376404 */
@@ -459,67 +487,4 @@ namespace chen
459487
460488 template <typename Value, typename Reference = Value&, typename Pointer = Value*, typename Distance = std::ptrdiff_t >
461489 using random_iterator = iterator<std::random_access_iterator_tag, Value, Reference, Pointer, Distance>;
462-
463- /* *
464- * Position iterator
465- * since input iterator is single-pass, we can't use std::distance on it
466- * however, in some cases we want to know input iterator's position, so I add this iterator
467- */
468- template <typename Value, typename Reference = Value&, typename Pointer = Value*, typename Distance = std::ptrdiff_t >
469- class position_iterator : public input_iterator <Value, Reference, Pointer, Distance>
470- {
471- public:
472- typedef input_iterator<Value, Reference, Pointer, Distance> super_class;
473-
474- using typename super_class::value_type;
475- using typename super_class::difference_type;
476- using typename super_class::pointer;
477- using typename super_class::reference;
478- using typename super_class::iterator_category;
479- using typename super_class::data_type;
480-
481- public:
482- /* *
483- * Construct by proxy
484- */
485- position_iterator (const iterator_helper::proxy<Value, data_type> &p) : super_class(p)
486- {
487- }
488-
489- /* *
490- * Wrap another iterator
491- */
492- template <typename Iterator>
493- position_iterator (Iterator it) : super_class(it)
494- {
495- }
496-
497- public:
498- /* *
499- * Current position after increment
500- */
501- Distance distance () const
502- {
503- return this ->_distance ;
504- }
505-
506- public:
507- /* *
508- * Input & Forward iterator
509- */
510- super_class& operator ++()
511- {
512- ++this ->_distance ;
513- return super_class::operator ++();
514- }
515-
516- iterator_helper::proxy<Value, data_type> operator ++(int )
517- {
518- ++this ->_distance ; // don't effect on proxy
519- return super_class::operator ++(0 );
520- }
521-
522- private:
523- Distance _distance = 0 ;
524- };
525490}
0 commit comments