Ruby  2.7.2p137(2020-10-01revision5445e0435260b449decf2ac16f9d09bae3cafe72)
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 "ruby/ruby.h"
16 #include "internal.h"
17 #include "id.h"
18 
19 #ifdef HAVE_FLOAT_H
20 #include <float.h>
21 #endif
22 
23 /*
24  * Document-class: Enumerator
25  *
26  * A class which allows both internal and external iteration.
27  *
28  * An Enumerator can be created by the following methods.
29  * - Object#to_enum
30  * - Object#enum_for
31  * - Enumerator.new
32  *
33  * Most methods have two forms: a block form where the contents
34  * are evaluated for each item in the enumeration, and a non-block form
35  * which returns a new Enumerator wrapping the iteration.
36  *
37  * enumerator = %w(one two three).each
38  * puts enumerator.class # => Enumerator
39  *
40  * enumerator.each_with_object("foo") do |item, obj|
41  * puts "#{obj}: #{item}"
42  * end
43  *
44  * # foo: one
45  * # foo: two
46  * # foo: three
47  *
48  * enum_with_obj = enumerator.each_with_object("foo")
49  * puts enum_with_obj.class # => Enumerator
50  *
51  * enum_with_obj.each do |item, obj|
52  * puts "#{obj}: #{item}"
53  * end
54  *
55  * # foo: one
56  * # foo: two
57  * # foo: three
58  *
59  * This allows you to chain Enumerators together. For example, you
60  * can map a list's elements to strings containing the index
61  * and the element as a string via:
62  *
63  * puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" }
64  * # => ["0:foo", "1:bar", "2:baz"]
65  *
66  * An Enumerator can also be used as an external iterator.
67  * For example, Enumerator#next returns the next value of the iterator
68  * or raises StopIteration if the Enumerator is at the end.
69  *
70  * e = [1,2,3].each # returns an enumerator object.
71  * puts e.next # => 1
72  * puts e.next # => 2
73  * puts e.next # => 3
74  * puts e.next # raises StopIteration
75  *
76  * You can use this to implement an internal iterator as follows:
77  *
78  * def ext_each(e)
79  * while true
80  * begin
81  * vs = e.next_values
82  * rescue StopIteration
83  * return $!.result
84  * end
85  * y = yield(*vs)
86  * e.feed y
87  * end
88  * end
89  *
90  * o = Object.new
91  *
92  * def o.each
93  * puts yield
94  * puts yield(1)
95  * puts yield(1, 2)
96  * 3
97  * end
98  *
99  * # use o.each as an internal iterator directly.
100  * puts o.each {|*x| puts x; [:b, *x] }
101  * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
102  *
103  * # convert o.each to an external iterator for
104  * # implementing an internal iterator.
105  * puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] }
106  * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
107  *
108  */
110 static VALUE rb_cLazy;
111 static ID id_rewind, id_new, id_to_enum;
112 static ID id_next, id_result, id_receiver, id_arguments, id_memo, id_method, id_force;
113 static ID id_begin, id_end, id_step, id_exclude_end;
114 static VALUE sym_each, sym_cycle, sym_yield;
115 
116 static VALUE lazy_use_super_method;
117 
118 #define id_call idCall
119 #define id_each idEach
120 #define id_eqq idEqq
121 #define id_initialize idInitialize
122 #define id_size idSize
123 
125 
126 struct enumerator {
138  int kw_splat;
139 };
140 
141 static VALUE rb_cGenerator, rb_cYielder, rb_cEnumProducer;
142 
143 struct generator {
146 };
147 
148 struct yielder {
150 };
151 
152 struct producer {
155 };
156 
157 typedef struct MEMO *lazyenum_proc_func(VALUE, struct MEMO *, VALUE, long);
159 typedef struct {
163 
164 struct proc_entry {
168 };
169 
170 static VALUE generator_allocate(VALUE klass);
171 static VALUE generator_init(VALUE obj, VALUE proc);
172 
173 static VALUE rb_cEnumChain;
174 
175 struct enum_chain {
177  long pos;
178 };
179 
181 
182 /*
183  * Enumerator
184  */
185 static void
186 enumerator_mark(void *p)
187 {
188  struct enumerator *ptr = p;
189  rb_gc_mark_movable(ptr->obj);
190  rb_gc_mark_movable(ptr->args);
191  rb_gc_mark_movable(ptr->fib);
192  rb_gc_mark_movable(ptr->dst);
193  rb_gc_mark_movable(ptr->lookahead);
194  rb_gc_mark_movable(ptr->feedvalue);
195  rb_gc_mark_movable(ptr->stop_exc);
196  rb_gc_mark_movable(ptr->size);
197  rb_gc_mark_movable(ptr->procs);
198 }
199 
200 static void
201 enumerator_compact(void *p)
202 {
203  struct enumerator *ptr = p;
204  ptr->obj = rb_gc_location(ptr->obj);
205  ptr->args = rb_gc_location(ptr->args);
206  ptr->fib = rb_gc_location(ptr->fib);
207  ptr->dst = rb_gc_location(ptr->dst);
208  ptr->lookahead = rb_gc_location(ptr->lookahead);
209  ptr->feedvalue = rb_gc_location(ptr->feedvalue);
210  ptr->stop_exc = rb_gc_location(ptr->stop_exc);
211  ptr->size = rb_gc_location(ptr->size);
212  ptr->procs = rb_gc_location(ptr->procs);
213 }
214 
215 #define enumerator_free RUBY_TYPED_DEFAULT_FREE
216 
217 static size_t
218 enumerator_memsize(const void *p)
219 {
220  return sizeof(struct enumerator);
221 }
222 
223 static const rb_data_type_t enumerator_data_type = {
224  "enumerator",
225  {
226  enumerator_mark,
228  enumerator_memsize,
229  enumerator_compact,
230  },
232 };
233 
234 static struct enumerator *
235 enumerator_ptr(VALUE obj)
236 {
237  struct enumerator *ptr;
238 
239  TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, ptr);
240  if (!ptr || ptr->obj == Qundef) {
241  rb_raise(rb_eArgError, "uninitialized enumerator");
242  }
243  return ptr;
244 }
245 
246 static void
247 proc_entry_mark(void *p)
248 {
249  struct proc_entry *ptr = p;
250  rb_gc_mark_movable(ptr->proc);
251  rb_gc_mark_movable(ptr->memo);
252 }
253 
254 static void
255 proc_entry_compact(void *p)
256 {
257  struct proc_entry *ptr = p;
258  ptr->proc = rb_gc_location(ptr->proc);
259  ptr->memo = rb_gc_location(ptr->memo);
260 }
261 
262 #define proc_entry_free RUBY_TYPED_DEFAULT_FREE
263 
264 static size_t
265 proc_entry_memsize(const void *p)
266 {
267  return p ? sizeof(struct proc_entry) : 0;
268 }
269 
270 static const rb_data_type_t proc_entry_data_type = {
271  "proc_entry",
272  {
273  proc_entry_mark,
275  proc_entry_memsize,
276  proc_entry_compact,
277  },
278 };
279 
280 static struct proc_entry *
281 proc_entry_ptr(VALUE proc_entry)
282 {
283  struct proc_entry *ptr;
284 
285  TypedData_Get_Struct(proc_entry, struct proc_entry, &proc_entry_data_type, ptr);
286 
287  return ptr;
288 }
289 
290 /*
291  * call-seq:
292  * obj.to_enum(method = :each, *args) -> enum
293  * obj.enum_for(method = :each, *args) -> enum
294  * obj.to_enum(method = :each, *args) {|*args| block} -> enum
295  * obj.enum_for(method = :each, *args){|*args| block} -> enum
296  *
297  * Creates a new Enumerator which will enumerate by calling +method+ on
298  * +obj+, passing +args+ if any. What was _yielded_ by method becomes
299  * values of enumerator.
300  *
301  * If a block is given, it will be used to calculate the size of
302  * the enumerator without the need to iterate it (see Enumerator#size).
303  *
304  * === Examples
305  *
306  * str = "xyz"
307  *
308  * enum = str.enum_for(:each_byte)
309  * enum.each { |b| puts b }
310  * # => 120
311  * # => 121
312  * # => 122
313  *
314  * # protect an array from being modified by some_method
315  * a = [1, 2, 3]
316  * some_method(a.to_enum)
317  *
318  * # String#split in block form is more memory-effective:
319  * very_large_string.split("|") { |chunk| return chunk if chunk.include?('DATE') }
320  * # This could be rewritten more idiomatically with to_enum:
321  * very_large_string.to_enum(:split, "|").lazy.grep(/DATE/).first
322  *
323  * It is typical to call to_enum when defining methods for
324  * a generic Enumerable, in case no block is passed.
325  *
326  * Here is such an example, with parameter passing and a sizing block:
327  *
328  * module Enumerable
329  * # a generic method to repeat the values of any enumerable
330  * def repeat(n)
331  * raise ArgumentError, "#{n} is negative!" if n < 0
332  * unless block_given?
333  * return to_enum(__method__, n) do # __method__ is :repeat here
334  * sz = size # Call size and multiply by n...
335  * sz * n if sz # but return nil if size itself is nil
336  * end
337  * end
338  * each do |*val|
339  * n.times { yield *val }
340  * end
341  * end
342  * end
343  *
344  * %i[hello world].repeat(2) { |w| puts w }
345  * # => Prints 'hello', 'hello', 'world', 'world'
346  * enum = (1..14).repeat(3)
347  * # => returns an Enumerator when called without a block
348  * enum.first(4) # => [1, 1, 1, 2]
349  * enum.size # => 42
350  */
351 static VALUE
352 obj_to_enum(int argc, VALUE *argv, VALUE obj)
353 {
354  VALUE enumerator, meth = sym_each;
355 
356  if (argc > 0) {
357  --argc;
358  meth = *argv++;
359  }
361  if (rb_block_given_p()) {
362  enumerator_ptr(enumerator)->size = rb_block_proc();
363  }
364  return enumerator;
365 }
366 
367 static VALUE
368 enumerator_allocate(VALUE klass)
369 {
370  struct enumerator *ptr;
371  VALUE enum_obj;
372 
373  enum_obj = TypedData_Make_Struct(klass, struct enumerator, &enumerator_data_type, ptr);
374  ptr->obj = Qundef;
375 
376  return enum_obj;
377 }
378 
379 #define PASS_KW_SPLAT (rb_empty_keyword_given_p() ? RB_PASS_EMPTY_KEYWORDS : rb_keyword_given_p())
380 
381 static VALUE
382 enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, VALUE size, int kw_splat)
383 {
384  struct enumerator *ptr;
385 
386  rb_check_frozen(enum_obj);
387  TypedData_Get_Struct(enum_obj, struct enumerator, &enumerator_data_type, ptr);
388 
389  if (!ptr) {
390  rb_raise(rb_eArgError, "unallocated enumerator");
391  }
392 
393  ptr->obj = obj;
394  ptr->meth = rb_to_id(meth);
395  if (argc) ptr->args = rb_ary_new4(argc, argv);
396  ptr->fib = 0;
397  ptr->dst = Qnil;
398  ptr->lookahead = Qundef;
399  ptr->feedvalue = Qundef;
400  ptr->stop_exc = Qfalse;
401  ptr->size = size;
402  ptr->size_fn = size_fn;
403  ptr->kw_splat = kw_splat;
404 
405  return enum_obj;
406 }
407 
408 /*
409  * call-seq:
410  * Enumerator.new(size = nil) { |yielder| ... }
411  * Enumerator.new(obj, method = :each, *args)
412  *
413  * Creates a new Enumerator object, which can be used as an
414  * Enumerable.
415  *
416  * In the first form, iteration is defined by the given block, in
417  * which a "yielder" object, given as block parameter, can be used to
418  * yield a value by calling the +yield+ method (aliased as <code><<</code>):
419  *
420  * fib = Enumerator.new do |y|
421  * a = b = 1
422  * loop do
423  * y << a
424  * a, b = b, a + b
425  * end
426  * end
427  *
428  * fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
429  *
430  * The optional parameter can be used to specify how to calculate the size
431  * in a lazy fashion (see Enumerator#size). It can either be a value or
432  * a callable object.
433  *
434  * In the deprecated second form, a generated Enumerator iterates over the
435  * given object using the given method with the given arguments passed.
436  *
437  * Use of this form is discouraged. Use Object#enum_for or Object#to_enum
438  * instead.
439  *
440  * e = Enumerator.new(ObjectSpace, :each_object)
441  * #-> ObjectSpace.enum_for(:each_object)
442  *
443  * e.select { |obj| obj.is_a?(Class) } # => array of all classes
444  *
445  */
446 static VALUE
447 enumerator_initialize(int argc, VALUE *argv, VALUE obj)
448 {
449  VALUE recv, meth = sym_each;
450  VALUE size = Qnil;
451  int kw_splat = 0;
452 
453  if (rb_block_given_p()) {
454  rb_check_arity(argc, 0, 1);
455  recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc());
456  if (argc) {
457  if (NIL_P(argv[0]) || rb_respond_to(argv[0], id_call) ||
458  (RB_TYPE_P(argv[0], T_FLOAT) && RFLOAT_VALUE(argv[0]) == HUGE_VAL)) {
459  size = argv[0];
460  }
461  else {
462  size = rb_to_int(argv[0]);
463  }
464  argc = 0;
465  }
466  }
467  else {
469  rb_warn_deprecated("Enumerator.new without a block", "Object#to_enum");
470  recv = *argv++;
471  if (--argc) {
472  meth = *argv++;
473  --argc;
474  }
476  }
477 
478  return enumerator_init(obj, recv, meth, argc, argv, 0, size, kw_splat);
479 }
480 
481 /* :nodoc: */
482 static VALUE
483 enumerator_init_copy(VALUE obj, VALUE orig)
484 {
485  struct enumerator *ptr0, *ptr1;
486 
487  if (!OBJ_INIT_COPY(obj, orig)) return obj;
488  ptr0 = enumerator_ptr(orig);
489  if (ptr0->fib) {
490  /* Fibers cannot be copied */
491  rb_raise(rb_eTypeError, "can't copy execution context");
492  }
493 
494  TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, ptr1);
495 
496  if (!ptr1) {
497  rb_raise(rb_eArgError, "unallocated enumerator");
498  }
499 
500  ptr1->obj = ptr0->obj;
501  ptr1->meth = ptr0->meth;
502  ptr1->args = ptr0->args;
503  ptr1->fib = 0;
504  ptr1->lookahead = Qundef;
505  ptr1->feedvalue = Qundef;
506  ptr1->size = ptr0->size;
507  ptr1->size_fn = ptr0->size_fn;
508 
509  return obj;
510 }
511 
512 /*
513  * For backwards compatibility; use rb_enumeratorize_with_size
514  */
515 VALUE
517 {
519 }
520 
521 static VALUE
522 lazy_to_enum_i(VALUE self, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, int kw_splat);
523 
524 VALUE
526 {
527  /* Similar effect as calling obj.to_enum, i.e. dispatching to either
528  Kernel#to_enum vs Lazy#to_enum */
529  if (RTEST(rb_obj_is_kind_of(obj, rb_cLazy)))
530  return lazy_to_enum_i(obj, meth, argc, argv, size_fn, PASS_KW_SPLAT);
531  else
532  return enumerator_init(enumerator_allocate(rb_cEnumerator),
534 }
535 
536 VALUE
538 {
539  /* Similar effect as calling obj.to_enum, i.e. dispatching to either
540  Kernel#to_enum vs Lazy#to_enum */
541  if (RTEST(rb_obj_is_kind_of(obj, rb_cLazy)))
542  return lazy_to_enum_i(obj, meth, argc, argv, size_fn, kw_splat);
543  else
544  return enumerator_init(enumerator_allocate(rb_cEnumerator),
546 }
547 
548 static VALUE
549 enumerator_block_call(VALUE obj, rb_block_call_func *func, VALUE arg)
550 {
551  int argc = 0;
552  const VALUE *argv = 0;
553  const struct enumerator *e = enumerator_ptr(obj);
554  ID meth = e->meth;
555 
556  if (e->args) {
557  argc = RARRAY_LENINT(e->args);
558  argv = RARRAY_CONST_PTR(e->args);
559  }
560  return rb_block_call_kw(e->obj, meth, argc, argv, func, arg, e->kw_splat);
561 }
562 
563 /*
564  * call-seq:
565  * enum.each { |elm| block } -> obj
566  * enum.each -> enum
567  * enum.each(*appending_args) { |elm| block } -> obj
568  * enum.each(*appending_args) -> an_enumerator
569  *
570  * Iterates over the block according to how this Enumerator was constructed.
571  * If no block and no arguments are given, returns self.
572  *
573  * === Examples
574  *
575  * "Hello, world!".scan(/\w+/) #=> ["Hello", "world"]
576  * "Hello, world!".to_enum(:scan, /\w+/).to_a #=> ["Hello", "world"]
577  * "Hello, world!".to_enum(:scan).each(/\w+/).to_a #=> ["Hello", "world"]
578  *
579  * obj = Object.new
580  *
581  * def obj.each_arg(a, b=:b, *rest)
582  * yield a
583  * yield b
584  * yield rest
585  * :method_returned
586  * end
587  *
588  * enum = obj.to_enum :each_arg, :a, :x
589  *
590  * enum.each.to_a #=> [:a, :x, []]
591  * enum.each.equal?(enum) #=> true
592  * enum.each { |elm| elm } #=> :method_returned
593  *
594  * enum.each(:y, :z).to_a #=> [:a, :x, [:y, :z]]
595  * enum.each(:y, :z).equal?(enum) #=> false
596  * enum.each(:y, :z) { |elm| elm } #=> :method_returned
597  *
598  */
599 static VALUE
600 enumerator_each(int argc, VALUE *argv, VALUE obj)
601 {
602  if (argc > 0) {
603  struct enumerator *e = enumerator_ptr(obj = rb_obj_dup(obj));
604  VALUE args = e->args;
605  if (args) {
606 #if SIZEOF_INT < SIZEOF_LONG
607  /* check int range overflow */
609 #endif
610  args = rb_ary_dup(args);
612  }
613  else {
615  }
616  e->args = args;
617  e->size = Qnil;
618  e->size_fn = 0;
619  }
620  if (!rb_block_given_p()) return obj;
621  return enumerator_block_call(obj, 0, obj);
622 }
623 
624 static VALUE
625 enumerator_with_index_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
626 {
627  struct MEMO *memo = (struct MEMO *)m;
628  VALUE idx = memo->v1;
629  MEMO_V1_SET(memo, rb_int_succ(idx));
630 
631  if (argc <= 1)
632  return rb_yield_values(2, val, idx);
633 
634  return rb_yield_values(2, rb_ary_new4(argc, argv), idx);
635 }
636 
637 static VALUE
638 enumerator_size(VALUE obj);
639 
640 static VALUE
641 enumerator_enum_size(VALUE obj, VALUE args, VALUE eobj)
642 {
643  return enumerator_size(obj);
644 }
645 
646 /*
647  * call-seq:
648  * e.with_index(offset = 0) {|(*args), idx| ... }
649  * e.with_index(offset = 0)
650  *
651  * Iterates the given block for each element with an index, which
652  * starts from +offset+. If no block is given, returns a new Enumerator
653  * that includes the index, starting from +offset+
654  *
655  * +offset+:: the starting index to use
656  *
657  */
658 static VALUE
659 enumerator_with_index(int argc, VALUE *argv, VALUE obj)
660 {
661  VALUE memo;
662 
663  rb_check_arity(argc, 0, 1);
664  RETURN_SIZED_ENUMERATOR(obj, argc, argv, enumerator_enum_size);
665  memo = (!argc || NIL_P(memo = argv[0])) ? INT2FIX(0) : rb_to_int(memo);
666  return enumerator_block_call(obj, enumerator_with_index_i, (VALUE)MEMO_NEW(memo, 0, 0));
667 }
668 
669 /*
670  * call-seq:
671  * e.each_with_index {|(*args), idx| ... }
672  * e.each_with_index
673  *
674  * Same as Enumerator#with_index(0), i.e. there is no starting offset.
675  *
676  * If no block is given, a new Enumerator is returned that includes the index.
677  *
678  */
679 static VALUE
680 enumerator_each_with_index(VALUE obj)
681 {
682  return enumerator_with_index(0, NULL, obj);
683 }
684 
685 static VALUE
686 enumerator_with_object_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, memo))
687 {
688  if (argc <= 1)
689  return rb_yield_values(2, val, memo);
690 
691  return rb_yield_values(2, rb_ary_new4(argc, argv), memo);
692 }
693 
694 /*
695  * call-seq:
696  * e.each_with_object(obj) {|(*args), obj| ... }
697  * e.each_with_object(obj)
698  * e.with_object(obj) {|(*args), obj| ... }
699  * e.with_object(obj)
700  *
701  * Iterates the given block for each element with an arbitrary object, +obj+,
702  * and returns +obj+
703  *
704  * If no block is given, returns a new Enumerator.
705  *
706  * === Example
707  *
708  * to_three = Enumerator.new do |y|
709  * 3.times do |x|
710  * y << x
711  * end
712  * end
713  *
714  * to_three_with_string = to_three.with_object("foo")
715  * to_three_with_string.each do |x,string|
716  * puts "#{string}: #{x}"
717  * end
718  *
719  * # => foo:0
720  * # => foo:1
721  * # => foo:2
722  */
723 static VALUE
724 enumerator_with_object(VALUE obj, VALUE memo)
725 {
726  RETURN_SIZED_ENUMERATOR(obj, 1, &memo, enumerator_enum_size);
727  enumerator_block_call(obj, enumerator_with_object_i, memo);
728 
729  return memo;
730 }
731 
732 static VALUE
734 {
735  struct enumerator *e = enumerator_ptr(obj);
736  VALUE feedvalue = Qnil;
738  rb_fiber_yield(1, &args);
739  if (e->feedvalue != Qundef) {
740  feedvalue = e->feedvalue;
741  e->feedvalue = Qundef;
742  }
743  return feedvalue;
744 }
745 
746 static VALUE
748 {
749  struct enumerator *e = enumerator_ptr(obj);
750  VALUE nil = Qnil;
751  VALUE result;
752 
753  result = rb_block_call(obj, id_each, 0, 0, next_ii, obj);
754  e->stop_exc = rb_exc_new2(rb_eStopIteration, "iteration reached an end");
755  rb_ivar_set(e->stop_exc, id_result, result);
756  return rb_fiber_yield(1, &nil);
757 }
758 
759 static void
760 next_init(VALUE obj, struct enumerator *e)
761 {
762  VALUE curr = rb_fiber_current();
763  e->dst = curr;
764  e->fib = rb_fiber_new(next_i, obj);
765  e->lookahead = Qundef;
766 }
767 
768 static VALUE
769 get_next_values(VALUE obj, struct enumerator *e)
770 {
771  VALUE curr, vs;
772 
773  if (e->stop_exc)
775 
776  curr = rb_fiber_current();
777 
778  if (!e->fib || !rb_fiber_alive_p(e->fib)) {
779  next_init(obj, e);
780  }
781 
782  vs = rb_fiber_resume(e->fib, 1, &curr);
783  if (e->stop_exc) {
784  e->fib = 0;
785  e->dst = Qnil;
786  e->lookahead = Qundef;
787  e->feedvalue = Qundef;
789  }
790  return vs;
791 }
792 
793 /*
794  * call-seq:
795  * e.next_values -> array
796  *
797  * Returns the next object as an array in the enumerator, and move the
798  * internal position forward. When the position reached at the end,
799  * StopIteration is raised.
800  *
801  * This method can be used to distinguish <code>yield</code> and <code>yield
802  * nil</code>.
803  *
804  * === Example
805  *
806  * o = Object.new
807  * def o.each
808  * yield
809  * yield 1
810  * yield 1, 2
811  * yield nil
812  * yield [1, 2]
813  * end
814  * e = o.to_enum
815  * p e.next_values
816  * p e.next_values
817  * p e.next_values
818  * p e.next_values
819  * p e.next_values
820  * e = o.to_enum
821  * p e.next
822  * p e.next
823  * p e.next
824  * p e.next
825  * p e.next
826  *
827  * ## yield args next_values next
828  * # yield [] nil
829  * # yield 1 [1] 1
830  * # yield 1, 2 [1, 2] [1, 2]
831  * # yield nil [nil] nil
832  * # yield [1, 2] [[1, 2]] [1, 2]
833  *
834  * Note that +next_values+ does not affect other non-external enumeration
835  * methods unless underlying iteration method itself has side-effect, e.g.
836  * IO#each_line.
837  *
838  */
839 
840 static VALUE
841 enumerator_next_values(VALUE obj)
842 {
843  struct enumerator *e = enumerator_ptr(obj);
844  VALUE vs;
845 
846  if (e->lookahead != Qundef) {
847  vs = e->lookahead;
848  e->lookahead = Qundef;
849  return vs;
850  }
851 
852  return get_next_values(obj, e);
853 }
854 
855 static VALUE
856 ary2sv(VALUE args, int dup)
857 {
858  if (!RB_TYPE_P(args, T_ARRAY))
859  return args;
860 
861  switch (RARRAY_LEN(args)) {
862  case 0:
863  return Qnil;
864 
865  case 1:
866  return RARRAY_AREF(args, 0);
867 
868  default:
869  if (dup)
870  return rb_ary_dup(args);
871  return args;
872  }
873 }
874 
875 /*
876  * call-seq:
877  * e.next -> object
878  *
879  * Returns the next object in the enumerator, and move the internal position
880  * forward. When the position reached at the end, StopIteration is raised.
881  *
882  * === Example
883  *
884  * a = [1,2,3]
885  * e = a.to_enum
886  * p e.next #=> 1
887  * p e.next #=> 2
888  * p e.next #=> 3
889  * p e.next #raises StopIteration
890  *
891  * Note that enumeration sequence by +next+ does not affect other non-external
892  * enumeration methods, unless the underlying iteration methods itself has
893  * side-effect, e.g. IO#each_line.
894  *
895  */
896 
897 static VALUE
898 enumerator_next(VALUE obj)
899 {
900  VALUE vs = enumerator_next_values(obj);
901  return ary2sv(vs, 0);
902 }
903 
904 static VALUE
905 enumerator_peek_values(VALUE obj)
906 {
907  struct enumerator *e = enumerator_ptr(obj);
908 
909  if (e->lookahead == Qundef) {
910  e->lookahead = get_next_values(obj, e);
911  }
912  return e->lookahead;
913 }
914 
915 /*
916  * call-seq:
917  * e.peek_values -> array
918  *
919  * Returns the next object as an array, similar to Enumerator#next_values, but
920  * doesn't move the internal position forward. If the position is already at
921  * the end, StopIteration is raised.
922  *
923  * === Example
924  *
925  * o = Object.new
926  * def o.each
927  * yield
928  * yield 1
929  * yield 1, 2
930  * end
931  * e = o.to_enum
932  * p e.peek_values #=> []
933  * e.next
934  * p e.peek_values #=> [1]
935  * p e.peek_values #=> [1]
936  * e.next
937  * p e.peek_values #=> [1, 2]
938  * e.next
939  * p e.peek_values # raises StopIteration
940  *
941  */
942 
943 static VALUE
944 enumerator_peek_values_m(VALUE obj)
945 {
946  return rb_ary_dup(enumerator_peek_values(obj));
947 }
948 
949 /*
950  * call-seq:
951  * e.peek -> object
952  *
953  * Returns the next object in the enumerator, but doesn't move the internal
954  * position forward. If the position is already at the end, StopIteration
955  * is raised.
956  *
957  * === Example
958  *
959  * a = [1,2,3]
960  * e = a.to_enum
961  * p e.next #=> 1
962  * p e.peek #=> 2
963  * p e.peek #=> 2
964  * p e.peek #=> 2
965  * p e.next #=> 2
966  * p e.next #=> 3
967  * p e.peek #raises StopIteration
968  *
969  */
970 
971 static VALUE
972 enumerator_peek(VALUE obj)
973 {
974  VALUE vs = enumerator_peek_values(obj);
975  return ary2sv(vs, 1);
976 }
977 
978 /*
979  * call-seq:
980  * e.feed obj -> nil
981  *
982  * Sets the value to be returned by the next yield inside +e+.
983  *
984  * If the value is not set, the yield returns nil.
985  *
986  * This value is cleared after being yielded.
987  *
988  * # Array#map passes the array's elements to "yield" and collects the
989  * # results of "yield" as an array.
990  * # Following example shows that "next" returns the passed elements and
991  * # values passed to "feed" are collected as an array which can be
992  * # obtained by StopIteration#result.
993  * e = [1,2,3].map
994  * p e.next #=> 1
995  * e.feed "a"
996  * p e.next #=> 2
997  * e.feed "b"
998  * p e.next #=> 3
999  * e.feed "c"
1000  * begin
1001  * e.next
1002  * rescue StopIteration
1003  * p $!.result #=> ["a", "b", "c"]
1004  * end
1005  *
1006  * o = Object.new
1007  * def o.each
1008  * x = yield # (2) blocks
1009  * p x # (5) => "foo"
1010  * x = yield # (6) blocks
1011  * p x # (8) => nil
1012  * x = yield # (9) blocks
1013  * p x # not reached w/o another e.next
1014  * end
1015  *
1016  * e = o.to_enum
1017  * e.next # (1)
1018  * e.feed "foo" # (3)
1019  * e.next # (4)
1020  * e.next # (7)
1021  * # (10)
1022  */
1023 
1024 static VALUE
1025 enumerator_feed(VALUE obj, VALUE v)
1026 {
1027  struct enumerator *e = enumerator_ptr(obj);
1028 
1029  if (e->feedvalue != Qundef) {
1030  rb_raise(rb_eTypeError, "feed value already set");
1031  }
1032  e->feedvalue = v;
1033 
1034  return Qnil;
1035 }
1036 
1037 /*
1038  * call-seq:
1039  * e.rewind -> e
1040  *
1041  * Rewinds the enumeration sequence to the beginning.
1042  *
1043  * If the enclosed object responds to a "rewind" method, it is called.
1044  */
1045 
1046 static VALUE
1047 enumerator_rewind(VALUE obj)
1048 {
1049  struct enumerator *e = enumerator_ptr(obj);
1050 
1051  rb_check_funcall(e->obj, id_rewind, 0, 0);
1052 
1053  e->fib = 0;
1054  e->dst = Qnil;
1055  e->lookahead = Qundef;
1056  e->feedvalue = Qundef;
1057  e->stop_exc = Qfalse;
1058  return obj;
1059 }
1060 
1061 static struct generator *generator_ptr(VALUE obj);
1062 static VALUE append_method(VALUE obj, VALUE str, ID default_method, VALUE default_args);
1063 
1064 static VALUE
1065 inspect_enumerator(VALUE obj, VALUE dummy, int recur)
1066 {
1067  struct enumerator *e;
1068  VALUE eobj, str, cname;
1069 
1070  TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, e);
1071 
1072  cname = rb_obj_class(obj);
1073 
1074  if (!e || e->obj == Qundef) {
1075  return rb_sprintf("#<%"PRIsVALUE": uninitialized>", rb_class_path(cname));
1076  }
1077 
1078  if (recur) {
1079  str = rb_sprintf("#<%"PRIsVALUE": ...>", rb_class_path(cname));
1080  return str;
1081  }
1082 
1083  if (e->procs) {
1084  long i;
1085 
1086  eobj = generator_ptr(e->obj)->obj;
1087  /* In case procs chained enumerator traversing all proc entries manually */
1088  if (rb_obj_class(eobj) == cname) {
1089  str = rb_inspect(eobj);
1090  }
1091  else {
1092  str = rb_sprintf("#<%"PRIsVALUE": %+"PRIsVALUE">", rb_class_path(cname), eobj);
1093  }
1094  for (i = 0; i < RARRAY_LEN(e->procs); i++) {
1095  str = rb_sprintf("#<%"PRIsVALUE": %"PRIsVALUE, cname, str);
1096  append_method(RARRAY_AREF(e->procs, i), str, e->meth, e->args);
1097  rb_str_buf_cat2(str, ">");
1098  }
1099  return str;
1100  }
1101 
1102  eobj = rb_attr_get(obj, id_receiver);
1103  if (NIL_P(eobj)) {
1104  eobj = e->obj;
1105  }
1106 
1107  /* (1..100).each_cons(2) => "#<Enumerator: 1..100:each_cons(2)>" */
1108  str = rb_sprintf("#<%"PRIsVALUE": %+"PRIsVALUE, rb_class_path(cname), eobj);
1109  append_method(obj, str, e->meth, e->args);
1110 
1111  rb_str_buf_cat2(str, ">");
1112 
1113  return str;
1114 }
1115 
1116 static int
1117 key_symbol_p(VALUE key, VALUE val, VALUE arg)
1118 {
1119  if (SYMBOL_P(key)) return ST_CONTINUE;
1120  *(int *)arg = FALSE;
1121  return ST_STOP;
1122 }
1123 
1124 static int
1125 kwd_append(VALUE key, VALUE val, VALUE str)
1126 {
1127  if (!SYMBOL_P(key)) rb_raise(rb_eRuntimeError, "non-symbol key inserted");
1128  rb_str_catf(str, "% "PRIsVALUE": %"PRIsVALUE", ", key, val);
1129  return ST_CONTINUE;
1130 }
1131 
1132 static VALUE
1133 append_method(VALUE obj, VALUE str, ID default_method, VALUE default_args)
1134 {
1135  VALUE method, eargs;
1136 
1137  method = rb_attr_get(obj, id_method);
1138  if (method != Qfalse) {
1139  if (!NIL_P(method)) {
1140  Check_Type(method, T_SYMBOL);
1141  method = rb_sym2str(method);
1142  }
1143  else {
1144  method = rb_id2str(default_method);
1145  }
1146  rb_str_buf_cat2(str, ":");
1147  rb_str_buf_append(str, method);
1148  }
1149 
1150  eargs = rb_attr_get(obj, id_arguments);
1151  if (NIL_P(eargs)) {
1152  eargs = default_args;
1153  }
1154  if (eargs != Qfalse) {
1155  long argc = RARRAY_LEN(eargs);
1156  const VALUE *argv = RARRAY_CONST_PTR(eargs); /* WB: no new reference */
1157 
1158  if (argc > 0) {
1159  VALUE kwds = Qnil;
1160 
1161  rb_str_buf_cat2(str, "(");
1162 
1163  if (RB_TYPE_P(argv[argc-1], T_HASH) && !RHASH_EMPTY_P(argv[argc-1])) {
1164  int all_key = TRUE;
1165  rb_hash_foreach(argv[argc-1], key_symbol_p, (VALUE)&all_key);
1166  if (all_key) kwds = argv[--argc];
1167  }
1168 
1169  while (argc--) {
1170  VALUE arg = *argv++;
1171 
1173  rb_str_buf_cat2(str, ", ");
1174  }
1175  if (!NIL_P(kwds)) {
1176  rb_hash_foreach(kwds, kwd_append, str);
1177  }
1179  rb_str_buf_cat2(str, ")");
1180  }
1181  }
1182 
1183  return str;
1184 }
1185 
1186 /*
1187  * call-seq:
1188  * e.inspect -> string
1189  *
1190  * Creates a printable version of <i>e</i>.
1191  */
1192 
1193 static VALUE
1194 enumerator_inspect(VALUE obj)
1195 {
1196  return rb_exec_recursive(inspect_enumerator, obj, 0);
1197 }
1198 
1199 /*
1200  * call-seq:
1201  * e.size -> int, Float::INFINITY or nil
1202  *
1203  * Returns the size of the enumerator, or +nil+ if it can't be calculated lazily.
1204  *
1205  * (1..100).to_a.permutation(4).size # => 94109400
1206  * loop.size # => Float::INFINITY
1207  * (1..100).drop_while.size # => nil
1208  */
1209 
1210 static VALUE
1211 enumerator_size(VALUE obj)
1212 {
1213  struct enumerator *e = enumerator_ptr(obj);
1214  int argc = 0;
1215  const VALUE *argv = NULL;
1216  VALUE size;
1217 
1218  if (e->procs) {
1219  struct generator *g = generator_ptr(e->obj);
1220  VALUE receiver = rb_check_funcall(g->obj, id_size, 0, 0);
1221  long i = 0;
1222 
1223  for (i = 0; i < RARRAY_LEN(e->procs); i++) {
1224  VALUE proc = RARRAY_AREF(e->procs, i);
1225  struct proc_entry *entry = proc_entry_ptr(proc);
1226  lazyenum_size_func *size_fn = entry->fn->size;
1227  if (!size_fn) {
1228  return Qnil;
1229  }
1230  receiver = (*size_fn)(proc, receiver);
1231  }
1232  return receiver;
1233  }
1234 
1235  if (e->size_fn) {
1236  return (*e->size_fn)(e->obj, e->args, obj);
1237  }
1238  if (e->args) {
1239  argc = (int)RARRAY_LEN(e->args);
1240  argv = RARRAY_CONST_PTR(e->args);
1241  }
1243  if (size != Qundef) return size;
1244  return e->size;
1245 }
1246 
1247 /*
1248  * Yielder
1249  */
1250 static void
1251 yielder_mark(void *p)
1252 {
1253  struct yielder *ptr = p;
1254  rb_gc_mark_movable(ptr->proc);
1255 }
1256 
1257 static void
1258 yielder_compact(void *p)
1259 {
1260  struct yielder *ptr = p;
1261  ptr->proc = rb_gc_location(ptr->proc);
1262 }
1263 
1264 #define yielder_free RUBY_TYPED_DEFAULT_FREE
1265 
1266 static size_t
1267 yielder_memsize(const void *p)
1268 {
1269  return sizeof(struct yielder);
1270 }
1271 
1272 static const rb_data_type_t yielder_data_type = {
1273  "yielder",
1274  {
1275  yielder_mark,
1276  yielder_free,
1277  yielder_memsize,
1278  yielder_compact,
1279  },
1281 };
1282 
1283 static struct yielder *
1284 yielder_ptr(VALUE obj)
1285 {
1286  struct yielder *ptr;
1287 
1288  TypedData_Get_Struct(obj, struct yielder, &yielder_data_type, ptr);
1289  if (!ptr || ptr->proc == Qundef) {
1290  rb_raise(rb_eArgError, "uninitialized yielder");
1291  }
1292  return ptr;
1293 }
1294 
1295 /* :nodoc: */
1296 static VALUE
1297 yielder_allocate(VALUE klass)
1298 {
1299  struct yielder *ptr;
1300  VALUE obj;
1301 
1302  obj = TypedData_Make_Struct(klass, struct yielder, &yielder_data_type, ptr);
1303  ptr->proc = Qundef;
1304 
1305  return obj;
1306 }
1307 
1308 static VALUE
1309 yielder_init(VALUE obj, VALUE proc)
1310 {
1311  struct yielder *ptr;
1312 
1313  TypedData_Get_Struct(obj, struct yielder, &yielder_data_type, ptr);
1314 
1315  if (!ptr) {
1316  rb_raise(rb_eArgError, "unallocated yielder");
1317  }
1318 
1319  ptr->proc = proc;
1320 
1321  return obj;
1322 }
1323 
1324 /* :nodoc: */
1325 static VALUE
1326 yielder_initialize(VALUE obj)
1327 {
1328  rb_need_block();
1329 
1330  return yielder_init(obj, rb_block_proc());
1331 }
1332 
1333 /* :nodoc: */
1334 static VALUE
1335 yielder_yield(VALUE obj, VALUE args)
1336 {
1337  struct yielder *ptr = yielder_ptr(obj);
1338 
1339  return rb_proc_call_kw(ptr->proc, args, RB_PASS_CALLED_KEYWORDS);
1340 }
1341 
1342 /* :nodoc: */
1343 static VALUE
1344 yielder_yield_push(VALUE obj, VALUE arg)
1345 {
1346  struct yielder *ptr = yielder_ptr(obj);
1347 
1348  rb_proc_call_with_block(ptr->proc, 1, &arg, Qnil);
1349 
1350  return obj;
1351 }
1352 
1353 /*
1354  * Returns a Proc object that takes an argument and yields it.
1355  *
1356  * This method is implemented so that a Yielder object can be directly
1357  * passed to another method as a block argument.
1358  *
1359  * enum = Enumerator.new { |y|
1360  * Dir.glob("*.rb") { |file|
1361  * File.open(file) { |f| f.each_line(&y) }
1362  * }
1363  * }
1364  */
1365 static VALUE
1366 yielder_to_proc(VALUE obj)
1367 {
1368  VALUE method = rb_obj_method(obj, sym_yield);
1369 
1370  return rb_funcall(method, idTo_proc, 0);
1371 }
1372 
1373 static VALUE
1374 yielder_yield_i(RB_BLOCK_CALL_FUNC_ARGLIST(obj, memo))
1375 {
1377 }
1378 
1379 static VALUE
1380 yielder_new(void)
1381 {
1382  return yielder_init(yielder_allocate(rb_cYielder), rb_proc_new(yielder_yield_i, 0));
1383 }
1384 
1385 /*
1386  * Generator
1387  */
1388 static void
1389 generator_mark(void *p)
1390 {
1391  struct generator *ptr = p;
1392  rb_gc_mark_movable(ptr->proc);
1393  rb_gc_mark_movable(ptr->obj);
1394 }
1395 
1396 static void
1397 generator_compact(void *p)
1398 {
1399  struct generator *ptr = p;
1400  ptr->proc = rb_gc_location(ptr->proc);
1401  ptr->obj = rb_gc_location(ptr->obj);
1402 }
1403 
1404 #define generator_free RUBY_TYPED_DEFAULT_FREE
1405 
1406 static size_t
1407 generator_memsize(const void *p)
1408 {
1409  return sizeof(struct generator);
1410 }
1411 
1412 static const rb_data_type_t generator_data_type = {
1413  "generator",
1414  {
1415  generator_mark,
1417  generator_memsize,
1418  generator_compact,
1419  },
1421 };
1422 
1423 static struct generator *
1424 generator_ptr(VALUE obj)
1425 {
1426  struct generator *ptr;
1427 
1428  TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr);
1429  if (!ptr || ptr->proc == Qundef) {
1430  rb_raise(rb_eArgError, "uninitialized generator");
1431  }
1432  return ptr;
1433 }
1434 
1435 /* :nodoc: */
1436 static VALUE
1437 generator_allocate(VALUE klass)
1438 {
1439  struct generator *ptr;
1440  VALUE obj;
1441 
1442  obj = TypedData_Make_Struct(klass, struct generator, &generator_data_type, ptr);
1443  ptr->proc = Qundef;
1444 
1445  return obj;
1446 }
1447 
1448 static VALUE
1449 generator_init(VALUE obj, VALUE proc)
1450 {
1451  struct generator *ptr;
1452 
1454  TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr);
1455 
1456  if (!ptr) {
1457  rb_raise(rb_eArgError, "unallocated generator");
1458  }
1459 
1460  ptr->proc = proc;
1461 
1462  return obj;
1463 }
1464 
1465 /* :nodoc: */
1466 static VALUE
1467 generator_initialize(int argc, VALUE *argv, VALUE obj)
1468 {
1469  VALUE proc;
1470 
1471  if (argc == 0) {
1472  rb_need_block();
1473 
1474  proc = rb_block_proc();
1475  }
1476  else {
1477  rb_scan_args(argc, argv, "1", &proc);
1478 
1479  if (!rb_obj_is_proc(proc))
1481  "wrong argument type %"PRIsVALUE" (expected Proc)",
1482  rb_obj_class(proc));
1483 
1484  if (rb_block_given_p()) {
1485  rb_warn("given block not used");
1486  }
1487  }
1488 
1489  return generator_init(obj, proc);
1490 }
1491 
1492 /* :nodoc: */
1493 static VALUE
1494 generator_init_copy(VALUE obj, VALUE orig)
1495 {
1496  struct generator *ptr0, *ptr1;
1497 
1498  if (!OBJ_INIT_COPY(obj, orig)) return obj;
1499 
1500  ptr0 = generator_ptr(orig);
1501 
1502  TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr1);
1503 
1504  if (!ptr1) {
1505  rb_raise(rb_eArgError, "unallocated generator");
1506  }
1507 
1508  ptr1->proc = ptr0->proc;
1509 
1510  return obj;
1511 }
1512 
1513 /* :nodoc: */
1514 static VALUE
1515 generator_each(int argc, VALUE *argv, VALUE obj)
1516 {
1517  struct generator *ptr = generator_ptr(obj);
1518  VALUE args = rb_ary_new2(argc + 1);
1519 
1520  rb_ary_push(args, yielder_new());
1521  if (argc > 0) {
1522  rb_ary_cat(args, argv, argc);
1523  }
1524 
1525  return rb_proc_call_kw(ptr->proc, args, RB_PASS_CALLED_KEYWORDS);
1526 }
1527 
1528 /* Lazy Enumerator methods */
1529 static VALUE
1530 enum_size(VALUE self)
1531 {
1532  VALUE r = rb_check_funcall(self, id_size, 0, 0);
1533  return (r == Qundef) ? Qnil : r;
1534 }
1535 
1536 static VALUE
1537 lazyenum_size(VALUE self, VALUE args, VALUE eobj)
1538 {
1539  return enum_size(self);
1540 }
1541 
1542 static VALUE
1543 lazy_size(VALUE self)
1544 {
1545  return enum_size(rb_ivar_get(self, id_receiver));
1546 }
1547 
1548 static VALUE
1549 lazy_receiver_size(VALUE generator, VALUE args, VALUE lazy)
1550 {
1551  return lazy_size(lazy);
1552 }
1553 
1554 static VALUE
1555 lazy_init_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
1556 {
1557  VALUE result;
1558  if (argc == 1) {
1559  VALUE args[2];
1560  args[0] = m;
1561  args[1] = val;
1562  result = rb_yield_values2(2, args);
1563  }
1564  else {
1565  VALUE args;
1566  int len = rb_long2int((long)argc + 1);
1567  VALUE *nargv = ALLOCV_N(VALUE, args, len);
1568 
1569  nargv[0] = m;
1570  if (argc > 0) {
1571  MEMCPY(nargv + 1, argv, VALUE, argc);
1572  }
1573  result = rb_yield_values2(len, nargv);
1574  ALLOCV_END(args);
1575  }
1576  if (result == Qundef) rb_iter_break();
1577  return Qnil;
1578 }
1579 
1580 static VALUE
1581 lazy_init_block_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
1582 {
1583  rb_block_call(m, id_each, argc-1, argv+1, lazy_init_iterator, val);
1584  return Qnil;
1585 }
1586 
1587 #define memo_value v2
1588 #define memo_flags u3.state
1589 #define LAZY_MEMO_BREAK 1
1590 #define LAZY_MEMO_PACKED 2
1591 #define LAZY_MEMO_BREAK_P(memo) ((memo)->memo_flags & LAZY_MEMO_BREAK)
1592 #define LAZY_MEMO_PACKED_P(memo) ((memo)->memo_flags & LAZY_MEMO_PACKED)
1593 #define LAZY_MEMO_SET_BREAK(memo) ((memo)->memo_flags |= LAZY_MEMO_BREAK)
1594 #define LAZY_MEMO_SET_VALUE(memo, value) MEMO_V2_SET(memo, value)
1595 #define LAZY_MEMO_SET_PACKED(memo) ((memo)->memo_flags |= LAZY_MEMO_PACKED)
1596 #define LAZY_MEMO_RESET_PACKED(memo) ((memo)->memo_flags &= ~LAZY_MEMO_PACKED)
1597 
1598 static VALUE
1599 lazy_init_yielder(RB_BLOCK_CALL_FUNC_ARGLIST(_, m))
1600 {
1601  VALUE yielder = RARRAY_AREF(m, 0);
1602  VALUE procs_array = RARRAY_AREF(m, 1);
1603  VALUE memos = rb_attr_get(yielder, id_memo);
1604  long i = 0;
1605  struct MEMO *result;
1606  int cont = 1;
1607 
1609  argc > 1 ? LAZY_MEMO_PACKED : 0);
1610 
1611  for (i = 0; i < RARRAY_LEN(procs_array); i++) {
1612  VALUE proc = RARRAY_AREF(procs_array, i);
1613  struct proc_entry *entry = proc_entry_ptr(proc);
1614  if (!(*entry->fn->proc)(proc, result, memos, i)) {
1615  cont = 0;
1616  break;
1617  }
1618  }
1619 
1620  if (cont) {
1621  rb_funcall2(yielder, idLTLT, 1, &(result->memo_value));
1622  }
1623  if (LAZY_MEMO_BREAK_P(result)) {
1624  rb_iter_break();
1625  }
1626  return result->memo_value;
1627 }
1628 
1629 static VALUE
1630 lazy_init_block(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
1631 {
1632  VALUE procs = RARRAY_AREF(m, 1);
1633 
1634  rb_ivar_set(val, id_memo, rb_ary_new2(RARRAY_LEN(procs)));
1635  rb_block_call(RARRAY_AREF(m, 0), id_each, 0, 0,
1636  lazy_init_yielder, rb_ary_new3(2, val, procs));
1637  return Qnil;
1638 }
1639 
1640 static VALUE
1641 lazy_generator_init(VALUE enumerator, VALUE procs)
1642 {
1643  VALUE generator;
1644  VALUE obj;
1645  struct generator *gen_ptr;
1646  struct enumerator *e = enumerator_ptr(enumerator);
1647 
1648  if (RARRAY_LEN(procs) > 0) {
1649  struct generator *old_gen_ptr = generator_ptr(e->obj);
1650  obj = old_gen_ptr->obj;
1651  }
1652  else {
1653  obj = enumerator;
1654  }
1655 
1656  generator = generator_allocate(rb_cGenerator);
1657 
1659  lazy_init_block, rb_ary_new3(2, obj, procs));
1660 
1661  gen_ptr = generator_ptr(generator);
1662  gen_ptr->obj = obj;
1663 
1664  return generator;
1665 }
1666 
1667 /*
1668  * Document-class: Enumerator::Lazy
1669  *
1670  * Enumerator::Lazy is a special type of Enumerator, that allows constructing
1671  * chains of operations without evaluating them immediately, and evaluating
1672  * values on as-needed basis. In order to do so it redefines most of Enumerable
1673  * methods so that they just construct another lazy enumerator.
1674  *
1675  * Enumerator::Lazy can be constructed from any Enumerable with the
1676  * Enumerable#lazy method.
1677  *
1678  * lazy = (1..Float::INFINITY).lazy.select(&:odd?).drop(10).take_while { |i| i < 30 }
1679  * # => #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: 1..Infinity>:select>:drop(10)>:take_while>
1680  *
1681  * The real enumeration is performed when any non-redefined Enumerable method
1682  * is called, like Enumerable#first or Enumerable#to_a (the latter is aliased
1683  * as #force for more semantic code):
1684  *
1685  * lazy.first(2)
1686  * #=> [21, 23]
1687  *
1688  * lazy.force
1689  * #=> [21, 23, 25, 27, 29]
1690  *
1691  * Note that most Enumerable methods that could be called with or without
1692  * a block, on Enumerator::Lazy will always require a block:
1693  *
1694  * [1, 2, 3].map #=> #<Enumerator: [1, 2, 3]:map>
1695  * [1, 2, 3].lazy.map # ArgumentError: tried to call lazy map without a block
1696  *
1697  * This class allows idiomatic calculations on long or infinite sequences, as well
1698  * as chaining of calculations without constructing intermediate arrays.
1699  *
1700  * Example for working with a slowly calculated sequence:
1701  *
1702  * require 'open-uri'
1703  *
1704  * # This will fetch all URLs before selecting
1705  * # necessary data
1706  * URLS.map { |u| JSON.parse(open(u).read) }
1707  * .select { |data| data.key?('stats') }
1708  * .first(5)
1709  *
1710  * # This will fetch URLs one-by-one, only till
1711  * # there is enough data to satisfy the condition
1712  * URLS.lazy.map { |u| JSON.parse(open(u).read) }
1713  * .select { |data| data.key?('stats') }
1714  * .first(5)
1715  *
1716  * Ending a chain with ".eager" generates a non-lazy enumerator, which
1717  * is suitable for returning or passing to another method that expects
1718  * a normal enumerator.
1719  *
1720  * def active_items
1721  * groups
1722  * .lazy
1723  * .flat_map(&:items)
1724  * .reject(&:disabled)
1725  * .eager
1726  * end
1727  *
1728  * # This works lazily; if a checked item is found, it stops
1729  * # iteration and does not look into remaining groups.
1730  * first_checked = active_items.find(&:checked)
1731  *
1732  * # This returns an array of items like a normal enumerator does.
1733  * all_checked = active_items.select(&:checked)
1734  *
1735  */
1736 
1737 /*
1738  * call-seq:
1739  * Lazy.new(obj, size=nil) { |yielder, *values| block }
1740  *
1741  * Creates a new Lazy enumerator. When the enumerator is actually enumerated
1742  * (e.g. by calling #force), +obj+ will be enumerated and each value passed
1743  * to the given block. The block can yield values back using +yielder+.
1744  * For example, to create a "filter+map" enumerator:
1745  *
1746  * def filter_map(sequence)
1747  * Lazy.new(sequence) do |yielder, *values|
1748  * result = yield *values
1749  * yielder << result if result
1750  * end
1751  * end
1752  *
1753  * filter_map(1..Float::INFINITY) {|i| i*i if i.even?}.first(5)
1754  * #=> [4, 16, 36, 64, 100]
1755  */
1756 static VALUE
1757 lazy_initialize(int argc, VALUE *argv, VALUE self)
1758 {
1759  VALUE obj, size = Qnil;
1760  VALUE generator;
1761 
1762  rb_check_arity(argc, 1, 2);
1763  if (!rb_block_given_p()) {
1764  rb_raise(rb_eArgError, "tried to call lazy new without a block");
1765  }
1766  obj = argv[0];
1767  if (argc > 1) {
1768  size = argv[1];
1769  }
1770  generator = generator_allocate(rb_cGenerator);
1771  rb_block_call(generator, id_initialize, 0, 0, lazy_init_block_i, obj);
1772  enumerator_init(self, generator, sym_each, 0, 0, 0, size, 0);
1773  rb_ivar_set(self, id_receiver, obj);
1774 
1775  return self;
1776 }
1777 
1778 #if 0 /* for RDoc */
1779 /*
1780  * call-seq:
1781  * lazy.to_a -> array
1782  * lazy.force -> array
1783  *
1784  * Expands +lazy+ enumerator to an array.
1785  * See Enumerable#to_a.
1786  */
1787 static VALUE lazy_to_a(VALUE self)
1788 {
1789 }
1790 #endif
1791 
1792 static void
1793 lazy_set_args(VALUE lazy, VALUE args)
1794 {
1795  ID id = rb_frame_this_func();
1796  rb_ivar_set(lazy, id_method, ID2SYM(id));
1797  if (NIL_P(args)) {
1798  /* Qfalse indicates that the arguments are empty */
1799  rb_ivar_set(lazy, id_arguments, Qfalse);
1800  }
1801  else {
1802  rb_ivar_set(lazy, id_arguments, args);
1803  }
1804 }
1805 
1806 static VALUE
1807 lazy_set_method(VALUE lazy, VALUE args, rb_enumerator_size_func *size_fn)
1808 {
1809  struct enumerator *e = enumerator_ptr(lazy);
1810  lazy_set_args(lazy, args);
1811  e->size_fn = size_fn;
1812  return lazy;
1813 }
1814 
1815 static VALUE
1816 lazy_add_method(VALUE obj, int argc, VALUE *argv, VALUE args, VALUE memo,
1817  const lazyenum_funcs *fn)
1818 {
1819  struct enumerator *new_e;
1820  VALUE new_obj;
1821  VALUE new_generator;
1822  VALUE new_procs;
1823  struct enumerator *e = enumerator_ptr(obj);
1824  struct proc_entry *entry;
1825  VALUE entry_obj = TypedData_Make_Struct(rb_cObject, struct proc_entry,
1826  &proc_entry_data_type, entry);
1827  if (rb_block_given_p()) {
1828  entry->proc = rb_block_proc();
1829  }
1830  entry->fn = fn;
1831  entry->memo = args;
1832 
1833  lazy_set_args(entry_obj, memo);
1834 
1835  new_procs = RTEST(e->procs) ? rb_ary_dup(e->procs) : rb_ary_new();
1836  new_generator = lazy_generator_init(obj, new_procs);
1837  rb_ary_push(new_procs, entry_obj);
1838 
1839  new_obj = enumerator_init_copy(enumerator_allocate(rb_cLazy), obj);
1840  new_e = DATA_PTR(new_obj);
1841  new_e->obj = new_generator;
1842  new_e->procs = new_procs;
1843 
1844  if (argc > 0) {
1845  new_e->meth = rb_to_id(*argv++);
1846  --argc;
1847  }
1848  else {
1849  new_e->meth = id_each;
1850  }
1851  new_e->args = rb_ary_new4(argc, argv);
1852  return new_obj;
1853 }
1854 
1855 /*
1856  * call-seq:
1857  * e.lazy -> lazy_enumerator
1858  *
1859  * Returns an Enumerator::Lazy, which redefines most Enumerable
1860  * methods to postpone enumeration and enumerate values only on an
1861  * as-needed basis.
1862  *
1863  * === Example
1864  *
1865  * The following program finds pythagorean triples:
1866  *
1867  * def pythagorean_triples
1868  * (1..Float::INFINITY).lazy.flat_map {|z|
1869  * (1..z).flat_map {|x|
1870  * (x..z).select {|y|
1871  * x**2 + y**2 == z**2
1872  * }.map {|y|
1873  * [x, y, z]
1874  * }
1875  * }
1876  * }
1877  * end
1878  * # show first ten pythagorean triples
1879  * p pythagorean_triples.take(10).force # take is lazy, so force is needed
1880  * p pythagorean_triples.first(10) # first is eager
1881  * # show pythagorean triples less than 100
1882  * p pythagorean_triples.take_while { |*, z| z < 100 }.force
1883  */
1884 static VALUE
1885 enumerable_lazy(VALUE obj)
1886 {
1887  VALUE result = lazy_to_enum_i(obj, sym_each, 0, 0, lazyenum_size, PASS_KW_SPLAT);
1888  /* Qfalse indicates that the Enumerator::Lazy has no method name */
1889  rb_ivar_set(result, id_method, Qfalse);
1890  return result;
1891 }
1892 
1893 static VALUE
1894 lazy_to_enum_i(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, int kw_splat)
1895 {
1896  return enumerator_init(enumerator_allocate(rb_cLazy),
1897  obj, meth, argc, argv, size_fn, Qnil, kw_splat);
1898 }
1899 
1900 /*
1901  * call-seq:
1902  * lzy.to_enum(method = :each, *args) -> lazy_enum
1903  * lzy.enum_for(method = :each, *args) -> lazy_enum
1904  * lzy.to_enum(method = :each, *args) {|*args| block } -> lazy_enum
1905  * lzy.enum_for(method = :each, *args) {|*args| block } -> lazy_enum
1906  *
1907  * Similar to Object#to_enum, except it returns a lazy enumerator.
1908  * This makes it easy to define Enumerable methods that will
1909  * naturally remain lazy if called from a lazy enumerator.
1910  *
1911  * For example, continuing from the example in Object#to_enum:
1912  *
1913  * # See Object#to_enum for the definition of repeat
1914  * r = 1..Float::INFINITY
1915  * r.repeat(2).first(5) # => [1, 1, 2, 2, 3]
1916  * r.repeat(2).class # => Enumerator
1917  * r.repeat(2).map{|n| n ** 2}.first(5) # => endless loop!
1918  * # works naturally on lazy enumerator:
1919  * r.lazy.repeat(2).class # => Enumerator::Lazy
1920  * r.lazy.repeat(2).map{|n| n ** 2}.first(5) # => [1, 1, 4, 4, 9]
1921  */
1922 
1923 static VALUE
1924 lazy_to_enum(int argc, VALUE *argv, VALUE self)
1925 {
1926  VALUE lazy, meth = sym_each, super_meth;
1927 
1928  if (argc > 0) {
1929  --argc;
1930  meth = *argv++;
1931  }
1932  if (RTEST((super_meth = rb_hash_aref(lazy_use_super_method, meth)))) {
1933  meth = super_meth;
1934  }
1935  lazy = lazy_to_enum_i(self, meth, argc, argv, 0, PASS_KW_SPLAT);
1936  if (rb_block_given_p()) {
1937  enumerator_ptr(lazy)->size = rb_block_proc();
1938  }
1939  return lazy;
1940 }
1941 
1942 static VALUE
1943 lazy_eager_size(VALUE self, VALUE args, VALUE eobj)
1944 {
1945  return enum_size(self);
1946 }
1947 
1948 /*
1949  * call-seq:
1950  * lzy.eager -> enum
1951  *
1952  * Returns a non-lazy Enumerator converted from the lazy enumerator.
1953  */
1954 
1955 static VALUE
1956 lazy_eager(VALUE self)
1957 {
1958  return enumerator_init(enumerator_allocate(rb_cEnumerator),
1959  self, sym_each, 0, 0, lazy_eager_size, Qnil, 0);
1960 }
1961 
1962 static VALUE
1963 lazyenum_yield(VALUE proc_entry, struct MEMO *result)
1964 {
1965  struct proc_entry *entry = proc_entry_ptr(proc_entry);
1966  return rb_proc_call_with_block(entry->proc, 1, &result->memo_value, Qnil);
1967 }
1968 
1969 static VALUE
1970 lazyenum_yield_values(VALUE proc_entry, struct MEMO *result)
1971 {
1972  struct proc_entry *entry = proc_entry_ptr(proc_entry);
1973  int argc = 1;
1974  const VALUE *argv = &result->memo_value;
1975  if (LAZY_MEMO_PACKED_P(result)) {
1976  const VALUE args = *argv;
1977  argc = RARRAY_LENINT(args);
1978  argv = RARRAY_CONST_PTR(args);
1979  }
1980  return rb_proc_call_with_block(entry->proc, argc, argv, Qnil);
1981 }
1982 
1983 static struct MEMO *
1984 lazy_map_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
1985 {
1986  VALUE value = lazyenum_yield_values(proc_entry, result);
1987  LAZY_MEMO_SET_VALUE(result, value);
1988  LAZY_MEMO_RESET_PACKED(result);
1989  return result;
1990 }
1991 
1992 static VALUE
1993 lazy_map_size(VALUE entry, VALUE receiver)
1994 {
1995  return receiver;
1996 }
1997 
1998 static const lazyenum_funcs lazy_map_funcs = {
1999  lazy_map_proc, lazy_map_size,
2000 };
2001 
2002 /*
2003  * call-seq:
2004  * lazy.collect { |obj| block } -> lazy_enumerator
2005  * lazy.map { |obj| block } -> lazy_enumerator
2006  *
2007  * Like Enumerable#map, but chains operation to be lazy-evaluated.
2008  *
2009  * (1..Float::INFINITY).lazy.map {|i| i**2 }
2010  * #=> #<Enumerator::Lazy: #<Enumerator::Lazy: 1..Infinity>:map>
2011  * (1..Float::INFINITY).lazy.map {|i| i**2 }.first(3)
2012  * #=> [1, 4, 9]
2013  */
2014 
2015 static VALUE
2016 lazy_map(VALUE obj)
2017 {
2018  if (!rb_block_given_p()) {
2019  rb_raise(rb_eArgError, "tried to call lazy map without a block");
2020  }
2021 
2022  return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_map_funcs);
2023 }
2024 
2025 static VALUE
2026 lazy_flat_map_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, yielder))
2027 {
2029 
2030  return rb_funcallv(yielder, idLTLT, 1, &arg);
2031 }
2032 
2033 static VALUE
2034 lazy_flat_map_each(VALUE obj, VALUE yielder)
2035 {
2036  rb_block_call(obj, id_each, 0, 0, lazy_flat_map_i, yielder);
2037  return Qnil;
2038 }
2039 
2040 static VALUE
2041 lazy_flat_map_to_ary(VALUE obj, VALUE yielder)
2042 {
2043  VALUE ary = rb_check_array_type(obj);
2044  if (NIL_P(ary)) {
2045  rb_funcall(yielder, idLTLT, 1, obj);
2046  }
2047  else {
2048  long i;
2049  for (i = 0; i < RARRAY_LEN(ary); i++) {
2050  rb_funcall(yielder, idLTLT, 1, RARRAY_AREF(ary, i));
2051  }
2052  }
2053  return Qnil;
2054 }
2055 
2056 static VALUE
2057 lazy_flat_map_proc(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
2058 {
2059  VALUE result = rb_yield_values2(argc - 1, &argv[1]);
2060  if (RB_TYPE_P(result, T_ARRAY)) {
2061  long i;
2062  for (i = 0; i < RARRAY_LEN(result); i++) {
2063  rb_funcall(argv[0], idLTLT, 1, RARRAY_AREF(result, i));
2064  }
2065  }
2066  else {
2067  if (rb_respond_to(result, id_force) && rb_respond_to(result, id_each)) {
2068  lazy_flat_map_each(result, argv[0]);
2069  }
2070  else {
2071  lazy_flat_map_to_ary(result, argv[0]);
2072  }
2073  }
2074  return Qnil;
2075 }
2076 
2077 /*
2078  * call-seq:
2079  * lazy.collect_concat { |obj| block } -> a_lazy_enumerator
2080  * lazy.flat_map { |obj| block } -> a_lazy_enumerator
2081  *
2082  * Returns a new lazy enumerator with the concatenated results of running
2083  * +block+ once for every element in the lazy enumerator.
2084  *
2085  * ["foo", "bar"].lazy.flat_map {|i| i.each_char.lazy}.force
2086  * #=> ["f", "o", "o", "b", "a", "r"]
2087  *
2088  * A value +x+ returned by +block+ is decomposed if either of
2089  * the following conditions is true:
2090  *
2091  * * +x+ responds to both each and force, which means that
2092  * +x+ is a lazy enumerator.
2093  * * +x+ is an array or responds to to_ary.
2094  *
2095  * Otherwise, +x+ is contained as-is in the return value.
2096  *
2097  * [{a:1}, {b:2}].lazy.flat_map {|i| i}.force
2098  * #=> [{:a=>1}, {:b=>2}]
2099  */
2100 static VALUE
2101 lazy_flat_map(VALUE obj)
2102 {
2103  if (!rb_block_given_p()) {
2104  rb_raise(rb_eArgError, "tried to call lazy flat_map without a block");
2105  }
2106 
2107  return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
2108  lazy_flat_map_proc, 0),
2109  Qnil, 0);
2110 }
2111 
2112 static struct MEMO *
2113 lazy_select_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2114 {
2115  VALUE chain = lazyenum_yield(proc_entry, result);
2116  if (!RTEST(chain)) return 0;
2117  return result;
2118 }
2119 
2120 static const lazyenum_funcs lazy_select_funcs = {
2121  lazy_select_proc, 0,
2122 };
2123 
2124 /*
2125  * call-seq:
2126  * lazy.find_all { |obj| block } -> lazy_enumerator
2127  * lazy.select { |obj| block } -> lazy_enumerator
2128  * lazy.filter { |obj| block } -> lazy_enumerator
2129  *
2130  * Like Enumerable#select, but chains operation to be lazy-evaluated.
2131  */
2132 static VALUE
2133 lazy_select(VALUE obj)
2134 {
2135  if (!rb_block_given_p()) {
2136  rb_raise(rb_eArgError, "tried to call lazy select without a block");
2137  }
2138 
2139  return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_select_funcs);
2140 }
2141 
2142 static struct MEMO *
2143 lazy_filter_map_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2144 {
2145  VALUE value = lazyenum_yield_values(proc_entry, result);
2146  if (!RTEST(value)) return 0;
2147  LAZY_MEMO_SET_VALUE(result, value);
2148  LAZY_MEMO_RESET_PACKED(result);
2149  return result;
2150 }
2151 
2152 static const lazyenum_funcs lazy_filter_map_funcs = {
2153  lazy_filter_map_proc, 0,
2154 };
2155 
2156 /*
2157  * call-seq:
2158  * lazy.filter_map { |obj| block } -> lazy_enumerator
2159  *
2160  * Like Enumerable#filter_map, but chains operation to be lazy-evaluated.
2161  *
2162  * (1..).lazy.filter_map { |i| i * 2 if i.even? }.first(5)
2163  * #=> [4, 8, 12, 16, 20]
2164  */
2165 
2166 static VALUE
2167 lazy_filter_map(VALUE obj)
2168 {
2169  if (!rb_block_given_p()) {
2170  rb_raise(rb_eArgError, "tried to call lazy filter_map without a block");
2171  }
2172 
2173  return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_filter_map_funcs);
2174 }
2175 
2176 static struct MEMO *
2177 lazy_reject_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2178 {
2179  VALUE chain = lazyenum_yield(proc_entry, result);
2180  if (RTEST(chain)) return 0;
2181  return result;
2182 }
2183 
2184 static const lazyenum_funcs lazy_reject_funcs = {
2185  lazy_reject_proc, 0,
2186 };
2187 
2188 /*
2189  * call-seq:
2190  * lazy.reject { |obj| block } -> lazy_enumerator
2191  *
2192  * Like Enumerable#reject, but chains operation to be lazy-evaluated.
2193  */
2194 
2195 static VALUE
2196 lazy_reject(VALUE obj)
2197 {
2198  if (!rb_block_given_p()) {
2199  rb_raise(rb_eArgError, "tried to call lazy reject without a block");
2200  }
2201 
2202  return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_reject_funcs);
2203 }
2204 
2205 static struct MEMO *
2206 lazy_grep_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2207 {
2208  struct proc_entry *entry = proc_entry_ptr(proc_entry);
2209  VALUE chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
2210  if (!RTEST(chain)) return 0;
2211  return result;
2212 }
2213 
2214 static struct MEMO *
2215 lazy_grep_iter_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2216 {
2217  struct proc_entry *entry = proc_entry_ptr(proc_entry);
2218  VALUE value, chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
2219 
2220  if (!RTEST(chain)) return 0;
2221  value = rb_proc_call_with_block(entry->proc, 1, &(result->memo_value), Qnil);
2222  LAZY_MEMO_SET_VALUE(result, value);
2223  LAZY_MEMO_RESET_PACKED(result);
2224 
2225  return result;
2226 }
2227 
2228 static const lazyenum_funcs lazy_grep_iter_funcs = {
2229  lazy_grep_iter_proc, 0,
2230 };
2231 
2232 static const lazyenum_funcs lazy_grep_funcs = {
2233  lazy_grep_proc, 0,
2234 };
2235 
2236 /*
2237  * call-seq:
2238  * lazy.grep(pattern) -> lazy_enumerator
2239  * lazy.grep(pattern) { |obj| block } -> lazy_enumerator
2240  *
2241  * Like Enumerable#grep, but chains operation to be lazy-evaluated.
2242  */
2243 
2244 static VALUE
2245 lazy_grep(VALUE obj, VALUE pattern)
2246 {
2247  const lazyenum_funcs *const funcs = rb_block_given_p() ?
2248  &lazy_grep_iter_funcs : &lazy_grep_funcs;
2249  return lazy_add_method(obj, 0, 0, pattern, rb_ary_new3(1, pattern), funcs);
2250 }
2251 
2252 static struct MEMO *
2253 lazy_grep_v_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2254 {
2255  struct proc_entry *entry = proc_entry_ptr(proc_entry);
2256  VALUE chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
2257  if (RTEST(chain)) return 0;
2258  return result;
2259 }
2260 
2261 static struct MEMO *
2262 lazy_grep_v_iter_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2263 {
2264  struct proc_entry *entry = proc_entry_ptr(proc_entry);
2265  VALUE value, chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
2266 
2267  if (RTEST(chain)) return 0;
2268  value = rb_proc_call_with_block(entry->proc, 1, &(result->memo_value), Qnil);
2269  LAZY_MEMO_SET_VALUE(result, value);
2270  LAZY_MEMO_RESET_PACKED(result);
2271 
2272  return result;
2273 }
2274 
2275 static const lazyenum_funcs lazy_grep_v_iter_funcs = {
2276  lazy_grep_v_iter_proc, 0,
2277 };
2278 
2279 static const lazyenum_funcs lazy_grep_v_funcs = {
2280  lazy_grep_v_proc, 0,
2281 };
2282 
2283 /*
2284  * call-seq:
2285  * lazy.grep_v(pattern) -> lazy_enumerator
2286  * lazy.grep_v(pattern) { |obj| block } -> lazy_enumerator
2287  *
2288  * Like Enumerable#grep_v, but chains operation to be lazy-evaluated.
2289  */
2290 
2291 static VALUE
2292 lazy_grep_v(VALUE obj, VALUE pattern)
2293 {
2294  const lazyenum_funcs *const funcs = rb_block_given_p() ?
2295  &lazy_grep_v_iter_funcs : &lazy_grep_v_funcs;
2296  return lazy_add_method(obj, 0, 0, pattern, rb_ary_new3(1, pattern), funcs);
2297 }
2298 
2299 static VALUE
2300 call_next(VALUE obj)
2301 {
2302  return rb_funcall(obj, id_next, 0);
2303 }
2304 
2305 static VALUE
2306 next_stopped(VALUE obj, VALUE _)
2307 {
2308  return Qnil;
2309 }
2310 
2311 static VALUE
2312 lazy_zip_arrays_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, arrays))
2313 {
2314  VALUE yielder, ary, memo;
2315  long i, count;
2316 
2317  yielder = argv[0];
2318  memo = rb_attr_get(yielder, id_memo);
2319  count = NIL_P(memo) ? 0 : NUM2LONG(memo);
2320 
2321  ary = rb_ary_new2(RARRAY_LEN(arrays) + 1);
2322  rb_ary_push(ary, argv[1]);
2323  for (i = 0; i < RARRAY_LEN(arrays); i++) {
2324  rb_ary_push(ary, rb_ary_entry(RARRAY_AREF(arrays, i), count));
2325  }
2326  rb_funcall(yielder, idLTLT, 1, ary);
2327  rb_ivar_set(yielder, id_memo, LONG2NUM(++count));
2328  return Qnil;
2329 }
2330 
2331 static VALUE
2332 lazy_zip_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, zip_args))
2333 {
2334  VALUE yielder, ary, arg, v;
2335  long i;
2336 
2337  yielder = argv[0];
2338  arg = rb_attr_get(yielder, id_memo);
2339  if (NIL_P(arg)) {
2340  arg = rb_ary_new2(RARRAY_LEN(zip_args));
2341  for (i = 0; i < RARRAY_LEN(zip_args); i++) {
2342  rb_ary_push(arg, rb_funcall(RARRAY_AREF(zip_args, i), id_to_enum, 0));
2343  }
2344  rb_ivar_set(yielder, id_memo, arg);
2345  }
2346 
2347  ary = rb_ary_new2(RARRAY_LEN(arg) + 1);
2348  v = Qnil;
2349  if (--argc > 0) {
2350  ++argv;
2351  v = argc > 1 ? rb_ary_new_from_values(argc, argv) : *argv;
2352  }
2353  rb_ary_push(ary, v);
2354  for (i = 0; i < RARRAY_LEN(arg); i++) {
2355  v = rb_rescue2(call_next, RARRAY_AREF(arg, i), next_stopped, 0,
2356  rb_eStopIteration, (VALUE)0);
2357  rb_ary_push(ary, v);
2358  }
2359  rb_funcall(yielder, idLTLT, 1, ary);
2360  return Qnil;
2361 }
2362 
2363 /*
2364  * call-seq:
2365  * lazy.zip(arg, ...) -> lazy_enumerator
2366  * lazy.zip(arg, ...) { |arr| block } -> nil
2367  *
2368  * Like Enumerable#zip, but chains operation to be lazy-evaluated.
2369  * However, if a block is given to zip, values are enumerated immediately.
2370  */
2371 static VALUE
2372 lazy_zip(int argc, VALUE *argv, VALUE obj)
2373 {
2374  VALUE ary, v;
2375  long i;
2376  rb_block_call_func *func = lazy_zip_arrays_func;
2377 
2378  if (rb_block_given_p()) {
2379  return rb_call_super(argc, argv);
2380  }
2381 
2382  ary = rb_ary_new2(argc);
2383  for (i = 0; i < argc; i++) {
2385  if (NIL_P(v)) {
2386  for (; i < argc; i++) {
2387  if (!rb_respond_to(argv[i], id_each)) {
2388  rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (must respond to :each)",
2389  rb_obj_class(argv[i]));
2390  }
2391  }
2392  ary = rb_ary_new4(argc, argv);
2393  func = lazy_zip_func;
2394  break;
2395  }
2396  rb_ary_push(ary, v);
2397  }
2398 
2399  return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
2400  func, ary),
2401  ary, lazy_receiver_size);
2402 }
2403 
2404 static struct MEMO *
2405 lazy_take_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2406 {
2407  long remain;
2408  struct proc_entry *entry = proc_entry_ptr(proc_entry);
2409  VALUE memo = rb_ary_entry(memos, memo_index);
2410 
2411  if (NIL_P(memo)) {
2412  memo = entry->memo;
2413  }
2414 
2415  remain = NUM2LONG(memo);
2416  if (remain == 0) {
2417  LAZY_MEMO_SET_BREAK(result);
2418  }
2419  else {
2420  if (--remain == 0) LAZY_MEMO_SET_BREAK(result);
2421  rb_ary_store(memos, memo_index, LONG2NUM(remain));
2422  }
2423  return result;
2424 }
2425 
2426 static VALUE
2427 lazy_take_size(VALUE entry, VALUE receiver)
2428 {
2429  long len = NUM2LONG(RARRAY_AREF(rb_ivar_get(entry, id_arguments), 0));
2430  if (NIL_P(receiver) || (FIXNUM_P(receiver) && FIX2LONG(receiver) < len))
2431  return receiver;
2432  return LONG2NUM(len);
2433 }
2434 
2435 static const lazyenum_funcs lazy_take_funcs = {
2436  lazy_take_proc, lazy_take_size,
2437 };
2438 
2439 /*
2440  * call-seq:
2441  * lazy.take(n) -> lazy_enumerator
2442  *
2443  * Like Enumerable#take, but chains operation to be lazy-evaluated.
2444  */
2445 
2446 static VALUE
2447 lazy_take(VALUE obj, VALUE n)
2448 {
2449  long len = NUM2LONG(n);
2450  int argc = 0;
2451  VALUE argv[2];
2452 
2453  if (len < 0) {
2454  rb_raise(rb_eArgError, "attempt to take negative size");
2455  }
2456 
2457  if (len == 0) {
2458  argv[0] = sym_cycle;
2459  argv[1] = INT2NUM(0);
2460  argc = 2;
2461  }
2462 
2463  return lazy_add_method(obj, argc, argv, n, rb_ary_new3(1, n), &lazy_take_funcs);
2464 }
2465 
2466 static struct MEMO *
2467 lazy_take_while_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2468 {
2469  VALUE take = lazyenum_yield_values(proc_entry, result);
2470  if (!RTEST(take)) {
2471  LAZY_MEMO_SET_BREAK(result);
2472  return 0;
2473  }
2474  return result;
2475 }
2476 
2477 static const lazyenum_funcs lazy_take_while_funcs = {
2478  lazy_take_while_proc, 0,
2479 };
2480 
2481 /*
2482  * call-seq:
2483  * lazy.take_while { |obj| block } -> lazy_enumerator
2484  *
2485  * Like Enumerable#take_while, but chains operation to be lazy-evaluated.
2486  */
2487 
2488 static VALUE
2489 lazy_take_while(VALUE obj)
2490 {
2491  if (!rb_block_given_p()) {
2492  rb_raise(rb_eArgError, "tried to call lazy take_while without a block");
2493  }
2494 
2495  return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_take_while_funcs);
2496 }
2497 
2498 static VALUE
2499 lazy_drop_size(VALUE proc_entry, VALUE receiver)
2500 {
2501  long len = NUM2LONG(RARRAY_AREF(rb_ivar_get(proc_entry, id_arguments), 0));
2502  if (NIL_P(receiver))
2503  return receiver;
2504  if (FIXNUM_P(receiver)) {
2505  len = FIX2LONG(receiver) - len;
2506  return LONG2FIX(len < 0 ? 0 : len);
2507  }
2508  return rb_funcall(receiver, '-', 1, LONG2NUM(len));
2509 }
2510 
2511 static struct MEMO *
2512 lazy_drop_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2513 {
2514  long remain;
2515  struct proc_entry *entry = proc_entry_ptr(proc_entry);
2516  VALUE memo = rb_ary_entry(memos, memo_index);
2517 
2518  if (NIL_P(memo)) {
2519  memo = entry->memo;
2520  }
2521  remain = NUM2LONG(memo);
2522  if (remain > 0) {
2523  --remain;
2524  rb_ary_store(memos, memo_index, LONG2NUM(remain));
2525  return 0;
2526  }
2527 
2528  return result;
2529 }
2530 
2531 static const lazyenum_funcs lazy_drop_funcs = {
2532  lazy_drop_proc, lazy_drop_size,
2533 };
2534 
2535 /*
2536  * call-seq:
2537  * lazy.drop(n) -> lazy_enumerator
2538  *
2539  * Like Enumerable#drop, but chains operation to be lazy-evaluated.
2540  */
2541 
2542 static VALUE
2543 lazy_drop(VALUE obj, VALUE n)
2544 {
2545  long len = NUM2LONG(n);
2546  VALUE argv[2];
2547  argv[0] = sym_each;
2548  argv[1] = n;
2549 
2550  if (len < 0) {
2551  rb_raise(rb_eArgError, "attempt to drop negative size");
2552  }
2553 
2554  return lazy_add_method(obj, 2, argv, n, rb_ary_new3(1, n), &lazy_drop_funcs);
2555 }
2556 
2557 static struct MEMO *
2558 lazy_drop_while_proc(VALUE proc_entry, struct MEMO* result, VALUE memos, long memo_index)
2559 {
2560  struct proc_entry *entry = proc_entry_ptr(proc_entry);
2561  VALUE memo = rb_ary_entry(memos, memo_index);
2562 
2563  if (NIL_P(memo)) {
2564  memo = entry->memo;
2565  }
2566 
2567  if (!RTEST(memo)) {
2568  VALUE drop = lazyenum_yield_values(proc_entry, result);
2569  if (RTEST(drop)) return 0;
2570  rb_ary_store(memos, memo_index, Qtrue);
2571  }
2572  return result;
2573 }
2574 
2575 static const lazyenum_funcs lazy_drop_while_funcs = {
2576  lazy_drop_while_proc, 0,
2577 };
2578 
2579 /*
2580  * call-seq:
2581  * lazy.drop_while { |obj| block } -> lazy_enumerator
2582  *
2583  * Like Enumerable#drop_while, but chains operation to be lazy-evaluated.
2584  */
2585 
2586 static VALUE
2587 lazy_drop_while(VALUE obj)
2588 {
2589  if (!rb_block_given_p()) {
2590  rb_raise(rb_eArgError, "tried to call lazy drop_while without a block");
2591  }
2592 
2593  return lazy_add_method(obj, 0, 0, Qfalse, Qnil, &lazy_drop_while_funcs);
2594 }
2595 
2596 static int
2597 lazy_uniq_check(VALUE chain, VALUE memos, long memo_index)
2598 {
2599  VALUE hash = rb_ary_entry(memos, memo_index);
2600 
2601  if (NIL_P(hash)) {
2602  hash = rb_obj_hide(rb_hash_new());
2603  rb_ary_store(memos, memo_index, hash);
2604  }
2605 
2606  return rb_hash_add_new_element(hash, chain, Qfalse);
2607 }
2608 
2609 static struct MEMO *
2610 lazy_uniq_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2611 {
2612  if (lazy_uniq_check(result->memo_value, memos, memo_index)) return 0;
2613  return result;
2614 }
2615 
2616 static struct MEMO *
2617 lazy_uniq_iter_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
2618 {
2619  VALUE chain = lazyenum_yield(proc_entry, result);
2620 
2621  if (lazy_uniq_check(chain, memos, memo_index)) return 0;
2622  return result;
2623 }
2624 
2625 static const lazyenum_funcs lazy_uniq_iter_funcs = {
2626  lazy_uniq_iter_proc, 0,
2627 };
2628 
2629 static const lazyenum_funcs lazy_uniq_funcs = {
2630  lazy_uniq_proc, 0,
2631 };
2632 
2633 /*
2634  * call-seq:
2635  * lazy.uniq -> lazy_enumerator
2636  * lazy.uniq { |item| block } -> lazy_enumerator
2637  *
2638  * Like Enumerable#uniq, but chains operation to be lazy-evaluated.
2639  */
2640 
2641 static VALUE
2642 lazy_uniq(VALUE obj)
2643 {
2644  const lazyenum_funcs *const funcs =
2645  rb_block_given_p() ? &lazy_uniq_iter_funcs : &lazy_uniq_funcs;
2646  return lazy_add_method(obj, 0, 0, Qnil, Qnil, funcs);
2647 }
2648 
2649 static struct MEMO *
2650 lazy_with_index_proc(VALUE proc_entry, struct MEMO* result, VALUE memos, long memo_index)
2651 {
2652  struct proc_entry *entry = proc_entry_ptr(proc_entry);
2653  VALUE memo = rb_ary_entry(memos, memo_index);
2654  VALUE argv[2];
2655 
2656  if (NIL_P(memo)) {
2657  memo = entry->memo;
2658  }
2659 
2660  argv[0] = result->memo_value;
2661  argv[1] = memo;
2662  if (entry->proc) {
2663  rb_proc_call_with_block(entry->proc, 2, argv, Qnil);
2664  LAZY_MEMO_RESET_PACKED(result);
2665  } else {
2667  LAZY_MEMO_SET_PACKED(result);
2668  }
2669  rb_ary_store(memos, memo_index, LONG2NUM(NUM2LONG(memo) + 1));
2670  return result;
2671 }
2672 
2673 static const lazyenum_funcs lazy_with_index_funcs = {
2674  lazy_with_index_proc, 0,
2675 };
2676 
2677 /*
2678  * call-seq:
2679  * lazy.with_index(offset = 0) {|(*args), idx| block }
2680  * lazy.with_index(offset = 0)
2681  *
2682  * If a block is given, iterates the given block for each element
2683  * with an index, which starts from +offset+, and returns a
2684  * lazy enumerator that yields the same values (without the index).
2685  *
2686  * If a block is not given, returns a new lazy enumerator that
2687  * includes the index, starting from +offset+.
2688  *
2689  * +offset+:: the starting index to use
2690  *
2691  * See Enumerator#with_index.
2692  */
2693 static VALUE
2694 lazy_with_index(int argc, VALUE *argv, VALUE obj)
2695 {
2696  VALUE memo;
2697 
2698  rb_scan_args(argc, argv, "01", &memo);
2699  if (NIL_P(memo))
2700  memo = LONG2NUM(0);
2701 
2702  return lazy_add_method(obj, 0, 0, memo, rb_ary_new_from_values(1, &memo), &lazy_with_index_funcs);
2703 }
2704 
2705 #if 0 /* for RDoc */
2706 
2707 /*
2708  * call-seq:
2709  * lazy.chunk { |elt| ... } -> lazy_enumerator
2710  *
2711  * Like Enumerable#chunk, but chains operation to be lazy-evaluated.
2712  */
2713 static VALUE lazy_chunk(VALUE self)
2714 {
2715 }
2716 
2717 /*
2718  * call-seq:
2719  * lazy.chunk_while {|elt_before, elt_after| bool } -> lazy_enumerator
2720  *
2721  * Like Enumerable#chunk_while, but chains operation to be lazy-evaluated.
2722  */
2723 static VALUE lazy_chunk_while(VALUE self)
2724 {
2725 }
2726 
2727 /*
2728  * call-seq:
2729  * lazy.slice_after(pattern) -> lazy_enumerator
2730  * lazy.slice_after { |elt| bool } -> lazy_enumerator
2731  *
2732  * Like Enumerable#slice_after, but chains operation to be lazy-evaluated.
2733  */
2734 static VALUE lazy_slice_after(VALUE self)
2735 {
2736 }
2737 
2738 /*
2739  * call-seq:
2740  * lazy.slice_before(pattern) -> lazy_enumerator
2741  * lazy.slice_before { |elt| bool } -> lazy_enumerator
2742  *
2743  * Like Enumerable#slice_before, but chains operation to be lazy-evaluated.
2744  */
2745 static VALUE lazy_slice_before(VALUE self)
2746 {
2747 }
2748 
2749 /*
2750  * call-seq:
2751  * lazy.slice_when {|elt_before, elt_after| bool } -> lazy_enumerator
2752  *
2753  * Like Enumerable#slice_when, but chains operation to be lazy-evaluated.
2754  */
2755 static VALUE lazy_slice_when(VALUE self)
2756 {
2757 }
2758 # endif
2759 
2760 static VALUE
2761 lazy_super(int argc, VALUE *argv, VALUE lazy)
2762 {
2763  return enumerable_lazy(rb_call_super(argc, argv));
2764 }
2765 
2766 /*
2767  * call-seq:
2768  * enum.lazy -> lazy_enumerator
2769  *
2770  * Returns self.
2771  */
2772 
2773 static VALUE
2774 lazy_lazy(VALUE obj)
2775 {
2776  return obj;
2777 }
2778 
2779 /*
2780  * Document-class: StopIteration
2781  *
2782  * Raised to stop the iteration, in particular by Enumerator#next. It is
2783  * rescued by Kernel#loop.
2784  *
2785  * loop do
2786  * puts "Hello"
2787  * raise StopIteration
2788  * puts "World"
2789  * end
2790  * puts "Done!"
2791  *
2792  * <em>produces:</em>
2793  *
2794  * Hello
2795  * Done!
2796  */
2797 
2798 /*
2799  * call-seq:
2800  * result -> value
2801  *
2802  * Returns the return value of the iterator.
2803  *
2804  * o = Object.new
2805  * def o.each
2806  * yield 1
2807  * yield 2
2808  * yield 3
2809  * 100
2810  * end
2811  *
2812  * e = o.to_enum
2813  *
2814  * puts e.next #=> 1
2815  * puts e.next #=> 2
2816  * puts e.next #=> 3
2817  *
2818  * begin
2819  * e.next
2820  * rescue StopIteration => ex
2821  * puts ex.result #=> 100
2822  * end
2823  *
2824  */
2825 
2826 static VALUE
2827 stop_result(VALUE self)
2828 {
2829  return rb_attr_get(self, id_result);
2830 }
2831 
2832 /*
2833  * Producer
2834  */
2835 
2836 static void
2837 producer_mark(void *p)
2838 {
2839  struct producer *ptr = p;
2840  rb_gc_mark_movable(ptr->init);
2841  rb_gc_mark_movable(ptr->proc);
2842 }
2843 
2844 static void
2845 producer_compact(void *p)
2846 {
2847  struct producer *ptr = p;
2848  ptr->init = rb_gc_location(ptr->init);
2849  ptr->proc = rb_gc_location(ptr->proc);
2850 }
2851 
2852 #define producer_free RUBY_TYPED_DEFAULT_FREE
2853 
2854 static size_t
2855 producer_memsize(const void *p)
2856 {
2857  return sizeof(struct producer);
2858 }
2859 
2860 static const rb_data_type_t producer_data_type = {
2861  "producer",
2862  {
2863  producer_mark,
2864  producer_free,
2865  producer_memsize,
2866  producer_compact,
2867  },
2869 };
2870 
2871 static struct producer *
2872 producer_ptr(VALUE obj)
2873 {
2874  struct producer *ptr;
2875 
2876  TypedData_Get_Struct(obj, struct producer, &producer_data_type, ptr);
2877  if (!ptr || ptr->proc == Qundef) {
2878  rb_raise(rb_eArgError, "uninitialized producer");
2879  }
2880  return ptr;
2881 }
2882 
2883 /* :nodoc: */
2884 static VALUE
2885 producer_allocate(VALUE klass)
2886 {
2887  struct producer *ptr;
2888  VALUE obj;
2889 
2890  obj = TypedData_Make_Struct(klass, struct producer, &producer_data_type, ptr);
2891  ptr->init = Qundef;
2892  ptr->proc = Qundef;
2893 
2894  return obj;
2895 }
2896 
2897 static VALUE
2898 producer_init(VALUE obj, VALUE init, VALUE proc)
2899 {
2900  struct producer *ptr;
2901 
2902  TypedData_Get_Struct(obj, struct producer, &producer_data_type, ptr);
2903 
2904  if (!ptr) {
2905  rb_raise(rb_eArgError, "unallocated producer");
2906  }
2907 
2908  ptr->init = init;
2909  ptr->proc = proc;
2910 
2911  return obj;
2912 }
2913 
2914 static VALUE
2915 producer_each_stop(VALUE dummy, VALUE exc)
2916 {
2917  return rb_attr_get(exc, id_result);
2918 }
2919 
2920 static VALUE
2921 producer_each_i(VALUE obj)
2922 {
2923  struct producer *ptr;
2924  VALUE init, proc, curr;
2925 
2926  ptr = producer_ptr(obj);
2927  init = ptr->init;
2928  proc = ptr->proc;
2929 
2930  if (init == Qundef) {
2931  curr = Qnil;
2932  } else {
2933  rb_yield(init);
2934  curr = init;
2935  }
2936 
2937  for (;;) {
2938  curr = rb_funcall(proc, id_call, 1, curr);
2939  rb_yield(curr);
2940  }
2941 
2942  return Qnil;
2943 }
2944 
2945 /* :nodoc: */
2946 static VALUE
2947 producer_each(VALUE obj)
2948 {
2949  rb_need_block();
2950 
2951  return rb_rescue2(producer_each_i, obj, producer_each_stop, (VALUE)0, rb_eStopIteration, (VALUE)0);
2952 }
2953 
2954 static VALUE
2955 producer_size(VALUE obj, VALUE args, VALUE eobj)
2956 {
2957  return DBL2NUM(HUGE_VAL);
2958 }
2959 
2960 /*
2961  * call-seq:
2962  * Enumerator.produce(initial = nil) { |prev| block } -> enumerator
2963  *
2964  * Creates an infinite enumerator from any block, just called over and
2965  * over. The result of the previous iteration is passed to the next one.
2966  * If +initial+ is provided, it is passed to the first iteration, and
2967  * becomes the first element of the enumerator; if it is not provided,
2968  * the first iteration receives +nil+, and its result becomes the first
2969  * element of the iterator.
2970  *
2971  * Raising StopIteration from the block stops an iteration.
2972  *
2973  * Enumerator.produce(1, &:succ) # => enumerator of 1, 2, 3, 4, ....
2974  *
2975  * Enumerator.produce { rand(10) } # => infinite random number sequence
2976  *
2977  * ancestors = Enumerator.produce(node) { |prev| node = prev.parent or raise StopIteration }
2978  * enclosing_section = ancestors.find { |n| n.type == :section }
2979  *
2980  * Using ::produce together with Enumerable methods like Enumerable#detect,
2981  * Enumerable#slice, Enumerable#take_while can provide Enumerator-based alternatives
2982  * for +while+ and +until+ cycles:
2983  *
2984  * # Find next Tuesday
2985  * require "date"
2986  * Enumerator.produce(Date.today, &:succ).detect(&:tuesday?)
2987  *
2988  * # Simple lexer:
2989  * require "strscan"
2990  * scanner = StringScanner.new("7+38/6")
2991  * PATTERN = %r{\d+|[-/+*]}
2992  * Enumerator.produce { scanner.scan(PATTERN) }.slice_after { scanner.eos? }.first
2993  * # => ["7", "+", "38", "/", "6"]
2994  */
2995 static VALUE
2996 enumerator_s_produce(int argc, VALUE *argv, VALUE klass)
2997 {
2998  VALUE init, producer;
2999 
3000  if (!rb_block_given_p()) rb_raise(rb_eArgError, "no block given");
3001 
3002  if (rb_scan_args(argc, argv, "01", &init) == 0) {
3003  init = Qundef;
3004  }
3005 
3006  producer = producer_init(producer_allocate(rb_cEnumProducer), init, rb_block_proc());
3007 
3008  return rb_enumeratorize_with_size_kw(producer, sym_each, 0, 0, producer_size, RB_NO_KEYWORDS);
3009 }
3010 
3011 /*
3012  * Document-class: Enumerator::Chain
3013  *
3014  * Enumerator::Chain is a subclass of Enumerator, which represents a
3015  * chain of enumerables that works as a single enumerator.
3016  *
3017  * This type of objects can be created by Enumerable#chain and
3018  * Enumerator#+.
3019  */
3020 
3021 static void
3022 enum_chain_mark(void *p)
3023 {
3024  struct enum_chain *ptr = p;
3025  rb_gc_mark_movable(ptr->enums);
3026 }
3027 
3028 static void
3029 enum_chain_compact(void *p)
3030 {
3031  struct enum_chain *ptr = p;
3032  ptr->enums = rb_gc_location(ptr->enums);
3033 }
3034 
3035 #define enum_chain_free RUBY_TYPED_DEFAULT_FREE
3036 
3037 static size_t
3038 enum_chain_memsize(const void *p)
3039 {
3040  return sizeof(struct enum_chain);
3041 }
3042 
3043 static const rb_data_type_t enum_chain_data_type = {
3044  "chain",
3045  {
3046  enum_chain_mark,
3048  enum_chain_memsize,
3049  enum_chain_compact,
3050  },
3052 };
3053 
3054 static struct enum_chain *
3055 enum_chain_ptr(VALUE obj)
3056 {
3057  struct enum_chain *ptr;
3058 
3059  TypedData_Get_Struct(obj, struct enum_chain, &enum_chain_data_type, ptr);
3060  if (!ptr || ptr->enums == Qundef) {
3061  rb_raise(rb_eArgError, "uninitialized chain");
3062  }
3063  return ptr;
3064 }
3065 
3066 /* :nodoc: */
3067 static VALUE
3068 enum_chain_allocate(VALUE klass)
3069 {
3070  struct enum_chain *ptr;
3071  VALUE obj;
3072 
3073  obj = TypedData_Make_Struct(klass, struct enum_chain, &enum_chain_data_type, ptr);
3074  ptr->enums = Qundef;
3075  ptr->pos = -1;
3076 
3077  return obj;
3078 }
3079 
3080 /*
3081  * call-seq:
3082  * Enumerator::Chain.new(*enums) -> enum
3083  *
3084  * Generates a new enumerator object that iterates over the elements
3085  * of given enumerable objects in sequence.
3086  *
3087  * e = Enumerator::Chain.new(1..3, [4, 5])
3088  * e.to_a #=> [1, 2, 3, 4, 5]
3089  * e.size #=> 5
3090  */
3091 static VALUE
3092 enum_chain_initialize(VALUE obj, VALUE enums)
3093 {
3094  struct enum_chain *ptr;
3095 
3097  TypedData_Get_Struct(obj, struct enum_chain, &enum_chain_data_type, ptr);
3098 
3099  if (!ptr) rb_raise(rb_eArgError, "unallocated chain");
3100 
3101  ptr->enums = rb_obj_freeze(enums);
3102  ptr->pos = -1;
3103 
3104  return obj;
3105 }
3106 
3107 /* :nodoc: */
3108 static VALUE
3109 enum_chain_init_copy(VALUE obj, VALUE orig)
3110 {
3111  struct enum_chain *ptr0, *ptr1;
3112 
3113  if (!OBJ_INIT_COPY(obj, orig)) return obj;
3114  ptr0 = enum_chain_ptr(orig);
3115 
3116  TypedData_Get_Struct(obj, struct enum_chain, &enum_chain_data_type, ptr1);
3117 
3118  if (!ptr1) rb_raise(rb_eArgError, "unallocated chain");
3119 
3120  ptr1->enums = ptr0->enums;
3121  ptr1->pos = ptr0->pos;
3122 
3123  return obj;
3124 }
3125 
3126 static VALUE
3127 enum_chain_total_size(VALUE enums)
3128 {
3129  VALUE total = INT2FIX(0);
3130  long i;
3131 
3132  for (i = 0; i < RARRAY_LEN(enums); i++) {
3133  VALUE size = enum_size(RARRAY_AREF(enums, i));
3134 
3135  if (NIL_P(size) || (RB_TYPE_P(size, T_FLOAT) && isinf(NUM2DBL(size)))) {
3136  return size;
3137  }
3138  if (!RB_INTEGER_TYPE_P(size)) {
3139  return Qnil;
3140  }
3141 
3142  total = rb_funcall(total, '+', 1, size);
3143  }
3144 
3145  return total;
3146 }
3147 
3148 /*
3149  * call-seq:
3150  * obj.size -> int, Float::INFINITY or nil
3151  *
3152  * Returns the total size of the enumerator chain calculated by
3153  * summing up the size of each enumerable in the chain. If any of the
3154  * enumerables reports its size as nil or Float::INFINITY, that value
3155  * is returned as the total size.
3156  */
3157 static VALUE
3158 enum_chain_size(VALUE obj)
3159 {
3160  return enum_chain_total_size(enum_chain_ptr(obj)->enums);
3161 }
3162 
3163 static VALUE
3164 enum_chain_enum_size(VALUE obj, VALUE args, VALUE eobj)
3165 {
3166  return enum_chain_size(obj);
3167 }
3168 
3169 static VALUE
3170 enum_chain_enum_no_size(VALUE obj, VALUE args, VALUE eobj)
3171 {
3172  return Qnil;
3173 }
3174 
3175 /*
3176  * call-seq:
3177  * obj.each(*args) { |...| ... } -> obj
3178  * obj.each(*args) -> enumerator
3179  *
3180  * Iterates over the elements of the first enumerable by calling the
3181  * "each" method on it with the given arguments, then proceeds to the
3182  * following enumerables in sequence until all of the enumerables are
3183  * exhausted.
3184  *
3185  * If no block is given, returns an enumerator.
3186  */
3187 static VALUE
3188 enum_chain_each(int argc, VALUE *argv, VALUE obj)
3189 {
3190  VALUE enums, block;
3191  struct enum_chain *objptr;
3192  long i;
3193 
3194  RETURN_SIZED_ENUMERATOR(obj, argc, argv, argc > 0 ? enum_chain_enum_no_size : enum_chain_enum_size);
3195 
3196  objptr = enum_chain_ptr(obj);
3197  enums = objptr->enums;
3198  block = rb_block_proc();
3199 
3200  for (i = 0; i < RARRAY_LEN(enums); i++) {
3201  objptr->pos = i;
3203  }
3204 
3205  return obj;
3206 }
3207 
3208 /*
3209  * call-seq:
3210  * obj.rewind -> obj
3211  *
3212  * Rewinds the enumerator chain by calling the "rewind" method on each
3213  * enumerable in reverse order. Each call is performed only if the
3214  * enumerable responds to the method.
3215  */
3216 static VALUE
3217 enum_chain_rewind(VALUE obj)
3218 {
3219  struct enum_chain *objptr = enum_chain_ptr(obj);
3220  VALUE enums = objptr->enums;
3221  long i;
3222 
3223  for (i = objptr->pos; 0 <= i && i < RARRAY_LEN(enums); objptr->pos = --i) {
3224  rb_check_funcall(RARRAY_AREF(enums, i), id_rewind, 0, 0);
3225  }
3226 
3227  return obj;
3228 }
3229 
3230 static VALUE
3231 inspect_enum_chain(VALUE obj, VALUE dummy, int recur)
3232 {
3234  struct enum_chain *ptr;
3235 
3236  TypedData_Get_Struct(obj, struct enum_chain, &enum_chain_data_type, ptr);
3237 
3238  if (!ptr || ptr->enums == Qundef) {
3239  return rb_sprintf("#<%"PRIsVALUE": uninitialized>", rb_class_path(klass));
3240  }
3241 
3242  if (recur) {
3243  return rb_sprintf("#<%"PRIsVALUE": ...>", rb_class_path(klass));
3244  }
3245 
3246  return rb_sprintf("#<%"PRIsVALUE": %+"PRIsVALUE">", rb_class_path(klass), ptr->enums);
3247 }
3248 
3249 /*
3250  * call-seq:
3251  * obj.inspect -> string
3252  *
3253  * Returns a printable version of the enumerator chain.
3254  */
3255 static VALUE
3256 enum_chain_inspect(VALUE obj)
3257 {
3258  return rb_exec_recursive(inspect_enum_chain, obj, 0);
3259 }
3260 
3261 /*
3262  * call-seq:
3263  * e.chain(*enums) -> enumerator
3264  *
3265  * Returns an enumerator object generated from this enumerator and
3266  * given enumerables.
3267  *
3268  * e = (1..3).chain([4, 5])
3269  * e.to_a #=> [1, 2, 3, 4, 5]
3270  */
3271 static VALUE
3273 {
3276 
3277  return enum_chain_initialize(enum_chain_allocate(rb_cEnumChain), enums);
3278 }
3279 
3280 /*
3281  * call-seq:
3282  * e + enum -> enumerator
3283  *
3284  * Returns an enumerator object generated from this enumerator and a
3285  * given enumerable.
3286  *
3287  * e = (1..3).each + [4, 5]
3288  * e.to_a #=> [1, 2, 3, 4, 5]
3289  */
3290 static VALUE
3291 enumerator_plus(VALUE obj, VALUE eobj)
3292 {
3293  VALUE enums = rb_ary_new_from_args(2, obj, eobj);
3294 
3295  return enum_chain_initialize(enum_chain_allocate(rb_cEnumChain), enums);
3296 }
3297 
3298 /*
3299  * Document-class: Enumerator::ArithmeticSequence
3300  *
3301  * Enumerator::ArithmeticSequence is a subclass of Enumerator,
3302  * that is a representation of sequences of numbers with common difference.
3303  * Instances of this class can be generated by the Range#step and Numeric#step
3304  * methods.
3305  */
3306 
3307 VALUE
3309  rb_enumerator_size_func *size_fn,
3310  VALUE beg, VALUE end, VALUE step, int excl)
3311 {
3312  VALUE aseq = enumerator_init(enumerator_allocate(rb_cArithSeq),
3313  obj, meth, argc, argv, size_fn, Qnil, PASS_KW_SPLAT);
3314  rb_ivar_set(aseq, id_begin, beg);
3315  rb_ivar_set(aseq, id_end, end);
3316  rb_ivar_set(aseq, id_step, step);
3317  rb_ivar_set(aseq, id_exclude_end, excl ? Qtrue : Qfalse);
3318  return aseq;
3319 }
3320 
3321 /*
3322  * call-seq: aseq.begin -> num or nil
3323  *
3324  * Returns the number that defines the first element of this arithmetic
3325  * sequence.
3326  */
3327 static inline VALUE
3328 arith_seq_begin(VALUE self)
3329 {
3330  return rb_ivar_get(self, id_begin);
3331 }
3332 
3333 /*
3334  * call-seq: aseq.end -> num or nil
3335  *
3336  * Returns the number that defines the end of this arithmetic sequence.
3337  */
3338 static inline VALUE
3339 arith_seq_end(VALUE self)
3340 {
3341  return rb_ivar_get(self, id_end);
3342 }
3343 
3344 /*
3345  * call-seq: aseq.step -> num
3346  *
3347  * Returns the number that defines the common difference between
3348  * two adjacent elements in this arithmetic sequence.
3349  */
3350 static inline VALUE
3351 arith_seq_step(VALUE self)
3352 {
3353  return rb_ivar_get(self, id_step);
3354 }
3355 
3356 /*
3357  * call-seq: aseq.exclude_end? -> true or false
3358  *
3359  * Returns <code>true</code> if this arithmetic sequence excludes its end value.
3360  */
3361 static inline VALUE
3362 arith_seq_exclude_end(VALUE self)
3363 {
3364  return rb_ivar_get(self, id_exclude_end);
3365 }
3366 
3367 static inline int
3368 arith_seq_exclude_end_p(VALUE self)
3369 {
3370  return RTEST(arith_seq_exclude_end(self));
3371 }
3372 
3373 int
3375 {
3377  component->begin = arith_seq_begin(obj);
3378  component->end = arith_seq_end(obj);
3379  component->step = arith_seq_step(obj);
3380  component->exclude_end = arith_seq_exclude_end_p(obj);
3381  return 1;
3382  }
3383  else if (rb_obj_is_kind_of(obj, rb_cRange)) {
3384  component->begin = RANGE_BEG(obj);
3385  component->end = RANGE_END(obj);
3386  component->step = INT2FIX(1);
3387  component->exclude_end = RTEST(RANGE_EXCL(obj));
3388  return 1;
3389  }
3390 
3391  return 0;
3392 }
3393 
3394 /*
3395  * call-seq:
3396  * aseq.first -> num or nil
3397  * aseq.first(n) -> an_array
3398  *
3399  * Returns the first number in this arithmetic sequence,
3400  * or an array of the first +n+ elements.
3401  */
3402 static VALUE
3403 arith_seq_first(int argc, VALUE *argv, VALUE self)
3404 {
3405  VALUE b, e, s, ary;
3406  long n;
3407  int x;
3408 
3409  rb_check_arity(argc, 0, 1);
3410 
3411  b = arith_seq_begin(self);
3412  e = arith_seq_end(self);
3413  s = arith_seq_step(self);
3414  if (argc == 0) {
3415  if (NIL_P(b)) {
3416  return Qnil;
3417  }
3418  if (!NIL_P(e)) {
3419  VALUE zero = INT2FIX(0);
3420  int r = rb_cmpint(rb_num_coerce_cmp(s, zero, idCmp), s, zero);
3421  if (r > 0 && RTEST(rb_funcall(b, '>', 1, e))) {
3422  return Qnil;
3423  }
3424  if (r < 0 && RTEST(rb_funcall(b, '<', 1, e))) {
3425  return Qnil;
3426  }
3427  }
3428  return b;
3429  }
3430 
3431  // TODO: the following code should be extracted as arith_seq_take
3432 
3433  n = NUM2LONG(argv[0]);
3434  if (n < 0) {
3435  rb_raise(rb_eArgError, "attempt to take negative size");
3436  }
3437  if (n == 0) {
3438  return rb_ary_new_capa(0);
3439  }
3440 
3441  x = arith_seq_exclude_end_p(self);
3442 
3443  if (FIXNUM_P(b) && NIL_P(e) && FIXNUM_P(s)) {
3444  long i = FIX2LONG(b), unit = FIX2LONG(s);
3445  ary = rb_ary_new_capa(n);
3446  while (n > 0 && FIXABLE(i)) {
3447  rb_ary_push(ary, LONG2FIX(i));
3448  i += unit; // FIXABLE + FIXABLE never overflow;
3449  --n;
3450  }
3451  if (n > 0) {
3452  b = LONG2NUM(i);
3453  while (n > 0) {
3454  rb_ary_push(ary, b);
3455  b = rb_big_plus(b, s);
3456  --n;
3457  }
3458  }
3459  return ary;
3460  }
3461  else if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(s)) {
3462  long i = FIX2LONG(b);
3463  long end = FIX2LONG(e);
3464  long unit = FIX2LONG(s);
3465  long len;
3466 
3467  if (unit >= 0) {
3468  if (!x) end += 1;
3469 
3470  len = end - i;
3471  if (len < 0) len = 0;
3472  ary = rb_ary_new_capa((n < len) ? n : len);
3473  while (n > 0 && i < end) {
3474  rb_ary_push(ary, LONG2FIX(i));
3475  if (i + unit < i) break;
3476  i += unit;
3477  --n;
3478  }
3479  }
3480  else {
3481  if (!x) end -= 1;
3482 
3483  len = i - end;
3484  if (len < 0) len = 0;
3485  ary = rb_ary_new_capa((n < len) ? n : len);
3486  while (n > 0 && i > end) {
3487  rb_ary_push(ary, LONG2FIX(i));
3488  if (i + unit > i) break;
3489  i += unit;
3490  --n;
3491  }
3492  }
3493  return ary;
3494  }
3495  else if (RB_FLOAT_TYPE_P(b) || RB_FLOAT_TYPE_P(e) || RB_FLOAT_TYPE_P(s)) {
3496  /* generate values like ruby_float_step */
3497 
3498  double unit = NUM2DBL(s);
3499  double beg = NUM2DBL(b);
3500  double end = NIL_P(e) ? (unit < 0 ? -1 : 1)*HUGE_VAL : NUM2DBL(e);
3501  double len = ruby_float_step_size(beg, end, unit, x);
3502  long i;
3503 
3504  if (n > len)
3505  n = (long)len;
3506 
3507  if (isinf(unit)) {
3508  if (len > 0) {
3509  ary = rb_ary_new_capa(1);
3510  rb_ary_push(ary, DBL2NUM(beg));
3511  }
3512  else {
3513  ary = rb_ary_new_capa(0);
3514  }
3515  }
3516  else if (unit == 0) {
3517  VALUE val = DBL2NUM(beg);
3518  ary = rb_ary_new_capa(n);
3519  for (i = 0; i < len; ++i) {
3520  rb_ary_push(ary, val);
3521  }
3522  }
3523  else {
3524  ary = rb_ary_new_capa(n);
3525  for (i = 0; i < n; ++i) {
3526  double d = i*unit+beg;
3527  if (unit >= 0 ? end < d : d < end) d = end;
3528  rb_ary_push(ary, DBL2NUM(d));
3529  }
3530  }
3531 
3532  return ary;
3533  }
3534 
3535  return rb_call_super(argc, argv);
3536 }
3537 
3538 /*
3539  * call-seq:
3540  * aseq.last -> num or nil
3541  * aseq.last(n) -> an_array
3542  *
3543  * Returns the last number in this arithmetic sequence,
3544  * or an array of the last +n+ elements.
3545  */
3546 static VALUE
3547 arith_seq_last(int argc, VALUE *argv, VALUE self)
3548 {
3549  VALUE b, e, s, len_1, len, last, nv, ary;
3550  int last_is_adjusted;
3551  long n;
3552 
3553  e = arith_seq_end(self);
3554  if (NIL_P(e)) {
3556  "cannot get the last element of endless arithmetic sequence");
3557  }
3558 
3559  b = arith_seq_begin(self);
3560  s = arith_seq_step(self);
3561 
3562  len_1 = rb_int_idiv(rb_int_minus(e, b), s);
3563  if (rb_num_negative_int_p(len_1)) {
3564  if (argc == 0) {
3565  return Qnil;
3566  }
3567  return rb_ary_new_capa(0);
3568  }
3569 
3570  last = rb_int_plus(b, rb_int_mul(s, len_1));
3571  if ((last_is_adjusted = arith_seq_exclude_end_p(self) && rb_equal(last, e))) {
3572  last = rb_int_minus(last, s);
3573  }
3574 
3575  if (argc == 0) {
3576  return last;
3577  }
3578 
3579  if (last_is_adjusted) {
3580  len = len_1;
3581  }
3582  else {
3583  len = rb_int_plus(len_1, INT2FIX(1));
3584  }
3585 
3586  rb_scan_args(argc, argv, "1", &nv);
3587  if (!RB_INTEGER_TYPE_P(nv)) {
3588  nv = rb_to_int(nv);
3589  }
3590  if (RTEST(rb_int_gt(nv, len))) {
3591  nv = len;
3592  }
3593  n = NUM2LONG(nv);
3594  if (n < 0) {
3595  rb_raise(rb_eArgError, "negative array size");
3596  }
3597 
3598  ary = rb_ary_new_capa(n);
3599  b = rb_int_minus(last, rb_int_mul(s, nv));
3600  while (n) {
3601  b = rb_int_plus(b, s);
3602  rb_ary_push(ary, b);
3603  --n;
3604  }
3605 
3606  return ary;
3607 }
3608 
3609 /*
3610  * call-seq:
3611  * aseq.inspect -> string
3612  *
3613  * Convert this arithmetic sequence to a printable form.
3614  */
3615 static VALUE
3616 arith_seq_inspect(VALUE self)
3617 {
3618  struct enumerator *e;
3619  VALUE eobj, str, eargs;
3620  int range_p;
3621 
3622  TypedData_Get_Struct(self, struct enumerator, &enumerator_data_type, e);
3623 
3624  eobj = rb_attr_get(self, id_receiver);
3625  if (NIL_P(eobj)) {
3626  eobj = e->obj;
3627  }
3628 
3629  range_p = RTEST(rb_obj_is_kind_of(eobj, rb_cRange));
3630  str = rb_sprintf("(%s%"PRIsVALUE"%s.", range_p ? "(" : "", eobj, range_p ? ")" : "");
3631 
3633 
3634  eargs = rb_attr_get(eobj, id_arguments);
3635  if (NIL_P(eargs)) {
3636  eargs = e->args;
3637  }
3638  if (eargs != Qfalse) {
3639  long argc = RARRAY_LEN(eargs);
3640  const VALUE *argv = RARRAY_CONST_PTR(eargs); /* WB: no new reference */
3641 
3642  if (argc > 0) {
3643  VALUE kwds = Qnil;
3644 
3645  rb_str_buf_cat2(str, "(");
3646 
3647  if (RB_TYPE_P(argv[argc-1], T_HASH)) {
3648  int all_key = TRUE;
3649  rb_hash_foreach(argv[argc-1], key_symbol_p, (VALUE)&all_key);
3650  if (all_key) kwds = argv[--argc];
3651  }
3652 
3653  while (argc--) {
3654  VALUE arg = *argv++;
3655 
3657  rb_str_buf_cat2(str, ", ");
3658  }
3659  if (!NIL_P(kwds)) {
3660  rb_hash_foreach(kwds, kwd_append, str);
3661  }
3662  rb_str_set_len(str, RSTRING_LEN(str)-2); /* drop the last ", " */
3663  rb_str_buf_cat2(str, ")");
3664  }
3665  }
3666 
3667  rb_str_buf_cat2(str, ")");
3668 
3669  return str;
3670 }
3671 
3672 /*
3673  * call-seq:
3674  * aseq == obj -> true or false
3675  *
3676  * Returns <code>true</code> only if +obj+ is an Enumerator::ArithmeticSequence,
3677  * has equivalent begin, end, step, and exclude_end? settings.
3678  */
3679 static VALUE
3680 arith_seq_eq(VALUE self, VALUE other)
3681 {
3682  if (!RTEST(rb_obj_is_kind_of(other, rb_cArithSeq))) {
3683  return Qfalse;
3684  }
3685 
3686  if (!rb_equal(arith_seq_begin(self), arith_seq_begin(other))) {
3687  return Qfalse;
3688  }
3689 
3690  if (!rb_equal(arith_seq_end(self), arith_seq_end(other))) {
3691  return Qfalse;
3692  }
3693 
3694  if (!rb_equal(arith_seq_step(self), arith_seq_step(other))) {
3695  return Qfalse;
3696  }
3697 
3698  if (arith_seq_exclude_end_p(self) != arith_seq_exclude_end_p(other)) {
3699  return Qfalse;
3700  }
3701 
3702  return Qtrue;
3703 }
3704 
3705 /*
3706  * call-seq:
3707  * aseq.hash -> integer
3708  *
3709  * Compute a hash-value for this arithmetic sequence.
3710  * Two arithmetic sequences with same begin, end, step, and exclude_end?
3711  * values will generate the same hash-value.
3712  *
3713  * See also Object#hash.
3714  */
3715 static VALUE
3716 arith_seq_hash(VALUE self)
3717 {
3718  st_index_t hash;
3719  VALUE v;
3720 
3721  hash = rb_hash_start(arith_seq_exclude_end_p(self));
3722  v = rb_hash(arith_seq_begin(self));
3723  hash = rb_hash_uint(hash, NUM2LONG(v));
3724  v = rb_hash(arith_seq_end(self));
3725  hash = rb_hash_uint(hash, NUM2LONG(v));
3726  v = rb_hash(arith_seq_step(self));
3727  hash = rb_hash_uint(hash, NUM2LONG(v));
3728  hash = rb_hash_end(hash);
3729 
3730  return ST2FIX(hash);
3731 }
3732 
3733 #define NUM_GE(x, y) RTEST(rb_num_coerce_relop((x), (y), idGE))
3734 
3739  int excl;
3740 };
3741 
3742 /*
3743  * call-seq:
3744  * aseq.each {|i| block } -> aseq
3745  * aseq.each -> aseq
3746  */
3747 static VALUE
3748 arith_seq_each(VALUE self)
3749 {
3750  VALUE c, e, s, len_1, last;
3751  int x;
3752 
3753  if (!rb_block_given_p()) return self;
3754 
3755  c = arith_seq_begin(self);
3756  e = arith_seq_end(self);
3757  s = arith_seq_step(self);
3758  x = arith_seq_exclude_end_p(self);
3759 
3760  if (!RB_TYPE_P(s, T_COMPLEX) && ruby_float_step(c, e, s, x, TRUE)) {
3761  return self;
3762  }
3763 
3764  if (NIL_P(e)) {
3765  while (1) {
3766  rb_yield(c);
3767  c = rb_int_plus(c, s);
3768  }
3769 
3770  return self;
3771  }
3772 
3773  if (rb_equal(s, INT2FIX(0))) {
3774  while (1) {
3775  rb_yield(c);
3776  }
3777 
3778  return self;
3779  }
3780 
3781  len_1 = rb_int_idiv(rb_int_minus(e, c), s);
3782  last = rb_int_plus(c, rb_int_mul(s, len_1));
3783  if (x && rb_equal(last, e)) {
3784  last = rb_int_minus(last, s);
3785  }
3786 
3787  if (rb_num_negative_int_p(s)) {
3788  while (NUM_GE(c, last)) {
3789  rb_yield(c);
3790  c = rb_int_plus(c, s);
3791  }
3792  }
3793  else {
3794  while (NUM_GE(last, c)) {
3795  rb_yield(c);
3796  c = rb_int_plus(c, s);
3797  }
3798  }
3799 
3800  return self;
3801 }
3802 
3803 static double
3804 arith_seq_float_step_size(double beg, double end, double step, int excl)
3805 {
3806  double const epsilon = DBL_EPSILON;
3807  double n, err;
3808 
3809  if (step == 0) {
3810  return HUGE_VAL;
3811  }
3812  n = (end - beg) / step;
3813  err = (fabs(beg) + fabs(end) + fabs(end - beg)) / fabs(step) * epsilon;
3814  if (isinf(step)) {
3815  return step > 0 ? beg <= end : beg >= end;
3816  }
3817  if (err > 0.5) err = 0.5;
3818  if (excl) {
3819  if (n <= 0) return 0;
3820  if (n < 1)
3821  n = 0;
3822  else
3823  n = floor(n - err);
3824  }
3825  else {
3826  if (n < 0) return 0;
3827  n = floor(n + err);
3828  }
3829  return n + 1;
3830 }
3831 
3832 /*
3833  * call-seq:
3834  * aseq.size -> num or nil
3835  *
3836  * Returns the number of elements in this arithmetic sequence if it is a finite
3837  * sequence. Otherwise, returns <code>nil</code>.
3838  */
3839 static VALUE
3840 arith_seq_size(VALUE self)
3841 {
3842  VALUE b, e, s, len_1, len, last;
3843  int x;
3844 
3845  b = arith_seq_begin(self);
3846  e = arith_seq_end(self);
3847  s = arith_seq_step(self);
3848  x = arith_seq_exclude_end_p(self);
3849 
3850  if (RB_FLOAT_TYPE_P(b) || RB_FLOAT_TYPE_P(e) || RB_FLOAT_TYPE_P(s)) {
3851  double ee, n;
3852 
3853  if (NIL_P(e)) {
3854  if (rb_num_negative_int_p(s)) {
3855  ee = -HUGE_VAL;
3856  }
3857  else {
3858  ee = HUGE_VAL;
3859  }
3860  }
3861  else {
3862  ee = NUM2DBL(e);
3863  }
3864 
3865  n = arith_seq_float_step_size(NUM2DBL(b), ee, NUM2DBL(s), x);
3866  if (isinf(n)) return DBL2NUM(n);
3867  if (POSFIXABLE(n)) return LONG2FIX(n);
3868  return rb_dbl2big(n);
3869  }
3870 
3871  if (NIL_P(e)) {
3872  return DBL2NUM(HUGE_VAL);
3873  }
3874 
3875  if (!rb_obj_is_kind_of(s, rb_cNumeric)) {
3876  s = rb_to_int(s);
3877  }
3878 
3879  if (rb_equal(s, INT2FIX(0))) {
3880  return DBL2NUM(HUGE_VAL);
3881  }
3882 
3883  len_1 = rb_int_idiv(rb_int_minus(e, b), s);
3884  if (rb_num_negative_int_p(len_1)) {
3885  return INT2FIX(0);
3886  }
3887 
3888  last = rb_int_plus(b, rb_int_mul(s, len_1));
3889  if (x && rb_equal(last, e)) {
3890  len = len_1;
3891  }
3892  else {
3893  len = rb_int_plus(len_1, INT2FIX(1));
3894  }
3895 
3896  return len;
3897 }
3898 
3899 void
3901 {
3902  ID id_private = rb_intern("private");
3903 
3904  rb_define_method(rb_mKernel, "to_enum", obj_to_enum, -1);
3905  rb_define_method(rb_mKernel, "enum_for", obj_to_enum, -1);
3906 
3907  rb_cEnumerator = rb_define_class("Enumerator", rb_cObject);
3909 
3910  rb_define_alloc_func(rb_cEnumerator, enumerator_allocate);
3911  rb_define_method(rb_cEnumerator, "initialize", enumerator_initialize, -1);
3912  rb_define_method(rb_cEnumerator, "initialize_copy", enumerator_init_copy, 1);
3913  rb_define_method(rb_cEnumerator, "each", enumerator_each, -1);
3914  rb_define_method(rb_cEnumerator, "each_with_index", enumerator_each_with_index, 0);
3915  rb_define_method(rb_cEnumerator, "each_with_object", enumerator_with_object, 1);
3916  rb_define_method(rb_cEnumerator, "with_index", enumerator_with_index, -1);
3917  rb_define_method(rb_cEnumerator, "with_object", enumerator_with_object, 1);
3918  rb_define_method(rb_cEnumerator, "next_values", enumerator_next_values, 0);
3919  rb_define_method(rb_cEnumerator, "peek_values", enumerator_peek_values_m, 0);
3920  rb_define_method(rb_cEnumerator, "next", enumerator_next, 0);
3921  rb_define_method(rb_cEnumerator, "peek", enumerator_peek, 0);
3922  rb_define_method(rb_cEnumerator, "feed", enumerator_feed, 1);
3923  rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);
3924  rb_define_method(rb_cEnumerator, "inspect", enumerator_inspect, 0);
3925  rb_define_method(rb_cEnumerator, "size", enumerator_size, 0);
3926  rb_define_method(rb_cEnumerator, "+", enumerator_plus, 1);
3928 
3929  /* Lazy */
3931  rb_define_method(rb_mEnumerable, "lazy", enumerable_lazy, 0);
3932 
3933  rb_define_alias(rb_cLazy, "_enumerable_map", "map");
3934  rb_define_alias(rb_cLazy, "_enumerable_collect", "collect");
3935  rb_define_alias(rb_cLazy, "_enumerable_flat_map", "flat_map");
3936  rb_define_alias(rb_cLazy, "_enumerable_collect_concat", "collect_concat");
3937  rb_define_alias(rb_cLazy, "_enumerable_select", "select");
3938  rb_define_alias(rb_cLazy, "_enumerable_find_all", "find_all");
3939  rb_define_alias(rb_cLazy, "_enumerable_filter", "filter");
3940  rb_define_alias(rb_cLazy, "_enumerable_filter_map", "filter_map");
3941  rb_define_alias(rb_cLazy, "_enumerable_reject", "reject");
3942  rb_define_alias(rb_cLazy, "_enumerable_grep", "grep");
3943  rb_define_alias(rb_cLazy, "_enumerable_grep_v", "grep_v");
3944  rb_define_alias(rb_cLazy, "_enumerable_zip", "zip");
3945  rb_define_alias(rb_cLazy, "_enumerable_take", "take");
3946  rb_define_alias(rb_cLazy, "_enumerable_take_while", "take_while");
3947  rb_define_alias(rb_cLazy, "_enumerable_drop", "drop");
3948  rb_define_alias(rb_cLazy, "_enumerable_drop_while", "drop_while");
3949  rb_define_alias(rb_cLazy, "_enumerable_uniq", "uniq");
3950  rb_define_private_method(rb_cLazy, "_enumerable_with_index", enumerator_with_index, -1);
3951 
3952  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_map")));
3953  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_collect")));
3954  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_flat_map")));
3955  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_collect_concat")));
3956  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_select")));
3957  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_find_all")));
3958  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_filter")));
3959  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_filter_map")));
3960  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_reject")));
3961  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_grep")));
3962  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_grep_v")));
3963  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_zip")));
3964  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_take")));
3965  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_take_while")));
3966  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_drop")));
3967  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_drop_while")));
3968  rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_uniq")));
3969 
3970  rb_define_method(rb_cLazy, "initialize", lazy_initialize, -1);
3971  rb_define_method(rb_cLazy, "to_enum", lazy_to_enum, -1);
3972  rb_define_method(rb_cLazy, "enum_for", lazy_to_enum, -1);
3973  rb_define_method(rb_cLazy, "eager", lazy_eager, 0);
3974  rb_define_method(rb_cLazy, "map", lazy_map, 0);
3975  rb_define_method(rb_cLazy, "collect", lazy_map, 0);
3976  rb_define_method(rb_cLazy, "flat_map", lazy_flat_map, 0);
3977  rb_define_method(rb_cLazy, "collect_concat", lazy_flat_map, 0);
3978  rb_define_method(rb_cLazy, "select", lazy_select, 0);
3979  rb_define_method(rb_cLazy, "find_all", lazy_select, 0);
3980  rb_define_method(rb_cLazy, "filter", lazy_select, 0);
3981  rb_define_method(rb_cLazy, "filter_map", lazy_filter_map, 0);
3982  rb_define_method(rb_cLazy, "reject", lazy_reject, 0);
3983  rb_define_method(rb_cLazy, "grep", lazy_grep, 1);
3984  rb_define_method(rb_cLazy, "grep_v", lazy_grep_v, 1);
3985  rb_define_method(rb_cLazy, "zip", lazy_zip, -1);
3986  rb_define_method(rb_cLazy, "take", lazy_take, 1);
3987  rb_define_method(rb_cLazy, "take_while", lazy_take_while, 0);
3988  rb_define_method(rb_cLazy, "drop", lazy_drop, 1);
3989  rb_define_method(rb_cLazy, "drop_while", lazy_drop_while, 0);
3990  rb_define_method(rb_cLazy, "lazy", lazy_lazy, 0);
3991  rb_define_method(rb_cLazy, "chunk", lazy_super, -1);
3992  rb_define_method(rb_cLazy, "slice_before", lazy_super, -1);
3993  rb_define_method(rb_cLazy, "slice_after", lazy_super, -1);
3994  rb_define_method(rb_cLazy, "slice_when", lazy_super, -1);
3995  rb_define_method(rb_cLazy, "chunk_while", lazy_super, -1);
3996  rb_define_method(rb_cLazy, "uniq", lazy_uniq, 0);
3997  rb_define_method(rb_cLazy, "with_index", lazy_with_index, -1);
3998 
3999  lazy_use_super_method = rb_hash_new_with_size(18);
4000  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("map")), ID2SYM(rb_intern("_enumerable_map")));
4001  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("collect")), ID2SYM(rb_intern("_enumerable_collect")));
4002  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("flat_map")), ID2SYM(rb_intern("_enumerable_flat_map")));
4003  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("collect_concat")), ID2SYM(rb_intern("_enumerable_collect_concat")));
4004  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("select")), ID2SYM(rb_intern("_enumerable_select")));
4005  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("find_all")), ID2SYM(rb_intern("_enumerable_find_all")));
4006  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("filter")), ID2SYM(rb_intern("_enumerable_filter")));
4007  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("filter_map")), ID2SYM(rb_intern("_enumerable_filter_map")));
4008  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("reject")), ID2SYM(rb_intern("_enumerable_reject")));
4009  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("grep")), ID2SYM(rb_intern("_enumerable_grep")));
4010  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("grep_v")), ID2SYM(rb_intern("_enumerable_grep_v")));
4011  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("zip")), ID2SYM(rb_intern("_enumerable_zip")));
4012  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("take")), ID2SYM(rb_intern("_enumerable_take")));
4013  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("take_while")), ID2SYM(rb_intern("_enumerable_take_while")));
4014  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("drop")), ID2SYM(rb_intern("_enumerable_drop")));
4015  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("drop_while")), ID2SYM(rb_intern("_enumerable_drop_while")));
4016  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("uniq")), ID2SYM(rb_intern("_enumerable_uniq")));
4017  rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("with_index")), ID2SYM(rb_intern("_enumerable_with_index")));
4018  rb_obj_freeze(lazy_use_super_method);
4019  rb_gc_register_mark_object(lazy_use_super_method);
4020 
4021 #if 0 /* for RDoc */
4022  rb_define_method(rb_cLazy, "to_a", lazy_to_a, 0);
4023  rb_define_method(rb_cLazy, "chunk", lazy_chunk, 0);
4024  rb_define_method(rb_cLazy, "chunk_while", lazy_chunk_while, 0);
4025  rb_define_method(rb_cLazy, "slice_after", lazy_slice_after, 0);
4026  rb_define_method(rb_cLazy, "slice_before", lazy_slice_before, 0);
4027  rb_define_method(rb_cLazy, "slice_when", lazy_slice_when, 0);
4028 #endif
4029  rb_define_alias(rb_cLazy, "force", "to_a");
4030 
4031  rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
4032  rb_define_method(rb_eStopIteration, "result", stop_result, 0);
4033 
4034  /* Generator */
4035  rb_cGenerator = rb_define_class_under(rb_cEnumerator, "Generator", rb_cObject);
4036  rb_include_module(rb_cGenerator, rb_mEnumerable);
4037  rb_define_alloc_func(rb_cGenerator, generator_allocate);
4038  rb_define_method(rb_cGenerator, "initialize", generator_initialize, -1);
4039  rb_define_method(rb_cGenerator, "initialize_copy", generator_init_copy, 1);
4040  rb_define_method(rb_cGenerator, "each", generator_each, -1);
4041 
4042  /* Yielder */
4043  rb_cYielder = rb_define_class_under(rb_cEnumerator, "Yielder", rb_cObject);
4044  rb_define_alloc_func(rb_cYielder, yielder_allocate);
4045  rb_define_method(rb_cYielder, "initialize", yielder_initialize, 0);
4046  rb_define_method(rb_cYielder, "yield", yielder_yield, -2);
4047  rb_define_method(rb_cYielder, "<<", yielder_yield_push, 1);
4048  rb_define_method(rb_cYielder, "to_proc", yielder_to_proc, 0);
4049 
4050  /* Producer */
4051  rb_cEnumProducer = rb_define_class_under(rb_cEnumerator, "Producer", rb_cObject);
4052  rb_define_alloc_func(rb_cEnumProducer, producer_allocate);
4053  rb_define_method(rb_cEnumProducer, "each", producer_each, 0);
4054  rb_define_singleton_method(rb_cEnumerator, "produce", enumerator_s_produce, -1);
4055 
4056  /* Chain */
4057  rb_cEnumChain = rb_define_class_under(rb_cEnumerator, "Chain", rb_cEnumerator);
4058  rb_define_alloc_func(rb_cEnumChain, enum_chain_allocate);
4059  rb_define_method(rb_cEnumChain, "initialize", enum_chain_initialize, -2);
4060  rb_define_method(rb_cEnumChain, "initialize_copy", enum_chain_init_copy, 1);
4061  rb_define_method(rb_cEnumChain, "each", enum_chain_each, -1);
4062  rb_define_method(rb_cEnumChain, "size", enum_chain_size, 0);
4063  rb_define_method(rb_cEnumChain, "rewind", enum_chain_rewind, 0);
4064  rb_define_method(rb_cEnumChain, "inspect", enum_chain_inspect, 0);
4065 
4066  /* ArithmeticSequence */
4070  rb_define_method(rb_cArithSeq, "begin", arith_seq_begin, 0);
4071  rb_define_method(rb_cArithSeq, "end", arith_seq_end, 0);
4072  rb_define_method(rb_cArithSeq, "exclude_end?", arith_seq_exclude_end, 0);
4073  rb_define_method(rb_cArithSeq, "step", arith_seq_step, 0);
4074  rb_define_method(rb_cArithSeq, "first", arith_seq_first, -1);
4075  rb_define_method(rb_cArithSeq, "last", arith_seq_last, -1);
4076  rb_define_method(rb_cArithSeq, "inspect", arith_seq_inspect, 0);
4077  rb_define_method(rb_cArithSeq, "==", arith_seq_eq, 1);
4078  rb_define_method(rb_cArithSeq, "===", arith_seq_eq, 1);
4079  rb_define_method(rb_cArithSeq, "eql?", arith_seq_eq, 1);
4080  rb_define_method(rb_cArithSeq, "hash", arith_seq_hash, 0);
4081  rb_define_method(rb_cArithSeq, "each", arith_seq_each, 0);
4082  rb_define_method(rb_cArithSeq, "size", arith_seq_size, 0);
4083 
4084  rb_provide("enumerator.so"); /* for backward compatibility */
4085 }
4086 
4087 #undef rb_intern
4088 void
4090 {
4091  id_rewind = rb_intern("rewind");
4092  id_new = rb_intern("new");
4093  id_next = rb_intern("next");
4094  id_result = rb_intern("result");
4095  id_receiver = rb_intern("receiver");
4096  id_arguments = rb_intern("arguments");
4097  id_memo = rb_intern("memo");
4098  id_method = rb_intern("method");
4099  id_force = rb_intern("force");
4100  id_to_enum = rb_intern("to_enum");
4101  id_begin = rb_intern("begin");
4102  id_end = rb_intern("end");
4103  id_step = rb_intern("step");
4104  id_exclude_end = rb_intern("exclude_end");
4105  sym_each = ID2SYM(id_each);
4106  sym_cycle = ID2SYM(rb_intern("cycle"));
4107  sym_yield = ID2SYM(rb_intern("yield"));
4108 
4109  InitVM(Enumerator);
4110 }
rb_ary_new_capa
VALUE rb_ary_new_capa(long capa)
Definition: array.c:717
ID
unsigned long ID
Definition: ruby.h:103
rb_check_funcall
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:505
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:649
generator_free
#define generator_free
Definition: enumerator.c:1404
ruby::backward::cxxanyargs::rb_proc_new
VALUE rb_proc_new(type *q, VALUE w)
Creates a rb_cProc instance.
Definition: cxxanyargs.hpp:324
TypedData_Make_Struct
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1244
Check_Type
#define Check_Type(v, t)
Definition: ruby.h:595
TRUE
#define TRUE
Definition: nkf.h:175
T_FLOAT
#define T_FLOAT
Definition: ruby.h:527
rb_include_module
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:869
enumerator::feedvalue
VALUE feedvalue
Definition: enumerator.c:133
DBL_EPSILON
#define DBL_EPSILON
Definition: numeric.c:61
rb_obj_hide
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
Definition: object.c:78
enumerator::obj
VALUE obj
Definition: enumerator.c:127
rb_arith_seq_new
VALUE rb_arith_seq_new(VALUE obj, VALUE meth, int argc, VALUE const *argv, rb_enumerator_size_func *size_fn, VALUE beg, VALUE end, VALUE step, int excl)
Definition: enumerator.c:3308
RB_PASS_CALLED_KEYWORDS
#define RB_PASS_CALLED_KEYWORDS
Definition: ruby.h:1980
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:1523
rb_gc_register_mark_object
void rb_gc_register_mark_object(VALUE obj)
Definition: gc.c:7066
rb_funcall2
#define rb_funcall2
Definition: ruby.h:1895
rb_str_buf_cat2
#define rb_str_buf_cat2
Definition: intern.h:911
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:315
rb_block_given_p
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:898
floor
double floor(double)
rb_cNumeric
RUBY_EXTERN VALUE rb_cNumeric
Definition: ruby.h:2037
int
__inline__ int
Definition: rb_mjit_min_header-2.7.2.h:2845
generator
Definition: enumerator.c:143
rb_yield_values_kw
VALUE rb_yield_values_kw(int n, const VALUE *argv, int kw_splat)
Definition: vm_eval.c:1277
ST_STOP
@ ST_STOP
Definition: st.h:99
enumerator
Definition: enumerator.c:126
MEMO::v1
const VALUE v1
Definition: internal.h:1281
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
id_each
#define id_each
Definition: enumerator.c:119
producer
Definition: enumerator.c:152
i
uint32_t i
Definition: rb_mjit_min_header-2.7.2.h:5460
rb_dbl2big
VALUE rb_dbl2big(double d)
Definition: bignum.c:5249
NUM2LONG
#define NUM2LONG(x)
Definition: ruby.h:679
yielder
Definition: enumerator.c:148
rb_attr_get
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1084
proc_entry::proc
VALUE proc
Definition: enumerator.c:165
rb_hash_aref
VALUE rb_hash_aref(VALUE hash, VALUE key)
Definition: hash.c:2037
rb_equal
VALUE rb_equal(VALUE, VALUE)
Same as Object#===, case equality.
Definition: object.c:124
VALUE
unsigned long VALUE
Definition: ruby.h:102
long
#define long
Definition: rb_mjit_min_header-2.7.2.h:2889
arith_seq_gen::end
VALUE end
Definition: enumerator.c:3737
rb_eArgError
VALUE rb_eArgError
Definition: error.c:925
enumerator::meth
ID meth
Definition: enumerator.c:128
rb_intern
#define rb_intern(str)
rb_ary_store
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:1079
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:560
rb_gc_location
VALUE rb_gc_location(VALUE value)
Definition: gc.c:8114
rb_cEnumerator
VALUE rb_cEnumerator
Definition: enumerator.c:109
rb_arithmetic_sequence_components_t
Definition: intern.h:281
rb_need_block
void rb_need_block(void)
Declares that the current method needs a block.
Definition: eval.c:932
InitVM_Enumerator
void InitVM_Enumerator(void)
Definition: enumerator.c:3900
id.h
rb_call_super
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:306
rb_inspect
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:551
RANGE_END
#define RANGE_END(r)
Definition: internal.h:2092
exc
const rb_iseq_t const VALUE exc
Definition: rb_mjit_min_header-2.7.2.h:13469
rb_eIndexError
VALUE rb_eIndexError
Definition: error.c:926
Qundef
#define Qundef
Definition: ruby.h:470
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1755
lazyenum_funcs
Definition: enumerator.c:159
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
rb_long2int
#define rb_long2int(n)
Definition: ruby.h:350
INT2NUM
#define INT2NUM(x)
Definition: ruby.h:1609
ptr
struct RIMemo * ptr
Definition: debug.c:65
MEMO_V1_SET
#define MEMO_V1_SET(m, v)
Definition: internal.h:1291
Qfalse
#define Qfalse
Definition: ruby.h:467
RETURN_SIZED_ENUMERATOR
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: intern.h:271
DBL2NUM
#define DBL2NUM(dbl)
Definition: ruby.h:967
LAZY_MEMO_SET_VALUE
#define LAZY_MEMO_SET_VALUE(memo, value)
Definition: enumerator.c:1594
rb_arithmetic_sequence_components_t::exclude_end
int exclude_end
Definition: intern.h:285
LAZY_MEMO_PACKED
#define LAZY_MEMO_PACKED
Definition: enumerator.c:1590
rb_id2str
#define rb_id2str(id)
Definition: vm_backtrace.c:30
rb_enumerator_size_func
VALUE rb_enumerator_size_func(VALUE, VALUE, VALUE)
Definition: intern.h:256
arith_seq_gen::step
VALUE step
Definition: enumerator.c:3738
rb_yield_values
#define rb_yield_values(argc,...)
Definition: rb_mjit_min_header-2.7.2.h:6580
rb_ary_new3
#define rb_ary_new3
Definition: intern.h:104
rb_arithmetic_sequence_components_t::begin
VALUE begin
Definition: intern.h:282
NULL
#define NULL
Definition: _sdbm.c:101
T_COMPLEX
#define T_COMPLEX
Definition: ruby.h:542
enumerator::size_fn
rb_enumerator_size_func * size_fn
Definition: enumerator.c:137
rb_cmpint
#define rb_cmpint(cmp, a, b)
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
last
unsigned int last
Definition: nkf.c:4324
FIX2LONG
#define FIX2LONG(x)
Definition: ruby.h:394
ID2SYM
#define ID2SYM(x)
Definition: ruby.h:414
ruby.h
rb_int_idiv
VALUE rb_int_idiv(VALUE x, VALUE y)
Definition: numeric.c:3843
T_SYMBOL
#define T_SYMBOL
Definition: ruby.h:540
rb_num_coerce_cmp
VALUE rb_num_coerce_cmp(VALUE, VALUE, ID)
Definition: numeric.c:453
enumerator_free
#define enumerator_free
Definition: enumerator.c:215
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1800
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:2190
rb_fiber_alive_p
VALUE rb_fiber_alive_p(VALUE fiber_value)
Definition: cont.c:2152
MEMO
MEMO.
Definition: internal.h:1278
RB_BLOCK_CALL_FUNC_ARGLIST
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Definition: ruby.h:1964
rb_undef_method
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1575
rb_check_arity
#define rb_check_arity
Definition: intern.h:347
InitVM
#define InitVM(ext)
Definition: ruby.h:2329
rb_hash_new_with_size
MJIT_FUNC_EXPORTED VALUE rb_hash_new_with_size(st_index_t size)
Definition: hash.c:1529
RARRAY_LENINT
#define RARRAY_LENINT(ary)
Definition: ruby.h:1071
rb_cRange
RUBY_EXTERN VALUE rb_cRange
Definition: ruby.h:2040
UNLIMITED_ARGUMENTS
#define UNLIMITED_ARGUMENTS
Definition: intern.h:57
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2671
const
#define const
Definition: strftime.c:103
rb_ary_entry
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1512
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1070
rb_eRangeError
VALUE rb_eRangeError
Definition: error.c:928
enumerator::kw_splat
int kw_splat
Definition: enumerator.c:138
rb_enum_values_pack
VALUE rb_enum_values_pack(int argc, const VALUE *argv)
Definition: enum.c:33
rb_int_succ
VALUE rb_int_succ(VALUE num)
Definition: numeric.c:3321
LONG2NUM
#define LONG2NUM(x)
Definition: ruby.h:1644
LAZY_MEMO_SET_BREAK
#define LAZY_MEMO_SET_BREAK(memo)
Definition: enumerator.c:1593
rb_obj_class
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
Definition: object.c:217
rb_hash_add_new_element
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:4547
rb_obj_is_proc
VALUE rb_obj_is_proc(VALUE)
Definition: proc.c:152
HUGE_VAL
#define HUGE_VAL
Definition: missing.h:161
lazyenum_funcs::size
lazyenum_size_func * size
Definition: enumerator.c:161
producer_free
#define producer_free
Definition: enumerator.c:2852
DATA_PTR
#define DATA_PTR(dta)
Definition: ruby.h:1175
rb_int_mul
VALUE rb_int_mul(VALUE x, VALUE y)
Definition: numeric.c:3699
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.2.h:13222
LAZY_MEMO_RESET_PACKED
#define LAZY_MEMO_RESET_PACKED(memo)
Definition: enumerator.c:1596
ALLOCV_END
#define ALLOCV_END(v)
Definition: ruby.h:1750
NUM_GE
#define NUM_GE(x, y)
Definition: enumerator.c:3733
rb_check_frozen
#define rb_check_frozen(obj)
Definition: intern.h:319
idLTLT
@ idLTLT
Definition: id.h:90
POSFIXABLE
#define POSFIXABLE(f)
Definition: ruby.h:397
ALLOCV_N
#define ALLOCV_N(type, v, n)
Definition: ruby.h:1749
rb_frame_this_func
ID rb_frame_this_func(void)
The original name of the current method.
Definition: eval.c:1183
RANGE_BEG
#define RANGE_BEG(r)
Definition: internal.h:2091
rb_ary_cat
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
Definition: array.c:1208
enum_chain::enums
VALUE enums
Definition: enumerator.c:176
RHASH_EMPTY_P
#define RHASH_EMPTY_P(h)
Definition: ruby.h:1131
enumerator::lookahead
VALUE lookahead
Definition: enumerator.c:132
proc_entry::fn
const lazyenum_funcs * fn
Definition: enumerator.c:167
rb_to_id
ID rb_to_id(VALUE)
Definition: string.c:11146
rb_exc_new2
#define rb_exc_new2
Definition: intern.h:292
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
st_index_t
st_data_t st_index_t
Definition: st.h:50
generator::obj
VALUE obj
Definition: enumerator.c:145
rb_hash_start
st_index_t rb_hash_start(st_index_t)
Definition: random.c:1434
rb_obj_freeze
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
Definition: object.c:1080
rb_block_call_func
VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
Definition: ruby.h:1966
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: psych_emitter.c:7
rb_obj_method
VALUE rb_obj_method(VALUE, VALUE)
Definition: proc.c:1861
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:924
yielder::proc
VALUE proc
Definition: enumerator.c:149
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:922
MEMO_NEW
#define MEMO_NEW(a, b, c)
Definition: internal.h:1296
producer::init
VALUE init
Definition: enumerator.c:153
size
int size
Definition: encoding.c:58
rb_str_set_len
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
FALSE
#define FALSE
Definition: nkf.h:174
FIXNUM_P
#define FIXNUM_P(f)
Definition: ruby.h:396
rb_gc_mark_movable
void rb_gc_mark_movable(VALUE ptr)
Definition: gc.c:5209
rb_to_int
VALUE rb_to_int(VALUE)
Converts val into Integer.
Definition: object.c:3021
rb_proc_call_with_block
VALUE rb_proc_call_with_block(VALUE, int argc, const VALUE *argv, VALUE)
Definition: proc.c:1000
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.2.h:5597
rb_hash_foreach
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
Definition: hash.c:1483
rb_iter_break
void rb_iter_break(void)
Definition: vm.c:1546
idTo_proc
@ idTo_proc
Definition: rb_mjit_min_header-2.7.2.h:8682
lazyenum_funcs::proc
lazyenum_proc_func * proc
Definition: enumerator.c:160
rb_obj_dup
VALUE rb_obj_dup(VALUE)
Equivalent to Object#dup in Ruby.
Definition: object.c:420
rb_enumeratorize_with_size_kw
VALUE rb_enumeratorize_with_size_kw(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, int kw_splat)
Definition: enumerator.c:537
rb_enumeratorize_with_size
VALUE rb_enumeratorize_with_size(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn)
Definition: enumerator.c:525
LAZY_MEMO_SET_PACKED
#define LAZY_MEMO_SET_PACKED(memo)
Definition: enumerator.c:1595
rb_check_array_type
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:909
key
key
Definition: openssl_missing.h:181
T_HASH
#define T_HASH
Definition: ruby.h:531
rb_yield_values2
VALUE rb_yield_values2(int n, const VALUE *argv)
Definition: vm_eval.c:1271
rb_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.2.h:6368
proc_entry
Definition: enumerator.c:164
CLASS_OF
#define CLASS_OF(v)
Definition: ruby.h:484
rb_str_buf_append
VALUE rb_str_buf_append(VALUE, VALUE)
Definition: string.c:2950
arith_seq_gen::current
VALUE current
Definition: enumerator.c:3736
rb_proc_call_kw
VALUE rb_proc_call_kw(VALUE, VALUE, int)
Definition: proc.c:948
PASS_KW_SPLAT
#define PASS_KW_SPLAT
Definition: enumerator.c:379
dup
int dup(int __fildes)
RARRAY_LEN
#define RARRAY_LEN(a)
Definition: ruby.h:1070
rb_check_funcall_kw
VALUE rb_check_funcall_kw(VALUE, ID, int, const VALUE *, int)
Definition: vm_eval.c:499
rb_ary_new4
#define rb_ary_new4
Definition: intern.h:105
rb_cArithSeq
VALUE rb_cArithSeq
Definition: enumerator.c:180
enumerator::fib
VALUE fib
Definition: enumerator.c:130
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
rb_ary_new2
#define rb_ary_new2
Definition: intern.h:103
rb_exc_raise
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:668
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.2.h:5738
enum_chain::pos
long pos
Definition: enumerator.c:177
TypedData_Get_Struct
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1252
rb_str_append
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2965
rb_ary_new_from_values
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
Definition: array.c:762
id_next
ID id_next
Definition: eventids1.c:76
id_begin
ID id_begin
Definition: eventids1.c:23
rb_provide
void rb_provide(const char *)
Definition: load.c:563
internal.h
OBJ_INIT_COPY
#define OBJ_INIT_COPY(obj, orig)
Definition: intern.h:331
T_ARRAY
#define T_ARRAY
Definition: ruby.h:530
rb_mKernel
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1998
lazyenum_proc_func
struct MEMO * lazyenum_proc_func(VALUE, struct MEMO *, VALUE, long)
Definition: enumerator.c:157
argv
char ** argv
Definition: ruby.c:223
LAZY_MEMO_BREAK_P
#define LAZY_MEMO_BREAK_P(memo)
Definition: enumerator.c:1591
enum_chain_free
#define enum_chain_free
Definition: enumerator.c:3035
ST_CONTINUE
@ ST_CONTINUE
Definition: st.h:99
LAZY_MEMO_PACKED_P
#define LAZY_MEMO_PACKED_P(memo)
Definition: enumerator.c:1592
rb_hash_uint
#define rb_hash_uint(h, i)
Definition: intern.h:815
rb_warn_deprecated
void rb_warn_deprecated(const char *fmt, const char *suggest,...)
Definition: error.c:366
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1197
rb_fiber_current
VALUE rb_fiber_current(void)
Definition: cont.c:1957
rb_fiber_resume
VALUE rb_fiber_resume(VALUE fiber_value, int argc, const VALUE *argv)
Definition: cont.c:2117
lazyenum_size_func
VALUE lazyenum_size_func(VALUE, VALUE)
Definition: enumerator.c:158
rb_hash
VALUE rb_hash(VALUE obj)
Definition: hash.c:129
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
ruby_float_step
int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl, int allow_endless)
Definition: numeric.c:2524
ruby_float_step_size
double ruby_float_step_size(double beg, double end, double unit, int excl)
Definition: numeric.c:2495
rb_hash_end
#define rb_hash_end(h)
Definition: intern.h:816
RARRAY_CONST_PTR
#define RARRAY_CONST_PTR(s)
Definition: psych_emitter.c:4
RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1207
MEMCPY
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1753
producer::proc
VALUE proc
Definition: enumerator.c:154
rb_hash_aset
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2852
ruby::backward::cxxanyargs::rb_block_call
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
Definition: cxxanyargs.hpp:178
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
rb_funcall
#define rb_funcall(recv, mid, argc,...)
Definition: rb_mjit_min_header-2.7.2.h:6581
fabs
double fabs(double)
argc
int argc
Definition: ruby.c:222
rb_arithmetic_sequence_extract
int rb_arithmetic_sequence_extract(VALUE obj, rb_arithmetic_sequence_components_t *component)
Definition: enumerator.c:3374
rb_exec_recursive
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:5075
rb_big_plus
VALUE rb_big_plus(VALUE x, VALUE y)
Definition: bignum.c:5824
rb_fiber_yield
VALUE rb_fiber_yield(int argc, const VALUE *argv)
Definition: cont.c:2129
generator::proc
VALUE proc
Definition: enumerator.c:144
RB_NO_KEYWORDS
#define RB_NO_KEYWORDS
Definition: ruby.h:1977
recur
#define recur(fmt)
Definition: date_strptime.c:152
err
int err
Definition: win32.c:135
enumerator::stop_exc
VALUE stop_exc
Definition: enumerator.c:134
id_initialize
#define id_initialize
Definition: enumerator.c:121
rb_data_type_struct
Definition: ruby.h:1148
RFLOAT_VALUE
#define RFLOAT_VALUE(v)
Definition: ruby.h:966
arith_seq_gen::excl
int excl
Definition: enumerator.c:3739
rb_int_gt
VALUE rb_int_gt(VALUE x, VALUE y)
Definition: numeric.c:4252
MEMO::value
const VALUE value
Definition: internal.h:1286
rb_arithmetic_sequence_components_t::end
VALUE end
Definition: intern.h:283
rb_ary_new_from_args
#define rb_ary_new_from_args(n,...)
Definition: rb_mjit_min_header-2.7.2.h:7196
_
#define _(args)
Definition: dln.h:28
count
int count
Definition: encoding.c:57
Qtrue
#define Qtrue
Definition: ruby.h:468
rb_str_catf
VALUE rb_str_catf(VALUE str, const char *format,...)
Definition: sprintf.c:1237
rb_eStopIteration
VALUE rb_eStopIteration
Definition: enumerator.c:124
rb_rescue2
VALUE rb_rescue2(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2,...)
An equivalent of rescue clause.
Definition: eval.c:962
enumerator::args
VALUE args
Definition: enumerator.c:129
v
int VALUE v
Definition: rb_mjit_min_header-2.7.2.h:12300
len
uint8_t len
Definition: escape.c:17
idCmp
@ idCmp
Definition: id.h:84
rb_class_path
VALUE rb_class_path(VALUE)
Definition: variable.c:153
SYMBOL_P
#define SYMBOL_P(x)
Definition: ruby.h:413
rb_funcall_with_block
VALUE rb_funcall_with_block(VALUE, ID, int, const VALUE *, VALUE)
Definition: vm_eval.c:1050
rb_enumeratorize
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, const VALUE *argv)
Definition: enumerator.c:516
isinf
#define isinf(__x)
Definition: rb_mjit_min_header-2.7.2.h:3686
rb_ary_dup
VALUE rb_ary_dup(VALUE ary)
Definition: array.c:2238
proc_entry_free
#define proc_entry_free
Definition: enumerator.c:262
proc_entry::memo
VALUE memo
Definition: enumerator.c:166
LONG2FIX
#define LONG2FIX(i)
Definition: ruby.h:265
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1300
rb_funcallv
#define rb_funcallv(recv, mid, argc, argv)
Definition: rb_mjit_min_header-2.7.2.h:7862
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:698
rb_sym2str
VALUE rb_sym2str(VALUE)
Definition: symbol.c:784
rb_arithmetic_sequence_components_t::step
VALUE step
Definition: intern.h:284
id_size
#define id_size
Definition: enumerator.c:122
Init_Enumerator
void Init_Enumerator(void)
Definition: enumerator.c:4089
enumerator::procs
VALUE procs
Definition: enumerator.c:136
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1237
rb_block_call_kw
VALUE rb_block_call_kw(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE, int)
Definition: vm_eval.c:1484
id_call
#define id_call
Definition: enumerator.c:118
FIXABLE
#define FIXABLE(f)
Definition: ruby.h:399
enumerator::dst
VALUE dst
Definition: enumerator.c:131
RB_INTEGER_TYPE_P
#define RB_INTEGER_TYPE_P(obj)
Definition: ruby_missing.h:15
yielder_free
#define yielder_free
Definition: enumerator.c:1264
ST2FIX
#define ST2FIX(h)
Definition: ruby_missing.h:21
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:723
rb_fiber_new
VALUE rb_fiber_new(rb_block_call_func_t func, VALUE obj)
Definition: cont.c:1795
Qnil
#define Qnil
Definition: ruby.h:469
RANGE_EXCL
#define RANGE_EXCL(r)
Definition: internal.h:2093
NUM2DBL
#define NUM2DBL(x)
Definition: ruby.h:774
rb_mEnumerable
VALUE rb_mEnumerable
Definition: enum.c:20
id_eqq
#define id_eqq
Definition: enumerator.c:120
rb_int_plus
VALUE rb_int_plus(VALUE x, VALUE y)
Definition: numeric.c:3610
rb_undef_alloc_func
void rb_undef_alloc_func(VALUE)
Definition: vm_method.c:722
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
enum_chain
Definition: enumerator.c:175
rb_define_private_method
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1569
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
Definition: object.c:692
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
RTEST
#define RTEST(v)
Definition: ruby.h:481
RB_FLOAT_TYPE_P
#define RB_FLOAT_TYPE_P(obj)
Definition: ruby.h:556
arith_seq_gen
Definition: enumerator.c:3735
enumerator::size
VALUE size
Definition: enumerator.c:135
rb_int_minus
VALUE rb_int_minus(VALUE x, VALUE y)
Definition: numeric.c:3649
n
const char size_t n
Definition: rb_mjit_min_header-2.7.2.h:5452
rb_block_proc
VALUE rb_block_proc(void)
Definition: proc.c:837