1/* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4 *
5 * rubyiterators.swg
6 *
7 * Implement a C++ 'output' iterator for Ruby.
8 *
9 * Users can derive form the Iterator to implemet their
10 * own iterators. As an example (real one since we use it for STL/STD
11 * containers), the template Iterator_T does the
12 * implementation for generic C++ iterators.
13 * ----------------------------------------------------------------------------- */
14
15%include <std_common.i>
16
17
18%fragment("ConstIterator","header") {
19namespace swig {
20  struct stop_iteration {
21  };
22
23  /**
24   * Abstract base class used to represent all iterators of STL containers.
25   */
26  struct ConstIterator {
27  public:
28    typedef ConstIterator self_type;
29
30  protected:
31    GC_VALUE _seq;
32
33  protected:
34    ConstIterator(VALUE seq) : _seq(seq)
35    {
36    }
37
38    // Random access iterator methods, but not required in Ruby
39    virtual ptrdiff_t distance(const ConstIterator &x) const
40    {
41      throw std::invalid_argument("distance not supported");
42    }
43
44    virtual bool equal (const ConstIterator &x) const
45    {
46      throw std::invalid_argument("equal not supported");
47    }
48
49    virtual self_type* advance(ptrdiff_t n)
50    {
51      throw std::invalid_argument("advance not supported");
52    }
53
54  public:
55    virtual ~ConstIterator() {}
56
57    // Access iterator method, required by Ruby
58    virtual VALUE value() const {
59      throw std::invalid_argument("value not supported");
60      return Qnil;
61    };
62
63    virtual VALUE setValue( const VALUE& v ) {
64      throw std::invalid_argument("value= not supported");
65      return Qnil;
66    }
67
68    virtual self_type* next( size_t n = 1 )
69    {
70      return this->advance( n );
71    }
72
73    virtual self_type* previous( size_t n = 1 )
74    {
75      ptrdiff_t nn = n;
76      return this->advance( -nn );
77    }
78
79    virtual VALUE to_s() const {
80      throw std::invalid_argument("to_s not supported");
81      return Qnil;
82    }
83
84    virtual VALUE inspect() const {
85      throw std::invalid_argument("inspect not supported");
86      return Qnil;
87    }
88
89    virtual ConstIterator *dup() const
90    {
91      throw std::invalid_argument("dup not supported");
92      return NULL;
93    }
94
95    //
96    // C++ common/needed methods.  We emulate a bidirectional
97    // operator, to be compatible with all the STL.
98    // The iterator traits will then tell the STL what type of
99    // iterator we really are.
100    //
101    ConstIterator() : _seq( Qnil )
102    {
103    }
104
105    ConstIterator( const self_type& b ) : _seq( b._seq )
106    {
107    }
108
109    self_type& operator=( const self_type& b )
110    {
111      _seq = b._seq;
112      return *this;
113    }
114
115    bool operator == (const ConstIterator& x)  const
116    {
117      return equal(x);
118    }
119
120    bool operator != (const ConstIterator& x) const
121    {
122      return ! operator==(x);
123    }
124
125    // Pre-decrement operator
126    self_type& operator--()
127    {
128      return *previous();
129    }
130
131    // Pre-increment operator
132    self_type& operator++()
133    {
134      return *next();
135    }
136
137    // Post-decrement operator
138    self_type operator--(int)
139    {
140      self_type r = *this;
141      previous();
142      return r;
143    }
144
145    // Post-increment operator
146    self_type operator++(int)
147    {
148      self_type r = *this;
149      next();
150      return r;
151    }
152
153    ConstIterator& operator += (ptrdiff_t n)
154    {
155      return *advance(n);
156    }
157
158    ConstIterator& operator -= (ptrdiff_t n)
159    {
160      return *advance(-n);
161    }
162
163    ConstIterator* operator + (ptrdiff_t n) const
164    {
165      return dup()->advance(n);
166    }
167
168    ConstIterator* operator - (ptrdiff_t n) const
169    {
170      return dup()->advance(-n);
171    }
172
173    ptrdiff_t operator - (const ConstIterator& x) const
174    {
175      return x.distance(*this);
176    }
177
178    static swig_type_info* descriptor() {
179      static int init = 0;
180      static swig_type_info* desc = 0;
181      if (!init) {
182	desc = SWIG_TypeQuery("swig::ConstIterator *");
183	init = 1;
184      }
185      return desc;
186    }
187  };
188
189
190  /**
191   * Abstract base class used to represent all non-const iterators of STL containers.
192   *
193   */
194  struct Iterator : public ConstIterator {
195  public:
196    typedef Iterator self_type;
197
198  protected:
199    Iterator(VALUE seq) : ConstIterator(seq)
200    {
201    }
202
203    virtual self_type* advance(ptrdiff_t n)
204    {
205      throw std::invalid_argument("operation not supported");
206    }
207
208  public:
209    static swig_type_info* descriptor() {
210      static int init = 0;
211      static swig_type_info* desc = 0;
212      if (!init) {
213	desc = SWIG_TypeQuery("swig::Iterator *");
214	init = 1;
215      }
216      return desc;
217    }
218
219    virtual Iterator *dup() const
220    {
221      throw std::invalid_argument("dup not supported");
222      return NULL;
223    }
224
225    virtual self_type* next( size_t n = 1 )
226    {
227      return this->advance( n );
228    }
229
230    virtual self_type* previous( size_t n = 1 )
231    {
232      ptrdiff_t nn = n;
233      return this->advance( -nn );
234    }
235
236    bool operator == (const ConstIterator& x)  const
237    {
238      return equal(x);
239    }
240
241    bool operator != (const Iterator& x) const
242    {
243      return ! operator==(x);
244    }
245
246    Iterator& operator += (ptrdiff_t n)
247    {
248      return *advance(n);
249    }
250
251    Iterator& operator -= (ptrdiff_t n)
252    {
253      return *advance(-n);
254    }
255
256    Iterator* operator + (ptrdiff_t n) const
257    {
258      return dup()->advance(n);
259    }
260
261    Iterator* operator - (ptrdiff_t n) const
262    {
263      return dup()->advance(-n);
264    }
265
266    ptrdiff_t operator - (const Iterator& x) const
267    {
268      return x.distance(*this);
269    }
270  };
271
272}
273}
274
275
276%fragment("ConstIterator_T","header",fragment="ConstIterator",fragment="StdTraits",fragment="StdIteratorTraits") {
277namespace swig {
278
279  /**
280   * Templated base classes for all custom const_iterators.
281   *
282   */
283  template<typename OutConstIterator>
284  class ConstIterator_T :  public ConstIterator
285  {
286  public:
287    typedef OutConstIterator const_iter;
288    typedef typename std::iterator_traits<const_iter>::value_type value_type;
289    typedef ConstIterator_T<const_iter> self_type;
290
291  protected:
292
293
294    virtual bool equal (const ConstIterator &iter) const
295    {
296      const self_type *iters = dynamic_cast<const self_type *>(&iter);
297      if (iters) {
298	return (current == iters->get_current());
299      } else {
300	throw std::invalid_argument("bad iterator type");
301      }
302    }
303
304    virtual ptrdiff_t distance(const ConstIterator &iter) const
305    {
306      const self_type *iters = dynamic_cast<const self_type *>(&iter);
307      if (iters) {
308	return std::distance(current, iters->get_current());
309      } else {
310	throw std::invalid_argument("bad iterator type");
311      }
312    }
313
314    virtual ConstIterator* advance(ptrdiff_t n)
315    {
316      std::advance( current, n );
317      return this;
318    }
319
320  public:
321    ConstIterator_T() : ConstIterator(Qnil)
322    {
323    }
324
325    ConstIterator_T(const_iter curr, VALUE seq = Qnil)
326      : ConstIterator(seq), current(curr)
327    {
328    }
329
330    const const_iter& get_current() const
331    {
332      return current;
333    }
334
335    const value_type& operator*() const
336    {
337      return *current;
338    }
339
340    virtual VALUE inspect() const
341    {
342      VALUE ret = rb_str_new2("#<");
343      ret = rb_str_cat2( ret, rb_obj_classname(_seq) );
344      ret = rb_str_cat2( ret, "::const_iterator " );
345      VALUE cur = value();
346      ret = rb_str_concat( ret, rb_inspect(cur) );
347      ret = rb_str_cat2( ret, ">" );
348      return ret;
349    }
350
351    virtual VALUE to_s()    const
352    {
353      VALUE ret = rb_str_new2( rb_obj_classname(_seq) );
354      ret = rb_str_cat2( ret, "::const_iterator " );
355      VALUE cur = value();
356      ret = rb_str_concat( ret, rb_obj_as_string(cur) );
357      return ret;
358    }
359
360  protected:
361    const_iter current;
362  };
363
364
365  /**
366   * Templated base classes for all custom non-const iterators.
367   *
368   */
369  template<typename InOutIterator>
370  class Iterator_T :  public Iterator
371  {
372  public:
373    typedef InOutIterator nonconst_iter;
374
375    // Make this class iterator STL compatible, by using iterator_traits
376    typedef typename std::iterator_traits<nonconst_iter >::iterator_category iterator_category;
377    typedef typename std::iterator_traits<nonconst_iter >::value_type        value_type;
378    typedef typename std::iterator_traits<nonconst_iter >::difference_type   difference_type;
379    typedef typename std::iterator_traits<nonconst_iter >::pointer           pointer;
380    typedef typename std::iterator_traits<nonconst_iter >::reference         reference;
381
382    typedef Iterator                         base;
383    typedef Iterator_T< nonconst_iter > self_type;
384
385  protected:
386
387    virtual bool equal (const ConstIterator &iter) const
388    {
389      const self_type *iters = dynamic_cast<const self_type *>(&iter);
390      if (iters) {
391	return (current == iters->get_current());
392      } else {
393	throw std::invalid_argument("bad iterator type");
394      }
395    }
396
397    virtual ptrdiff_t distance(const ConstIterator &iter) const
398    {
399      const self_type *iters = dynamic_cast<const self_type *>(&iter);
400      if (iters) {
401	return std::distance(current, iters->get_current());
402      } else {
403	throw std::invalid_argument("bad iterator type");
404      }
405    }
406
407    virtual Iterator* advance(ptrdiff_t n)
408    {
409      std::advance( current, n );
410      return this;
411    }
412
413  public:
414
415    Iterator_T(nonconst_iter curr, VALUE seq = Qnil)
416      : Iterator(seq), current(curr)
417    {
418    }
419
420    const nonconst_iter& get_current() const
421    {
422      return current;
423    }
424
425    self_type& operator=( const self_type& b )
426    {
427      base::operator=( b );
428      return *this;
429    }
430
431    self_type& operator=( const value_type& b )
432    {
433      *current = b;
434      return *this;
435    }
436
437    const value_type& operator*() const
438    {
439      return *current;
440    }
441
442    value_type& operator*()
443    {
444      return *current;
445    }
446
447    virtual VALUE inspect() const
448    {
449      VALUE ret = rb_str_new2("#<");
450      ret = rb_str_cat2( ret, rb_obj_classname(_seq) );
451      ret = rb_str_cat2( ret, "::iterator " );
452      VALUE cur = value();
453      ret = rb_str_concat( ret, rb_inspect(cur) );
454      ret = rb_str_cat2( ret, ">" );
455      return ret;
456    }
457
458    virtual VALUE to_s()    const
459    {
460      VALUE ret = rb_str_new2( rb_obj_classname(_seq) );
461      ret = rb_str_cat2( ret, "::iterator " );
462      VALUE cur = value();
463      ret = rb_str_concat( ret, rb_obj_as_string(cur) );
464      return ret;
465    }
466
467  protected:
468    nonconst_iter current;
469  };
470
471
472  /**
473   * Auxiliary functor to store the value of a ruby object inside
474   * a reference of a compatible C++ type.  ie: Ruby -> C++
475   *
476   */
477  template <class ValueType>
478  struct asval_oper
479  {
480    typedef ValueType    value_type;
481    typedef bool        result_type;
482    bool operator()(VALUE obj, value_type& v) const
483    {
484      return ( swig::asval< value_type >(obj, &v) == SWIG_OK );
485    }
486  };
487
488  /**
489   * Auxiliary functor to return a ruby object from a C++ type.
490   * ie: C++ -> Ruby
491   *
492   */
493  template <class ValueType>
494  struct from_oper
495  {
496    typedef const ValueType& argument_type;
497    typedef VALUE result_type;
498    result_type operator()(argument_type v) const
499    {
500      return swig::from(v);
501    }
502  };
503
504
505  /**
506   * ConstIterator class for a const_iterator with no end() boundaries.
507   *
508   */
509  template<typename OutConstIterator,
510	   typename ValueType = typename std::iterator_traits<OutConstIterator>::value_type,
511	   typename FromOper = from_oper<ValueType> >
512  class ConstIteratorOpen_T :  public ConstIterator_T<OutConstIterator>
513  {
514  public:
515    FromOper from;
516    typedef OutConstIterator const_iter;
517    typedef ValueType value_type;
518    typedef ConstIterator_T<const_iter>  base;
519    typedef ConstIteratorOpen_T<OutConstIterator, ValueType, FromOper> self_type;
520
521    ConstIteratorOpen_T(const_iter curr, VALUE seq = Qnil)
522      : ConstIterator_T<OutConstIterator>(curr, seq)
523    {
524    }
525
526    virtual VALUE value() const {
527      return from(static_cast<const value_type&>(*(base::current)));
528    }
529
530    ConstIterator *dup() const
531    {
532      return new self_type(*this);
533    }
534  };
535
536  /**
537   * Iterator class for an iterator with no end() boundaries.
538   *
539   */
540  template<typename InOutIterator,
541	   typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
542	   typename FromOper = from_oper<ValueType>,
543	   typename AsvalOper = asval_oper<ValueType> >
544  class IteratorOpen_T :  public Iterator_T<InOutIterator>
545  {
546  public:
547    FromOper  from;
548    AsvalOper asval;
549    typedef InOutIterator nonconst_iter;
550    typedef ValueType value_type;
551    typedef Iterator_T<nonconst_iter>  base;
552    typedef IteratorOpen_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
553
554  public:
555    IteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil)
556      : Iterator_T<InOutIterator>(curr, seq)
557    {
558    }
559
560    virtual VALUE value() const {
561      return from(static_cast<const value_type&>(*(base::current)));
562    }
563
564    virtual VALUE setValue( const VALUE& v )
565    {
566      value_type& dst = *base::current;
567      if ( asval(v, dst) ) return v;
568      return Qnil;
569    }
570
571    Iterator *dup() const
572    {
573      return new self_type(*this);
574    }
575  };
576
577  /**
578   * ConstIterator class for a const_iterator where begin() and end() boundaries are known.
579   *
580   */
581  template<typename OutConstIterator,
582	   typename ValueType = typename std::iterator_traits<OutConstIterator>::value_type,
583	   typename FromOper = from_oper<ValueType> >
584  class ConstIteratorClosed_T :  public ConstIterator_T<OutConstIterator>
585  {
586  public:
587    FromOper from;
588    typedef OutConstIterator const_iter;
589    typedef ValueType value_type;
590    typedef ConstIterator_T<const_iter>  base;
591    typedef ConstIteratorClosed_T<OutConstIterator, ValueType, FromOper> self_type;
592
593  protected:
594    virtual ConstIterator* advance(ptrdiff_t n)
595    {
596      std::advance( base::current, n );
597      if ( base::current == end )
598	throw stop_iteration();
599      return this;
600    }
601
602  public:
603    ConstIteratorClosed_T(const_iter curr, const_iter first,
604			  const_iter last, VALUE seq = Qnil)
605      : ConstIterator_T<OutConstIterator>(curr, seq), begin(first), end(last)
606    {
607    }
608
609    virtual VALUE value() const {
610      if (base::current == end) {
611	throw stop_iteration();
612      } else {
613	return from(static_cast<const value_type&>(*(base::current)));
614      }
615    }
616
617    ConstIterator *dup() const
618    {
619      return new self_type(*this);
620    }
621
622
623  private:
624    const_iter begin;
625    const_iter end;
626  };
627
628  /**
629   * Iterator class for a iterator where begin() and end() boundaries are known.
630   *
631   */
632  template<typename InOutIterator,
633	   typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
634	   typename FromOper = from_oper<ValueType>,
635	   typename AsvalOper = asval_oper<ValueType> >
636  class IteratorClosed_T :  public Iterator_T<InOutIterator>
637  {
638  public:
639    FromOper   from;
640    AsvalOper asval;
641    typedef InOutIterator nonconst_iter;
642    typedef ValueType value_type;
643    typedef Iterator_T<nonconst_iter>  base;
644    typedef IteratorClosed_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
645
646  protected:
647    virtual Iterator* advance(ptrdiff_t n)
648    {
649      std::advance( base::current, n );
650      if ( base::current == end )
651	throw stop_iteration();
652      return this;
653    }
654
655  public:
656    IteratorClosed_T(nonconst_iter curr, nonconst_iter first,
657		     nonconst_iter last, VALUE seq = Qnil)
658      : Iterator_T<InOutIterator>(curr, seq), begin(first), end(last)
659    {
660    }
661
662    virtual VALUE value() const {
663      if (base::current == end) {
664	throw stop_iteration();
665      } else {
666	return from(static_cast<const value_type&>(*(base::current)));
667      }
668    }
669
670    // Iterator setter method, required by Ruby
671    virtual VALUE setValue( const VALUE& v )
672    {
673      if (base::current == end)
674	throw stop_iteration();
675
676      value_type& dst = *base::current;
677      if ( asval( v, dst ) ) return v;
678      return Qnil;
679    }
680
681    Iterator *dup() const
682    {
683      return new self_type(*this);
684    }
685
686  private:
687    nonconst_iter begin;
688    nonconst_iter end;
689  };
690
691  /* Partial specialization for bools which don't allow de-referencing */
692  template< typename InOutIterator, typename FromOper, typename AsvalOper >
693  class IteratorOpen_T< InOutIterator, bool, FromOper, AsvalOper > :
694    public Iterator_T<InOutIterator>
695  {
696  public:
697    FromOper   from;
698    AsvalOper asval;
699    typedef InOutIterator nonconst_iter;
700    typedef bool value_type;
701    typedef Iterator_T<nonconst_iter>  base;
702    typedef IteratorOpen_T<InOutIterator, bool, FromOper, AsvalOper> self_type;
703
704    IteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil)
705      : Iterator_T<InOutIterator>(curr, seq)
706    {
707    }
708
709    virtual VALUE value() const {
710      return from(static_cast<const value_type&>(*(base::current)));
711    }
712
713    virtual VALUE setValue( const VALUE& v )
714    {
715      bool tmp = *base::current;
716      if ( asval( v, tmp ) )
717	{
718	  *base::current = tmp;
719	  return v;
720	}
721      return Qnil;
722    }
723
724    Iterator *dup() const
725    {
726      return new self_type(*this);
727    }
728
729  };
730
731  /* Partial specialization for bools which don't allow de-referencing */
732  template< typename InOutIterator, typename FromOper, typename AsvalOper >
733  class IteratorClosed_T< InOutIterator, bool, FromOper, AsvalOper > :
734    public Iterator_T<InOutIterator>
735  {
736  public:
737    FromOper   from;
738    AsvalOper asval;
739    typedef InOutIterator nonconst_iter;
740    typedef bool value_type;
741    typedef Iterator_T<nonconst_iter>  base;
742    typedef IteratorClosed_T<InOutIterator, bool, FromOper, AsvalOper> self_type;
743
744  protected:
745    virtual Iterator* advance(ptrdiff_t n)
746    {
747      std::advance( base::current, n );
748      if ( base::current == end )
749	throw stop_iteration();
750      return this;
751    }
752
753  public:
754    IteratorClosed_T(nonconst_iter curr, nonconst_iter first,
755		     nonconst_iter last, VALUE seq = Qnil)
756      : Iterator_T<InOutIterator>(curr, seq), begin(first), end(last)
757    {
758    }
759
760    virtual VALUE value() const {
761      if (base::current == end) {
762	throw stop_iteration();
763      } else {
764	return from(static_cast<const value_type&>(*(base::current)));
765      }
766    }
767
768    virtual VALUE setValue( const VALUE& v )
769    {
770      if (base::current == end)
771	throw stop_iteration();
772
773      bool tmp = *base::current;
774      if ( asval( v, tmp ) )
775	{
776	  *base::current = tmp;
777	  return v;
778	}
779      return Qnil;
780    }
781
782    Iterator *dup() const
783    {
784      return new self_type(*this);
785    }
786
787  private:
788    nonconst_iter begin;
789    nonconst_iter end;
790  };
791
792
793  /**
794   * Helper function used to wrap a bounded const_iterator.  This is to be used in
795   * a %typemap(out), for example.
796   *
797   */
798  template<typename InOutIter>
799  inline Iterator*
800  make_nonconst_iterator(const InOutIter& current, const InOutIter& begin,
801			 const InOutIter& end, VALUE seq = Qnil)
802  {
803    return new IteratorClosed_T<InOutIter>(current, begin, end, seq);
804  }
805
806  /**
807   * Helper function used to wrap an unbounded const_iterator.  This is to be used in
808   * a %typemap(out), for example.
809   *
810   */
811  template<typename InOutIter>
812  inline Iterator*
813  make_nonconst_iterator(const InOutIter& current, VALUE seq = Qnil)
814  {
815    return new IteratorOpen_T<InOutIter>(current, seq);
816  }
817
818  /**
819   * Helper function used to wrap a bounded const_iterator.  This is to be used in
820   * a %typemap(out), for example.
821   *
822   */
823  template<typename OutIter>
824  inline ConstIterator*
825  make_const_iterator(const OutIter& current, const OutIter& begin,
826                       const OutIter& end, VALUE seq = Qnil)
827  {
828    return new ConstIteratorClosed_T<OutIter>(current, begin, end, seq);
829  }
830
831  /**
832   * Helper function used to wrap an unbounded const_iterator.  This is to be used in
833   * a %typemap(out), for example.
834   *
835   */
836  template<typename OutIter>
837  inline ConstIterator*
838  make_const_iterator(const OutIter& current, VALUE seq = Qnil)
839  {
840    return new ConstIteratorOpen_T<OutIter>(current, seq);
841  }
842}
843}
844
845
846%fragment("ConstIterator");
847
848
849//
850// This part is just so SWIG is aware of the base abstract iterator class.
851//
852namespace swig
853{
854  /*
855    Throw a StopIteration exception
856  */
857  %ignore stop_iteration;
858  struct stop_iteration {};
859
860  %typemap(throws) stop_iteration {
861    (void)$1;
862    SWIG_Ruby_ExceptionType(NULL, Qnil);
863    SWIG_fail;
864  }
865
866  /*
867     Mark methods that return new objects
868  */
869  %newobject ConstIterator::dup;
870  %newobject ConstIterator::operator + (ptrdiff_t n) const;
871  %newobject ConstIterator::operator - (ptrdiff_t n) const;
872
873  %nodirector ConstIterator;
874
875  %catches(swig::stop_iteration)  ConstIterator::value() const;
876  %catches(swig::stop_iteration)  ConstIterator::incr(size_t n = 1);
877  %catches(swig::stop_iteration)  ConstIterator::decr(size_t n = 1);
878  %catches(std::invalid_argument) ConstIterator::distance(const ConstIterator &x) const;
879  %catches(std::invalid_argument) ConstIterator::equal (const ConstIterator &x) const;
880  %catches(swig::stop_iteration)  ConstIterator::next();
881  %catches(swig::stop_iteration)  ConstIterator::previous();
882  %catches(swig::stop_iteration)  ConstIterator::advance(ptrdiff_t n);
883  %catches(swig::stop_iteration)  ConstIterator::operator += (ptrdiff_t n);
884  %catches(swig::stop_iteration)  ConstIterator::operator -= (ptrdiff_t n);
885  %catches(swig::stop_iteration)  ConstIterator::operator + (ptrdiff_t n) const;
886  %catches(swig::stop_iteration)  ConstIterator::operator - (ptrdiff_t n) const;
887
888
889  struct ConstIterator
890  {
891  protected:
892    ConstIterator(VALUE seq);
893
894  public:
895    virtual ~ConstIterator();
896
897    // Access iterator method, required by Ruby
898    virtual VALUE value() const;
899
900    // C++ common/needed methods
901    virtual ConstIterator *dup() const;
902
903    virtual VALUE inspect()    const;
904    virtual VALUE to_s()    const;
905
906    virtual ConstIterator* next(size_t n = 1);
907    virtual ConstIterator* previous(size_t n = 1);
908
909    bool operator == (const ConstIterator& x)  const;
910    ConstIterator* operator + (ptrdiff_t n) const;
911    ConstIterator* operator - (ptrdiff_t n) const;
912    ptrdiff_t operator - (const ConstIterator& x) const;
913  };
914
915  struct Iterator : public ConstIterator
916  {
917    %rename("value=") setValue( const VALUE& v );
918    virtual VALUE setValue( const VALUE& v );
919
920    virtual Iterator *dup() const;
921
922    virtual Iterator* next(size_t n = 1);
923    virtual Iterator* previous(size_t n = 1);
924
925    virtual VALUE inspect()    const;
926    virtual VALUE to_s()    const;
927
928    bool operator == (const Iterator& x)  const;
929    Iterator* operator + (ptrdiff_t n) const;
930    Iterator* operator - (ptrdiff_t n) const;
931    ptrdiff_t operator - (const Iterator& x) const;
932  };
933
934}
935
936