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
This commit is contained in:
Gonzalo Garramuno 2007-05-08 10:11:41 +00:00
commit d162646475
3 changed files with 348 additions and 280 deletions

View file

@ -4,7 +4,7 @@
the complex Constructor method, and the Real and Imag complex the complex Constructor method, and the Real and Imag complex
accesor methods. accesor methods.
See the std_complex.i and ccomplex.i for concret examples. See the std_complex.i and ccomplex.i for concrete examples.
*/ */
/* /*

View file

@ -163,6 +163,14 @@ namespace swig {
{ {
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> template <class T>
struct RubySequence_Ref struct RubySequence_Ref
{ {
@ -201,6 +209,14 @@ namespace swig
int _index; 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> template <class T>
struct RubySequence_ArrowProxy struct RubySequence_ArrowProxy
{ {
@ -210,7 +226,13 @@ namespace swig
T m_value; 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 struct RubySequence_InputIterator
{ {
typedef RubySequence_InputIterator<T, Reference > self; typedef RubySequence_InputIterator<T, Reference > self;
@ -219,7 +241,7 @@ namespace swig
typedef Reference reference; typedef Reference reference;
typedef T value_type; typedef T value_type;
typedef T* pointer; typedef T* pointer;
typedef int difference_type; typedef ptrdiff_t difference_type;
RubySequence_InputIterator() 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> template <class T>
struct RubySequence_Cont struct RubySequence_Cont
{ {
@ -404,22 +431,24 @@ namespace swig
%typemap(out,noblock=1,fragment="RubySequence_Cont") %typemap(out,noblock=1,fragment="RubySequence_Cont")
const_iterator, const_reverse_iterator { 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); swig::ConstIterator::descriptor(),SWIG_POINTER_OWN);
} }
%typemap(out,noblock=1,fragment="RubySequence_Cont") %typemap(out,noblock=1,fragment="RubySequence_Cont")
iterator, reverse_iterator { 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); swig::Iterator::descriptor(),SWIG_POINTER_OWN);
} }
%typemap(out,noblock=1,fragment="RubySequence_Cont") %typemap(out,noblock=1,fragment="RubySequence_Cont")
std::pair<const_iterator, const_iterator> { std::pair<const_iterator, const_iterator> {
$result = rb_ary_new2(2); $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); 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); swig::ConstIterator::descriptor(),SWIG_POINTER_OWN);
RARRAY_LEN($result) = 2; RARRAY_LEN($result) = 2;
} }
@ -427,9 +456,9 @@ namespace swig
%typemap(out,noblock=1,fragment="RubySequence_Cont") %typemap(out,noblock=1,fragment="RubySequence_Cont")
std::pair<iterator, iterator> { std::pair<iterator, iterator> {
$result = rb_ary_new2(2); $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); 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); swig::Iterator::descriptor(),SWIG_POINTER_OWN);
RARRAY_LEN($result) = 2; RARRAY_LEN($result) = 2;
} }
@ -440,7 +469,7 @@ namespace swig
%typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator") %typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator")
std::pair<const_iterator, bool> { std::pair<const_iterator, bool> {
$result = rb_ary_new2(2); $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); swig::ConstIterator::descriptor(),SWIG_POINTER_OWN);
RARRAY_PTR($result)[1] = SWIG_From(bool)(%static_cast($1,const $type &).second); RARRAY_PTR($result)[1] = SWIG_From(bool)(%static_cast($1,const $type &).second);
RARRAY_LEN($result) = 2; RARRAY_LEN($result) = 2;
@ -449,7 +478,7 @@ namespace swig
%typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator") %typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator")
std::pair<iterator, bool> { std::pair<iterator, bool> {
$result = rb_ary_new2(2); $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); swig::Iterator::descriptor(),SWIG_POINTER_OWN);
RARRAY_PTR($result)[1] = SWIG_From(bool)(%static_cast($1,const $type &).second); RARRAY_PTR($result)[1] = SWIG_From(bool)(%static_cast($1,const $type &).second);
RARRAY_LEN($result) = 2; RARRAY_LEN($result) = 2;
@ -491,7 +520,8 @@ namespace swig
%typecheck(%checkcode(ITERATOR),noblock=1,fragment="RubySequence_Cont") %typecheck(%checkcode(ITERATOR),noblock=1,fragment="RubySequence_Cont")
const_iterator, const_reverse_iterator { const_iterator, const_reverse_iterator {
swig::ConstIterator *iter = 0; 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)); $1 = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::ConstIterator_T<$type > *>(iter) != 0));
} }
@ -509,12 +539,12 @@ namespace swig
// %newobject const_iterator; // %newobject const_iterator;
// %extend { // %extend {
// swig::Iterator* iterator(VALUE* RUBY_SELF) { // swig::Iterator* iterator(VALUE* RUBY_SELF) {
// return swig::make_inout_iterator($self->begin(), $self->begin(), // return swig::make_nonconst_iterator($self->begin(), $self->begin(),
// $self->end(), *RUBY_SELF); // $self->end(), *RUBY_SELF);
// } // }
// swig::ConstIterator* const_iterator(VALUE* 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); // $self->end(), *RUBY_SELF);
// } // }
// } // }

View file

@ -15,70 +15,102 @@
%include <std_common.i> %include <std_common.i>
/**
* Abstract base class used to represent all iterators of STL containers.
*/
%fragment("ConstIterator","header") { %fragment("ConstIterator","header") {
namespace swig { namespace swig {
struct stop_iteration { struct stop_iteration {
}; };
/**
* Abstract base class used to represent all iterators of STL containers.
*/
struct ConstIterator { struct ConstIterator {
public:
typedef ConstIterator self_type;
protected: protected:
VALUE _seq; GC_VALUE _seq;
protected: protected:
ConstIterator(VALUE seq) : _seq(seq) 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: public:
virtual ~ConstIterator() {} virtual ~ConstIterator() {}
// Access iterator method, required by Ruby // 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 VALUE setValue( const VALUE& v ) {
virtual ConstIterator *incr(size_t n = 1) = 0; throw std::invalid_argument("value= not supported");
return Qnil;
// Backward iterator method, very common in C++, but not required in Ruby
virtual ConstIterator *decr(size_t n = 1)
{
throw stop_iteration();
} }
// Random access iterator methods, but not required in Ruby virtual self_type* next( size_t n = 1 )
virtual ptrdiff_t distance(const ConstIterator &x) const
{ {
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
virtual ConstIterator *dup() const = 0;
VALUE next()
{ {
VALUE obj = value(); throw std::invalid_argument("dup not supported");
incr(); return NULL;
return obj;
} }
VALUE previous() //
// 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 )
{ {
decr();
return value();
} }
ConstIterator *advance(ptrdiff_t n) ConstIterator( const self_type& b ) : _seq( b._seq )
{ {
return (n > 0) ? incr(n) : decr(-n);
} }
self_type& operator=( const self_type& b )
{
_seq = b._seq;
return *this;
}
bool operator == (const ConstIterator& x) const bool operator == (const ConstIterator& x) const
{ {
return equal(x); return equal(x);
@ -89,6 +121,34 @@ namespace swig {
return ! operator==(x); 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) ConstIterator& operator += (ptrdiff_t n)
{ {
return *advance(n); return *advance(n);
@ -98,7 +158,7 @@ namespace swig {
{ {
return *advance(-n); return *advance(-n);
} }
ConstIterator* operator + (ptrdiff_t n) const ConstIterator* operator + (ptrdiff_t n) const
{ {
return dup()->advance(n); return dup()->advance(n);
@ -123,22 +183,28 @@ namespace swig {
} }
return desc; 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 { struct Iterator : public ConstIterator {
public:
typedef Iterator self_type;
protected: protected:
Iterator(VALUE seq) : ConstIterator(seq) Iterator(VALUE seq) : ConstIterator(seq)
{ {
} }
public: virtual self_type* advance(ptrdiff_t n)
// Iterator setter method, required by Ruby {
virtual bool set( const VALUE& v ) = 0; throw std::invalid_argument("operation not supported");
}
public:
static swig_type_info* descriptor() { static swig_type_info* descriptor() {
static int init = 0; static int init = 0;
static swig_type_info* desc = 0; static swig_type_info* desc = 0;
@ -148,15 +214,23 @@ namespace swig {
} }
return desc; return desc;
} }
// C++ common/needed methods virtual Iterator *dup() const
virtual Iterator *dup() const = 0;
Iterator *advance(ptrdiff_t n)
{ {
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 bool operator == (const ConstIterator& x) const
{ {
return equal(x); return equal(x);
@ -201,29 +275,21 @@ namespace swig {
namespace swig { namespace swig {
/** /**
* Abstract base classes for all custom const_iterators. * Templated base classes for all custom const_iterators.
* *
*/ */
template<typename OutConstIterator> template<typename OutConstIterator>
class ConstIterator_T : public ConstIterator class ConstIterator_T : public ConstIterator
{ {
public: public:
typedef OutConstIterator out_iterator; typedef OutConstIterator const_iter;
typedef typename std::iterator_traits<out_iterator>::value_type value_type; typedef typename std::iterator_traits<const_iter>::value_type value_type;
typedef ConstIterator_T<out_iterator> self_type; typedef ConstIterator_T<const_iter> self_type;
ConstIterator_T(out_iterator curr, VALUE seq = Qnil) protected:
: ConstIterator(seq), current(curr)
{
}
const out_iterator& get_current() const
{
return current;
}
bool equal (const ConstIterator &iter) const virtual bool equal (const ConstIterator &iter) const
{ {
const self_type *iters = dynamic_cast<const self_type *>(&iter); const self_type *iters = dynamic_cast<const self_type *>(&iter);
if (iters) { if (iters) {
@ -242,7 +308,24 @@ namespace swig {
throw std::invalid_argument("bad iterator type"); 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 virtual VALUE inspect() const
{ {
VALUE ret = rb_str_new2("#<"); VALUE ret = rb_str_new2("#<");
@ -264,33 +347,33 @@ namespace swig {
} }
protected: 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> template<typename InOutIterator>
class Iterator_T : public Iterator class Iterator_T : public Iterator
{ {
public: public:
typedef InOutIterator inout_iterator; typedef InOutIterator nonconst_iter;
typedef typename std::iterator_traits<inout_iterator>::value_type value_type;
typedef Iterator_T<inout_iterator> self_type;
Iterator_T(inout_iterator curr, VALUE seq = Qnil) // Make this class iterator STL compatible, by using iterator_traits
: Iterator(seq), current(curr) 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 typedef Iterator base;
{ typedef Iterator_T< nonconst_iter > self_type;
return current;
}
bool equal (const ConstIterator &iter) const protected:
virtual bool equal (const ConstIterator &iter) const
{ {
const self_type *iters = dynamic_cast<const self_type *>(&iter); const self_type *iters = dynamic_cast<const self_type *>(&iter);
if (iters) { if (iters) {
@ -309,6 +392,36 @@ namespace swig {
throw std::invalid_argument("bad iterator type"); 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 virtual VALUE inspect() const
{ {
@ -331,11 +444,15 @@ namespace swig {
} }
protected: 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> template <class ValueType>
struct asval_oper 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> template <class ValueType>
struct from_oper struct from_oper
{ {
@ -370,12 +492,12 @@ namespace swig {
{ {
public: public:
FromOper from; FromOper from;
typedef OutConstIterator out_iterator; typedef OutConstIterator const_iter;
typedef ValueType value_type; typedef ValueType value_type;
typedef ConstIterator_T<out_iterator> base; typedef ConstIterator_T<const_iter> base;
typedef ConstIteratorOpen_T<OutConstIterator, ValueType, FromOper> self_type; 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) : ConstIterator_T<OutConstIterator>(curr, seq)
{ {
} }
@ -388,22 +510,6 @@ namespace swig {
{ {
return new self_type(*this); 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: public:
FromOper from; FromOper from;
AsvalOper asval; AsvalOper asval;
typedef InOutIterator inout_iterator; typedef InOutIterator nonconst_iter;
typedef ValueType value_type; 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; 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) : Iterator_T<InOutIterator>(curr, seq)
{ {
} }
@ -433,32 +540,17 @@ namespace swig {
return from(static_cast<const value_type&>(*(base::current))); 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; value_type& dst = *base::current;
return asval(v, dst); if ( asval(v, dst) ) return v;
return Qnil;
} }
Iterator *dup() const Iterator *dup() const
{ {
return new self_type(*this); 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: public:
FromOper from; FromOper from;
typedef OutConstIterator out_iterator; typedef OutConstIterator const_iter;
typedef ValueType value_type; typedef ValueType value_type;
typedef ConstIterator_T<out_iterator> base; typedef ConstIterator_T<const_iter> base;
typedef ConstIteratorClosed_T<OutConstIterator, ValueType, FromOper> self_type; typedef ConstIteratorClosed_T<OutConstIterator, ValueType, FromOper> self_type;
ConstIteratorClosed_T(out_iterator curr, out_iterator first, protected:
out_iterator last, VALUE seq = Qnil) 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) : ConstIterator_T<OutConstIterator>(curr, seq), begin(first), end(last)
{ {
} }
@ -491,39 +593,15 @@ namespace swig {
} }
} }
ConstIterator *dup() const ConstIterator *dup() const
{ {
return new self_type(*this); 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: private:
out_iterator begin; const_iter begin;
out_iterator end; const_iter end;
}; };
/** /**
@ -539,13 +617,23 @@ namespace swig {
public: public:
FromOper from; FromOper from;
AsvalOper asval; AsvalOper asval;
typedef InOutIterator inout_iterator; typedef InOutIterator nonconst_iter;
typedef ValueType value_type; 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; typedef IteratorClosed_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
IteratorClosed_T(inout_iterator curr, inout_iterator first, protected:
inout_iterator last, VALUE seq = Qnil) 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) : Iterator_T<InOutIterator>(curr, seq), begin(first), end(last)
{ {
} }
@ -559,14 +647,14 @@ namespace swig {
} }
// Iterator setter method, required by Ruby // 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(); throw stop_iteration();
} else {
value_type& dst = *base::current; value_type& dst = *base::current;
return asval( v, dst ); if ( asval( v, dst ) ) return v;
} return Qnil;
} }
Iterator *dup() const Iterator *dup() const
@ -574,33 +662,9 @@ namespace swig {
return new self_type(*this); 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: private:
inout_iterator begin; nonconst_iter begin;
inout_iterator end; nonconst_iter end;
}; };
/* Partial specialization for bools which don't allow de-referencing */ /* Partial specialization for bools which don't allow de-referencing */
@ -611,12 +675,12 @@ namespace swig {
public: public:
FromOper from; FromOper from;
AsvalOper asval; AsvalOper asval;
typedef InOutIterator inout_iterator; typedef InOutIterator nonconst_iter;
typedef bool value_type; 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; 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) : Iterator_T<InOutIterator>(curr, seq)
{ {
} }
@ -625,31 +689,21 @@ namespace swig {
return from(static_cast<const value_type&>(*(base::current))); 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 Iterator *dup() const
{ {
return new self_type(*this); 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: public:
FromOper from; FromOper from;
AsvalOper asval; AsvalOper asval;
typedef InOutIterator inout_iterator; typedef InOutIterator nonconst_iter;
typedef bool value_type; 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; typedef IteratorClosed_T<InOutIterator, bool, FromOper, AsvalOper> self_type;
IteratorClosed_T(inout_iterator curr, inout_iterator first, protected:
inout_iterator last, VALUE seq = Qnil) 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) : 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 Iterator *dup() const
@ -690,34 +763,9 @@ namespace swig {
return new self_type(*this); 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: private:
inout_iterator begin; nonconst_iter begin;
inout_iterator end; nonconst_iter end;
}; };
@ -728,8 +776,8 @@ namespace swig {
*/ */
template<typename InOutIter> template<typename InOutIter>
inline Iterator* inline Iterator*
make_inout_iterator(const InOutIter& current, const InOutIter& begin, make_nonconst_iterator(const InOutIter& current, const InOutIter& begin,
const InOutIter& end, VALUE seq = Qnil) const InOutIter& end, VALUE seq = Qnil)
{ {
return new IteratorClosed_T<InOutIter>(current, begin, end, seq); return new IteratorClosed_T<InOutIter>(current, begin, end, seq);
} }
@ -741,7 +789,7 @@ namespace swig {
*/ */
template<typename InOutIter> template<typename InOutIter>
inline Iterator* 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); return new IteratorOpen_T<InOutIter>(current, seq);
} }
@ -753,7 +801,7 @@ namespace swig {
*/ */
template<typename OutIter> template<typename OutIter>
inline ConstIterator* 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) const OutIter& end, VALUE seq = Qnil)
{ {
return new ConstIteratorClosed_T<OutIter>(current, begin, end, seq); return new ConstIteratorClosed_T<OutIter>(current, begin, end, seq);
@ -766,7 +814,7 @@ namespace swig {
*/ */
template<typename OutIter> template<typename OutIter>
inline ConstIterator* 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); return new ConstIteratorOpen_T<OutIter>(current, seq);
} }
@ -826,28 +874,16 @@ namespace swig
virtual ~ConstIterator(); virtual ~ConstIterator();
// Access iterator method, required by Ruby // Access iterator method, required by Ruby
virtual VALUE value() const = 0; virtual VALUE value() const;
// 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;
// C++ common/needed methods // C++ common/needed methods
virtual ConstIterator *dup() const = 0; virtual ConstIterator *dup() const;
virtual VALUE inspect() const = 0; virtual VALUE inspect() const;
virtual VALUE to_s() const = 0; virtual VALUE to_s() const;
VALUE next(); virtual ConstIterator* next(size_t n = 1);
VALUE previous(); virtual ConstIterator* previous(size_t n = 1);
ConstIterator *advance(ptrdiff_t n);
bool operator == (const ConstIterator& x) const; bool operator == (const ConstIterator& x) const;
ConstIterator* operator + (ptrdiff_t n) const; ConstIterator* operator + (ptrdiff_t n) const;
@ -857,14 +893,16 @@ namespace swig
struct Iterator : public ConstIterator 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 Iterator *dup() const;
virtual ptrdiff_t distance(const Iterator &x) const;
virtual bool equal (const Iterator &x) const;
virtual Iterator *dup() const = 0; virtual Iterator* next(size_t n = 1);
Iterator *advance(ptrdiff_t n); virtual Iterator* previous(size_t n = 1);
virtual VALUE inspect() const;
virtual VALUE to_s() const;
bool operator == (const Iterator& x) const; bool operator == (const Iterator& x) const;
Iterator* operator + (ptrdiff_t n) const; Iterator* operator + (ptrdiff_t n) const;