diff --git a/Lib/ruby/rubyautodoc.swg b/Lib/ruby/rubyautodoc.swg index bf44f5658..ade4bde1d 100644 --- a/Lib/ruby/rubyautodoc.swg +++ b/Lib/ruby/rubyautodoc.swg @@ -59,7 +59,7 @@ AUTODOC(reject, "Iterate thru each element in the $class and reject those that f AUTODOC(reject_bang, "Iterate thru each element in the $class and reject those that fail a condition. A block must be provided. $class is modified in place"); AUTODOC(select, "Iterate thru each element in the $class and select those that match a condition. A block must be provided"); AUTODOC(delete_at, "Delete an element at a certain index"); -AUTODOC(__delete__, "Delete an element at a certain index"); +AUTODOC(__delete__, "Delete a matching element"); // diff --git a/Lib/ruby/rubyclasses.swg b/Lib/ruby/rubyclasses.swg index 17d58d2d2..6cf7c9fb5 100644 --- a/Lib/ruby/rubyclasses.swg +++ b/Lib/ruby/rubyclasses.swg @@ -1,7 +1,7 @@ #ifdef __cplusplus /* - GC_VALUE is used as a replacement of VALUE. + GC_VALUE is used as a replacement of Ruby's VALUE. GC_VALUE automatically handles registering and unregistering of the underlying ruby object with the GC. @@ -17,7 +17,8 @@ } }; - or as a input/output value (not much use for this, thou): + or as a input/output value (not much use for this, as VALUE works as + well here, thou): GC_VALUE func(GC_VALUE obj) { GC_VALUE out = rb_obj_classname(obj); @@ -34,11 +35,19 @@ */ namespace swig { - // we don't ignore it, so it will get printed nicely with inspect - //%ignore GC_VALUE; + + %nodirector GC_VALUE; + + // We ignore the constructor so that user can never create a GC_VALUE manually + %ignore GC_VALUE::GC_VALUE; + struct GC_VALUE { VALUE inspect() const; VALUE to_s() const; + GC_VALUE(); + protected: + GC_VALUE( const GC_VALUE& ); + ~GC_VALUE(); }; %exception GC_VALUE {}; @@ -132,6 +141,12 @@ namespace swig { } +/** + * std::less< GC_VALUE > functor so that STL containers will accept + * GC_VALUE. + * + */ + namespace std { template <> struct less< swig::GC_VALUE >: public binary_function< swig::GC_VALUE, diff --git a/Lib/ruby/rubycontainer.swg b/Lib/ruby/rubycontainer.swg index 61b10c8fb..9f5b95ad8 100644 --- a/Lib/ruby/rubycontainer.swg +++ b/Lib/ruby/rubycontainer.swg @@ -579,23 +579,6 @@ namespace swig %extend { - // Implementing delete requires semantics that go beyond the - // default requirements of STD containers. - // - // VALUE __delete__( Sequence::value_type e ) { - // VALUE r = Qnil; - // std::size_t len = $self->size(); - // std::remove_if( $self->begin(), $self->end(), - // std::bind2nd( std::equal_to< Sequence::value_type >(), - // e ) ); - // - // if ( $self->size() != len ) - // r = swig::from< Sequence::value_type >( e ); - // else if ( rb_block_given_p() ) - // r = rb_yield(Qnil); - // return r; - // } - VALUE slice( difference_type i, difference_type j ) { if ( j <= 0 ) return Qnil; @@ -681,6 +664,12 @@ namespace swig return r; } + + VALUE __delete2__(const value_type& i) { + VALUE r = Qnil; + return r; + } + } %enddef @@ -1033,3 +1022,6 @@ namespace swig { }; } } + + +%include diff --git a/Lib/ruby/rubycontainer_extended.swg b/Lib/ruby/rubycontainer_extended.swg new file mode 100644 index 000000000..e868bcb0c --- /dev/null +++ b/Lib/ruby/rubycontainer_extended.swg @@ -0,0 +1,140 @@ +/** + * @file rubycontainer_extended.swg + * @author gga + * @date Sat May 5 05:36:01 2007 + * + * @brief This file contains additional functions that make containers + * behave closer to ruby primitive types. + * However, some of these functions place some restrictions on + * the underlying object inside of the container (that it has + * an == comparison function, that it has an = assignment + * operator, etc). + * + */ + + +/** + * Macro used to add extend functions that require operator== in object. + * + * @param Container STL container + * @param Type class inside container + * + */ +%define %swig_container_with_equal_operator( Container, Type ) + + VALUE __delete__( const Type& val ) { + VALUE r = Qnil; + Container::iterator e = $self->end(); + Container::iterator i = std::remove( $self->begin(), e, val ); + // remove dangling elements now + $self->erase( i, e ); + + if ( i != e ) + r = swig::from< Type >( val ); + else if ( rb_block_given_p() ) + r = rb_yield(Qnil); + return r; + } + +%enddef // end of %swig_container_with_equal_operator + + + + +/** + * Macro used to add extend functions that require the assignment + * operator (ie. = ) of contained class + * + * @param Container STL container + * @param Type class inside container + * + */ + +%define %swig_container_with_assignment( Container, Type ) + + + // + // map! + // + Container< Type >* map_bang() { + + if ( !rb_block_given_p() ) + rb_raise( rb_eArgError, "No block given" ); + + VALUE r = Qnil; + Container< Type >::iterator i = $self->begin(); + Container< Type >::iterator e = $self->end(); + + try { + for ( ; i != e; ++i ) + { + r = swig::from< Type >( *i ); + r = rb_yield( r ); + *i = swig::as< Type >( r ); + } + } + catch ( const std::invalid_argument& ) + { + rb_raise(rb_eTypeError, + "Yield block did not return a valid element for " #Container); + } + + return $self; + } + + +%enddef // end of %swig_container_with_assignment + + + + + +/** + * Macro used to add all extended functions to a container + * + * @param Container STL container + * @param Type class inside container + * + */ +%define %swig_container_extend( Container, Type ) + +%extend Container< Type > { + + %swig_container_with_assignment( %arg(Container), Type ); + %swig_container_with_equal_operator( %arg(Container), Type ); + +} + +%enddef + + +/** + * Private macro used to add all extended functions to C/C++ + * primitive types + * + * @param Container an STL container, like std::vector (with no class template) + * + */ +%define %__swig_container_extend_primtypes( Container ) + +%swig_container_extend( %arg( Container ), bool ); +%swig_container_extend( %arg( Container ), char ); +%swig_container_extend( %arg( Container ), short ); +%swig_container_extend( %arg( Container ), int ); +%swig_container_extend( %arg( Container ), unsigned short ); +%swig_container_extend( %arg( Container ), unsigned int ); +%swig_container_extend( %arg( Container ), float ); +%swig_container_extend( %arg( Container ), double ); +%swig_container_extend( %arg( Container ), std::complex ); +%swig_container_extend( %arg( Container ), std::string ); +%swig_container_extend( %arg( Container ), swig::GC_VALUE ); +%swig_container_extend( %arg( Container ), swig::GC_VALUE ); + +%enddef + + +%__swig_container_extend_primtypes( std::vector ); +%__swig_container_extend_primtypes( std::set ); +%__swig_container_extend_primtypes( std::list ); +%__swig_container_extend_primtypes( std::deque ); + diff --git a/Lib/ruby/rubyerrors.swg b/Lib/ruby/rubyerrors.swg index d0a47e3ce..604ed9826 100644 --- a/Lib/ruby/rubyerrors.swg +++ b/Lib/ruby/rubyerrors.swg @@ -130,7 +130,7 @@ const char* Ruby_Format_TypeError( const char* msg, { str = rb_str_cat2( str, "\n\tin SWIG method '" ); str = rb_str_cat2( str, name ); - str = rb_str_cat2( str, "'\n" ); + str = rb_str_cat2( str, "'" ); } return StringValuePtr( str ); diff --git a/Lib/ruby/rubyiterators.swg b/Lib/ruby/rubyiterators.swg index 1743d1519..78ddd3959 100644 --- a/Lib/ruby/rubyiterators.swg +++ b/Lib/ruby/rubyiterators.swg @@ -4,7 +4,7 @@ * * rubyiterators.swg * - * Implement a ruby 'output' iterator for Ruby. + * Implement a C++ 'output' iterator for Ruby. * * Users can derive form the RubySwigIterator to implemet their * own iterators. As an example (real one since we use it for STL/STD @@ -14,6 +14,10 @@ %include + +/** + * Abstract base class used to represent all iterators of STL containers. + */ %fragment("RubySwigIterator","header") { namespace swig { struct stop_iteration { @@ -34,9 +38,6 @@ namespace swig { // Access iterator method, required by Ruby virtual VALUE value() const = 0; -// // Set referenced object -// virtual bool set(VALUE v) = 0; - // Forward iterator method, required by Ruby virtual RubySwigIterator *incr(size_t n = 1) = 0; @@ -60,6 +61,11 @@ namespace swig { // C++ common/needed methods virtual RubySwigIterator *copy() const = 0; + virtual VALUE __deref__() + { + return Qnil; + } + VALUE next() { VALUE obj = value(); @@ -126,8 +132,14 @@ namespace swig { } } + %fragment("RubySwigIterator_T","header",fragment="RubySwigIterator",fragment="StdTraits",fragment="StdIteratorTraits") { namespace swig { + + /** + * Abstract base classes for all custom iterators. + * + */ template class RubySwigIterator_T : public RubySwigIterator { @@ -182,6 +194,11 @@ namespace swig { } }; + + /** + * Iterator class for a const_iterator with no end() boundaries. + * + */ template::value_type, typename FromOper = from_oper > @@ -202,14 +219,6 @@ namespace swig { virtual VALUE value() const { return from(static_cast(*(base::current))); } - -// virtual bool set(VALUE v) { -// value_type val; -// if ( !asval(v, &val) ) return SWIG_ERROR; -// *(base::current) = val; -// return SWIG_OK; -// } - RubySwigIterator *copy() const { @@ -233,6 +242,11 @@ namespace swig { } }; + + /** + * Iterator class for a const_iterator where begin() and end() boundaries are known. + * + */ template::value_type, typename FromOper = from_oper > @@ -258,13 +272,6 @@ namespace swig { } } -// virtual bool set(VALUE v) { -// value_type val; -// if ( !asval(v, &val) ) return SWIG_ERROR; -// *(base::current) = val; -// return SWIG_OK; -// } - RubySwigIterator *copy() const { return new self_type(*this); @@ -299,6 +306,12 @@ namespace swig { out_iterator end; }; + + /** + * Helper function used to wrap a bounded const_iterator. This is to be used in + * a %typemap(out), for example. + * + */ template inline RubySwigIterator* make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, VALUE seq = Qnil) @@ -306,6 +319,11 @@ namespace swig { return new RubySwigIteratorClosed_T(current, begin, end, seq); } + /** + * Helper function used to wrap an unbounded const_iterator. This is to be used in + * a %typemap(out), for example. + * + */ template inline RubySwigIterator* make_output_iterator(const OutIter& current, VALUE seq = Qnil) @@ -317,6 +335,11 @@ namespace swig { %fragment("RubySwigIterator"); + + +// +// This part is just so SWIG is aware of the base abstract iterator class. +// namespace swig { /* @@ -365,9 +388,6 @@ namespace swig // Access iterator method, required by Ruby virtual VALUE value() const = 0; -// // Set referenced object, required by Ruby -// virtual bool set(VALUE val) = 0; - // Forward iterator method, required by Ruby virtual RubySwigIterator *incr(size_t n = 1) = 0;