106 static ID id_eqq,
id_next, id_result, id_lazy, id_receiver, id_arguments, id_memo, id_method, id_force;
107 static VALUE sym_each, sym_cycle;
125 static VALUE rb_cGenerator, rb_cYielder;
156 enumerator_mark(
void *p)
170 #define enumerator_free RUBY_TYPED_DEFAULT_FREE 173 enumerator_memsize(
const void *p)
201 proc_entry_mark(
void *p)
208 #define proc_entry_free RUBY_TYPED_DEFAULT_FREE 211 proc_entry_memsize(
const void *p)
228 struct proc_entry *ptr;
307 enumerator_allocate(
VALUE klass)
383 enumerator_initialize(
int argc,
VALUE *argv,
VALUE obj)
385 VALUE recv, meth = sym_each;
390 recv = generator_init(generator_allocate(rb_cGenerator),
rb_block_proc());
404 rb_warn(
"Enumerator.new without a block is deprecated; use Object#to_enum");
412 return enumerator_init(obj, recv, meth, argc, argv, 0, size);
422 ptr0 = enumerator_ptr(orig);
464 return lazy_to_enum_i(obj, meth, argc, argv, size_fn);
467 obj, meth, argc, argv, size_fn,
Qnil);
474 const VALUE *argv = 0;
475 const struct enumerator *e = enumerator_ptr(obj);
522 enumerator_each(
int argc,
VALUE *argv,
VALUE obj)
528 #if SIZEOF_INT < SIZEOF_LONG 541 return enumerator_block_call(obj, 0, obj);
547 struct MEMO *memo = (
struct MEMO *)m;
558 enumerator_size(
VALUE obj);
563 return enumerator_size(obj);
579 enumerator_with_index(
int argc,
VALUE *argv,
VALUE obj)
589 return enumerator_block_call(obj, enumerator_with_index_i, (
VALUE)
MEMO_NEW(memo, 0, 0));
603 enumerator_each_with_index(
VALUE obj)
605 return enumerator_with_index(0,
NULL, obj);
650 enumerator_block_call(obj, enumerator_with_object_i, memo);
764 enumerator_next_values(
VALUE obj)
775 return get_next_values(obj, e);
779 ary2sv(
VALUE args,
int dup)
821 enumerator_next(
VALUE obj)
823 VALUE vs = enumerator_next_values(obj);
824 return ary2sv(vs, 0);
828 enumerator_peek_values(
VALUE obj)
867 enumerator_peek_values_m(
VALUE obj)
869 return rb_ary_dup(enumerator_peek_values(obj));
895 enumerator_peek(
VALUE obj)
897 VALUE vs = enumerator_peek_values(obj);
898 return ary2sv(vs, 1);
970 enumerator_rewind(
VALUE obj)
991 VALUE eobj, str, cname;
1010 eobj = generator_ptr(e->
obj)->
obj;
1033 append_method(obj, str, e->
meth, e->
args);
1043 VALUE method, eargs;
1047 if (!
NIL_P(method)) {
1060 eargs = default_args;
1070 VALUE arg = *argv++;
1090 enumerator_inspect(
VALUE obj)
1107 enumerator_size(
VALUE obj)
1121 struct proc_entry *entry = proc_entry_ptr(proc);
1126 receiver = (*size_fn)(
proc, receiver);
1147 yielder_mark(
void *p)
1153 #define yielder_free RUBY_TYPED_DEFAULT_FREE 1156 yielder_memsize(
const void *p)
1158 return sizeof(
struct yielder);
1172 yielder_ptr(
VALUE obj)
1185 yielder_allocate(
VALUE klass)
1214 yielder_initialize(
VALUE obj)
1225 struct yielder *ptr = yielder_ptr(obj);
1234 yielder_yield(obj, args);
1247 return yielder_init(yielder_allocate(rb_cYielder),
rb_proc_new(yielder_yield_i, 0));
1254 generator_mark(
void *p)
1261 #define generator_free RUBY_TYPED_DEFAULT_FREE 1264 generator_memsize(
const void *p)
1276 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
1280 generator_ptr(
VALUE obj)
1293 generator_allocate(
VALUE klass)
1323 generator_initialize(
int argc,
VALUE *argv,
VALUE obj)
1337 "wrong argument type %"PRIsVALUE" (expected Proc)",
1341 rb_warn(
"given block not used");
1345 return generator_init(obj, proc);
1356 ptr0 = generator_ptr(orig);
1371 generator_each(
int argc,
VALUE *argv,
VALUE obj)
1373 struct generator *ptr = generator_ptr(obj);
1386 enum_size(
VALUE self)
1395 return enum_size(
self);
1399 lazy_size(
VALUE self)
1407 return lazy_size(lazy);
1443 #define memo_value v2 1444 #define memo_flags u3.state 1445 #define LAZY_MEMO_BREAK 1 1446 #define LAZY_MEMO_PACKED 2 1447 #define LAZY_MEMO_BREAK_P(memo) ((memo)->memo_flags & LAZY_MEMO_BREAK) 1448 #define LAZY_MEMO_PACKED_P(memo) ((memo)->memo_flags & LAZY_MEMO_PACKED) 1449 #define LAZY_MEMO_SET_BREAK(memo) ((memo)->memo_flags |= LAZY_MEMO_BREAK) 1450 #define LAZY_MEMO_SET_VALUE(memo, value) MEMO_V2_SET(memo, value) 1451 #define LAZY_MEMO_SET_PACKED(memo) ((memo)->memo_flags |= LAZY_MEMO_PACKED) 1452 #define LAZY_MEMO_RESET_PACKED(memo) ((memo)->memo_flags &= ~LAZY_MEMO_PACKED) 1461 struct MEMO *result;
1467 for (i = 0; i <
RARRAY_LEN(procs_array); i++) {
1469 struct proc_entry *entry = proc_entry_ptr(proc);
1470 if (!(*entry->
fn->
proc)(proc, result, memos, i)) {
1482 return result->memo_value;
1501 struct generator *gen_ptr;
1502 struct enumerator *e = enumerator_ptr(enumerator);
1505 struct generator *old_gen_ptr = generator_ptr(e->
obj);
1506 obj = old_gen_ptr->
obj;
1512 generator = generator_allocate(rb_cGenerator);
1517 gen_ptr = generator_ptr(generator);
1552 lazy_initialize(
int argc,
VALUE *argv,
VALUE self)
1565 generator = generator_allocate(rb_cGenerator);
1566 rb_block_call(generator, id_initialize, 0, 0, lazy_init_block_i, obj);
1567 enumerator_init(
self, generator, sym_each, 0, 0, 0, size);
1590 struct enumerator *e = enumerator_ptr(lazy);
1591 lazy_set_args(lazy, args);
1600 struct enumerator *new_e;
1602 VALUE new_generator;
1604 struct enumerator *e = enumerator_ptr(obj);
1605 struct proc_entry *entry;
1607 &proc_entry_data_type, entry);
1614 lazy_set_args(entry_obj, memo);
1617 new_generator = lazy_generator_init(obj, new_procs);
1620 new_obj = enumerator_init_copy(enumerator_allocate(
rb_cLazy), obj);
1622 new_e->
obj = new_generator;
1623 new_e->
procs = new_procs;
1668 enumerable_lazy(
VALUE obj)
1670 VALUE result = lazy_to_enum_i(obj, sym_each, 0, 0, lazyenum_size);
1679 return enumerator_init(enumerator_allocate(
rb_cLazy),
1680 obj, meth, argc, argv, size_fn,
Qnil);
1707 lazy_to_enum(
int argc,
VALUE *argv,
VALUE self)
1709 VALUE lazy, meth = sym_each;
1715 lazy = lazy_to_enum_i(
self, meth, argc, argv, 0);
1723 lazyenum_yield(
VALUE proc_entry,
struct MEMO *result)
1725 struct proc_entry *entry = proc_entry_ptr(proc_entry);
1730 lazyenum_yield_values(
VALUE proc_entry,
struct MEMO *result)
1732 struct proc_entry *entry = proc_entry_ptr(proc_entry);
1734 const VALUE *argv = &result->memo_value;
1743 static struct MEMO *
1744 lazy_map_proc(
VALUE proc_entry,
struct MEMO *result,
VALUE memos,
long memo_index)
1746 VALUE value = lazyenum_yield_values(proc_entry, result);
1759 lazy_map_proc, lazy_map_size,
1769 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_map_funcs);
1786 lazy_flat_map_to_ary(
VALUE obj,
VALUE yielder)
1813 lazy_flat_map_each(result, argv[0]);
1816 lazy_flat_map_to_ary(result, argv[0]);
1846 lazy_flat_map(
VALUE obj)
1853 lazy_flat_map_proc, 0),
1857 static struct MEMO *
1858 lazy_select_proc(
VALUE proc_entry,
struct MEMO *result,
VALUE memos,
long memo_index)
1860 VALUE chain = lazyenum_yield(proc_entry, result);
1861 if (!
RTEST(chain))
return 0;
1866 lazy_select_proc, 0,
1870 lazy_select(
VALUE obj)
1876 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_select_funcs);
1879 static struct MEMO *
1880 lazy_reject_proc(
VALUE proc_entry,
struct MEMO *result,
VALUE memos,
long memo_index)
1882 VALUE chain = lazyenum_yield(proc_entry, result);
1883 if (
RTEST(chain))
return 0;
1888 lazy_reject_proc, 0,
1892 lazy_reject(
VALUE obj)
1898 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_reject_funcs);
1901 static struct MEMO *
1902 lazy_grep_proc(
VALUE proc_entry,
struct MEMO *result,
VALUE memos,
long memo_index)
1904 struct proc_entry *entry = proc_entry_ptr(proc_entry);
1906 if (!
RTEST(chain))
return 0;
1910 static struct MEMO *
1911 lazy_grep_iter_proc(
VALUE proc_entry,
struct MEMO *result,
VALUE memos,
long memo_index)
1913 struct proc_entry *entry = proc_entry_ptr(proc_entry);
1916 if (!
RTEST(chain))
return 0;
1925 lazy_grep_iter_proc, 0,
1936 &lazy_grep_iter_funcs : &lazy_grep_funcs;
1937 return lazy_add_method(obj, 0, 0, pattern,
rb_ary_new3(1, pattern), funcs);
1946 if (!
RTEST(result)) {
1958 if (!
RTEST(result)) {
1969 lazy_grep_v_iter : lazy_grep_v_func,
1975 call_next(
VALUE obj)
1981 next_stopped(
VALUE obj)
2009 VALUE yielder, ary, arg, v;
2050 for (i = 0; i <
argc; i++) {
2053 for (; i <
argc; i++) {
2060 func = lazy_zip_func;
2068 ary, lazy_receiver_size);
2071 static struct MEMO *
2072 lazy_take_proc(
VALUE proc_entry,
struct MEMO *result,
VALUE memos,
long memo_index)
2075 struct proc_entry *entry = proc_entry_ptr(proc_entry);
2103 lazy_take_proc, lazy_take_size,
2118 argv[0] = sym_cycle;
2123 return lazy_add_method(obj, argc, argv, n,
rb_ary_new3(1, n), &lazy_take_funcs);
2126 static struct MEMO *
2127 lazy_take_while_proc(
VALUE proc_entry,
struct MEMO *result,
VALUE memos,
long memo_index)
2129 VALUE take = lazyenum_yield_values(proc_entry, result);
2138 lazy_take_while_proc, 0,
2142 lazy_take_while(
VALUE obj)
2148 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_take_while_funcs);
2152 lazy_drop_size(
VALUE proc_entry,
VALUE receiver)
2155 if (
NIL_P(receiver))
2159 return LONG2FIX(len < 0 ? 0 : len);
2164 static struct MEMO *
2165 lazy_drop_proc(
VALUE proc_entry,
struct MEMO *result,
VALUE memos,
long memo_index)
2168 struct proc_entry *entry = proc_entry_ptr(proc_entry);
2185 lazy_drop_proc, lazy_drop_size,
2200 return lazy_add_method(obj, 2, argv, n,
rb_ary_new3(1, n), &lazy_drop_funcs);
2203 static struct MEMO *
2204 lazy_drop_while_proc(
VALUE proc_entry,
struct MEMO* result,
VALUE memos,
long memo_index)
2206 struct proc_entry *entry = proc_entry_ptr(proc_entry);
2214 VALUE drop = lazyenum_yield_values(proc_entry, result);
2215 if (
RTEST(drop))
return 0;
2222 lazy_drop_while_proc, 0,
2226 lazy_drop_while(
VALUE obj)
2232 return lazy_add_method(obj, 0, 0,
Qfalse,
Qnil, &lazy_drop_while_funcs);
2248 return lazy_uniq_i(i, hash, argc, argv, yielder);
2256 return lazy_uniq_i(i, hash, argc, argv, yielder);
2260 lazy_uniq(
VALUE obj)
2271 lazy_super(
int argc,
VALUE *argv,
VALUE lazy)
2277 lazy_lazy(
VALUE obj)
2330 stop_result(
VALUE self)
2399 rb_define_method(rb_cGenerator,
"initialize_copy", generator_init_copy, 1);
2422 id_initialize =
rb_intern(
"initialize");
void rb_warn(const char *fmt,...)
VALUE rb_ary_entry(VALUE ary, long offset)
VALUE rb_proc_call_with_block(VALUE, int argc, const VALUE *argv, VALUE)
#define RUBY_TYPED_FREE_IMMEDIATELY
VALUE rb_yield_values(int n,...)
int rb_block_given_p(void)
Determines if the current method is given a block.
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_enumerator_size_func(VALUE, VALUE, VALUE)
VALUE rb_fiber_resume(VALUE fibval, int argc, const VALUE *argv)
#define OBJ_INIT_COPY(obj, orig)
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
#define TypedData_Get_Struct(obj, type, data_type, sval)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE rb_fiber_alive_p(VALUE fibval)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_obj_dup(VALUE)
call-seq: obj.dup -> an_object
VALUE rb_ivar_get(VALUE, ID)
VALUE rb_fiber_current(void)
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
void rb_include_module(VALUE klass, VALUE module)
VALUE rb_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
void rb_gc_mark(VALUE ptr)
#define MEMO_NEW(a, b, c)
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
VALUE rb_str_buf_append(VALUE, VALUE)
#define LAZY_MEMO_SET_VALUE(memo, value)
VALUE rb_rescue2(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2,...)
An equivalent of rescue clause.
void InitVM_Enumerator(void)
rb_enumerator_size_func * size_fn
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class
#define RB_TYPE_P(obj, type)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
VALUE rb_enumeratorize_with_size(VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn)
RUBY_EXTERN VALUE rb_cObject
VALUE rb_str_buf_cat2(VALUE, const char *)
RUBY_EXTERN VALUE rb_mKernel
#define LAZY_MEMO_RESET_PACKED(memo)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
void rb_ary_store(VALUE ary, long idx, VALUE val)
lazyenum_size_func * size
struct MEMO * lazyenum_proc_func(VALUE, struct MEMO *, VALUE, long)
VALUE rb_fiber_new(VALUE(*func)(ANYARGS), VALUE obj)
#define ALLOCV_N(type, v, n)
#define MEMCPY(p1, p2, type, n)
#define LAZY_MEMO_SET_BREAK(memo)
VALUE rb_int_succ(VALUE num)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
#define RARRAY_CONST_PTR(a)
void rb_need_block(void)
Declares that the current method needs a block.
VALUE rb_obj_is_proc(VALUE)
VALUE rb_sprintf(const char *format,...)
#define MEMO_V1_SET(m, v)
VALUE rb_class_path(VALUE)
VALUE rb_fiber_yield(int argc, const VALUE *argv)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
VALUE rb_ivar_set(VALUE, ID, VALUE)
VALUE lazyenum_size_func(VALUE, VALUE)
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
VALUE rb_call_super(int, const VALUE *)
VALUE rb_proc_call(VALUE, VALUE)
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
#define RARRAY_LENINT(ary)
#define LAZY_MEMO_BREAK_P(memo)
int rb_respond_to(VALUE, ID)
register unsigned int len
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
VALUE rb_yield_values2(int n, const VALUE *argv)
#define UNLIMITED_ARGUMENTS
VALUE rb_enum_values_pack(int argc, const VALUE *argv)
#define RARRAY_AREF(a, i)
VALUE rb_block_proc(void)
lazyenum_proc_func * proc
VALUE rb_check_array_type(VALUE ary)
ID rb_frame_this_func(void)
The original name of the current method.
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, const VALUE *argv)
VALUE rb_proc_new(VALUE(*)(ANYARGS), VALUE)
void Init_Enumerator(void)
#define LAZY_MEMO_PACKED_P(memo)
#define TypedData_Make_Struct(klass, type, data_type, sval)
VALUE rb_ary_dup(VALUE ary)
const lazyenum_funcs * fn
#define rb_check_frozen(obj)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_str_append(VALUE, VALUE)
void rb_provide(const char *)
VALUE rb_to_int(VALUE)
Converts val into Integer.
VALUE rb_attr_get(VALUE, ID)