@@ -2563,6 +2563,48 @@ rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
2563
2563
return rb_ary_delete_at (ary , NUM2LONG (arg1 ));
2564
2564
}
2565
2565
2566
+ static VALUE
2567
+ ary_reject (VALUE orig , VALUE result )
2568
+ {
2569
+ long i ;
2570
+ int rejected = 0 ;
2571
+
2572
+ for (i = 0 ; i < RARRAY_LEN (orig ); i ++ ) {
2573
+ VALUE v = RARRAY_PTR (orig )[i ];
2574
+ if (!RTEST (rb_yield (v ))) {
2575
+ rb_ary_push_1 (result , v );
2576
+ }
2577
+ else {
2578
+ rejected = 1 ;
2579
+ }
2580
+ }
2581
+ return rejected ? result : 0 ;
2582
+ }
2583
+
2584
+ static VALUE
2585
+ ary_protecting_reject (VALUE arg )
2586
+ {
2587
+ VALUE * args = (VALUE * )arg ;
2588
+ return ary_reject (args [0 ], args [1 ]);
2589
+ }
2590
+
2591
+ static VALUE
2592
+ ary_reject_bang (VALUE ary )
2593
+ {
2594
+ VALUE args [2 ];
2595
+ int state = 0 ;
2596
+
2597
+ rb_ary_modify_check (ary );
2598
+ args [0 ] = ary ;
2599
+ args [1 ] = rb_ary_new ();
2600
+ if (!rb_protect (ary_protecting_reject , (VALUE )args , & state )) {
2601
+ return Qnil ;
2602
+ }
2603
+ rb_ary_replace (ary , args [1 ]);
2604
+ if (state ) rb_jump_tag (state );
2605
+ return ary ;
2606
+ }
2607
+
2566
2608
/*
2567
2609
* call-seq:
2568
2610
* ary.reject! {|item| block } -> ary or nil
@@ -2580,23 +2622,8 @@ rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
2580
2622
static VALUE
2581
2623
rb_ary_reject_bang (VALUE ary )
2582
2624
{
2583
- long i1 , i2 ;
2584
-
2585
2625
RETURN_ENUMERATOR (ary , 0 , 0 );
2586
- rb_ary_modify (ary );
2587
- for (i1 = i2 = 0 ; i1 < RARRAY_LEN (ary ); i1 ++ ) {
2588
- VALUE v = RARRAY_PTR (ary )[i1 ];
2589
- if (RTEST (rb_yield (v ))) continue ;
2590
- if (i1 != i2 ) {
2591
- rb_ary_store (ary , i2 , v );
2592
- }
2593
- i2 ++ ;
2594
- }
2595
-
2596
- if (RARRAY_LEN (ary ) == i2 ) return Qnil ;
2597
- if (i2 < RARRAY_LEN (ary ))
2598
- ARY_SET_LEN (ary , i2 );
2599
- return ary ;
2626
+ return ary_reject_bang (ary );
2600
2627
}
2601
2628
2602
2629
/*
@@ -2615,10 +2642,12 @@ rb_ary_reject_bang(VALUE ary)
2615
2642
static VALUE
2616
2643
rb_ary_reject (VALUE ary )
2617
2644
{
2645
+ VALUE rejected_ary ;
2646
+
2618
2647
RETURN_ENUMERATOR (ary , 0 , 0 );
2619
- ary = rb_ary_dup ( ary );
2620
- rb_ary_reject_bang (ary );
2621
- return ary ;
2648
+ rejected_ary = rb_ary_new ( );
2649
+ ary_reject (ary , rejected_ary );
2650
+ return rejected_ary ;
2622
2651
}
2623
2652
2624
2653
/*
@@ -2640,7 +2669,7 @@ static VALUE
2640
2669
rb_ary_delete_if (VALUE ary )
2641
2670
{
2642
2671
RETURN_ENUMERATOR (ary , 0 , 0 );
2643
- rb_ary_reject_bang (ary );
2672
+ ary_reject_bang (ary );
2644
2673
return ary ;
2645
2674
}
2646
2675
0 commit comments