diff options
author | Gonzalo Garramuno <ggarra@advancedsl.com.ar> | 2007-05-08 10:11:41 +0000 |
---|---|---|
committer | Gonzalo Garramuno <ggarra@advancedsl.com.ar> | 2007-05-08 10:11:41 +0000 |
commit | d162646475076ded694204809e7bdf48c171bb86 (patch) | |
tree | f88c0a64e61e601aec96303978273ef5ec36128a /Lib/ruby | |
parent | 6b686171661406b960884a447ffe24e6d2d40419 (diff) | |
download | swig-d162646475076ded694204809e7bdf48c171bb86.tar.gz |
Fixed swig::ConstIterator to use a GC_VALUE
instead of a normal value.
Fixed container iterator typemaps to pass self
in as sequence (this makes iterator print itself ok)
Fixed typo in rubycomplex comment.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9790 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Diffstat (limited to 'Lib/ruby')
-rw-r--r-- | Lib/ruby/rubycomplex.swg | 2 | ||||
-rw-r--r-- | Lib/ruby/rubycontainer.swg | 58 | ||||
-rw-r--r-- | Lib/ruby/rubyiterators.swg | 566 |
3 files changed, 347 insertions, 279 deletions
diff --git a/Lib/ruby/rubycomplex.swg b/Lib/ruby/rubycomplex.swg index dcdc44e1f..222cf8499 100644 --- a/Lib/ruby/rubycomplex.swg +++ b/Lib/ruby/rubycomplex.swg @@ -4,7 +4,7 @@ the complex Constructor method, and the Real and Imag complex accesor methods. - See the std_complex.i and ccomplex.i for concret examples. + See the std_complex.i and ccomplex.i for concrete examples. */ /* diff --git a/Lib/ruby/rubycontainer.swg b/Lib/ruby/rubycontainer.swg index 331757698..e2ede1d2d 100644 --- a/Lib/ruby/rubycontainer.swg +++ b/Lib/ruby/rubycontainer.swg @@ -163,6 +163,14 @@ namespace swig { { namespace swig { + + /** + * This class is a proxy class for references, used to return and set values + * of an element of a Ruby Array of stuff. + * It can be used by RubySequence_InputIterator to make it work with STL + * algorithms. + * + */ template <class T> struct RubySequence_Ref { @@ -201,6 +209,14 @@ namespace swig int _index; }; + + /** + * This class is a proxy to return a pointer to a class, usually + * RubySequence_Ref. + * It can be used by RubySequence_InputIterator to make it work with STL + * algorithms. + * + */ template <class T> struct RubySequence_ArrowProxy { @@ -210,7 +226,13 @@ namespace swig T m_value; }; - template <class T, class Reference > + + /** + * Input Iterator. This adapator class is a random access iterator that + * allows you to use STL algorithms with a Ruby class (a Ruby Array by default). + * + */ + template <class T, class Reference = RubySequence_Ref< T > > struct RubySequence_InputIterator { typedef RubySequence_InputIterator<T, Reference > self; @@ -219,7 +241,7 @@ namespace swig typedef Reference reference; typedef T value_type; typedef T* pointer; - typedef int difference_type; + typedef ptrdiff_t difference_type; RubySequence_InputIterator() { @@ -306,6 +328,11 @@ namespace swig }; + /** + * This adaptor class allows you to use a Ruby Array as if it was an STL + * container, giving it begin(), end(), and iterators. + * + */ template <class T> struct RubySequence_Cont { @@ -404,22 +431,24 @@ namespace swig %typemap(out,noblock=1,fragment="RubySequence_Cont") const_iterator, const_reverse_iterator { - $result = SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &)), + $result = SWIG_NewPointerObj(swig::make_const_iterator(%static_cast($1,const $type &), + self), swig::ConstIterator::descriptor(),SWIG_POINTER_OWN); } %typemap(out,noblock=1,fragment="RubySequence_Cont") iterator, reverse_iterator { - $result = SWIG_NewPointerObj(swig::make_inout_iterator(%static_cast($1,const $type &)), + $result = SWIG_NewPointerObj(swig::make_nonconst_iterator(%static_cast($1,const $type &), + self), swig::Iterator::descriptor(),SWIG_POINTER_OWN); } %typemap(out,noblock=1,fragment="RubySequence_Cont") std::pair<const_iterator, const_iterator> { $result = rb_ary_new2(2); - RARRAY_PTR($result)[0] = SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).first), + RARRAY_PTR($result)[0] = SWIG_NewPointerObj(swig::make_const_iterator(%static_cast($1,const $type &).first), swig::ConstIterator::descriptor(),SWIG_POINTER_OWN); - RARRAY_PTR($result)[1] = SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).second), + RARRAY_PTR($result)[1] = SWIG_NewPointerObj(swig::make_const_iterator(%static_cast($1,const $type &).second), swig::ConstIterator::descriptor(),SWIG_POINTER_OWN); RARRAY_LEN($result) = 2; } @@ -427,9 +456,9 @@ namespace swig %typemap(out,noblock=1,fragment="RubySequence_Cont") std::pair<iterator, iterator> { $result = rb_ary_new2(2); - RARRAY_PTR($result)[0] = SWIG_NewPointerObj(swig::make_inout_iterator(%static_cast($1,const $type &).first), + RARRAY_PTR($result)[0] = SWIG_NewPointerObj(swig::make_nonconst_iterator(%static_cast($1,const $type &).first), swig::Iterator::descriptor(),SWIG_POINTER_OWN); - RARRAY_PTR($result)[1] = SWIG_NewPointerObj(swig::make_inout_iterator(%static_cast($1,const $type &).second), + RARRAY_PTR($result)[1] = SWIG_NewPointerObj(swig::make_nonconst_iterator(%static_cast($1,const $type &).second), swig::Iterator::descriptor(),SWIG_POINTER_OWN); RARRAY_LEN($result) = 2; } @@ -440,7 +469,7 @@ namespace swig %typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator") std::pair<const_iterator, bool> { $result = rb_ary_new2(2); - RARRAY_PTR($result)[0] = SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).first), + RARRAY_PTR($result)[0] = SWIG_NewPointerObj(swig::make_const_iterator(%static_cast($1,const $type &).first), swig::ConstIterator::descriptor(),SWIG_POINTER_OWN); RARRAY_PTR($result)[1] = SWIG_From(bool)(%static_cast($1,const $type &).second); RARRAY_LEN($result) = 2; @@ -449,7 +478,7 @@ namespace swig %typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator") std::pair<iterator, bool> { $result = rb_ary_new2(2); - RARRAY_PTR($result)[0] = SWIG_NewPointerObj(swig::make_inout_iterator(%static_cast($1,const $type &).first), + RARRAY_PTR($result)[0] = SWIG_NewPointerObj(swig::make_nonconst_iterator(%static_cast($1,const $type &).first), swig::Iterator::descriptor(),SWIG_POINTER_OWN); RARRAY_PTR($result)[1] = SWIG_From(bool)(%static_cast($1,const $type &).second); RARRAY_LEN($result) = 2; @@ -491,7 +520,8 @@ namespace swig %typecheck(%checkcode(ITERATOR),noblock=1,fragment="RubySequence_Cont") const_iterator, const_reverse_iterator { swig::ConstIterator *iter = 0; - int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::ConstIterator::descriptor(), 0); + int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), + swig::ConstIterator::descriptor(), 0); $1 = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::ConstIterator_T<$type > *>(iter) != 0)); } @@ -509,12 +539,12 @@ namespace swig // %newobject const_iterator; // %extend { // swig::Iterator* iterator(VALUE* RUBY_SELF) { -// return swig::make_inout_iterator($self->begin(), $self->begin(), -// $self->end(), *RUBY_SELF); +// return swig::make_nonconst_iterator($self->begin(), $self->begin(), +// $self->end(), *RUBY_SELF); // } // swig::ConstIterator* const_iterator(VALUE* RUBY_SELF) { -// return swig::make_output_iterator($self->begin(), $self->begin(), +// return swig::make_const_iterator($self->begin(), $self->begin(), // $self->end(), *RUBY_SELF); // } // } diff --git a/Lib/ruby/rubyiterators.swg b/Lib/ruby/rubyiterators.swg index 1c3092419..fa70f74d3 100644 --- a/Lib/ruby/rubyiterators.swg +++ b/Lib/ruby/rubyiterators.swg @@ -15,70 +15,102 @@ %include <std_common.i> -/** - * Abstract base class used to represent all iterators of STL containers. - */ %fragment("ConstIterator","header") { namespace swig { struct stop_iteration { }; + /** + * Abstract base class used to represent all iterators of STL containers. + */ struct ConstIterator { + public: + typedef ConstIterator self_type; + protected: - VALUE _seq; + GC_VALUE _seq; protected: ConstIterator(VALUE seq) : _seq(seq) { } + + // Random access iterator methods, but not required in Ruby + virtual ptrdiff_t distance(const ConstIterator &x) const + { + throw std::invalid_argument("distance not supported"); + } + + virtual bool equal (const ConstIterator &x) const + { + throw std::invalid_argument("equal not supported"); + } + + virtual self_type* advance(ptrdiff_t n) + { + throw std::invalid_argument("advance not supported"); + } public: virtual ~ConstIterator() {} // Access iterator method, required by Ruby - virtual VALUE value() const = 0; + virtual VALUE value() const { + throw std::invalid_argument("value not supported"); + return Qnil; + }; - // Forward iterator method, required by Ruby - virtual ConstIterator *incr(size_t n = 1) = 0; - - // Backward iterator method, very common in C++, but not required in Ruby - virtual ConstIterator *decr(size_t n = 1) - { - throw stop_iteration(); + virtual VALUE setValue( const VALUE& v ) { + throw std::invalid_argument("value= not supported"); + return Qnil; } - // Random access iterator methods, but not required in Ruby - virtual ptrdiff_t distance(const ConstIterator &x) const + virtual self_type* next( size_t n = 1 ) { - throw std::invalid_argument("operation not supported"); + return this->advance( n ); } - virtual bool equal (const ConstIterator &x) const + virtual self_type* previous( size_t n = 1 ) { - throw std::invalid_argument("operation not supported"); + return this->advance( -n ); + } + + virtual VALUE to_s() const { + throw std::invalid_argument("to_s not supported"); + return Qnil; + } + + virtual VALUE inspect() const { + throw std::invalid_argument("inspect not supported"); + return Qnil; } - // C++ common/needed methods - virtual ConstIterator *dup() const = 0; + virtual ConstIterator *dup() const + { + throw std::invalid_argument("dup not supported"); + return NULL; + } - VALUE next() + // + // C++ common/needed methods. We emulate a bidirectional + // operator, to be compatible with all the STL. + // The iterator traits will then tell the STL what type of + // iterator we really are. + // + ConstIterator() : _seq( Qnil ) { - VALUE obj = value(); - incr(); - return obj; } - VALUE previous() + ConstIterator( const self_type& b ) : _seq( b._seq ) { - decr(); - return value(); } - ConstIterator *advance(ptrdiff_t n) + self_type& operator=( const self_type& b ) { - return (n > 0) ? incr(n) : decr(-n); + _seq = b._seq; + return *this; } - + bool operator == (const ConstIterator& x) const { return equal(x); @@ -89,6 +121,34 @@ namespace swig { return ! operator==(x); } + // Pre-decrement operator + self_type& operator--() + { + return *previous(); + } + + // Pre-increment operator + self_type& operator++() + { + return *next(); + } + + // Post-decrement operator + self_type operator--(int) + { + self_type r = *this; + previous(); + return r; + } + + // Post-increment operator + self_type operator++(int) + { + self_type r = *this; + next(); + return r; + } + ConstIterator& operator += (ptrdiff_t n) { return *advance(n); @@ -98,7 +158,7 @@ namespace swig { { return *advance(-n); } - + ConstIterator* operator + (ptrdiff_t n) const { return dup()->advance(n); @@ -123,22 +183,28 @@ namespace swig { } return desc; } - - // Ruby common/needed printing methods - virtual VALUE inspect() const = 0; - virtual VALUE to_s() const = 0; }; + + /** + * Abstract base class used to represent all non-const iterators of STL containers. + * + */ struct Iterator : public ConstIterator { + public: + typedef Iterator self_type; + protected: Iterator(VALUE seq) : ConstIterator(seq) { } - public: - // Iterator setter method, required by Ruby - virtual bool set( const VALUE& v ) = 0; + virtual self_type* advance(ptrdiff_t n) + { + throw std::invalid_argument("operation not supported"); + } + public: static swig_type_info* descriptor() { static int init = 0; static swig_type_info* desc = 0; @@ -148,15 +214,23 @@ namespace swig { } return desc; } - - // C++ common/needed methods - virtual Iterator *dup() const = 0; - - Iterator *advance(ptrdiff_t n) + + virtual Iterator *dup() const { - return (Iterator*) ( (n > 0) ? incr(n) : decr(-n) ); + throw std::invalid_argument("dup not supported"); + return NULL; } + virtual self_type* next( size_t n = 1 ) + { + return this->advance( n ); + } + + virtual self_type* previous( size_t n = 1 ) + { + return this->advance( -n ); + } + bool operator == (const ConstIterator& x) const { return equal(x); @@ -201,29 +275,21 @@ namespace swig { namespace swig { /** - * Abstract base classes for all custom const_iterators. + * Templated base classes for all custom const_iterators. * */ template<typename OutConstIterator> class ConstIterator_T : public ConstIterator { public: - typedef OutConstIterator out_iterator; - typedef typename std::iterator_traits<out_iterator>::value_type value_type; - typedef ConstIterator_T<out_iterator> self_type; + typedef OutConstIterator const_iter; + typedef typename std::iterator_traits<const_iter>::value_type value_type; + typedef ConstIterator_T<const_iter> self_type; - ConstIterator_T(out_iterator curr, VALUE seq = Qnil) - : ConstIterator(seq), current(curr) - { - } - - const out_iterator& get_current() const - { - return current; - } + protected: - bool equal (const ConstIterator &iter) const + virtual bool equal (const ConstIterator &iter) const { const self_type *iters = dynamic_cast<const self_type *>(&iter); if (iters) { @@ -242,7 +308,24 @@ namespace swig { throw std::invalid_argument("bad iterator type"); } } - + + virtual ConstIterator* advance(ptrdiff_t n) + { + std::advance( current, n ); + return this; + } + + public: + ConstIterator_T(const_iter curr, VALUE seq = Qnil) + : ConstIterator(seq), current(curr) + { + } + + const const_iter& get_current() const + { + return current; + } + virtual VALUE inspect() const { VALUE ret = rb_str_new2("#<"); @@ -264,33 +347,33 @@ namespace swig { } protected: - out_iterator current; + const_iter current; }; /** - * Abstract base classes for all custom iterators. + * Templated base classes for all custom non-const iterators. * */ template<typename InOutIterator> class Iterator_T : public Iterator { public: - typedef InOutIterator inout_iterator; - typedef typename std::iterator_traits<inout_iterator>::value_type value_type; - typedef Iterator_T<inout_iterator> self_type; + typedef InOutIterator nonconst_iter; - Iterator_T(inout_iterator curr, VALUE seq = Qnil) - : Iterator(seq), current(curr) - { - } + // Make this class iterator STL compatible, by using iterator_traits + typedef typename std::iterator_traits<nonconst_iter >::iterator_category iterator_category; + typedef typename std::iterator_traits<nonconst_iter >::value_type value_type; + typedef typename std::iterator_traits<nonconst_iter >::difference_type difference_type; + typedef typename std::iterator_traits<nonconst_iter >::pointer pointer; + typedef typename std::iterator_traits<nonconst_iter >::reference reference; - const inout_iterator& get_current() const - { - return current; - } + typedef Iterator base; + typedef Iterator_T< nonconst_iter > self_type; - bool equal (const ConstIterator &iter) const + protected: + + virtual bool equal (const ConstIterator &iter) const { const self_type *iters = dynamic_cast<const self_type *>(&iter); if (iters) { @@ -309,6 +392,36 @@ namespace swig { throw std::invalid_argument("bad iterator type"); } } + + virtual Iterator* advance(ptrdiff_t n) + { + std::advance( current, n ); + return this; + } + + public: + + Iterator_T(nonconst_iter curr, VALUE seq = Qnil) + : Iterator(seq), current(curr) + { + } + + const nonconst_iter& get_current() const + { + return current; + } + + self_type& operator=( const self_type& b ) + { + base::operator=( b ); + return *this; + } + + self_type& operator=( const value_type& b ) + { + *current = b; + return *this; + } virtual VALUE inspect() const { @@ -331,11 +444,15 @@ namespace swig { } protected: - inout_iterator current; + nonconst_iter current; }; - + /** + * Auxiliary functor to store the value of a ruby object inside + * a reference of a compatible C++ type. ie: Ruby -> C++ + * + */ template <class ValueType> struct asval_oper { @@ -347,6 +464,11 @@ namespace swig { } }; + /** + * Auxiliary functor to return a ruby object from a C++ type. + * ie: C++ -> Ruby + * + */ template <class ValueType> struct from_oper { @@ -370,12 +492,12 @@ namespace swig { { public: FromOper from; - typedef OutConstIterator out_iterator; + typedef OutConstIterator const_iter; typedef ValueType value_type; - typedef ConstIterator_T<out_iterator> base; + typedef ConstIterator_T<const_iter> base; typedef ConstIteratorOpen_T<OutConstIterator, ValueType, FromOper> self_type; - ConstIteratorOpen_T(out_iterator curr, VALUE seq = Qnil) + ConstIteratorOpen_T(const_iter curr, VALUE seq = Qnil) : ConstIterator_T<OutConstIterator>(curr, seq) { } @@ -388,22 +510,6 @@ namespace swig { { return new self_type(*this); } - - ConstIterator *incr(size_t n = 1) - { - while (n--) { - ++base::current; - } - return this; - } - - ConstIterator *decr(size_t n = 1) - { - while (n--) { - --base::current; - } - return this; - } }; /** @@ -419,12 +525,13 @@ namespace swig { public: FromOper from; AsvalOper asval; - typedef InOutIterator inout_iterator; + typedef InOutIterator nonconst_iter; typedef ValueType value_type; - typedef Iterator_T<inout_iterator> base; + typedef Iterator_T<nonconst_iter> base; typedef IteratorOpen_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type; - - IteratorOpen_T(inout_iterator curr, VALUE seq = Qnil) + + public: + IteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil) : Iterator_T<InOutIterator>(curr, seq) { } @@ -433,32 +540,17 @@ namespace swig { return from(static_cast<const value_type&>(*(base::current))); } - virtual bool set( const VALUE& v ) + virtual VALUE setValue( const VALUE& v ) { value_type& dst = *base::current; - return asval(v, dst); + if ( asval(v, dst) ) return v; + return Qnil; } Iterator *dup() const { return new self_type(*this); } - - Iterator *incr(size_t n = 1) - { - while (n--) { - ++base::current; - } - return this; - } - - Iterator *decr(size_t n = 1) - { - while (n--) { - --base::current; - } - return this; - } }; /** @@ -472,13 +564,23 @@ namespace swig { { public: FromOper from; - typedef OutConstIterator out_iterator; + typedef OutConstIterator const_iter; typedef ValueType value_type; - typedef ConstIterator_T<out_iterator> base; + typedef ConstIterator_T<const_iter> base; typedef ConstIteratorClosed_T<OutConstIterator, ValueType, FromOper> self_type; - ConstIteratorClosed_T(out_iterator curr, out_iterator first, - out_iterator last, VALUE seq = Qnil) + protected: + virtual ConstIterator* advance(ptrdiff_t n) + { + std::advance( base::current, n ); + if ( base::current == end ) + throw stop_iteration(); + return this; + } + + public: + ConstIteratorClosed_T(const_iter curr, const_iter first, + const_iter last, VALUE seq = Qnil) : ConstIterator_T<OutConstIterator>(curr, seq), begin(first), end(last) { } @@ -491,39 +593,15 @@ namespace swig { } } - ConstIterator *dup() const { return new self_type(*this); } - ConstIterator *incr(size_t n = 1) - { - while (n--) { - if (base::current == end) { - throw stop_iteration(); - } else { - ++base::current; - } - } - return this; - } - - ConstIterator *decr(size_t n = 1) - { - while (n--) { - if (base::current == begin) { - throw stop_iteration(); - } else { - --base::current; - } - } - return this; - } private: - out_iterator begin; - out_iterator end; + const_iter begin; + const_iter end; }; /** @@ -539,13 +617,23 @@ namespace swig { public: FromOper from; AsvalOper asval; - typedef InOutIterator inout_iterator; + typedef InOutIterator nonconst_iter; typedef ValueType value_type; - typedef Iterator_T<inout_iterator> base; + typedef Iterator_T<nonconst_iter> base; typedef IteratorClosed_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type; - IteratorClosed_T(inout_iterator curr, inout_iterator first, - inout_iterator last, VALUE seq = Qnil) + protected: + virtual Iterator* advance(ptrdiff_t n) + { + std::advance( base::current, n ); + if ( base::current == end ) + throw stop_iteration(); + return this; + } + + public: + IteratorClosed_T(nonconst_iter curr, nonconst_iter first, + nonconst_iter last, VALUE seq = Qnil) : Iterator_T<InOutIterator>(curr, seq), begin(first), end(last) { } @@ -559,14 +647,14 @@ namespace swig { } // Iterator setter method, required by Ruby - virtual bool set( const VALUE& v ) + virtual VALUE setValue( const VALUE& v ) { - if (base::current == end) { + if (base::current == end) throw stop_iteration(); - } else { - value_type& dst = *base::current; - return asval( v, dst ); - } + + value_type& dst = *base::current; + if ( asval( v, dst ) ) return v; + return Qnil; } Iterator *dup() const @@ -574,33 +662,9 @@ namespace swig { return new self_type(*this); } - Iterator *incr(size_t n = 1) - { - while (n--) { - if (base::current == end) { - throw stop_iteration(); - } else { - ++base::current; - } - } - return this; - } - - Iterator *decr(size_t n = 1) - { - while (n--) { - if (base::current == begin) { - throw stop_iteration(); - } else { - --base::current; - } - } - return this; - } - private: - inout_iterator begin; - inout_iterator end; + nonconst_iter begin; + nonconst_iter end; }; /* Partial specialization for bools which don't allow de-referencing */ @@ -611,12 +675,12 @@ namespace swig { public: FromOper from; AsvalOper asval; - typedef InOutIterator inout_iterator; + typedef InOutIterator nonconst_iter; typedef bool value_type; - typedef Iterator_T<inout_iterator> base; + typedef Iterator_T<nonconst_iter> base; typedef IteratorOpen_T<InOutIterator, bool, FromOper, AsvalOper> self_type; - IteratorOpen_T(inout_iterator curr, VALUE seq = Qnil) + IteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil) : Iterator_T<InOutIterator>(curr, seq) { } @@ -625,31 +689,21 @@ namespace swig { return from(static_cast<const value_type&>(*(base::current))); } - virtual bool set( const VALUE& v ) + virtual VALUE setValue( const VALUE& v ) { - return false; + bool tmp = *base::current; + if ( asval( v, tmp ) ) + { + *base::current = tmp; + return v; + } + return Qnil; } Iterator *dup() const { return new self_type(*this); } - - Iterator *incr(size_t n = 1) - { - while (n--) { - ++base::current; - } - return this; - } - - Iterator *decr(size_t n = 1) - { - while (n--) { - --base::current; - } - return this; - } }; @@ -661,13 +715,23 @@ namespace swig { public: FromOper from; AsvalOper asval; - typedef InOutIterator inout_iterator; + typedef InOutIterator nonconst_iter; typedef bool value_type; - typedef Iterator_T<inout_iterator> base; + typedef Iterator_T<nonconst_iter> base; typedef IteratorClosed_T<InOutIterator, bool, FromOper, AsvalOper> self_type; - IteratorClosed_T(inout_iterator curr, inout_iterator first, - inout_iterator last, VALUE seq = Qnil) + protected: + virtual Iterator* advance(ptrdiff_t n) + { + std::advance( base::current, n ); + if ( base::current == end ) + throw stop_iteration(); + return this; + } + + public: + IteratorClosed_T(nonconst_iter curr, nonconst_iter first, + nonconst_iter last, VALUE seq = Qnil) : Iterator_T<InOutIterator>(curr, seq), begin(first), end(last) { } @@ -680,9 +744,18 @@ namespace swig { } } - virtual bool set( const VALUE& v ) + virtual VALUE setValue( const VALUE& v ) { - return false; + if (base::current == end) + throw stop_iteration(); + + bool tmp = *base::current; + if ( asval( v, tmp ) ) + { + *base::current = tmp; + return v; + } + return Qnil; } Iterator *dup() const @@ -690,34 +763,9 @@ namespace swig { return new self_type(*this); } - Iterator *incr(size_t n = 1) - { - while (n--) { - if (base::current == end) { - throw stop_iteration(); - } else { - ++base::current; - } - } - return this; - } - - Iterator *decr(size_t n = 1) - { - while (n--) { - if (base::current == begin) { - throw stop_iteration(); - } else { - --base::current; - } - } - return this; - } - private: - inout_iterator begin; - inout_iterator end; - + nonconst_iter begin; + nonconst_iter end; }; @@ -728,8 +776,8 @@ namespace swig { */ template<typename InOutIter> inline Iterator* - make_inout_iterator(const InOutIter& current, const InOutIter& begin, - const InOutIter& end, VALUE seq = Qnil) + make_nonconst_iterator(const InOutIter& current, const InOutIter& begin, + const InOutIter& end, VALUE seq = Qnil) { return new IteratorClosed_T<InOutIter>(current, begin, end, seq); } @@ -741,7 +789,7 @@ namespace swig { */ template<typename InOutIter> inline Iterator* - make_inout_iterator(const InOutIter& current, VALUE seq = Qnil) + make_nonconst_iterator(const InOutIter& current, VALUE seq = Qnil) { return new IteratorOpen_T<InOutIter>(current, seq); } @@ -753,7 +801,7 @@ namespace swig { */ template<typename OutIter> inline ConstIterator* - make_output_iterator(const OutIter& current, const OutIter& begin, + make_const_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, VALUE seq = Qnil) { return new ConstIteratorClosed_T<OutIter>(current, begin, end, seq); @@ -766,7 +814,7 @@ namespace swig { */ template<typename OutIter> inline ConstIterator* - make_output_iterator(const OutIter& current, VALUE seq = Qnil) + make_const_iterator(const OutIter& current, VALUE seq = Qnil) { return new ConstIteratorOpen_T<OutIter>(current, seq); } @@ -826,28 +874,16 @@ namespace swig virtual ~ConstIterator(); // Access iterator method, required by Ruby - virtual VALUE value() const = 0; - - // Forward iterator method, required by Ruby - virtual ConstIterator *incr(size_t n = 1) = 0; - - // Backward iterator method, very common in C++, but not required in Ruby - virtual ConstIterator *decr(size_t n = 1); - - // Random access iterator methods, but not required in Ruby - virtual ptrdiff_t distance(const ConstIterator &x) const; - - virtual bool equal (const ConstIterator &x) const; + virtual VALUE value() const; // C++ common/needed methods - virtual ConstIterator *dup() const = 0; + virtual ConstIterator *dup() const; - virtual VALUE inspect() const = 0; - virtual VALUE to_s() const = 0; + virtual VALUE inspect() const; + virtual VALUE to_s() const; - VALUE next(); - VALUE previous(); - ConstIterator *advance(ptrdiff_t n); + virtual ConstIterator* next(size_t n = 1); + virtual ConstIterator* previous(size_t n = 1); bool operator == (const ConstIterator& x) const; ConstIterator* operator + (ptrdiff_t n) const; @@ -857,14 +893,16 @@ namespace swig struct Iterator : public ConstIterator { - virtual bool set( const VALUE& v ) = 0; + %rename("value=") setValue( const VALUE& v ); + virtual VALUE setValue( const VALUE& v ); - // Random access iterator methods, but not required in Ruby - virtual ptrdiff_t distance(const Iterator &x) const; - virtual bool equal (const Iterator &x) const; + virtual Iterator *dup() const; + + virtual Iterator* next(size_t n = 1); + virtual Iterator* previous(size_t n = 1); - virtual Iterator *dup() const = 0; - Iterator *advance(ptrdiff_t n); + virtual VALUE inspect() const; + virtual VALUE to_s() const; bool operator == (const Iterator& x) const; Iterator* operator + (ptrdiff_t n) const; |