Ruby  2.5.0dev(2017-10-22revision60238)
enumerator.c
Go to the documentation of this file.
1 /************************************************
2 
3  enumerator.c - provides Enumerator class
4 
5  $Author$
6 
7  Copyright (C) 2001-2003 Akinori MUSHA
8 
9  $Idaemons: /home/cvs/rb/enumerator/enumerator.c,v 1.1.1.1 2001/07/15 10:12:48 knu Exp $
10  $RoughId: enumerator.c,v 1.6 2003/07/27 11:03:24 nobu Exp $
11  $Id$
12 
13 ************************************************/
14 
15 #include "internal.h"
16 
17 /*
18  * Document-class: Enumerator
19  *
20  * A class which allows both internal and external iteration.
21  *
22  * An Enumerator can be created by the following methods.
23  * - Kernel#to_enum
24  * - Kernel#enum_for
25  * - Enumerator.new
26  *
27  * Most methods have two forms: a block form where the contents
28  * are evaluated for each item in the enumeration, and a non-block form
29  * which returns a new Enumerator wrapping the iteration.
30  *
31  * enumerator = %w(one two three).each
32  * puts enumerator.class # => Enumerator
33  *
34  * enumerator.each_with_object("foo") do |item, obj|
35  * puts "#{obj}: #{item}"
36  * end
37  *
38  * # foo: one
39  * # foo: two
40  * # foo: three
41  *
42  * enum_with_obj = enumerator.each_with_object("foo")
43  * puts enum_with_obj.class # => Enumerator
44  *
45  * enum_with_obj.each do |item, obj|
46  * puts "#{obj}: #{item}"
47  * end
48  *
49  * # foo: one
50  * # foo: two
51  * # foo: three
52  *
53  * This allows you to chain Enumerators together. For example, you
54  * can map a list's elements to strings containing the index
55  * and the element as a string via:
56  *
57  * puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" }
58  * # => ["0:foo", "1:bar", "2:baz"]
59  *
60  * An Enumerator can also be used as an external iterator.
61  * For example, Enumerator#next returns the next value of the iterator
62  * or raises StopIteration if the Enumerator is at the end.
63  *
64  * e = [1,2,3].each # returns an enumerator object.
65  * puts e.next # => 1
66  * puts e.next # => 2
67  * puts e.next # => 3
68  * puts e.next # raises StopIteration
69  *
70  * You can use this to implement an internal iterator as follows:
71  *
72  * def ext_each(e)
73  * while true
74  * begin
75  * vs = e.next_values
76  * rescue StopIteration
77  * return $!.result
78  * end
79  * y = yield(*vs)
80  * e.feed y
81  * end
82  * end
83  *
84  * o = Object.new
85  *
86  * def o.each
87  * puts yield
88  * puts yield(1)
89  * puts yield(1, 2)
90  * 3
91  * end
92  *
93  * # use o.each as an internal iterator directly.
94  * puts o.each {|*x| puts x; [:b, *x] }
95  * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
96  *
97  * # convert o.each to an external iterator for
98  * # implementing an internal iterator.
99  * puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] }
100  * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
101  *
102  */
105 static ID id_rewind, id_each, id_new, id_initialize, id_yield, id_call, id_size, id_to_enum;
106 static ID id_eqq, id_next, id_result, id_lazy, id_receiver, id_arguments, id_memo, id_method, id_force;
107 static VALUE sym_each, sym_cycle;
108 
110 
111 struct enumerator {
123 };
124 
125 static VALUE rb_cGenerator, rb_cYielder;
126 
127 struct generator {
130 };
131 
132 struct yielder {
134 };
135 
136 typedef struct MEMO *lazyenum_proc_func(VALUE, struct MEMO *, VALUE, long);
138 typedef struct {
142 
143 struct proc_entry {
147 };
148 
149 static VALUE generator_allocate(VALUE klass);
150 static VALUE generator_init(VALUE obj, VALUE proc);
151 
152 /*
153  * Enumerator
154  */
155 static void
156 enumerator_mark(void *p)
157 {
158  struct enumerator *ptr = p;
159  rb_gc_mark(ptr->obj);
160  rb_gc_mark(ptr->args);
161  rb_gc_mark(ptr->fib);
162  rb_gc_mark(ptr->dst);
163  rb_gc_mark(ptr->lookahead);
164  rb_gc_mark(ptr->feedvalue);
165  rb_gc_mark(ptr->stop_exc);
166  rb_gc_mark(ptr->size);
167  rb_gc_mark(ptr->procs);
168 }
169 
170 #define enumerator_free RUBY_TYPED_DEFAULT_FREE
171 
172 static size_t
173 enumerator_memsize(const void *p)
174 {
175  return sizeof(struct enumerator);
176 }
177 
178 static const rb_data_type_t enumerator_data_type = {
179  "enumerator",
180  {
181  enumerator_mark,
183  enumerator_memsize,
184  },
186 };
187 
188 static struct enumerator *
189 enumerator_ptr(VALUE obj)
190 {
191  struct enumerator *ptr;
192 
193  TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, ptr);
194  if (!ptr || ptr->obj == Qundef) {
195  rb_raise(rb_eArgError, "uninitialized enumerator");
196  }
197  return ptr;
198 }
199 
200 static void
201 proc_entry_mark(void *p)
202 {
203  struct proc_entry *ptr = p;
204  rb_gc_mark(ptr->proc);
205  rb_gc_mark(ptr->memo);
206 }
207 
208 #define proc_entry_free RUBY_TYPED_DEFAULT_FREE
209 
210 static size_t
211 proc_entry_memsize(const void *p)
212 {
213  return p ? sizeof(struct proc_entry) : 0;
214 }
215 
216 static const rb_data_type_t proc_entry_data_type = {
217  "proc_entry",
218  {
219  proc_entry_mark,
221  proc_entry_memsize,
222  },
223 };
224 
225 static struct proc_entry *
226 proc_entry_ptr(VALUE proc_entry)
227 {
228  struct proc_entry *ptr;
229 
230  TypedData_Get_Struct(proc_entry, struct proc_entry, &proc_entry_data_type, ptr);
231 
232  return ptr;
233 }
234 
235 /*
236  * call-seq:
237  * obj.to_enum(method = :each, *args) -> enum
238  * obj.enum_for(method = :each, *args) -> enum
239  * obj.to_enum(method = :each, *args) {|*args| block} -> enum
240  * obj.enum_for(method = :each, *args){|*args| block} -> enum
241  *
242  * Creates a new Enumerator which will enumerate by calling +method+ on
243  * +obj+, passing +args+ if any.
244  *
245  * If a block is given, it will be used to calculate the size of
246  * the enumerator without the need to iterate it (see Enumerator#size).
247  *
248  * === Examples
249  *
250  * str = "xyz"
251  *
252  * enum = str.enum_for(:each_byte)
253  * enum.each { |b| puts b }
254  * # => 120
255  * # => 121
256  * # => 122
257  *
258  * # protect an array from being modified by some_method
259  * a = [1, 2, 3]
260  * some_method(a.to_enum)
261  *
262  * It is typical to call to_enum when defining methods for
263  * a generic Enumerable, in case no block is passed.
264  *
265  * Here is such an example, with parameter passing and a sizing block:
266  *
267  * module Enumerable
268  * # a generic method to repeat the values of any enumerable
269  * def repeat(n)
270  * raise ArgumentError, "#{n} is negative!" if n < 0
271  * unless block_given?
272  * return to_enum(__method__, n) do # __method__ is :repeat here
273  * sz = size # Call size and multiply by n...
274  * sz * n if sz # but return nil if size itself is nil
275  * end
276  * end
277  * each do |*val|
278  * n.times { yield *val }
279  * end
280  * end
281  * end
282  *
283  * %i[hello world].repeat(2) { |w| puts w }
284  * # => Prints 'hello', 'hello', 'world', 'world'
285  * enum = (1..14).repeat(3)
286  * # => returns an Enumerator when called without a block
287  * enum.first(4) # => [1, 1, 1, 2]
288  * enum.size # => 42
289  */
290 static VALUE
291 obj_to_enum(int argc, VALUE *argv, VALUE obj)
292 {
293  VALUE enumerator, meth = sym_each;
294 
295  if (argc > 0) {
296  --argc;
297  meth = *argv++;
298  }
299  enumerator = rb_enumeratorize_with_size(obj, meth, argc, argv, 0);
300  if (rb_block_given_p()) {
301  enumerator_ptr(enumerator)->size = rb_block_proc();
302  }
303  return enumerator;
304 }
305 
306 static VALUE
307 enumerator_allocate(VALUE klass)
308 {
309  struct enumerator *ptr;
310  VALUE enum_obj;
311 
312  enum_obj = TypedData_Make_Struct(klass, struct enumerator, &enumerator_data_type, ptr);
313  ptr->obj = Qundef;
314 
315  return enum_obj;
316 }
317 
318 static VALUE
319 enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, VALUE size)
320 {
321  struct enumerator *ptr;
322 
323  rb_check_frozen(enum_obj);
324  TypedData_Get_Struct(enum_obj, struct enumerator, &enumerator_data_type, ptr);
325 
326  if (!ptr) {
327  rb_raise(rb_eArgError, "unallocated enumerator");
328  }
329 
330  ptr->obj = obj;
331  ptr->meth = rb_to_id(meth);
332  if (argc) ptr->args = rb_ary_new4(argc, argv);
333  ptr->fib = 0;
334  ptr->dst = Qnil;
335  ptr->lookahead = Qundef;
336  ptr->feedvalue = Qundef;
337  ptr->stop_exc = Qfalse;
338  ptr->size = size;
339  ptr->size_fn = size_fn;
340 
341  return enum_obj;
342 }
343 
344 /*
345  * call-seq:
346  * Enumerator.new(size = nil) { |yielder| ... }
347  * Enumerator.new(obj, method = :each, *args)
348  *
349  * Creates a new Enumerator object, which can be used as an
350  * Enumerable.
351  *
352  * In the first form, iteration is defined by the given block, in
353  * which a "yielder" object, given as block parameter, can be used to
354  * yield a value by calling the +yield+ method (aliased as +<<+):
355  *
356  * fib = Enumerator.new do |y|
357  * a = b = 1
358  * loop do
359  * y << a
360  * a, b = b, a + b
361  * end
362  * end
363  *
364  * p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
365  *
366  * The optional parameter can be used to specify how to calculate the size
367  * in a lazy fashion (see Enumerator#size). It can either be a value or
368  * a callable object.
369  *
370  * In the second, deprecated, form, a generated Enumerator iterates over the
371  * given object using the given method with the given arguments passed.
372  *
373  * Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum
374  * instead.
375  *
376  * e = Enumerator.new(ObjectSpace, :each_object)
377  * #-> ObjectSpace.enum_for(:each_object)
378  *
379  * e.select { |obj| obj.is_a?(Class) } #=> array of all classes
380  *
381  */
382 static VALUE
383 enumerator_initialize(int argc, VALUE *argv, VALUE obj)
384 {
385  VALUE recv, meth = sym_each;
386  VALUE size = Qnil;
387 
388  if (rb_block_given_p()) {
389  rb_check_arity(argc, 0, 1);
390  recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc());
391  if (argc) {
392  if (NIL_P(argv[0]) || rb_respond_to(argv[0], id_call) ||
393  (RB_TYPE_P(argv[0], T_FLOAT) && RFLOAT_VALUE(argv[0]) == INFINITY)) {
394  size = argv[0];
395  }
396  else {
397  size = rb_to_int(argv[0]);
398  }
399  argc = 0;
400  }
401  }
402  else {
404  rb_warn("Enumerator.new without a block is deprecated; use Object#to_enum");
405  recv = *argv++;
406  if (--argc) {
407  meth = *argv++;
408  --argc;
409  }
410  }
411 
412  return enumerator_init(obj, recv, meth, argc, argv, 0, size);
413 }
414 
415 /* :nodoc: */
416 static VALUE
417 enumerator_init_copy(VALUE obj, VALUE orig)
418 {
419  struct enumerator *ptr0, *ptr1;
420 
421  if (!OBJ_INIT_COPY(obj, orig)) return obj;
422  ptr0 = enumerator_ptr(orig);
423  if (ptr0->fib) {
424  /* Fibers cannot be copied */
425  rb_raise(rb_eTypeError, "can't copy execution context");
426  }
427 
428  TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, ptr1);
429 
430  if (!ptr1) {
431  rb_raise(rb_eArgError, "unallocated enumerator");
432  }
433 
434  ptr1->obj = ptr0->obj;
435  ptr1->meth = ptr0->meth;
436  ptr1->args = ptr0->args;
437  ptr1->fib = 0;
438  ptr1->lookahead = Qundef;
439  ptr1->feedvalue = Qundef;
440  ptr1->size = ptr0->size;
441  ptr1->size_fn = ptr0->size_fn;
442 
443  return obj;
444 }
445 
446 /*
447  * For backwards compatibility; use rb_enumeratorize_with_size
448  */
449 VALUE
450 rb_enumeratorize(VALUE obj, VALUE meth, int argc, const VALUE *argv)
451 {
452  return rb_enumeratorize_with_size(obj, meth, argc, argv, 0);
453 }
454 
455 static VALUE
456 lazy_to_enum_i(VALUE self, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn);
457 
458 VALUE
459 rb_enumeratorize_with_size(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn)
460 {
461  /* Similar effect as calling obj.to_enum, i.e. dispatching to either
462  Kernel#to_enum vs Lazy#to_enum */
463  if (RTEST(rb_obj_is_kind_of(obj, rb_cLazy)))
464  return lazy_to_enum_i(obj, meth, argc, argv, size_fn);
465  else
466  return enumerator_init(enumerator_allocate(rb_cEnumerator),
467  obj, meth, argc, argv, size_fn, Qnil);
468 }
469 
470 static VALUE
471 enumerator_block_call(VALUE obj, rb_block_call_func *func, VALUE arg)
472 {
473  int argc = 0;
474  const VALUE *argv = 0;
475  const struct enumerator *e = enumerator_ptr(obj);
476  ID meth = e->meth;
477 
478  if (e->args) {
479  argc = RARRAY_LENINT(e->args);
480  argv = RARRAY_CONST_PTR(e->args);
481  }
482  return rb_block_call(e->obj, meth, argc, argv, func, arg);
483 }
484 
485 /*
486  * call-seq:
487  * enum.each { |elm| block } -> obj
488  * enum.each -> enum
489  * enum.each(*appending_args) { |elm| block } -> obj
490  * enum.each(*appending_args) -> an_enumerator
491  *
492  * Iterates over the block according to how this Enumerator was constructed.
493  * If no block and no arguments are given, returns self.
494  *
495  * === Examples
496  *
497  * "Hello, world!".scan(/\w+/) #=> ["Hello", "world"]
498  * "Hello, world!".to_enum(:scan, /\w+/).to_a #=> ["Hello", "world"]
499  * "Hello, world!".to_enum(:scan).each(/\w+/).to_a #=> ["Hello", "world"]
500  *
501  * obj = Object.new
502  *
503  * def obj.each_arg(a, b=:b, *rest)
504  * yield a
505  * yield b
506  * yield rest
507  * :method_returned
508  * end
509  *
510  * enum = obj.to_enum :each_arg, :a, :x
511  *
512  * enum.each.to_a #=> [:a, :x, []]
513  * enum.each.equal?(enum) #=> true
514  * enum.each { |elm| elm } #=> :method_returned
515  *
516  * enum.each(:y, :z).to_a #=> [:a, :x, [:y, :z]]
517  * enum.each(:y, :z).equal?(enum) #=> false
518  * enum.each(:y, :z) { |elm| elm } #=> :method_returned
519  *
520  */
521 static VALUE
522 enumerator_each(int argc, VALUE *argv, VALUE obj)
523 {
524  if (argc > 0) {
525  struct enumerator *e = enumerator_ptr(obj = rb_obj_dup(obj));
526  VALUE args = e->args;
527  if (args) {
528 #if SIZEOF_INT < SIZEOF_LONG
529  /* check int range overflow */
530  rb_long2int(RARRAY_LEN(args) + argc);
531 #endif
532  args = rb_ary_dup(args);
533  rb_ary_cat(args, argv, argc);
534  }
535  else {
536  args = rb_ary_new4(argc, argv);
537  }
538  e->args = args;
539  }
540  if (!rb_block_given_p()) return obj;
541  return enumerator_block_call(obj, 0, obj);
542 }
543 
544 static VALUE
545 enumerator_with_index_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
546 {
547  struct MEMO *memo = (struct MEMO *)m;
548  VALUE idx = memo->v1;
549  MEMO_V1_SET(memo, rb_int_succ(idx));
550 
551  if (argc <= 1)
552  return rb_yield_values(2, val, idx);
553 
554  return rb_yield_values(2, rb_ary_new4(argc, argv), idx);
555 }
556 
557 static VALUE
558 enumerator_size(VALUE obj);
559 
560 static VALUE
561 enumerator_enum_size(VALUE obj, VALUE args, VALUE eobj)
562 {
563  return enumerator_size(obj);
564 }
565 
566 /*
567  * call-seq:
568  * e.with_index(offset = 0) {|(*args), idx| ... }
569  * e.with_index(offset = 0)
570  *
571  * Iterates the given block for each element with an index, which
572  * starts from +offset+. If no block is given, returns a new Enumerator
573  * that includes the index, starting from +offset+
574  *
575  * +offset+:: the starting index to use
576  *
577  */
578 static VALUE
579 enumerator_with_index(int argc, VALUE *argv, VALUE obj)
580 {
581  VALUE memo;
582 
583  rb_scan_args(argc, argv, "01", &memo);
584  RETURN_SIZED_ENUMERATOR(obj, argc, argv, enumerator_enum_size);
585  if (NIL_P(memo))
586  memo = INT2FIX(0);
587  else
588  memo = rb_to_int(memo);
589  return enumerator_block_call(obj, enumerator_with_index_i, (VALUE)MEMO_NEW(memo, 0, 0));
590 }
591 
592 /*
593  * call-seq:
594  * e.each_with_index {|(*args), idx| ... }
595  * e.each_with_index
596  *
597  * Same as Enumerator#with_index(0), i.e. there is no starting offset.
598  *
599  * If no block is given, a new Enumerator is returned that includes the index.
600  *
601  */
602 static VALUE
603 enumerator_each_with_index(VALUE obj)
604 {
605  return enumerator_with_index(0, NULL, obj);
606 }
607 
608 static VALUE
609 enumerator_with_object_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, memo))
610 {
611  if (argc <= 1)
612  return rb_yield_values(2, val, memo);
613 
614  return rb_yield_values(2, rb_ary_new4(argc, argv), memo);
615 }
616 
617 /*
618  * call-seq:
619  * e.each_with_object(obj) {|(*args), obj| ... }
620  * e.each_with_object(obj)
621  * e.with_object(obj) {|(*args), obj| ... }
622  * e.with_object(obj)
623  *
624  * Iterates the given block for each element with an arbitrary object, +obj+,
625  * and returns +obj+
626  *
627  * If no block is given, returns a new Enumerator.
628  *
629  * === Example
630  *
631  * to_three = Enumerator.new do |y|
632  * 3.times do |x|
633  * y << x
634  * end
635  * end
636  *
637  * to_three_with_string = to_three.with_object("foo")
638  * to_three_with_string.each do |x,string|
639  * puts "#{string}: #{x}"
640  * end
641  *
642  * # => foo:0
643  * # => foo:1
644  * # => foo:2
645  */
646 static VALUE
647 enumerator_with_object(VALUE obj, VALUE memo)
648 {
649  RETURN_SIZED_ENUMERATOR(obj, 1, &memo, enumerator_enum_size);
650  enumerator_block_call(obj, enumerator_with_object_i, memo);
651 
652  return memo;
653 }
654 
655 static VALUE
656 next_ii(RB_BLOCK_CALL_FUNC_ARGLIST(i, obj))
657 {
658  struct enumerator *e = enumerator_ptr(obj);
659  VALUE feedvalue = Qnil;
660  VALUE args = rb_ary_new4(argc, argv);
661  rb_fiber_yield(1, &args);
662  if (e->feedvalue != Qundef) {
663  feedvalue = e->feedvalue;
664  e->feedvalue = Qundef;
665  }
666  return feedvalue;
667 }
668 
669 static VALUE
670 next_i(VALUE curr, VALUE obj)
671 {
672  struct enumerator *e = enumerator_ptr(obj);
673  VALUE nil = Qnil;
674  VALUE result;
675 
676  result = rb_block_call(obj, id_each, 0, 0, next_ii, obj);
677  e->stop_exc = rb_exc_new2(rb_eStopIteration, "iteration reached an end");
678  rb_ivar_set(e->stop_exc, id_result, result);
679  return rb_fiber_yield(1, &nil);
680 }
681 
682 static void
683 next_init(VALUE obj, struct enumerator *e)
684 {
685  VALUE curr = rb_fiber_current();
686  e->dst = curr;
687  e->fib = rb_fiber_new(next_i, obj);
688  e->lookahead = Qundef;
689 }
690 
691 static VALUE
692 get_next_values(VALUE obj, struct enumerator *e)
693 {
694  VALUE curr, vs;
695 
696  if (e->stop_exc)
698 
699  curr = rb_fiber_current();
700 
701  if (!e->fib || !rb_fiber_alive_p(e->fib)) {
702  next_init(obj, e);
703  }
704 
705  vs = rb_fiber_resume(e->fib, 1, &curr);
706  if (e->stop_exc) {
707  e->fib = 0;
708  e->dst = Qnil;
709  e->lookahead = Qundef;
710  e->feedvalue = Qundef;
712  }
713  return vs;
714 }
715 
716 /*
717  * call-seq:
718  * e.next_values -> array
719  *
720  * Returns the next object as an array in the enumerator, and move the
721  * internal position forward. When the position reached at the end,
722  * StopIteration is raised.
723  *
724  * This method can be used to distinguish <code>yield</code> and <code>yield
725  * nil</code>.
726  *
727  * === Example
728  *
729  * o = Object.new
730  * def o.each
731  * yield
732  * yield 1
733  * yield 1, 2
734  * yield nil
735  * yield [1, 2]
736  * end
737  * e = o.to_enum
738  * p e.next_values
739  * p e.next_values
740  * p e.next_values
741  * p e.next_values
742  * p e.next_values
743  * e = o.to_enum
744  * p e.next
745  * p e.next
746  * p e.next
747  * p e.next
748  * p e.next
749  *
750  * ## yield args next_values next
751  * # yield [] nil
752  * # yield 1 [1] 1
753  * # yield 1, 2 [1, 2] [1, 2]
754  * # yield nil [nil] nil
755  * # yield [1, 2] [[1, 2]] [1, 2]
756  *
757  * Note that +next_values+ does not affect other non-external enumeration
758  * methods unless underlying iteration method itself has side-effect, e.g.
759  * IO#each_line.
760  *
761  */
762 
763 static VALUE
764 enumerator_next_values(VALUE obj)
765 {
766  struct enumerator *e = enumerator_ptr(obj);
767  VALUE vs;
768 
769  if (e->lookahead != Qundef) {
770  vs = e->lookahead;
771  e->lookahead = Qundef;
772  return vs;
773  }
774 
775  return get_next_values(obj, e);
776 }
777 
778 static VALUE
779 ary2sv(VALUE args, int dup)
780 {
781  if (!RB_TYPE_P(args, T_ARRAY))
782  return args;
783 
784  switch (RARRAY_LEN(args)) {
785  case 0:
786  return Qnil;
787 
788  case 1:
789  return RARRAY_AREF(args, 0);
790 
791  default:
792  if (dup)
793  return rb_ary_dup(args);
794  return args;
795  }
796 }
797 
798 /*
799  * call-seq:
800  * e.next -> object
801  *
802  * Returns the next object in the enumerator, and move the internal position
803  * forward. When the position reached at the end, StopIteration is raised.
804  *
805  * === Example
806  *
807  * a = [1,2,3]
808  * e = a.to_enum
809  * p e.next #=> 1
810  * p e.next #=> 2
811  * p e.next #=> 3
812  * p e.next #raises StopIteration
813  *
814  * Note that enumeration sequence by +next+ does not affect other non-external
815  * enumeration methods, unless the underlying iteration methods itself has
816  * side-effect, e.g. IO#each_line.
817  *
818  */
819 
820 static VALUE
821 enumerator_next(VALUE obj)
822 {
823  VALUE vs = enumerator_next_values(obj);
824  return ary2sv(vs, 0);
825 }
826 
827 static VALUE
828 enumerator_peek_values(VALUE obj)
829 {
830  struct enumerator *e = enumerator_ptr(obj);
831 
832  if (e->lookahead == Qundef) {
833  e->lookahead = get_next_values(obj, e);
834  }
835  return e->lookahead;
836 }
837 
838 /*
839  * call-seq:
840  * e.peek_values -> array
841  *
842  * Returns the next object as an array, similar to Enumerator#next_values, but
843  * doesn't move the internal position forward. If the position is already at
844  * the end, StopIteration is raised.
845  *
846  * === Example
847  *
848  * o = Object.new
849  * def o.each
850  * yield
851  * yield 1
852  * yield 1, 2
853  * end
854  * e = o.to_enum
855  * p e.peek_values #=> []
856  * e.next
857  * p e.peek_values #=> [1]
858  * p e.peek_values #=> [1]
859  * e.next
860  * p e.peek_values #=> [1, 2]
861  * e.next
862  * p e.peek_values # raises StopIteration
863  *
864  */
865 
866 static VALUE
867 enumerator_peek_values_m(VALUE obj)
868 {
869  return rb_ary_dup(enumerator_peek_values(obj));
870 }
871 
872 /*
873  * call-seq:
874  * e.peek -> object
875  *
876  * Returns the next object in the enumerator, but doesn't move the internal
877  * position forward. If the position is already at the end, StopIteration
878  * is raised.
879  *
880  * === Example
881  *
882  * a = [1,2,3]
883  * e = a.to_enum
884  * p e.next #=> 1
885  * p e.peek #=> 2
886  * p e.peek #=> 2
887  * p e.peek #=> 2
888  * p e.next #=> 2
889  * p e.next #=> 3
890  * p e.peek #raises StopIteration
891  *
892  */
893 
894 static VALUE
895 enumerator_peek(VALUE obj)
896 {
897  VALUE vs = enumerator_peek_values(obj);
898  return ary2sv(vs, 1);
899 }
900 
901 /*
902  * call-seq:
903  * e.feed obj -> nil
904  *
905  * Sets the value to be returned by the next yield inside +e+.
906  *
907  * If the value is not set, the yield returns nil.
908  *
909  * This value is cleared after being yielded.
910  *
911  * # Array#map passes the array's elements to "yield" and collects the
912  * # results of "yield" as an array.
913  * # Following example shows that "next" returns the passed elements and
914  * # values passed to "feed" are collected as an array which can be
915  * # obtained by StopIteration#result.
916  * e = [1,2,3].map
917  * p e.next #=> 1
918  * e.feed "a"
919  * p e.next #=> 2
920  * e.feed "b"
921  * p e.next #=> 3
922  * e.feed "c"
923  * begin
924  * e.next
925  * rescue StopIteration
926  * p $!.result #=> ["a", "b", "c"]
927  * end
928  *
929  * o = Object.new
930  * def o.each
931  * x = yield # (2) blocks
932  * p x # (5) => "foo"
933  * x = yield # (6) blocks
934  * p x # (8) => nil
935  * x = yield # (9) blocks
936  * p x # not reached w/o another e.next
937  * end
938  *
939  * e = o.to_enum
940  * e.next # (1)
941  * e.feed "foo" # (3)
942  * e.next # (4)
943  * e.next # (7)
944  * # (10)
945  */
946 
947 static VALUE
948 enumerator_feed(VALUE obj, VALUE v)
949 {
950  struct enumerator *e = enumerator_ptr(obj);
951 
952  if (e->feedvalue != Qundef) {
953  rb_raise(rb_eTypeError, "feed value already set");
954  }
955  e->feedvalue = v;
956 
957  return Qnil;
958 }
959 
960 /*
961  * call-seq:
962  * e.rewind -> e
963  *
964  * Rewinds the enumeration sequence to the beginning.
965  *
966  * If the enclosed object responds to a "rewind" method, it is called.
967  */
968 
969 static VALUE
970 enumerator_rewind(VALUE obj)
971 {
972  struct enumerator *e = enumerator_ptr(obj);
973 
974  rb_check_funcall(e->obj, id_rewind, 0, 0);
975 
976  e->fib = 0;
977  e->dst = Qnil;
978  e->lookahead = Qundef;
979  e->feedvalue = Qundef;
980  e->stop_exc = Qfalse;
981  return obj;
982 }
983 
984 static struct generator *generator_ptr(VALUE obj);
985 static VALUE append_method(VALUE obj, VALUE str, ID default_method, VALUE default_args);
986 
987 static VALUE
988 inspect_enumerator(VALUE obj, VALUE dummy, int recur)
989 {
990  struct enumerator *e;
991  VALUE eobj, str, cname;
992 
993  TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, e);
994 
995  cname = rb_obj_class(obj);
996 
997  if (!e || e->obj == Qundef) {
998  return rb_sprintf("#<%"PRIsVALUE": uninitialized>", rb_class_path(cname));
999  }
1000 
1001  if (recur) {
1002  str = rb_sprintf("#<%"PRIsVALUE": ...>", rb_class_path(cname));
1003  OBJ_TAINT(str);
1004  return str;
1005  }
1006 
1007  if (e->procs) {
1008  long i;
1009 
1010  eobj = generator_ptr(e->obj)->obj;
1011  /* In case procs chained enumerator traversing all proc entries manually */
1012  if (rb_obj_class(eobj) == cname) {
1013  str = rb_inspect(eobj);
1014  }
1015  else {
1016  str = rb_sprintf("#<%"PRIsVALUE": %+"PRIsVALUE">", rb_class_path(cname), eobj);
1017  }
1018  for (i = 0; i < RARRAY_LEN(e->procs); i++) {
1019  str = rb_sprintf("#<%"PRIsVALUE": %"PRIsVALUE, cname, str);
1020  append_method(RARRAY_AREF(e->procs, i), str, e->meth, e->args);
1021  rb_str_buf_cat2(str, ">");
1022  }
1023  return str;
1024  }
1025 
1026  eobj = rb_attr_get(obj, id_receiver);
1027  if (NIL_P(eobj)) {
1028  eobj = e->obj;
1029  }
1030 
1031  /* (1..100).each_cons(2) => "#<Enumerator: 1..100:each_cons(2)>" */
1032  str = rb_sprintf("#<%"PRIsVALUE": %+"PRIsVALUE, rb_class_path(cname), eobj);
1033  append_method(obj, str, e->meth, e->args);
1034 
1035  rb_str_buf_cat2(str, ">");
1036 
1037  return str;
1038 }
1039 
1040 static VALUE
1041 append_method(VALUE obj, VALUE str, ID default_method, VALUE default_args)
1042 {
1043  VALUE method, eargs;
1044 
1045  method = rb_attr_get(obj, id_method);
1046  if (method != Qfalse) {
1047  if (!NIL_P(method)) {
1048  Check_Type(method, T_SYMBOL);
1049  method = rb_sym2str(method);
1050  }
1051  else {
1052  method = rb_id2str(default_method);
1053  }
1054  rb_str_buf_cat2(str, ":");
1055  rb_str_buf_append(str, method);
1056  }
1057 
1058  eargs = rb_attr_get(obj, id_arguments);
1059  if (NIL_P(eargs)) {
1060  eargs = default_args;
1061  }
1062  if (eargs != Qfalse) {
1063  long argc = RARRAY_LEN(eargs);
1064  const VALUE *argv = RARRAY_CONST_PTR(eargs); /* WB: no new reference */
1065 
1066  if (argc > 0) {
1067  rb_str_buf_cat2(str, "(");
1068 
1069  while (argc--) {
1070  VALUE arg = *argv++;
1071 
1072  rb_str_append(str, rb_inspect(arg));
1073  rb_str_buf_cat2(str, argc > 0 ? ", " : ")");
1074  OBJ_INFECT(str, arg);
1075  }
1076  }
1077  }
1078 
1079  return str;
1080 }
1081 
1082 /*
1083  * call-seq:
1084  * e.inspect -> string
1085  *
1086  * Creates a printable version of <i>e</i>.
1087  */
1088 
1089 static VALUE
1090 enumerator_inspect(VALUE obj)
1091 {
1092  return rb_exec_recursive(inspect_enumerator, obj, 0);
1093 }
1094 
1095 /*
1096  * call-seq:
1097  * e.size -> int, Float::INFINITY or nil
1098  *
1099  * Returns the size of the enumerator, or +nil+ if it can't be calculated lazily.
1100  *
1101  * (1..100).to_a.permutation(4).size # => 94109400
1102  * loop.size # => Float::INFINITY
1103  * (1..100).drop_while.size # => nil
1104  */
1105 
1106 static VALUE
1107 enumerator_size(VALUE obj)
1108 {
1109  struct enumerator *e = enumerator_ptr(obj);
1110  int argc = 0;
1111  const VALUE *argv = NULL;
1112  VALUE size;
1113 
1114  if (e->procs) {
1115  struct generator *g = generator_ptr(e->obj);
1116  VALUE receiver = rb_check_funcall(g->obj, id_size, 0, 0);
1117  long i = 0;
1118 
1119  for (i = 0; i < RARRAY_LEN(e->procs); i++) {
1120  VALUE proc = RARRAY_AREF(e->procs, i);
1121  struct proc_entry *entry = proc_entry_ptr(proc);
1122  lazyenum_size_func *size_fn = entry->fn->size;
1123  if (!size_fn) {
1124  return Qnil;
1125  }
1126  receiver = (*size_fn)(proc, receiver);
1127  }
1128  return receiver;
1129  }
1130 
1131  if (e->size_fn) {
1132  return (*e->size_fn)(e->obj, e->args, obj);
1133  }
1134  if (e->args) {
1135  argc = (int)RARRAY_LEN(e->args);
1136  argv = RARRAY_CONST_PTR(e->args);
1137  }
1138  size = rb_check_funcall(e->size, id_call, argc, argv);
1139  if (size != Qundef) return size;
1140  return e->size;
1141 }
1142 
1143 /*
1144  * Yielder
1145  */
1146 static void
1147 yielder_mark(void *p)
1148 {
1149  struct yielder *ptr = p;
1150  rb_gc_mark(ptr->proc);
1151 }
1152 
1153 #define yielder_free RUBY_TYPED_DEFAULT_FREE
1154 
1155 static size_t
1156 yielder_memsize(const void *p)
1157 {
1158  return sizeof(struct yielder);
1159 }
1160 
1161 static const rb_data_type_t yielder_data_type = {
1162  "yielder",
1163  {
1164  yielder_mark,
1165  yielder_free,
1166  yielder_memsize,
1167  },
1169 };
1170 
1171 static struct yielder *
1172 yielder_ptr(VALUE obj)
1173 {
1174  struct yielder *ptr;
1175 
1176  TypedData_Get_Struct(obj, struct yielder, &yielder_data_type, ptr);
1177  if (!ptr || ptr->proc == Qundef) {
1178  rb_raise(rb_eArgError, "uninitialized yielder");
1179  }
1180  return ptr;
1181 }
1182 
1183 /* :nodoc: */
1184 static VALUE
1185 yielder_allocate(VALUE klass)
1186 {
1187  struct yielder *ptr;
1188  VALUE obj;
1189 
1190  obj = TypedData_Make_Struct(klass, struct yielder, &yielder_data_type, ptr);
1191  ptr->proc = Qundef;
1192 
1193  return obj;
1194 }
1195 
1196 static VALUE
1197 yielder_init(VALUE obj, VALUE proc)
1198 {
1199  struct yielder *ptr;
1200 
1201  TypedData_Get_Struct(obj, struct yielder, &yielder_data_type, ptr);
1202 
1203  if (!ptr) {
1204  rb_raise(rb_eArgError, "unallocated yielder");
1205  }
1206 
1207  ptr->proc = proc;
1208 
1209  return obj;
1210 }
1211 
1212 /* :nodoc: */
1213 static VALUE
1214 yielder_initialize(VALUE obj)
1215 {
1216  rb_need_block();
1217 
1218  return yielder_init(obj, rb_block_proc());
1219 }
1220 
1221 /* :nodoc: */
1222 static VALUE
1223 yielder_yield(VALUE obj, VALUE args)
1224 {
1225  struct yielder *ptr = yielder_ptr(obj);
1226 
1227  return rb_proc_call(ptr->proc, args);
1228 }
1229 
1230 /* :nodoc: */
1231 static VALUE
1232 yielder_yield_push(VALUE obj, VALUE args)
1233 {
1234  yielder_yield(obj, args);
1235  return obj;
1236 }
1237 
1238 static VALUE
1239 yielder_yield_i(RB_BLOCK_CALL_FUNC_ARGLIST(obj, memo))
1240 {
1241  return rb_yield_values2(argc, argv);
1242 }
1243 
1244 static VALUE
1245 yielder_new(void)
1246 {
1247  return yielder_init(yielder_allocate(rb_cYielder), rb_proc_new(yielder_yield_i, 0));
1248 }
1249 
1250 /*
1251  * Generator
1252  */
1253 static void
1254 generator_mark(void *p)
1255 {
1256  struct generator *ptr = p;
1257  rb_gc_mark(ptr->proc);
1258  rb_gc_mark(ptr->obj);
1259 }
1260 
1261 #define generator_free RUBY_TYPED_DEFAULT_FREE
1262 
1263 static size_t
1264 generator_memsize(const void *p)
1265 {
1266  return sizeof(struct generator);
1267 }
1268 
1269 static const rb_data_type_t generator_data_type = {
1270  "generator",
1271  {
1272  generator_mark,
1274  generator_memsize,
1275  },
1276  0, 0, RUBY_TYPED_FREE_IMMEDIATELY
1277 };
1278 
1279 static struct generator *
1280 generator_ptr(VALUE obj)
1281 {
1282  struct generator *ptr;
1283 
1284  TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr);
1285  if (!ptr || ptr->proc == Qundef) {
1286  rb_raise(rb_eArgError, "uninitialized generator");
1287  }
1288  return ptr;
1289 }
1290 
1291 /* :nodoc: */
1292 static VALUE
1293 generator_allocate(VALUE klass)
1294 {
1295  struct generator *ptr;
1296  VALUE obj;
1297 
1298  obj = TypedData_Make_Struct(klass, struct generator, &generator_data_type, ptr);
1299  ptr->proc = Qundef;
1300 
1301  return obj;
1302 }
1303 
1304 static VALUE
1305 generator_init(VALUE obj, VALUE proc)
1306 {
1307  struct generator *ptr;
1308 
1309  rb_check_frozen(obj);
1310  TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr);
1311 
1312  if (!ptr) {
1313  rb_raise(rb_eArgError, "unallocated generator");
1314  }
1315 
1316  ptr->proc = proc;
1317 
1318  return obj;
1319 }
1320 
1321 /* :nodoc: */
1322 static VALUE
1323 generator_initialize(int argc, VALUE *argv, VALUE obj)
1324 {
1325  VALUE proc;
1326 
1327  if (argc == 0) {
1328  rb_need_block();
1329 
1330  proc = rb_block_proc();
1331  }
1332  else {
1333  rb_scan_args(argc, argv, "1", &proc);
1334 
1335  if (!rb_obj_is_proc(proc))
1337  "wrong argument type %"PRIsVALUE" (expected Proc)",
1338  rb_obj_class(proc));
1339 
1340  if (rb_block_given_p()) {
1341  rb_warn("given block not used");
1342  }
1343  }
1344 
1345  return generator_init(obj, proc);
1346 }
1347 
1348 /* :nodoc: */
1349 static VALUE
1350 generator_init_copy(VALUE obj, VALUE orig)
1351 {
1352  struct generator *ptr0, *ptr1;
1353 
1354  if (!OBJ_INIT_COPY(obj, orig)) return obj;
1355 
1356  ptr0 = generator_ptr(orig);
1357 
1358  TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr1);
1359 
1360  if (!ptr1) {
1361  rb_raise(rb_eArgError, "unallocated generator");
1362  }
1363 
1364  ptr1->proc = ptr0->proc;
1365 
1366  return obj;
1367 }
1368 
1369 /* :nodoc: */
1370 static VALUE
1371 generator_each(int argc, VALUE *argv, VALUE obj)
1372 {
1373  struct generator *ptr = generator_ptr(obj);
1374  VALUE args = rb_ary_new2(argc + 1);
1375 
1376  rb_ary_push(args, yielder_new());
1377  if (argc > 0) {
1378  rb_ary_cat(args, argv, argc);
1379  }
1380 
1381  return rb_proc_call(ptr->proc, args);
1382 }
1383 
1384 /* Lazy Enumerator methods */
1385 static VALUE
1386 enum_size(VALUE self)
1387 {
1388  VALUE r = rb_check_funcall(self, id_size, 0, 0);
1389  return (r == Qundef) ? Qnil : r;
1390 }
1391 
1392 static VALUE
1393 lazyenum_size(VALUE self, VALUE args, VALUE eobj)
1394 {
1395  return enum_size(self);
1396 }
1397 
1398 static VALUE
1399 lazy_size(VALUE self)
1400 {
1401  return enum_size(rb_ivar_get(self, id_receiver));
1402 }
1403 
1404 static VALUE
1405 lazy_receiver_size(VALUE generator, VALUE args, VALUE lazy)
1406 {
1407  return lazy_size(lazy);
1408 }
1409 
1410 static VALUE
1411 lazy_init_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
1412 {
1413  VALUE result;
1414  if (argc == 1) {
1415  VALUE args[2];
1416  args[0] = m;
1417  args[1] = val;
1418  result = rb_yield_values2(2, args);
1419  }
1420  else {
1421  VALUE args;
1422  int len = rb_long2int((long)argc + 1);
1423  VALUE *nargv = ALLOCV_N(VALUE, args, len);
1424 
1425  nargv[0] = m;
1426  if (argc > 0) {
1427  MEMCPY(nargv + 1, argv, VALUE, argc);
1428  }
1429  result = rb_yield_values2(len, nargv);
1430  ALLOCV_END(args);
1431  }
1432  if (result == Qundef) rb_iter_break();
1433  return Qnil;
1434 }
1435 
1436 static VALUE
1437 lazy_init_block_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
1438 {
1439  rb_block_call(m, id_each, argc-1, argv+1, lazy_init_iterator, val);
1440  return Qnil;
1441 }
1442 
1443 #define memo_value v2
1444 #define memo_flags u3.state
1445 #define LAZY_MEMO_BREAK 1
1446 #define LAZY_MEMO_PACKED 2
1447 #define LAZY_MEMO_BREAK_P(memo) ((memo)->memo_flags & LAZY_MEMO_BREAK)
1448 #define LAZY_MEMO_PACKED_P(memo) ((memo)->memo_flags & LAZY_MEMO_PACKED)
1449 #define LAZY_MEMO_SET_BREAK(memo) ((memo)->memo_flags |= LAZY_MEMO_BREAK)
1450 #define LAZY_MEMO_SET_VALUE(memo, value) MEMO_V2_SET(memo, value)
1451 #define LAZY_MEMO_SET_PACKED(memo) ((memo)->memo_flags |= LAZY_MEMO_PACKED)
1452 #define LAZY_MEMO_RESET_PACKED(memo) ((memo)->memo_flags &= ~LAZY_MEMO_PACKED)
1453 
1454 static VALUE
1455 lazy_init_yielder(VALUE val, VALUE m, int argc, VALUE *argv)
1456 {
1457  VALUE yielder = RARRAY_AREF(m, 0);
1458  VALUE procs_array = RARRAY_AREF(m, 1);
1459  VALUE memos = rb_attr_get(yielder, id_memo);
1460  long i = 0;
1461  struct MEMO *result;
1462  int cont = 1;
1463 
1464  result = MEMO_NEW(Qnil, rb_enum_values_pack(argc, argv),
1465  argc > 1 ? LAZY_MEMO_PACKED : 0);
1466 
1467  for (i = 0; i < RARRAY_LEN(procs_array); i++) {
1468  VALUE proc = RARRAY_AREF(procs_array, i);
1469  struct proc_entry *entry = proc_entry_ptr(proc);
1470  if (!(*entry->fn->proc)(proc, result, memos, i)) {
1471  cont = 0;
1472  break;
1473  }
1474  }
1475 
1476  if (cont) {
1477  rb_funcall2(yielder, id_yield, 1, &(result->memo_value));
1478  }
1479  if (LAZY_MEMO_BREAK_P(result)) {
1480  rb_iter_break();
1481  }
1482  return result->memo_value;
1483 }
1484 
1485 static VALUE
1486 lazy_init_block(VALUE val, VALUE m, int argc, VALUE *argv)
1487 {
1488  VALUE procs = RARRAY_AREF(m, 1);
1489 
1490  rb_ivar_set(val, id_memo, rb_ary_new2(RARRAY_LEN(procs)));
1491  rb_block_call(RARRAY_AREF(m, 0), id_each, 0, 0,
1492  lazy_init_yielder, rb_ary_new3(2, val, procs));
1493  return Qnil;
1494 }
1495 
1496 static VALUE
1497 lazy_generator_init(VALUE enumerator, VALUE procs)
1498 {
1499  VALUE generator;
1500  VALUE obj;
1501  struct generator *gen_ptr;
1502  struct enumerator *e = enumerator_ptr(enumerator);
1503 
1504  if (RARRAY_LEN(procs) > 0) {
1505  struct generator *old_gen_ptr = generator_ptr(e->obj);
1506  obj = old_gen_ptr->obj;
1507  }
1508  else {
1509  obj = enumerator;
1510  }
1511 
1512  generator = generator_allocate(rb_cGenerator);
1513 
1514  rb_block_call(generator, id_initialize, 0, 0,
1515  lazy_init_block, rb_ary_new3(2, obj, procs));
1516 
1517  gen_ptr = generator_ptr(generator);
1518  gen_ptr->obj = obj;
1519 
1520  return generator;
1521 }
1522 
1523 /*
1524  * call-seq:
1525  * Lazy.new(obj, size=nil) { |yielder, *values| ... }
1526  *
1527  * Creates a new Lazy enumerator. When the enumerator is actually enumerated
1528  * (e.g. by calling #force), +obj+ will be enumerated and each value passed
1529  * to the given block. The block can yield values back using +yielder+.
1530  * For example, to create a method +filter_map+ in both lazy and
1531  * non-lazy fashions:
1532  *
1533  * module Enumerable
1534  * def filter_map(&block)
1535  * map(&block).compact
1536  * end
1537  * end
1538  *
1539  * class Enumerator::Lazy
1540  * def filter_map
1541  * Lazy.new(self) do |yielder, *values|
1542  * result = yield *values
1543  * yielder << result if result
1544  * end
1545  * end
1546  * end
1547  *
1548  * (1..Float::INFINITY).lazy.filter_map{|i| i*i if i.even?}.first(5)
1549  * # => [4, 16, 36, 64, 100]
1550  */
1551 static VALUE
1552 lazy_initialize(int argc, VALUE *argv, VALUE self)
1553 {
1554  VALUE obj, size = Qnil;
1555  VALUE generator;
1556 
1557  rb_check_arity(argc, 1, 2);
1558  if (!rb_block_given_p()) {
1559  rb_raise(rb_eArgError, "tried to call lazy new without a block");
1560  }
1561  obj = argv[0];
1562  if (argc > 1) {
1563  size = argv[1];
1564  }
1565  generator = generator_allocate(rb_cGenerator);
1566  rb_block_call(generator, id_initialize, 0, 0, lazy_init_block_i, obj);
1567  enumerator_init(self, generator, sym_each, 0, 0, 0, size);
1568  rb_ivar_set(self, id_receiver, obj);
1569 
1570  return self;
1571 }
1572 
1573 static void
1574 lazy_set_args(VALUE lazy, VALUE args)
1575 {
1576  ID id = rb_frame_this_func();
1577  rb_ivar_set(lazy, id_method, ID2SYM(id));
1578  if (NIL_P(args)) {
1579  /* Qfalse indicates that the arguments are empty */
1580  rb_ivar_set(lazy, id_arguments, Qfalse);
1581  }
1582  else {
1583  rb_ivar_set(lazy, id_arguments, args);
1584  }
1585 }
1586 
1587 static VALUE
1588 lazy_set_method(VALUE lazy, VALUE args, rb_enumerator_size_func *size_fn)
1589 {
1590  struct enumerator *e = enumerator_ptr(lazy);
1591  lazy_set_args(lazy, args);
1592  e->size_fn = size_fn;
1593  return lazy;
1594 }
1595 
1596 static VALUE
1597 lazy_add_method(VALUE obj, int argc, VALUE *argv, VALUE args, VALUE memo,
1598  const lazyenum_funcs *fn)
1599 {
1600  struct enumerator *new_e;
1601  VALUE new_obj;
1602  VALUE new_generator;
1603  VALUE new_procs;
1604  struct enumerator *e = enumerator_ptr(obj);
1605  struct proc_entry *entry;
1606  VALUE entry_obj = TypedData_Make_Struct(rb_cObject, struct proc_entry,
1607  &proc_entry_data_type, entry);
1608  if (rb_block_given_p()) {
1609  entry->proc = rb_block_proc();
1610  }
1611  entry->fn = fn;
1612  entry->memo = args;
1613 
1614  lazy_set_args(entry_obj, memo);
1615 
1616  new_procs = RTEST(e->procs) ? rb_ary_dup(e->procs) : rb_ary_new();
1617  new_generator = lazy_generator_init(obj, new_procs);
1618  rb_ary_push(new_procs, entry_obj);
1619 
1620  new_obj = enumerator_init_copy(enumerator_allocate(rb_cLazy), obj);
1621  new_e = DATA_PTR(new_obj);
1622  new_e->obj = new_generator;
1623  new_e->procs = new_procs;
1624 
1625  if (argc > 0) {
1626  new_e->meth = rb_to_id(*argv++);
1627  --argc;
1628  }
1629  else {
1630  new_e->meth = id_each;
1631  }
1632  new_e->args = rb_ary_new4(argc, argv);
1633  return new_obj;
1634 }
1635 
1636 /*
1637  * call-seq:
1638  * e.lazy -> lazy_enumerator
1639  *
1640  * Returns a lazy enumerator, whose methods map/collect,
1641  * flat_map/collect_concat, select/find_all, reject, grep, grep_v, zip, take,
1642  * take_while, drop, and drop_while enumerate values only on an
1643  * as-needed basis. However, if a block is given to zip, values
1644  * are enumerated immediately.
1645  *
1646  * === Example
1647  *
1648  * The following program finds pythagorean triples:
1649  *
1650  * def pythagorean_triples
1651  * (1..Float::INFINITY).lazy.flat_map {|z|
1652  * (1..z).flat_map {|x|
1653  * (x..z).select {|y|
1654  * x**2 + y**2 == z**2
1655  * }.map {|y|
1656  * [x, y, z]
1657  * }
1658  * }
1659  * }
1660  * end
1661  * # show first ten pythagorean triples
1662  * p pythagorean_triples.take(10).force # take is lazy, so force is needed
1663  * p pythagorean_triples.first(10) # first is eager
1664  * # show pythagorean triples less than 100
1665  * p pythagorean_triples.take_while { |*, z| z < 100 }.force
1666  */
1667 static VALUE
1668 enumerable_lazy(VALUE obj)
1669 {
1670  VALUE result = lazy_to_enum_i(obj, sym_each, 0, 0, lazyenum_size);
1671  /* Qfalse indicates that the Enumerator::Lazy has no method name */
1672  rb_ivar_set(result, id_method, Qfalse);
1673  return result;
1674 }
1675 
1676 static VALUE
1677 lazy_to_enum_i(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn)
1678 {
1679  return enumerator_init(enumerator_allocate(rb_cLazy),
1680  obj, meth, argc, argv, size_fn, Qnil);
1681 }
1682 
1683 /*
1684  * call-seq:
1685  * lzy.to_enum(method = :each, *args) -> lazy_enum
1686  * lzy.enum_for(method = :each, *args) -> lazy_enum
1687  * lzy.to_enum(method = :each, *args) {|*args| block} -> lazy_enum
1688  * lzy.enum_for(method = :each, *args){|*args| block} -> lazy_enum
1689  *
1690  * Similar to Kernel#to_enum, except it returns a lazy enumerator.
1691  * This makes it easy to define Enumerable methods that will
1692  * naturally remain lazy if called from a lazy enumerator.
1693  *
1694  * For example, continuing from the example in Kernel#to_enum:
1695  *
1696  * # See Kernel#to_enum for the definition of repeat
1697  * r = 1..Float::INFINITY
1698  * r.repeat(2).first(5) # => [1, 1, 2, 2, 3]
1699  * r.repeat(2).class # => Enumerator
1700  * r.repeat(2).map{|n| n ** 2}.first(5) # => endless loop!
1701  * # works naturally on lazy enumerator:
1702  * r.lazy.repeat(2).class # => Enumerator::Lazy
1703  * r.lazy.repeat(2).map{|n| n ** 2}.first(5) # => [1, 1, 4, 4, 9]
1704  */
1705 
1706 static VALUE
1707 lazy_to_enum(int argc, VALUE *argv, VALUE self)
1708 {
1709  VALUE lazy, meth = sym_each;
1710 
1711  if (argc > 0) {
1712  --argc;
1713  meth = *argv++;
1714  }
1715  lazy = lazy_to_enum_i(self, meth, argc, argv, 0);
1716  if (rb_block_given_p()) {
1717  enumerator_ptr(lazy)->size = rb_block_proc();
1718  }
1719  return lazy;
1720 }
1721 
1722 static VALUE
1723 lazyenum_yield(VALUE proc_entry, struct MEMO *result)
1724 {
1725  struct proc_entry *entry = proc_entry_ptr(proc_entry);
1726  return rb_proc_call_with_block(entry->proc, 1, &result->memo_value, Qnil);
1727 }
1728 
1729 static VALUE
1730 lazyenum_yield_values(VALUE proc_entry, struct MEMO *result)
1731 {
1732  struct proc_entry *entry = proc_entry_ptr(proc_entry);
1733  int argc = 1;
1734  const VALUE *argv = &result->memo_value;
1735  if (LAZY_MEMO_PACKED_P(result)) {
1736  const VALUE args = *argv;
1737  argc = RARRAY_LENINT(args);
1738  argv = RARRAY_CONST_PTR(args);
1739  }
1740  return rb_proc_call_with_block(entry->proc, argc, argv, Qnil);
1741 }
1742 
1743 static struct MEMO *
1744 lazy_map_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
1745 {
1746  VALUE value = lazyenum_yield_values(proc_entry, result);
1747  LAZY_MEMO_SET_VALUE(result, value);
1748  LAZY_MEMO_RESET_PACKED(result);
1749  return result;
1750 }
1751 
1752 static VALUE
1753 lazy_map_size(VALUE entry, VALUE receiver)
1754 {
1755  return receiver;
1756 }
1757 
1758 static const lazyenum_funcs lazy_map_funcs = {
1759  lazy_map_proc, lazy_map_size,
1760 };
1761 
1762 static VALUE
1763 lazy_map(VALUE obj)
1764 {
1765  if (!rb_block_given_p()) {
1766  rb_raise(rb_eArgError, "tried to call lazy map without a block");
1767  }
1768 
1769  return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_map_funcs);
1770 }
1771 
1772 static VALUE
1773 lazy_flat_map_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, yielder))
1774 {
1775  return rb_funcallv(yielder, id_yield, argc, argv);
1776 }
1777 
1778 static VALUE
1779 lazy_flat_map_each(VALUE obj, VALUE yielder)
1780 {
1781  rb_block_call(obj, id_each, 0, 0, lazy_flat_map_i, yielder);
1782  return Qnil;
1783 }
1784 
1785 static VALUE
1786 lazy_flat_map_to_ary(VALUE obj, VALUE yielder)
1787 {
1788  VALUE ary = rb_check_array_type(obj);
1789  if (NIL_P(ary)) {
1790  rb_funcall(yielder, id_yield, 1, obj);
1791  }
1792  else {
1793  long i;
1794  for (i = 0; i < RARRAY_LEN(ary); i++) {
1795  rb_funcall(yielder, id_yield, 1, RARRAY_AREF(ary, i));
1796  }
1797  }
1798  return Qnil;
1799 }
1800 
1801 static VALUE
1802 lazy_flat_map_proc(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
1803 {
1804  VALUE result = rb_yield_values2(argc - 1, &argv[1]);
1805  if (RB_TYPE_P(result, T_ARRAY)) {
1806  long i;
1807  for (i = 0; i < RARRAY_LEN(result); i++) {
1808  rb_funcall(argv[0], id_yield, 1, RARRAY_AREF(result, i));
1809  }
1810  }
1811  else {
1812  if (rb_respond_to(result, id_force) && rb_respond_to(result, id_each)) {
1813  lazy_flat_map_each(result, argv[0]);
1814  }
1815  else {
1816  lazy_flat_map_to_ary(result, argv[0]);
1817  }
1818  }
1819  return Qnil;
1820 }
1821 
1822 /*
1823  * call-seq:
1824  * lazy.collect_concat { |obj| block } -> a_lazy_enumerator
1825  * lazy.flat_map { |obj| block } -> a_lazy_enumerator
1826  *
1827  * Returns a new lazy enumerator with the concatenated results of running
1828  * <i>block</i> once for every element in <i>lazy</i>.
1829  *
1830  * ["foo", "bar"].lazy.flat_map {|i| i.each_char.lazy}.force
1831  * #=> ["f", "o", "o", "b", "a", "r"]
1832  *
1833  * A value <i>x</i> returned by <i>block</i> is decomposed if either of
1834  * the following conditions is true:
1835  *
1836  * a) <i>x</i> responds to both each and force, which means that
1837  * <i>x</i> is a lazy enumerator.
1838  * b) <i>x</i> is an array or responds to to_ary.
1839  *
1840  * Otherwise, <i>x</i> is contained as-is in the return value.
1841  *
1842  * [{a:1}, {b:2}].lazy.flat_map {|i| i}.force
1843  * #=> [{:a=>1}, {:b=>2}]
1844  */
1845 static VALUE
1846 lazy_flat_map(VALUE obj)
1847 {
1848  if (!rb_block_given_p()) {
1849  rb_raise(rb_eArgError, "tried to call lazy flat_map without a block");
1850  }
1851 
1852  return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
1853  lazy_flat_map_proc, 0),
1854  Qnil, 0);
1855 }
1856 
1857 static struct MEMO *
1858 lazy_select_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
1859 {
1860  VALUE chain = lazyenum_yield(proc_entry, result);
1861  if (!RTEST(chain)) return 0;
1862  return result;
1863 }
1864 
1865 static const lazyenum_funcs lazy_select_funcs = {
1866  lazy_select_proc, 0,
1867 };
1868 
1869 static VALUE
1870 lazy_select(VALUE obj)
1871 {
1872  if (!rb_block_given_p()) {
1873  rb_raise(rb_eArgError, "tried to call lazy select without a block");
1874  }
1875 
1876  return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_select_funcs);
1877 }
1878 
1879 static struct MEMO *
1880 lazy_reject_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
1881 {
1882  VALUE chain = lazyenum_yield(proc_entry, result);
1883  if (RTEST(chain)) return 0;
1884  return result;
1885 }
1886 
1887 static const lazyenum_funcs lazy_reject_funcs = {
1888  lazy_reject_proc, 0,
1889 };
1890 
1891 static VALUE
1892 lazy_reject(VALUE obj)
1893 {
1894  if (!rb_block_given_p()) {
1895  rb_raise(rb_eArgError, "tried to call lazy reject without a block");
1896  }
1897 
1898  return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_reject_funcs);
1899 }
1900 
1901 static struct MEMO *
1902 lazy_grep_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
1903 {
1904  struct proc_entry *entry = proc_entry_ptr(proc_entry);
1905  VALUE chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
1906  if (!RTEST(chain)) return 0;
1907  return result;
1908 }
1909 
1910 static struct MEMO *
1911 lazy_grep_iter_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
1912 {
1913  struct proc_entry *entry = proc_entry_ptr(proc_entry);
1914  VALUE value, chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
1915 
1916  if (!RTEST(chain)) return 0;
1917  value = rb_proc_call_with_block(entry->proc, 1, &(result->memo_value), Qnil);
1918  LAZY_MEMO_SET_VALUE(result, value);
1919  LAZY_MEMO_RESET_PACKED(result);
1920 
1921  return result;
1922 }
1923 
1924 static const lazyenum_funcs lazy_grep_iter_funcs = {
1925  lazy_grep_iter_proc, 0,
1926 };
1927 
1928 static const lazyenum_funcs lazy_grep_funcs = {
1929  lazy_grep_proc, 0,
1930 };
1931 
1932 static VALUE
1933 lazy_grep(VALUE obj, VALUE pattern)
1934 {
1935  const lazyenum_funcs *const funcs = rb_block_given_p() ?
1936  &lazy_grep_iter_funcs : &lazy_grep_funcs;
1937  return lazy_add_method(obj, 0, 0, pattern, rb_ary_new3(1, pattern), funcs);
1938 }
1939 
1940 static VALUE
1941 lazy_grep_v_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
1942 {
1943  VALUE i = rb_enum_values_pack(argc - 1, argv + 1);
1944  VALUE result = rb_funcall(m, id_eqq, 1, i);
1945 
1946  if (!RTEST(result)) {
1947  rb_funcall(argv[0], id_yield, 1, i);
1948  }
1949  return Qnil;
1950 }
1951 
1952 static VALUE
1953 lazy_grep_v_iter(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
1954 {
1955  VALUE i = rb_enum_values_pack(argc - 1, argv + 1);
1956  VALUE result = rb_funcall(m, id_eqq, 1, i);
1957 
1958  if (!RTEST(result)) {
1959  rb_funcall(argv[0], id_yield, 1, rb_yield(i));
1960  }
1961  return Qnil;
1962 }
1963 
1964 static VALUE
1965 lazy_grep_v(VALUE obj, VALUE pattern)
1966 {
1967  return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
1968  rb_block_given_p() ?
1969  lazy_grep_v_iter : lazy_grep_v_func,
1970  pattern),
1971  rb_ary_new3(1, pattern), 0);
1972 }
1973 
1974 static VALUE
1975 call_next(VALUE obj)
1976 {
1977  return rb_funcall(obj, id_next, 0);
1978 }
1979 
1980 static VALUE
1981 next_stopped(VALUE obj)
1982 {
1983  return Qnil;
1984 }
1985 
1986 static VALUE
1987 lazy_zip_arrays_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, arrays))
1988 {
1989  VALUE yielder, ary, memo;
1990  long i, count;
1991 
1992  yielder = argv[0];
1993  memo = rb_attr_get(yielder, id_memo);
1994  count = NIL_P(memo) ? 0 : NUM2LONG(memo);
1995 
1996  ary = rb_ary_new2(RARRAY_LEN(arrays) + 1);
1997  rb_ary_push(ary, argv[1]);
1998  for (i = 0; i < RARRAY_LEN(arrays); i++) {
1999  rb_ary_push(ary, rb_ary_entry(RARRAY_AREF(arrays, i), count));
2000  }
2001  rb_funcall(yielder, id_yield, 1, ary);
2002  rb_ivar_set(yielder, id_memo, LONG2NUM(++count));
2003  return Qnil;
2004 }
2005 
2006 static VALUE
2007 lazy_zip_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, zip_args))
2008 {
2009  VALUE yielder, ary, arg, v;
2010  long i;
2011 
2012  yielder = argv[0];
2013  arg = rb_attr_get(yielder, id_memo);
2014  if (NIL_P(arg)) {
2015  arg = rb_ary_new2(RARRAY_LEN(zip_args));
2016  for (i = 0; i < RARRAY_LEN(zip_args); i++) {
2017  rb_ary_push(arg, rb_funcall(RARRAY_AREF(zip_args, i), id_to_enum, 0));
2018  }
2019  rb_ivar_set(yielder, id_memo, arg);
2020  }
2021 
2022  ary = rb_ary_new2(RARRAY_LEN(arg) + 1);
2023  v = Qnil;
2024  if (--argc > 0) {
2025  ++argv;
2026  v = argc > 1 ? rb_ary_new_from_values(argc, argv) : *argv;
2027  }
2028  rb_ary_push(ary, v);
2029  for (i = 0; i < RARRAY_LEN(arg); i++) {
2030  v = rb_rescue2(call_next, RARRAY_AREF(arg, i), next_stopped, 0,
2031  rb_eStopIteration, (VALUE)0);
2032  rb_ary_push(ary, v);
2033  }
2034  rb_funcall(yielder, id_yield, 1, ary);
2035  return Qnil;
2036 }
2037 
2038 static VALUE
2039 lazy_zip(int argc, VALUE *argv, VALUE obj)
2040 {
2041  VALUE ary, v;
2042  long i;
2043  rb_block_call_func *func = lazy_zip_arrays_func;
2044 
2045  if (rb_block_given_p()) {
2046  return rb_call_super(argc, argv);
2047  }
2048 
2049  ary = rb_ary_new2(argc);
2050  for (i = 0; i < argc; i++) {
2051  v = rb_check_array_type(argv[i]);
2052  if (NIL_P(v)) {
2053  for (; i < argc; i++) {
2054  if (!rb_respond_to(argv[i], id_each)) {
2055  rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (must respond to :each)",
2056  rb_obj_class(argv[i]));
2057  }
2058  }
2059  ary = rb_ary_new4(argc, argv);
2060  func = lazy_zip_func;
2061  break;
2062  }
2063  rb_ary_push(ary, v);
2064  }
2065 
2066  return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
2067  func, ary),
2068  ary, lazy_receiver_size);
2069 }
2070 
2071 static struct MEMO *
2072 lazy_take_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2073 {
2074  long remain;
2075  struct proc_entry *entry = proc_entry_ptr(proc_entry);
2076  VALUE memo = rb_ary_entry(memos, memo_index);
2077 
2078  if (NIL_P(memo)) {
2079  memo = entry->memo;
2080  }
2081 
2082  remain = NUM2LONG(memo);
2083  if (remain == 0) {
2084  LAZY_MEMO_SET_BREAK(result);
2085  }
2086  else {
2087  if (--remain == 0) LAZY_MEMO_SET_BREAK(result);
2088  rb_ary_store(memos, memo_index, LONG2NUM(remain));
2089  }
2090  return result;
2091 }
2092 
2093 static VALUE
2094 lazy_take_size(VALUE entry, VALUE receiver)
2095 {
2096  long len = NUM2LONG(RARRAY_AREF(rb_ivar_get(entry, id_arguments), 0));
2097  if (NIL_P(receiver) || (FIXNUM_P(receiver) && FIX2LONG(receiver) < len))
2098  return receiver;
2099  return LONG2NUM(len);
2100 }
2101 
2102 static const lazyenum_funcs lazy_take_funcs = {
2103  lazy_take_proc, lazy_take_size,
2104 };
2105 
2106 static VALUE
2107 lazy_take(VALUE obj, VALUE n)
2108 {
2109  long len = NUM2LONG(n);
2110  int argc = 0;
2111  VALUE argv[2];
2112 
2113  if (len < 0) {
2114  rb_raise(rb_eArgError, "attempt to take negative size");
2115  }
2116 
2117  if (len == 0) {
2118  argv[0] = sym_cycle;
2119  argv[1] = INT2NUM(0);
2120  argc = 2;
2121  }
2122 
2123  return lazy_add_method(obj, argc, argv, n, rb_ary_new3(1, n), &lazy_take_funcs);
2124 }
2125 
2126 static struct MEMO *
2127 lazy_take_while_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2128 {
2129  VALUE take = lazyenum_yield_values(proc_entry, result);
2130  if (!RTEST(take)) {
2131  LAZY_MEMO_SET_BREAK(result);
2132  return 0;
2133  }
2134  return result;
2135 }
2136 
2137 static const lazyenum_funcs lazy_take_while_funcs = {
2138  lazy_take_while_proc, 0,
2139 };
2140 
2141 static VALUE
2142 lazy_take_while(VALUE obj)
2143 {
2144  if (!rb_block_given_p()) {
2145  rb_raise(rb_eArgError, "tried to call lazy take_while without a block");
2146  }
2147 
2148  return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_take_while_funcs);
2149 }
2150 
2151 static VALUE
2152 lazy_drop_size(VALUE proc_entry, VALUE receiver)
2153 {
2154  long len = NUM2LONG(RARRAY_AREF(rb_ivar_get(proc_entry, id_arguments), 0));
2155  if (NIL_P(receiver))
2156  return receiver;
2157  if (FIXNUM_P(receiver)) {
2158  len = FIX2LONG(receiver) - len;
2159  return LONG2FIX(len < 0 ? 0 : len);
2160  }
2161  return rb_funcall(receiver, '-', 1, LONG2NUM(len));
2162 }
2163 
2164 static struct MEMO *
2165 lazy_drop_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2166 {
2167  long remain;
2168  struct proc_entry *entry = proc_entry_ptr(proc_entry);
2169  VALUE memo = rb_ary_entry(memos, memo_index);
2170 
2171  if (NIL_P(memo)) {
2172  memo = entry->memo;
2173  }
2174  remain = NUM2LONG(memo);
2175  if (remain > 0) {
2176  --remain;
2177  rb_ary_store(memos, memo_index, LONG2NUM(remain));
2178  return 0;
2179  }
2180 
2181  return result;
2182 }
2183 
2184 static const lazyenum_funcs lazy_drop_funcs = {
2185  lazy_drop_proc, lazy_drop_size,
2186 };
2187 
2188 static VALUE
2189 lazy_drop(VALUE obj, VALUE n)
2190 {
2191  long len = NUM2LONG(n);
2192  VALUE argv[2];
2193  argv[0] = sym_each;
2194  argv[1] = n;
2195 
2196  if (len < 0) {
2197  rb_raise(rb_eArgError, "attempt to drop negative size");
2198  }
2199 
2200  return lazy_add_method(obj, 2, argv, n, rb_ary_new3(1, n), &lazy_drop_funcs);
2201 }
2202 
2203 static struct MEMO *
2204 lazy_drop_while_proc(VALUE proc_entry, struct MEMO* result, VALUE memos, long memo_index)
2205 {
2206  struct proc_entry *entry = proc_entry_ptr(proc_entry);
2207  VALUE memo = rb_ary_entry(memos, memo_index);
2208 
2209  if (NIL_P(memo)) {
2210  memo = entry->memo;
2211  }
2212 
2213  if (!RTEST(memo)) {
2214  VALUE drop = lazyenum_yield_values(proc_entry, result);
2215  if (RTEST(drop)) return 0;
2216  rb_ary_store(memos, memo_index, Qtrue);
2217  }
2218  return result;
2219 }
2220 
2221 static const lazyenum_funcs lazy_drop_while_funcs = {
2222  lazy_drop_while_proc, 0,
2223 };
2224 
2225 static VALUE
2226 lazy_drop_while(VALUE obj)
2227 {
2228  if (!rb_block_given_p()) {
2229  rb_raise(rb_eArgError, "tried to call lazy drop_while without a block");
2230  }
2231 
2232  return lazy_add_method(obj, 0, 0, Qfalse, Qnil, &lazy_drop_while_funcs);
2233 }
2234 
2235 static VALUE
2236 lazy_uniq_i(VALUE i, VALUE hash, int argc, const VALUE *argv, VALUE yielder)
2237 {
2238  if (rb_hash_add_new_element(hash, i, Qfalse))
2239  return Qnil;
2240  return rb_funcallv(yielder, id_yield, argc, argv);
2241 }
2242 
2243 static VALUE
2244 lazy_uniq_func(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
2245 {
2246  VALUE yielder = (--argc, *argv++);
2247  i = rb_enum_values_pack(argc, argv);
2248  return lazy_uniq_i(i, hash, argc, argv, yielder);
2249 }
2250 
2251 static VALUE
2252 lazy_uniq_iter(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
2253 {
2254  VALUE yielder = (--argc, *argv++);
2255  i = rb_yield_values2(argc, argv);
2256  return lazy_uniq_i(i, hash, argc, argv, yielder);
2257 }
2258 
2259 static VALUE
2260 lazy_uniq(VALUE obj)
2261 {
2262  rb_block_call_func *const func =
2263  rb_block_given_p() ? lazy_uniq_iter : lazy_uniq_func;
2264  VALUE hash = rb_obj_hide(rb_hash_new());
2265  return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
2266  func, hash),
2267  0, 0);
2268 }
2269 
2270 static VALUE
2271 lazy_super(int argc, VALUE *argv, VALUE lazy)
2272 {
2273  return enumerable_lazy(rb_call_super(argc, argv));
2274 }
2275 
2276 static VALUE
2277 lazy_lazy(VALUE obj)
2278 {
2279  return obj;
2280 }
2281 
2282 /*
2283  * Document-class: StopIteration
2284  *
2285  * Raised to stop the iteration, in particular by Enumerator#next. It is
2286  * rescued by Kernel#loop.
2287  *
2288  * loop do
2289  * puts "Hello"
2290  * raise StopIteration
2291  * puts "World"
2292  * end
2293  * puts "Done!"
2294  *
2295  * <em>produces:</em>
2296  *
2297  * Hello
2298  * Done!
2299  */
2300 
2301 /*
2302  * call-seq:
2303  * result -> value
2304  *
2305  * Returns the return value of the iterator.
2306  *
2307  * o = Object.new
2308  * def o.each
2309  * yield 1
2310  * yield 2
2311  * yield 3
2312  * 100
2313  * end
2314  *
2315  * e = o.to_enum
2316  *
2317  * puts e.next #=> 1
2318  * puts e.next #=> 2
2319  * puts e.next #=> 3
2320  *
2321  * begin
2322  * e.next
2323  * rescue StopIteration => ex
2324  * puts ex.result #=> 100
2325  * end
2326  *
2327  */
2328 
2329 static VALUE
2330 stop_result(VALUE self)
2331 {
2332  return rb_attr_get(self, id_result);
2333 }
2334 
2335 void
2337 {
2338  rb_define_method(rb_mKernel, "to_enum", obj_to_enum, -1);
2339  rb_define_method(rb_mKernel, "enum_for", obj_to_enum, -1);
2340 
2341  rb_cEnumerator = rb_define_class("Enumerator", rb_cObject);
2343 
2344  rb_define_alloc_func(rb_cEnumerator, enumerator_allocate);
2345  rb_define_method(rb_cEnumerator, "initialize", enumerator_initialize, -1);
2346  rb_define_method(rb_cEnumerator, "initialize_copy", enumerator_init_copy, 1);
2347  rb_define_method(rb_cEnumerator, "each", enumerator_each, -1);
2348  rb_define_method(rb_cEnumerator, "each_with_index", enumerator_each_with_index, 0);
2349  rb_define_method(rb_cEnumerator, "each_with_object", enumerator_with_object, 1);
2350  rb_define_method(rb_cEnumerator, "with_index", enumerator_with_index, -1);
2351  rb_define_method(rb_cEnumerator, "with_object", enumerator_with_object, 1);
2352  rb_define_method(rb_cEnumerator, "next_values", enumerator_next_values, 0);
2353  rb_define_method(rb_cEnumerator, "peek_values", enumerator_peek_values_m, 0);
2354  rb_define_method(rb_cEnumerator, "next", enumerator_next, 0);
2355  rb_define_method(rb_cEnumerator, "peek", enumerator_peek, 0);
2356  rb_define_method(rb_cEnumerator, "feed", enumerator_feed, 1);
2357  rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);
2358  rb_define_method(rb_cEnumerator, "inspect", enumerator_inspect, 0);
2359  rb_define_method(rb_cEnumerator, "size", enumerator_size, 0);
2360 
2361  /* Lazy */
2363  rb_define_method(rb_mEnumerable, "lazy", enumerable_lazy, 0);
2364  rb_define_method(rb_cLazy, "initialize", lazy_initialize, -1);
2365  rb_define_method(rb_cLazy, "to_enum", lazy_to_enum, -1);
2366  rb_define_method(rb_cLazy, "enum_for", lazy_to_enum, -1);
2367  rb_define_method(rb_cLazy, "map", lazy_map, 0);
2368  rb_define_method(rb_cLazy, "collect", lazy_map, 0);
2369  rb_define_method(rb_cLazy, "flat_map", lazy_flat_map, 0);
2370  rb_define_method(rb_cLazy, "collect_concat", lazy_flat_map, 0);
2371  rb_define_method(rb_cLazy, "select", lazy_select, 0);
2372  rb_define_method(rb_cLazy, "find_all", lazy_select, 0);
2373  rb_define_method(rb_cLazy, "reject", lazy_reject, 0);
2374  rb_define_method(rb_cLazy, "grep", lazy_grep, 1);
2375  rb_define_method(rb_cLazy, "grep_v", lazy_grep_v, 1);
2376  rb_define_method(rb_cLazy, "zip", lazy_zip, -1);
2377  rb_define_method(rb_cLazy, "take", lazy_take, 1);
2378  rb_define_method(rb_cLazy, "take_while", lazy_take_while, 0);
2379  rb_define_method(rb_cLazy, "drop", lazy_drop, 1);
2380  rb_define_method(rb_cLazy, "drop_while", lazy_drop_while, 0);
2381  rb_define_method(rb_cLazy, "lazy", lazy_lazy, 0);
2382  rb_define_method(rb_cLazy, "chunk", lazy_super, -1);
2383  rb_define_method(rb_cLazy, "slice_before", lazy_super, -1);
2384  rb_define_method(rb_cLazy, "slice_after", lazy_super, -1);
2385  rb_define_method(rb_cLazy, "slice_when", lazy_super, -1);
2386  rb_define_method(rb_cLazy, "chunk_while", lazy_super, -1);
2387  rb_define_method(rb_cLazy, "uniq", lazy_uniq, 0);
2388 
2389  rb_define_alias(rb_cLazy, "force", "to_a");
2390 
2391  rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
2392  rb_define_method(rb_eStopIteration, "result", stop_result, 0);
2393 
2394  /* Generator */
2395  rb_cGenerator = rb_define_class_under(rb_cEnumerator, "Generator", rb_cObject);
2396  rb_include_module(rb_cGenerator, rb_mEnumerable);
2397  rb_define_alloc_func(rb_cGenerator, generator_allocate);
2398  rb_define_method(rb_cGenerator, "initialize", generator_initialize, -1);
2399  rb_define_method(rb_cGenerator, "initialize_copy", generator_init_copy, 1);
2400  rb_define_method(rb_cGenerator, "each", generator_each, -1);
2401 
2402  /* Yielder */
2403  rb_cYielder = rb_define_class_under(rb_cEnumerator, "Yielder", rb_cObject);
2404  rb_define_alloc_func(rb_cYielder, yielder_allocate);
2405  rb_define_method(rb_cYielder, "initialize", yielder_initialize, 0);
2406  rb_define_method(rb_cYielder, "yield", yielder_yield, -2);
2407  rb_define_method(rb_cYielder, "<<", yielder_yield_push, -2);
2408 
2409  rb_provide("enumerator.so"); /* for backward compatibility */
2410 }
2411 
2412 #undef rb_intern
2413 void
2415 {
2416  id_rewind = rb_intern("rewind");
2417  id_each = rb_intern("each");
2418  id_call = rb_intern("call");
2419  id_size = rb_intern("size");
2420  id_yield = rb_intern("yield");
2421  id_new = rb_intern("new");
2422  id_initialize = rb_intern("initialize");
2423  id_next = rb_intern("next");
2424  id_result = rb_intern("result");
2425  id_lazy = rb_intern("lazy");
2426  id_eqq = rb_intern("===");
2427  id_receiver = rb_intern("receiver");
2428  id_arguments = rb_intern("arguments");
2429  id_memo = rb_intern("memo");
2430  id_method = rb_intern("method");
2431  id_force = rb_intern("force");
2432  id_to_enum = rb_intern("to_enum");
2433  sym_each = ID2SYM(id_each);
2434  sym_cycle = ID2SYM(rb_intern("cycle"));
2435 
2436  InitVM(Enumerator);
2437 }
#define T_SYMBOL
Definition: ruby.h:508
VALUE size
Definition: enumerator.c:120
#define rb_exc_new2
Definition: intern.h:243
void rb_warn(const char *fmt,...)
Definition: error.c:246
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1215
#define RARRAY_LEN(a)
Definition: ruby.h:1019
VALUE rb_proc_call_with_block(VALUE, int argc, const VALUE *argv, VALUE)
Definition: proc.c:892
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1138
#define id_each
Definition: enum.c:24
#define INT2NUM(x)
Definition: ruby.h:1538
#define LAZY_MEMO_PACKED
Definition: enumerator.c:1446
VALUE rb_yield_values(int n,...)
Definition: vm_eval.c:985
int count
Definition: encoding.c:56
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:835
VALUE feedvalue
Definition: enumerator.c:118
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2284
#define InitVM(ext)
Definition: ruby.h:2164
#define Qtrue
Definition: ruby.h:437
VALUE rb_enumerator_size_func(VALUE, VALUE, VALUE)
Definition: intern.h:225
VALUE rb_fiber_resume(VALUE fibval, int argc, const VALUE *argv)
Definition: cont.c:1590
#define OBJ_INIT_COPY(obj, orig)
Definition: intern.h:283
#define rb_id2str(id)
Definition: vm_backtrace.c:29
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:3150
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1183
#define rb_check_arity
Definition: intern.h:298
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:924
#define rb_long2int(n)
Definition: ruby.h:319
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
VALUE rb_cEnumerator
Definition: enumerator.c:103
VALUE rb_fiber_alive_p(VALUE fibval)
Definition: cont.c:1631
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:693
#define Check_Type(v, t)
Definition: ruby.h:562
VALUE obj
Definition: enumerator.c:112
VALUE rb_obj_dup(VALUE)
call-seq: obj.dup -> an_object
Definition: object.c:526
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1210
VALUE rb_fiber_current(void)
Definition: cont.c:1419
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:4709
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE proc
Definition: enumerator.c:128
#define generator_free
Definition: enumerator.c:1261
#define DATA_PTR(dta)
Definition: ruby.h:1106
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:864
VALUE rb_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
void rb_gc_mark(VALUE ptr)
Definition: gc.c:4464
#define T_ARRAY
Definition: ruby.h:498
#define MEMO_NEW(a, b, c)
Definition: internal.h:963
#define FIXNUM_P(f)
Definition: ruby.h:365
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:656
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
Definition: array.c:936
VALUE rb_str_buf_append(VALUE, VALUE)
Definition: string.c:2884
#define LAZY_MEMO_SET_VALUE(memo, value)
Definition: enumerator.c:1450
VALUE rb_rescue2(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2,...)
An equivalent of rescue clause.
Definition: eval.c:895
#define rb_ary_new2
Definition: intern.h:90
VALUE rb_eArgError
Definition: error.c:802
void InitVM_Enumerator(void)
Definition: enumerator.c:2336
rb_enumerator_size_func * size_fn
Definition: enumerator.c:122
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Definition: ruby.h:1851
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class
Definition: object.c:277
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
ID id_next
Definition: eventids1.c:72
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
Definition: object.c:842
VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
Definition: ruby.h:1853
void rb_iter_break(void)
Definition: vm.c:1491
VALUE rb_enumeratorize_with_size(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn)
Definition: enumerator.c:459
#define val
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
#define id_size
Definition: enum.c:29
VALUE rb_ary_new(void)
Definition: array.c:499
VALUE rb_str_buf_cat2(VALUE, const char *)
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1881
VALUE rb_eIndexError
Definition: error.c:803
#define LAZY_MEMO_RESET_PACKED(memo)
Definition: enumerator.c:1452
#define NIL_P(v)
Definition: ruby.h:451
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:646
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:815
VALUE proc
Definition: enumerator.c:133
lazyenum_size_func * size
Definition: enumerator.c:140
MEMO.
Definition: internal.h:945
struct MEMO * lazyenum_proc_func(VALUE, struct MEMO *, VALUE, long)
Definition: enumerator.c:136
VALUE rb_fiber_new(VALUE(*func)(ANYARGS), VALUE obj)
Definition: cont.c:1317
#define T_FLOAT
Definition: ruby.h:495
int argc
Definition: ruby.c:187
#define Qfalse
Definition: ruby.h:436
#define ALLOCV_N(type, v, n)
Definition: ruby.h:1657
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1661
VALUE rb_cLazy
Definition: enumerator.c:104
#define rb_ary_new4
Definition: intern.h:92
#define LAZY_MEMO_SET_BREAK(memo)
Definition: enumerator.c:1449
VALUE lookahead
Definition: enumerator.c:117
#define ALLOCV_END(v)
Definition: ruby.h:1658
VALUE rb_int_succ(VALUE num)
Definition: numeric.c:3229
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1758
#define enumerator_free
Definition: enumerator.c:170
VALUE rb_yield(VALUE)
Definition: vm_eval.c:973
#define RARRAY_CONST_PTR(a)
Definition: ruby.h:1021
void rb_need_block(void)
Declares that the current method needs a block.
Definition: eval.c:865
VALUE rb_obj_is_proc(VALUE)
Definition: proc.c:116
VALUE rb_mEnumerable
Definition: enum.c:19
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1452
#define MEMO_V1_SET(m, v)
Definition: internal.h:958
#define const
Definition: strftime.c:103
VALUE rb_class_path(VALUE)
Definition: variable.c:295
VALUE rb_fiber_yield(int argc, const VALUE *argv)
Definition: cont.c:1606
VALUE rb_hash_new(void)
Definition: hash.c:424
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1908
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1315
VALUE lazyenum_size_func(VALUE, VALUE)
Definition: enumerator.c:137
#define PRIsVALUE
Definition: ruby.h:135
unsigned long ID
Definition: ruby.h:86
ID id_call
Definition: eventids1.c:28
VALUE fib
Definition: enumerator.c:115
#define Qnil
Definition: ruby.h:438
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:615
VALUE rb_eStopIteration
Definition: enumerator.c:109
unsigned long VALUE
Definition: ruby.h:85
#define rb_funcall2
Definition: ruby.h:1791
VALUE proc
Definition: enumerator.c:144
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: intern.h:234
VALUE rb_eTypeError
Definition: error.c:801
#define rb_ary_new3
Definition: intern.h:91
VALUE stop_exc
Definition: enumerator.c:119
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:389
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:238
#define INFINITY
Definition: missing.h:149
VALUE rb_proc_call(VALUE, VALUE)
Definition: proc.c:872
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
Definition: object.c:72
#define RARRAY_LENINT(ary)
Definition: ruby.h:1020
#define LAZY_MEMO_BREAK_P(memo)
Definition: enumerator.c:1447
ID id_yield
Definition: eventids1.c:131
#define LONG2NUM(x)
Definition: ruby.h:1573
#define rb_funcallv
Definition: console.c:21
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1994
register unsigned int len
Definition: zonetab.h:51
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
Definition: array.c:538
VALUE memo
Definition: enumerator.c:145
#define recur(fmt)
VALUE dst
Definition: enumerator.c:116
#define RFLOAT_VALUE(v)
Definition: ruby.h:933
VALUE rb_yield_values2(int n, const VALUE *argv)
Definition: vm_eval.c:1007
#define INT2FIX(i)
Definition: ruby.h:232
#define UNLIMITED_ARGUMENTS
Definition: intern.h:44
VALUE rb_enum_values_pack(int argc, const VALUE *argv)
Definition: enum.c:32
#define RARRAY_AREF(a, i)
Definition: ruby.h:1033
const VALUE v1
Definition: internal.h:948
VALUE rb_block_proc(void)
Definition: proc.c:780
lazyenum_proc_func * proc
Definition: enumerator.c:139
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:651
ID rb_frame_this_func(void)
The original name of the current method.
Definition: eval.c:1103
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, const VALUE *argv)
Definition: enumerator.c:450
#define LONG2FIX(i)
Definition: ruby.h:234
#define RTEST(v)
Definition: ruby.h:450
VALUE rb_proc_new(VALUE(*)(ANYARGS), VALUE)
Definition: proc.c:2649
#define OBJ_INFECT(x, s)
Definition: ruby.h:1302
void Init_Enumerator(void)
Definition: enumerator.c:2414
#define LAZY_MEMO_PACKED_P(memo)
Definition: enumerator.c:1448
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1175
VALUE rb_ary_dup(VALUE ary)
Definition: array.c:1930
VALUE procs
Definition: enumerator.c:121
#define ID2SYM(x)
Definition: ruby.h:383
const lazyenum_funcs * fn
Definition: enumerator.c:146
VALUE args
Definition: enumerator.c:114
Definition: enumerator.c:143
#define proc_entry_free
Definition: enumerator.c:208
#define rb_check_frozen(obj)
Definition: intern.h:271
#define yielder_free
Definition: enumerator.c:1153
#define rb_intern(str)
#define NULL
Definition: _sdbm.c:102
#define FIX2LONG(x)
Definition: ruby.h:363
#define Qundef
Definition: ruby.h:439
#define OBJ_TAINT(x)
Definition: ruby.h:1298
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2900
const VALUE value
Definition: internal.h:953
void rb_provide(const char *)
Definition: load.c:572
ID rb_to_id(VALUE)
Definition: string.c:10496
VALUE obj
Definition: enumerator.c:129
#define NUM2LONG(x)
Definition: ruby.h:648
VALUE rb_to_int(VALUE)
Converts val into Integer.
Definition: object.c:3084
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1224
#define id_eqq
Definition: enum.c:25
char ** argv
Definition: ruby.c:188
#define rb_sym2str(sym)
Definition: console.c:107