diff --git a/CHANGES.current b/CHANGES.current index 6547a88be..bbf97a67f 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.10 (in progress) ============================ +2013-03-29: wsfulton + [Ruby] Fix delete_if (reject!) for the STL container wrappers which previously would + sometimes seg fault or not work. + 2013-03-19: wsfulton [C#, Java, D] Fix seg fault in SWIG using directors when class and virtual method names are the same except being in different namespaces when the %nspace feature is not being used. diff --git a/Examples/test-suite/ruby/li_std_set_runme.rb b/Examples/test-suite/ruby/li_std_set_runme.rb index 65354be58..a85418471 100755 --- a/Examples/test-suite/ruby/li_std_set_runme.rb +++ b/Examples/test-suite/ruby/li_std_set_runme.rb @@ -61,3 +61,7 @@ s.to_a == [1,[1,2],'hello'] # sort order: s.sort {|a,b| a.hash <=> b.hash} EOF +iv = Set_int.new([0,1,2,3,4,5,6]) +iv.delete_if { |x| x == 0 || x == 3 || x == 6 } +swig_assert_equal(iv.to_s, '1245', binding) + diff --git a/Examples/test-suite/ruby/li_std_vector_runme.rb b/Examples/test-suite/ruby/li_std_vector_runme.rb index 8bcad2d19..fe3d9e0ce 100755 --- a/Examples/test-suite/ruby/li_std_vector_runme.rb +++ b/Examples/test-suite/ruby/li_std_vector_runme.rb @@ -64,6 +64,11 @@ y = average([1, 2, 3, 4]) half([10, 10.5, 11, 11.5]) EOF +iv = IntVector.new([0,1,2,3,4,5,6]) +iv.delete_if { |x| x == 0 || x == 3 || x == 6 } +swig_assert_equal(iv.to_s, '1245', binding) + + dv = DoubleVector.new(10) swig_assert( "dv.respond_to? :each_with_index", binding ) diff --git a/Lib/ruby/rubycontainer.swg b/Lib/ruby/rubycontainer.swg index d8d15f690..d4eaa5f73 100644 --- a/Lib/ruby/rubycontainer.swg +++ b/Lib/ruby/rubycontainer.swg @@ -677,27 +677,6 @@ namespace swig return r; } - %alias reject_bang "delete_if"; - Sequence* reject_bang() { - if ( !rb_block_given_p() ) - rb_raise( rb_eArgError, "no block given" ); - - Sequence::iterator i = self->begin(); - Sequence::iterator e = self->end(); - for ( ; i != e; ) - { - VALUE r = swig::from< Sequence::value_type >(*i); - if ( RTEST( rb_yield(r) ) ) { - $self->erase(i++); - e = self->end(); - } else { - ++i; - } - } - - return self; - } - VALUE delete_at(difference_type i) { VALUE r = Qnil; try { @@ -757,6 +736,19 @@ namespace swig } %enddef +%define %swig_sequence_methods_extra(Sequence...) + %extend { + %alias reject_bang "delete_if"; + Sequence* reject_bang() { + if ( !rb_block_given_p() ) + rb_raise( rb_eArgError, "no block given" ); + + $self->erase( std::remove_if( $self->begin(), $self->end(), + swig::yield< Sequence::value_type >() ), $self->end() ); + return $self; + } + } +%enddef /** * Macro used to add functions for Sequences @@ -764,6 +756,7 @@ namespace swig */ %define %swig_sequence_methods(Sequence...) %swig_sequence_methods_common(%arg(Sequence)); + %swig_sequence_methods_extra(%arg(Sequence)); %swig_sequence_back_inserters(%arg(Sequence)); %extend { diff --git a/Lib/ruby/std_set.i b/Lib/ruby/std_set.i index 00596b4a6..e38702ef5 100644 --- a/Lib/ruby/std_set.i +++ b/Lib/ruby/std_set.i @@ -152,10 +152,29 @@ } %} +%define %swig_sequence_methods_extra_set(Sequence...) + %extend { + %alias reject_bang "delete_if"; + Sequence* reject_bang() { + if ( !rb_block_given_p() ) + rb_raise( rb_eArgError, "no block given" ); + + for ( Sequence::iterator i = $self->begin(); i != $self->end(); ) { + VALUE r = swig::from< Sequence::value_type >(*i); + Sequence::iterator current = i++; + if ( RTEST( rb_yield(r) ) ) + $self->erase(current); + } + + return self; + } + } +%enddef %define %swig_set_methods(set...) %swig_sequence_methods_common(%arg(set)); + %swig_sequence_methods_extra_set(%arg(set)); %fragment("RubyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool),fragment="RubySequence_Cont") {}