11
11
************************************************/
12
12
13
13
#include "ruby.h"
14
+ #include "node.h"
14
15
15
16
VALUE rb_mEnumerable ;
16
17
static ID id_each , id_eqq , id_cmp ;
@@ -58,19 +59,14 @@ enum_grep(obj, pat)
58
59
return tmp ;
59
60
}
60
61
61
- struct find_arg {
62
- int found ;
63
- VALUE val ;
64
- };
65
-
66
62
static VALUE
67
- find_i (i , arg )
63
+ find_i (i , memo )
68
64
VALUE i ;
69
- struct find_arg * arg ;
65
+ NODE * memo ;
70
66
{
71
67
if (RTEST (rb_yield (i ))) {
72
- arg -> found = Qtrue ;
73
- arg -> val = i ;
68
+ memo -> u2 . value = Qtrue ;
69
+ memo -> u1 . value = i ;
74
70
rb_iter_break ();
75
71
}
76
72
return Qnil ;
@@ -82,18 +78,19 @@ enum_find(argc, argv, obj)
82
78
VALUE * argv ;
83
79
VALUE obj ;
84
80
{
85
- struct find_arg arg ;
81
+ NODE * memo = rb_node_newnode ( NODE_MEMO , Qnil , Qfalse , 0 ) ;
86
82
VALUE if_none ;
87
83
88
84
rb_scan_args (argc , argv , "01" , & if_none );
89
- arg . found = Qfalse ;
90
- rb_iterate ( rb_each , obj , find_i , ( VALUE ) & arg );
91
- if ( arg . found ) {
92
- return arg . val ;
85
+ rb_iterate ( rb_each , obj , find_i , ( VALUE ) memo ) ;
86
+ if ( memo -> u2 . value ) {
87
+ rb_gc_force_recycle (( VALUE ) memo );
88
+ return memo -> u1 . value ;
93
89
}
94
90
if (!NIL_P (if_none )) {
95
91
rb_eval_cmd (if_none , Qnil );
96
92
}
93
+ rb_gc_force_recycle ((VALUE )memo );
97
94
return Qnil ;
98
95
}
99
96
@@ -189,33 +186,35 @@ enum_sort(obj)
189
186
}
190
187
191
188
static VALUE
192
- min_i (i , min )
193
- VALUE i , * min ;
189
+ min_i (i , memo )
190
+ VALUE i ;
191
+ NODE * memo ;
194
192
{
195
193
VALUE cmp ;
196
194
197
- if (NIL_P (* min ))
198
- * min = i ;
195
+ if (NIL_P (memo -> u1 . value ))
196
+ memo -> u1 . value = i ;
199
197
else {
200
- cmp = rb_funcall (i , id_cmp , 1 , * min );
198
+ cmp = rb_funcall (i , id_cmp , 1 , memo -> u1 . value );
201
199
if (NUM2LONG (cmp ) < 0 )
202
- * min = i ;
200
+ memo -> u1 . value = i ;
203
201
}
204
202
return Qnil ;
205
203
}
206
204
207
205
static VALUE
208
- min_ii (i , min )
209
- VALUE i , * min ;
206
+ min_ii (i , memo )
207
+ VALUE i ;
208
+ NODE * memo ;
210
209
{
211
210
VALUE cmp ;
212
211
213
- if (NIL_P (* min ))
214
- * min = i ;
212
+ if (NIL_P (memo -> u1 . value ))
213
+ memo -> u1 . value = i ;
215
214
else {
216
- cmp = rb_yield (rb_assoc_new (i , * min ));
215
+ cmp = rb_yield (rb_assoc_new (i , memo -> u1 . value ));
217
216
if (NUM2LONG (cmp ) < 0 )
218
- * min = i ;
217
+ memo -> u1 . value = i ;
219
218
}
220
219
return Qnil ;
221
220
}
@@ -224,40 +223,43 @@ static VALUE
224
223
enum_min (obj )
225
224
VALUE obj ;
226
225
{
227
- VALUE min = Qnil ;
226
+ NODE * memo = rb_node_newnode ( NODE_MEMO , Qnil , 0 , 0 ) ;
228
227
229
- rb_iterate (rb_each , obj , rb_iterator_p ()?min_ii :min_i , (VALUE )& min );
230
- return min ;
228
+ rb_iterate (rb_each , obj , rb_iterator_p ()?min_ii :min_i , (VALUE )memo );
229
+ rb_gc_force_recycle ((VALUE )memo );
230
+ return memo -> u1 .value ;
231
231
}
232
232
233
233
static VALUE
234
- max_i (i , max )
235
- VALUE i , * max ;
234
+ max_i (i , memo )
235
+ VALUE i ;
236
+ NODE * memo ;
236
237
{
237
238
VALUE cmp ;
238
239
239
- if (NIL_P (* max ))
240
- * max = i ;
240
+ if (NIL_P (memo -> u1 . value ))
241
+ memo -> u1 . value = i ;
241
242
else {
242
- cmp = rb_funcall (i , id_cmp , 1 , * max );
243
+ cmp = rb_funcall (i , id_cmp , 1 , memo -> u1 . value );
243
244
if (NUM2LONG (cmp ) > 0 )
244
- * max = i ;
245
+ memo -> u1 . value = i ;
245
246
}
246
247
return Qnil ;
247
248
}
248
249
249
250
static VALUE
250
- max_ii (i , max )
251
- VALUE i , * max ;
251
+ max_ii (i , memo )
252
+ VALUE i ;
253
+ NODE * memo ;
252
254
{
253
255
VALUE cmp ;
254
256
255
- if (NIL_P (* max ))
256
- * max = i ;
257
+ if (NIL_P (memo -> u1 . value ))
258
+ memo -> u1 . value = i ;
257
259
else {
258
- cmp = rb_yield (rb_assoc_new (i , * max ));
260
+ cmp = rb_yield (rb_assoc_new (i , memo -> u1 . value ));
259
261
if (NUM2LONG (cmp ) > 0 )
260
- * max = i ;
262
+ memo -> u1 . value = i ;
261
263
}
262
264
return Qnil ;
263
265
}
@@ -266,54 +268,20 @@ static VALUE
266
268
enum_max (obj )
267
269
VALUE obj ;
268
270
{
269
- VALUE max = Qnil ;
270
-
271
- rb_iterate (rb_each , obj , rb_iterator_p ()?max_ii :max_i , (VALUE )& max );
272
- return max ;
273
- }
274
-
275
- struct i_v_pair {
276
- int i ;
277
- VALUE v ;
278
- int found ;
279
- };
280
-
281
- static VALUE
282
- index_i (item , iv )
283
- VALUE item ;
284
- struct i_v_pair * iv ;
285
- {
286
- if (rb_equal (item , iv -> v )) {
287
- iv -> found = 1 ;
288
- rb_iter_break ();
289
- }
290
- else {
291
- iv -> i ++ ;
292
- }
293
- return Qnil ;
294
- }
271
+ NODE * memo = rb_node_newnode (NODE_MEMO , Qnil , 0 , 0 );
295
272
296
- static VALUE
297
- enum_index (obj , val )
298
- VALUE obj , val ;
299
- {
300
- struct i_v_pair iv ;
301
-
302
- iv .i = 0 ;
303
- iv .v = val ;
304
- iv .found = 0 ;
305
- rb_iterate (rb_each , obj , index_i , (VALUE )& iv );
306
- if (iv .found ) return INT2FIX (iv .i );
307
- return Qnil ; /* not found */
273
+ rb_iterate (rb_each , obj , rb_iterator_p ()?max_ii :max_i , (VALUE )memo );
274
+ rb_gc_force_recycle ((VALUE )memo );
275
+ return memo -> u1 .value ;
308
276
}
309
277
310
278
static VALUE
311
- member_i (item , iv )
279
+ member_i (item , memo )
312
280
VALUE item ;
313
- struct i_v_pair * iv ;
281
+ NODE * memo ;
314
282
{
315
- if (rb_equal (item , iv -> v )) {
316
- iv -> i = 1 ;
283
+ if (rb_equal (item , memo -> u1 . value )) {
284
+ memo -> u2 . value = Qtrue ;
317
285
rb_iter_break ();
318
286
}
319
287
return Qnil ;
@@ -323,36 +291,34 @@ static VALUE
323
291
enum_member (obj , val )
324
292
VALUE obj , val ;
325
293
{
326
- struct i_v_pair iv ;
294
+ VALUE result ;
295
+
296
+ NODE * memo = rb_node_newnode (NODE_MEMO , val , Qfalse , 0 );
327
297
328
- iv .i = 0 ;
329
- iv .v = val ;
330
- rb_iterate (rb_each , obj , member_i , (VALUE )& iv );
331
- if (iv .i ) return Qtrue ;
332
- return Qfalse ;
298
+ rb_iterate (rb_each , obj , member_i , (VALUE )memo );
299
+ result = memo -> u2 .value ;
300
+ rb_gc_force_recycle ((VALUE )memo );
301
+ return result ;
333
302
}
334
303
335
304
static VALUE
336
- each_with_index_i (val , indexp )
305
+ each_with_index_i (val , memo )
337
306
VALUE val ;
338
- int * indexp ;
307
+ NODE * memo ;
339
308
{
340
- #if 1
341
- rb_yield (rb_assoc_new (val , INT2FIX (* indexp )));
342
- #else
343
- rb_yield (rb_ary_concat (rb_Array (val ), INT2FIX (* indexp )));
344
- #endif
345
- (* indexp )++ ;
309
+ rb_yield (rb_assoc_new (val , INT2FIX (memo -> u3 .cnt )));
310
+ memo -> u3 .cnt ++ ;
346
311
return Qnil ;
347
312
}
348
313
349
314
static VALUE
350
315
enum_each_with_index (obj )
351
316
VALUE obj ;
352
317
{
353
- int index = 0 ;
318
+ NODE * memo = rb_node_newnode ( NODE_MEMO , 0 , 0 , 0 ) ;
354
319
355
- rb_iterate (rb_each , obj , each_with_index_i , (VALUE )& index );
320
+ rb_iterate (rb_each , obj , each_with_index_i , (VALUE )memo );
321
+ rb_gc_force_recycle ((VALUE )memo );
356
322
return Qnil ;
357
323
}
358
324
@@ -374,7 +340,6 @@ Init_Enumerable()
374
340
rb_define_method (rb_mEnumerable ,"collect" , enum_collect , 0 );
375
341
rb_define_method (rb_mEnumerable ,"min" , enum_min , 0 );
376
342
rb_define_method (rb_mEnumerable ,"max" , enum_max , 0 );
377
- rb_define_method (rb_mEnumerable ,"index" , enum_index , 1 );
378
343
rb_define_method (rb_mEnumerable ,"member?" , enum_member , 1 );
379
344
rb_define_method (rb_mEnumerable ,"include?" , enum_member , 1 );
380
345
rb_define_method (rb_mEnumerable ,"each_with_index" , enum_each_with_index , 0 );
0 commit comments