15#include "ruby/internal/config.h"
23#include "internal/class.h"
24#include "internal/enumerator.h"
25#include "internal/error.h"
26#include "internal/hash.h"
27#include "internal/imemo.h"
28#include "internal/numeric.h"
29#include "internal/range.h"
30#include "internal/rational.h"
159static VALUE rb_cLazy;
160static ID id_rewind, id_new, id_to_enum, id_each_entry;
161static ID id_next, id_result, id_receiver, id_arguments, id_memo, id_method, id_force;
162static ID id_begin, id_end, id_step, id_exclude_end;
163static VALUE sym_each, sym_cycle, sym_yield;
165static VALUE lazy_use_super_method;
167#define id_call idCall
168#define id_each idEach
170#define id_initialize idInitialize
171#define id_size idSize
190static VALUE rb_cGenerator, rb_cYielder, rb_cEnumProducer;
210 lazyenum_proc_func *proc;
211 lazyenum_size_func *size;
212 lazyenum_precheck_func *precheck;
224static VALUE rb_cEnumChain;
231static VALUE rb_cEnumProduct;
243enumerator_mark(
void *p)
246 rb_gc_mark_movable(ptr->obj);
247 rb_gc_mark_movable(ptr->args);
248 rb_gc_mark_movable(ptr->fib);
249 rb_gc_mark_movable(ptr->dst);
250 rb_gc_mark_movable(ptr->lookahead);
251 rb_gc_mark_movable(ptr->feedvalue);
252 rb_gc_mark_movable(ptr->stop_exc);
253 rb_gc_mark_movable(ptr->size);
254 rb_gc_mark_movable(ptr->procs);
258enumerator_compact(
void *p)
261 ptr->obj = rb_gc_location(ptr->obj);
262 ptr->args = rb_gc_location(ptr->args);
263 ptr->fib = rb_gc_location(ptr->fib);
264 ptr->dst = rb_gc_location(ptr->dst);
265 ptr->lookahead = rb_gc_location(ptr->lookahead);
266 ptr->feedvalue = rb_gc_location(ptr->feedvalue);
267 ptr->stop_exc = rb_gc_location(ptr->stop_exc);
268 ptr->size = rb_gc_location(ptr->size);
269 ptr->procs = rb_gc_location(ptr->procs);
272#define enumerator_free RUBY_TYPED_DEFAULT_FREE
275enumerator_memsize(
const void *p)
288 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
292enumerator_ptr(
VALUE obj)
297 if (!ptr || UNDEF_P(ptr->obj)) {
304proc_entry_mark(
void *p)
307 rb_gc_mark_movable(ptr->proc);
308 rb_gc_mark_movable(ptr->memo);
312proc_entry_compact(
void *p)
315 ptr->proc = rb_gc_location(ptr->proc);
316 ptr->memo = rb_gc_location(ptr->memo);
319#define proc_entry_free RUBY_TYPED_DEFAULT_FREE
322proc_entry_memsize(
const void *p)
417 enumerator = rb_enumeratorize_with_size(obj, meth, argc, argv, 0);
425enumerator_allocate(
VALUE klass)
457 ptr->size_fn = size_fn;
458 ptr->kw_splat = kw_splat;
464convert_to_feasible_size_value(
VALUE obj)
472 else if (RB_FLOAT_TYPE_P(obj) &&
RFLOAT_VALUE(obj) == HUGE_VAL) {
506enumerator_initialize(
int argc,
VALUE *argv,
VALUE obj)
509 VALUE recv = generator_init(generator_allocate(rb_cGenerator), iter);
510 VALUE arg0 = rb_check_arity(argc, 0, 1) ? argv[0] :
Qnil;
511 VALUE size = convert_to_feasible_size_value(arg0);
513 return enumerator_init(obj, recv, sym_each, 0, 0, 0, size,
false);
523 ptr0 = enumerator_ptr(orig);
535 ptr1->obj = ptr0->obj;
536 ptr1->meth = ptr0->meth;
537 ptr1->args = ptr0->args;
541 ptr1->size = ptr0->size;
542 ptr1->size_fn = ptr0->size_fn;
553 return rb_enumeratorize_with_size(obj, meth, argc, argv, 0);
557static int lazy_precheck(
VALUE procs);
565 base_class = rb_cLazy;
568 obj = enumerator_init(enumerator_allocate(
rb_cEnumerator), obj, sym_each, 0, 0, 0,
Qnil,
false);
571 return enumerator_init(enumerator_allocate(base_class),
572 obj, meth, argc, argv, size_fn,
Qnil, kw_splat);
578 return rb_enumeratorize_with_size_kw(obj, meth, argc, argv, size_fn,
rb_keyword_given_p());
585 const VALUE *argv = 0;
586 const struct enumerator *e = enumerator_ptr(obj);
590 argc = RARRAY_LENINT(e->args);
633enumerator_each(
int argc,
VALUE *argv,
VALUE obj)
640#if SIZEOF_INT < SIZEOF_LONG
644 args = rb_ary_dup(args);
645 rb_ary_cat(args, argv, argc);
656 if (!lazy_precheck(e->procs))
return Qnil;
658 return enumerator_block_call(obj, 0, obj);
664 struct MEMO *memo = (
struct MEMO *)m;
665 VALUE idx = memo->v1;
666 MEMO_V1_SET(memo, rb_int_succ(idx));
669 return rb_yield_values(2, val, idx);
671 return rb_yield_values(2,
rb_ary_new4(argc, argv), idx);
675enumerator_size(
VALUE obj);
680 return enumerator_size(obj);
696enumerator_with_index(
int argc,
VALUE *argv,
VALUE obj)
700 rb_check_arity(argc, 0, 1);
703 return enumerator_block_call(obj, enumerator_with_index_i, (
VALUE)MEMO_NEW(memo, 0, 0));
717enumerator_each_with_index(
VALUE obj)
719 return enumerator_with_index(0, NULL, obj);
726 return rb_yield_values(2, val, memo);
728 return rb_yield_values(2,
rb_ary_new4(argc, argv), memo);
764 enumerator_block_call(obj, enumerator_with_object_i, memo);
775 rb_fiber_yield(1, &args);
776 if (!UNDEF_P(e->feedvalue)) {
777 feedvalue = e->feedvalue;
793 return rb_fiber_yield(1, &nil);
799 VALUE curr = rb_fiber_current();
801 e->fib = rb_fiber_new(next_i, obj);
813 curr = rb_fiber_current();
815 if (!e->fib || !rb_fiber_alive_p(e->fib)) {
819 vs = rb_fiber_resume(e->fib, 1, &curr);
876enumerator_next_values(
VALUE obj)
881 if (!UNDEF_P(e->lookahead)) {
887 return get_next_values(obj, e);
891ary2sv(
VALUE args,
int dup)
905 return rb_ary_dup(args);
931enumerator_next(
VALUE obj)
933 VALUE vs = enumerator_next_values(obj);
934 return ary2sv(vs, 0);
938enumerator_peek_values(
VALUE obj)
942 if (UNDEF_P(e->lookahead)) {
943 e->lookahead = get_next_values(obj, e);
979enumerator_peek_values_m(
VALUE obj)
981 return rb_ary_dup(enumerator_peek_values(obj));
1009enumerator_peek(
VALUE obj)
1011 VALUE vs = enumerator_peek_values(obj);
1012 return ary2sv(vs, 1);
1066 if (!UNDEF_P(e->feedvalue)) {
1084enumerator_rewind(
VALUE obj)
1102inspect_enumerator(
VALUE obj,
VALUE dummy,
int recur)
1105 VALUE eobj, str, cname;
1111 if (!e || UNDEF_P(e->obj)) {
1123 eobj = generator_ptr(e->obj)->obj;
1132 str =
rb_sprintf(
"#<%"PRIsVALUE
": %"PRIsVALUE, cname, str);
1133 append_method(
RARRAY_AREF(e->procs, i), str, e->meth, e->args);
1146 append_method(obj, str, e->meth, e->args);
1156 if (
SYMBOL_P(key))
return ST_CONTINUE;
1157 *(
int *)arg = FALSE;
1165 rb_str_catf(str,
"% "PRIsVALUE
": %"PRIsVALUE
", ", key, val);
1172 VALUE method, eargs;
1176 if (!
NIL_P(method)) {
1181 method = rb_id2str(default_method);
1189 eargs = default_args;
1202 rb_hash_foreach(argv[argc-1], key_symbol_p, (
VALUE)&all_key);
1203 if (all_key) kwds = argv[--argc];
1207 VALUE arg = *argv++;
1213 rb_hash_foreach(kwds, kwd_append, str);
1231enumerator_inspect(
VALUE obj)
1248enumerator_size(
VALUE obj)
1252 const VALUE *argv = NULL;
1256 struct generator *g = generator_ptr(e->obj);
1262 struct proc_entry *entry = proc_entry_ptr(proc);
1263 lazyenum_size_func *size_fn = entry->fn->size;
1267 receiver = (*size_fn)(proc, receiver);
1273 return (*e->size_fn)(e->obj, e->args, obj);
1280 if (!UNDEF_P(size))
return size;
1288yielder_mark(
void *p)
1291 rb_gc_mark_movable(ptr->proc);
1295yielder_compact(
void *p)
1298 ptr->proc = rb_gc_location(ptr->proc);
1301#define yielder_free RUBY_TYPED_DEFAULT_FREE
1304yielder_memsize(
const void *p)
1306 return sizeof(
struct yielder);
1317 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
1321yielder_ptr(
VALUE obj)
1326 if (!ptr || UNDEF_P(ptr->proc)) {
1334yielder_allocate(
VALUE klass)
1363yielder_initialize(
VALUE obj)
1374 struct yielder *ptr = yielder_ptr(obj);
1383 struct yielder *ptr = yielder_ptr(obj);
1403yielder_to_proc(
VALUE obj)
1407 return rb_funcall(method, idTo_proc, 0);
1419 return yielder_init(yielder_allocate(rb_cYielder),
rb_proc_new(yielder_yield_i, 0));
1426generator_mark(
void *p)
1429 rb_gc_mark_movable(ptr->proc);
1430 rb_gc_mark_movable(ptr->obj);
1434generator_compact(
void *p)
1437 ptr->proc = rb_gc_location(ptr->proc);
1438 ptr->obj = rb_gc_location(ptr->obj);
1441#define generator_free RUBY_TYPED_DEFAULT_FREE
1444generator_memsize(
const void *p)
1457 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
1461generator_ptr(
VALUE obj)
1466 if (!ptr || UNDEF_P(ptr->proc)) {
1474generator_allocate(
VALUE klass)
1504generator_initialize(
int argc,
VALUE *argv,
VALUE obj)
1514 rb_scan_args(argc, argv,
"1", &proc);
1518 "wrong argument type %"PRIsVALUE
" (expected Proc)",
1522 rb_warn(
"given block not used");
1526 return generator_init(obj, proc);
1537 ptr0 = generator_ptr(orig);
1545 ptr1->proc = ptr0->proc;
1552generator_each(
int argc,
VALUE *argv,
VALUE obj)
1554 struct generator *ptr = generator_ptr(obj);
1557 rb_ary_push(args, yielder_new());
1559 rb_ary_cat(args, argv, argc);
1567enum_size(
VALUE self)
1570 return UNDEF_P(r) ?
Qnil : r;
1576 return enum_size(self);
1579#define lazy_receiver_size lazy_map_size
1610 rb_block_call(m, id_each, argc-1, argv+1, lazy_init_iterator, val);
1614#define memo_value v2
1615#define memo_flags u3.state
1616#define LAZY_MEMO_BREAK 1
1617#define LAZY_MEMO_PACKED 2
1618#define LAZY_MEMO_BREAK_P(memo) ((memo)->memo_flags & LAZY_MEMO_BREAK)
1619#define LAZY_MEMO_PACKED_P(memo) ((memo)->memo_flags & LAZY_MEMO_PACKED)
1620#define LAZY_MEMO_SET_BREAK(memo) ((memo)->memo_flags |= LAZY_MEMO_BREAK)
1621#define LAZY_MEMO_RESET_BREAK(memo) ((memo)->memo_flags &= ~LAZY_MEMO_BREAK)
1622#define LAZY_MEMO_SET_VALUE(memo, value) MEMO_V2_SET(memo, value)
1623#define LAZY_MEMO_SET_PACKED(memo) ((memo)->memo_flags |= LAZY_MEMO_PACKED)
1624#define LAZY_MEMO_RESET_PACKED(memo) ((memo)->memo_flags &= ~LAZY_MEMO_PACKED)
1634 struct MEMO *result;
1636 result = MEMO_NEW(m, rb_enum_values_pack(argc, argv),
1637 argc > 1 ? LAZY_MEMO_PACKED : 0);
1638 return lazy_yielder_result(result,
yielder, procs_array, memos, 0);
1642lazy_yielder_yield(
struct MEMO *result,
long memo_index,
int argc,
const VALUE *argv)
1644 VALUE m = result->v1;
1648 LAZY_MEMO_SET_VALUE(result, rb_enum_values_pack(argc, argv));
1650 LAZY_MEMO_SET_PACKED(result);
1652 LAZY_MEMO_RESET_PACKED(result);
1653 return lazy_yielder_result(result,
yielder, procs_array, memos, memo_index);
1663 struct proc_entry *entry = proc_entry_ptr(proc);
1664 if (!(*entry->fn->proc)(proc, result, memos, i)) {
1673 if (LAZY_MEMO_BREAK_P(result)) {
1676 return result->memo_value;
1699 struct generator *old_gen_ptr = generator_ptr(e->obj);
1700 obj = old_gen_ptr->obj;
1706 generator = generator_allocate(rb_cGenerator);
1718lazy_precheck(
VALUE procs)
1721 long num_procs =
RARRAY_LEN(procs), i = num_procs;
1724 struct proc_entry *entry = proc_entry_ptr(proc);
1725 lazyenum_precheck_func *precheck = entry->fn->precheck;
1726 if (precheck && !precheck(proc))
return FALSE;
1823lazy_initialize(
int argc,
VALUE *argv,
VALUE self)
1828 rb_check_arity(argc, 1, 2);
1836 generator = generator_allocate(rb_cGenerator);
1838 enumerator_init(self,
generator, sym_each, 0, 0, 0, size, 0);
1854lazy_to_a(
VALUE self)
1862 ID id = rb_frame_this_func();
1878 lazy_set_args(lazy, args);
1879 e->size_fn = size_fn;
1890 VALUE new_generator;
1895 &proc_entry_data_type, entry);
1902 lazy_set_args(entry_obj, memo);
1904 new_procs =
RTEST(e->procs) ? rb_ary_dup(e->procs) : rb_ary_new();
1905 new_generator = lazy_generator_init(obj, new_procs);
1906 rb_ary_push(new_procs, entry_obj);
1908 new_obj = enumerator_init_copy(enumerator_allocate(rb_cLazy), obj);
1910 new_e->obj = new_generator;
1911 new_e->procs = new_procs;
1918 new_e->meth = id_each;
1954enumerable_lazy(
VALUE obj)
1965 return enumerator_init(enumerator_allocate(rb_cLazy),
1966 obj, meth, argc, argv, size_fn,
Qnil, kw_splat);
1993lazy_to_enum(
int argc,
VALUE *argv,
VALUE self)
1995 VALUE lazy, meth = sym_each, super_meth;
2001 if (
RTEST((super_meth = rb_hash_aref(lazy_use_super_method, meth)))) {
2014 return enum_size(self);
2025lazy_eager(
VALUE self)
2028 self, sym_each, 0, 0, lazy_eager_size,
Qnil, 0);
2043 const VALUE *argv = &result->memo_value;
2044 if (LAZY_MEMO_PACKED_P(result)) {
2045 const VALUE args = *argv;
2046 argc = RARRAY_LENINT(args);
2056 LAZY_MEMO_SET_VALUE(result, value);
2057 LAZY_MEMO_RESET_PACKED(result);
2068 lazy_map_proc, lazy_map_size,
2091 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_map_funcs);
2095 struct MEMO *result;
2104 return lazy_yielder_yield(arg->result, arg->index, argc, argv);
2112 const long proc_index = memo_index + 1;
2113 int break_p = LAZY_MEMO_BREAK_P(result);
2115 if (RB_TYPE_P(value,
T_ARRAY)) {
2119 struct flat_map_i_arg arg = {.result = result, .index = proc_index};
2120 LAZY_MEMO_RESET_BREAK(result);
2122 if (break_p) LAZY_MEMO_SET_BREAK(result);
2126 if (ary || !
NIL_P(ary = rb_check_array_type(value))) {
2128 LAZY_MEMO_RESET_BREAK(result);
2131 lazy_yielder_yield(result, proc_index, 1, &argv);
2133 if (break_p) LAZY_MEMO_SET_BREAK(result);
2137 LAZY_MEMO_SET_VALUE(result, value);
2138 LAZY_MEMO_RESET_PACKED(result);
2143 lazy_flat_map_proc, 0,
2170lazy_flat_map(
VALUE obj)
2176 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_flat_map_funcs);
2183 if (!
RTEST(chain))
return 0;
2188 lazy_select_proc, 0,
2200lazy_select(
VALUE obj)
2206 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_select_funcs);
2213 if (!
RTEST(value))
return 0;
2214 LAZY_MEMO_SET_VALUE(result, value);
2215 LAZY_MEMO_RESET_PACKED(result);
2220 lazy_filter_map_proc, 0,
2234lazy_filter_map(
VALUE obj)
2240 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_filter_map_funcs);
2247 if (
RTEST(chain))
return 0;
2252 lazy_reject_proc, 0,
2263lazy_reject(
VALUE obj)
2269 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_reject_funcs);
2276 VALUE chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
2277 if (!
RTEST(chain))
return 0;
2285 VALUE value, chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
2287 if (!
RTEST(chain))
return 0;
2289 LAZY_MEMO_SET_VALUE(result, value);
2290 LAZY_MEMO_RESET_PACKED(result);
2296 lazy_grep_iter_proc, 0,
2315 &lazy_grep_iter_funcs : &lazy_grep_funcs;
2316 return lazy_add_method(obj, 0, 0, pattern,
rb_ary_new3(1, pattern), funcs);
2323 VALUE chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
2324 if (
RTEST(chain))
return 0;
2332 VALUE value, chain = rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
2334 if (
RTEST(chain))
return 0;
2336 LAZY_MEMO_SET_VALUE(result, value);
2337 LAZY_MEMO_RESET_PACKED(result);
2343 lazy_grep_v_iter_proc, 0,
2347 lazy_grep_v_proc, 0,
2362 &lazy_grep_v_iter_funcs : &lazy_grep_v_funcs;
2363 return lazy_add_method(obj, 0, 0, pattern,
rb_ary_new3(1, pattern), funcs);
2369 return rb_funcall(obj, id_next, 0);
2382 VALUE ary, arrays = entry->memo;
2383 VALUE memo = rb_ary_entry(memos, memo_index);
2387 rb_ary_push(ary, result->memo_value);
2389 rb_ary_push(ary, rb_ary_entry(
RARRAY_AREF(arrays, i), count));
2391 LAZY_MEMO_SET_VALUE(result, ary);
2392 LAZY_MEMO_SET_PACKED(result);
2393 rb_ary_store(memos, memo_index,
LONG2NUM(++count));
2401 VALUE arg = rb_ary_entry(memos, memo_index);
2402 VALUE zip_args = entry->memo;
2409 rb_ary_push(arg, rb_funcall(
RARRAY_AREF(zip_args, i), id_to_enum, 0));
2411 rb_ary_store(memos, memo_index, arg);
2415 rb_ary_push(ary, result->memo_value);
2419 rb_ary_push(ary, v);
2421 LAZY_MEMO_SET_VALUE(result, ary);
2422 LAZY_MEMO_SET_PACKED(result);
2427 {lazy_zip_func, lazy_receiver_size,},
2428 {lazy_zip_arrays_func, lazy_receiver_size,},
2451 for (i = 0; i < argc; i++) {
2452 v = rb_check_array_type(argv[i]);
2454 for (; i < argc; i++) {
2461 funcs = &lazy_zip_funcs[0];
2464 rb_ary_push(ary, v);
2467 return lazy_add_method(obj, 0, 0, ary, ary, funcs);
2475 VALUE memo = rb_ary_entry(memos, memo_index);
2482 if (--remain == 0) LAZY_MEMO_SET_BREAK(result);
2483 rb_ary_store(memos, memo_index,
LONG2NUM(remain));
2500 return entry->memo !=
INT2FIX(0);
2504 lazy_take_proc, lazy_take_size, lazy_take_precheck,
2525 return lazy_add_method(obj, 0, 0, n,
rb_ary_new3(1, n), &lazy_take_funcs);
2533 LAZY_MEMO_SET_BREAK(result);
2540 lazy_take_while_proc, 0,
2551lazy_take_while(
VALUE obj)
2557 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_take_while_funcs);
2564 if (
NIL_P(receiver))
2568 return LONG2FIX(len < 0 ? 0 : len);
2570 return rb_funcall(receiver,
'-', 1,
LONG2NUM(len));
2578 VALUE memo = rb_ary_entry(memos, memo_index);
2586 rb_ary_store(memos, memo_index,
LONG2NUM(remain));
2594 lazy_drop_proc, lazy_drop_size,
2616 return lazy_add_method(obj, 2, argv, n,
rb_ary_new3(1, n), &lazy_drop_funcs);
2623 VALUE memo = rb_ary_entry(memos, memo_index);
2631 if (
RTEST(drop))
return 0;
2632 rb_ary_store(memos, memo_index,
Qtrue);
2638 lazy_drop_while_proc, 0,
2649lazy_drop_while(
VALUE obj)
2655 return lazy_add_method(obj, 0, 0,
Qfalse,
Qnil, &lazy_drop_while_funcs);
2659lazy_uniq_check(
VALUE chain,
VALUE memos,
long memo_index)
2661 VALUE hash = rb_ary_entry(memos, memo_index);
2665 rb_ary_store(memos, memo_index, hash);
2668 return rb_hash_add_new_element(hash, chain,
Qfalse);
2674 if (lazy_uniq_check(result->memo_value, memos, memo_index))
return 0;
2683 if (lazy_uniq_check(chain, memos, memo_index))
return 0;
2688 lazy_uniq_iter_proc, 0,
2708 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, funcs);
2714 if (
NIL_P(result->memo_value))
return 0;
2719 lazy_compact_proc, 0,
2730lazy_compact(
VALUE obj)
2732 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_compact_funcs);
2739 VALUE memo = rb_ary_entry(memos, memo_index);
2746 argv[0] = result->memo_value;
2750 LAZY_MEMO_RESET_PACKED(result);
2753 LAZY_MEMO_SET_VALUE(result, rb_ary_new_from_values(2, argv));
2754 LAZY_MEMO_SET_PACKED(result);
2761lazy_with_index_size(
VALUE proc,
VALUE receiver)
2767 lazy_with_index_proc, lazy_with_index_size,
2788lazy_with_index(
int argc,
VALUE *argv,
VALUE obj)
2792 rb_scan_args(argc, argv,
"01", &memo);
2796 return lazy_add_method(obj, 0, 0, memo, rb_ary_new_from_values(1, &memo), &lazy_with_index_funcs);
2808lazy_chunk(
VALUE self)
2819lazy_chunk_while(
VALUE self)
2831lazy_slice_after(
VALUE self)
2843lazy_slice_before(
VALUE self)
2854lazy_slice_when(
VALUE self)
2926stop_result(
VALUE self)
2936producer_mark(
void *p)
2939 rb_gc_mark_movable(ptr->init);
2940 rb_gc_mark_movable(ptr->proc);
2944producer_compact(
void *p)
2947 ptr->init = rb_gc_location(ptr->init);
2948 ptr->proc = rb_gc_location(ptr->proc);
2951#define producer_free RUBY_TYPED_DEFAULT_FREE
2954producer_memsize(
const void *p)
2967 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
2971producer_ptr(
VALUE obj)
2976 if (!ptr || UNDEF_P(ptr->proc)) {
2984producer_allocate(
VALUE klass)
3019NORETURN(
static VALUE producer_each_i(
VALUE obj));
3022producer_each_i(
VALUE obj)
3025 VALUE init, proc, curr;
3027 ptr = producer_ptr(obj);
3031 if (UNDEF_P(init)) {
3040 curr = rb_funcall(proc, id_call, 1, curr);
3049producer_each(
VALUE obj)
3098enumerator_s_produce(
int argc,
VALUE *argv,
VALUE klass)
3104 if (rb_scan_args(argc, argv,
"01", &init) == 0) {
3124enum_chain_mark(
void *p)
3127 rb_gc_mark_movable(ptr->enums);
3131enum_chain_compact(
void *p)
3134 ptr->enums = rb_gc_location(ptr->enums);
3137#define enum_chain_free RUBY_TYPED_DEFAULT_FREE
3140enum_chain_memsize(
const void *p)
3153 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
3157enum_chain_ptr(
VALUE obj)
3162 if (!ptr || UNDEF_P(ptr->enums)) {
3170enum_chain_allocate(
VALUE klass)
3210new_enum_chain(
VALUE enums)
3213 VALUE obj = enum_chain_initialize(enum_chain_allocate(rb_cEnumChain), enums);
3217 return enumerable_lazy(obj);
3231 ptr0 = enum_chain_ptr(orig);
3237 ptr1->enums = ptr0->enums;
3238 ptr1->pos = ptr0->pos;
3244enum_chain_total_size(
VALUE enums)
3252 if (
NIL_P(size) || (RB_FLOAT_TYPE_P(size) && isinf(
NUM2DBL(size)))) {
3259 total = rb_funcall(total,
'+', 1, size);
3275enum_chain_size(
VALUE obj)
3277 return enum_chain_total_size(enum_chain_ptr(obj)->enums);
3283 return enum_chain_size(obj);
3305enum_chain_each(
int argc,
VALUE *argv,
VALUE obj)
3313 objptr = enum_chain_ptr(obj);
3314 enums = objptr->enums;
3334enum_chain_rewind(
VALUE obj)
3336 struct enum_chain *objptr = enum_chain_ptr(obj);
3337 VALUE enums = objptr->enums;
3340 for (i = objptr->pos; 0 <= i && i <
RARRAY_LEN(enums); objptr->pos = --i) {
3348inspect_enum_chain(
VALUE obj,
VALUE dummy,
int recur)
3355 if (!ptr || UNDEF_P(ptr->enums)) {
3373enum_chain_inspect(
VALUE obj)
3391 VALUE enums = rb_ary_new_from_values(1, &obj);
3392 rb_ary_cat(enums, argv, argc);
3393 return new_enum_chain(enums);
3409 return new_enum_chain(rb_ary_new_from_args(2, obj, eobj));
3446enum_product_mark(
void *p)
3449 rb_gc_mark_movable(ptr->enums);
3453enum_product_compact(
void *p)
3456 ptr->enums = rb_gc_location(ptr->enums);
3459#define enum_product_free RUBY_TYPED_DEFAULT_FREE
3462enum_product_memsize(
const void *p)
3472 enum_product_memsize,
3473 enum_product_compact,
3475 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
3479enum_product_ptr(
VALUE obj)
3484 if (!ptr || UNDEF_P(ptr->enums)) {
3492enum_product_allocate(
VALUE klass)
3515enum_product_initialize(
int argc,
VALUE *argv,
VALUE obj)
3520 rb_scan_args(argc, argv,
"*:", &enums, &options);
3523 rb_exc_raise(rb_keyword_error_new(
"unknown", rb_hash_keys(options)));
3543 ptr0 = enum_product_ptr(orig);
3549 ptr1->enums = ptr0->enums;
3555enum_product_total_size(
VALUE enums)
3570 total = rb_funcall(total,
'*', 1, size);
3586enum_product_size(
VALUE obj)
3588 return enum_product_total_size(enum_product_ptr(obj)->enums);
3594 return enum_product_size(obj);
3611 pstate->argv[pstate->index++] = value;
3613 VALUE val = product_each(pstate->obj, pstate);
3622 VALUE enums = ptr->enums;
3624 if (pstate->index < pstate->argc) {
3630 rb_funcall(pstate->block, id_call, 1, rb_ary_new_from_values(pstate->argc, pstate->argv));
3640 int argc = RARRAY_LENINT(ptr->enums);
3649 return product_each(obj, &state);
3665enum_product_each(
VALUE obj)
3681enum_product_rewind(
VALUE obj)
3684 VALUE enums = ptr->enums;
3695inspect_enum_product(
VALUE obj,
VALUE dummy,
int recur)
3702 if (!ptr || UNDEF_P(ptr->enums)) {
3720enum_product_inspect(
VALUE obj)
3742enumerator_s_product(
int argc,
VALUE *argv,
VALUE klass)
3746 rb_scan_args(argc, argv,
"*:&", &enums, &options, &block);
3749 rb_exc_raise(rb_keyword_error_new(
"unknown", rb_hash_keys(options)));
3752 VALUE obj = enum_product_initialize(argc, argv, enum_product_allocate(rb_cEnumProduct));
3754 if (!
NIL_P(block)) {
3755 enum_product_run(obj, block);
3779 VALUE aseq = enumerator_init(enumerator_allocate(rb_cArithSeq),
3795arith_seq_begin(
VALUE self)
3806arith_seq_end(
VALUE self)
3818arith_seq_step(
VALUE self)
3829arith_seq_exclude_end(
VALUE self)
3835arith_seq_exclude_end_p(
VALUE self)
3837 return RTEST(arith_seq_exclude_end(self));
3844 component->
begin = arith_seq_begin(obj);
3845 component->
end = arith_seq_end(obj);
3846 component->
step = arith_seq_step(obj);
3847 component->
exclude_end = arith_seq_exclude_end_p(obj);
3859rb_arithmetic_sequence_beg_len_step(
VALUE obj,
long *begp,
long *lenp,
long *stepp,
long len,
int err)
3861 RBIMPL_NONNULL_ARG(begp);
3862 RBIMPL_NONNULL_ARG(lenp);
3863 RBIMPL_NONNULL_ARG(stepp);
3866 if (!rb_arithmetic_sequence_extract(obj, &aseq)) {
3886 if (err == 0 && (step < -1 || step > 1)) {
3896 return rb_range_component_beg_len(aseq.
begin, aseq.
end, aseq.
exclude_end, begp, lenp, len, err);
3913arith_seq_first(
int argc,
VALUE *argv,
VALUE self)
3919 rb_check_arity(argc, 0, 1);
3921 b = arith_seq_begin(self);
3922 e = arith_seq_end(self);
3923 s = arith_seq_step(self);
3931 if (r > 0 &&
RTEST(rb_funcall(b,
'>', 1, e))) {
3934 if (r < 0 &&
RTEST(rb_funcall(b,
'<', 1, e))) {
3948 return rb_ary_new_capa(0);
3951 x = arith_seq_exclude_end_p(self);
3955 ary = rb_ary_new_capa(n);
3964 rb_ary_push(ary, b);
3965 b = rb_big_plus(b, s);
3981 if (len < 0) len = 0;
3982 ary = rb_ary_new_capa((n < len) ? n : len);
3983 while (n > 0 && i < end) {
3985 if (i + unit < i)
break;
3994 if (len < 0) len = 0;
3995 ary = rb_ary_new_capa((n < len) ? n : len);
3996 while (n > 0 && i > end) {
3998 if (i + unit > i)
break;
4005 else if (RB_FLOAT_TYPE_P(b) || RB_FLOAT_TYPE_P(e) || RB_FLOAT_TYPE_P(s)) {
4010 double end =
NIL_P(e) ? (unit < 0 ? -1 : 1)*HUGE_VAL :
NUM2DBL(e);
4011 double len = ruby_float_step_size(beg, end, unit, x);
4019 ary = rb_ary_new_capa(1);
4020 rb_ary_push(ary,
DBL2NUM(beg));
4023 ary = rb_ary_new_capa(0);
4026 else if (unit == 0) {
4028 ary = rb_ary_new_capa(n);
4029 for (i = 0; i < len; ++i) {
4030 rb_ary_push(ary, val);
4034 ary = rb_ary_new_capa(n);
4035 for (i = 0; i < n; ++i) {
4036 double d = i*unit+beg;
4037 if (unit >= 0 ? end < d : d < end) d = end;
4052 return rb_int_plus(a, b);
4054 else if (RB_FLOAT_TYPE_P(a)) {
4055 return rb_float_plus(a, b);
4058 return rb_rational_plus(a, b);
4061 return rb_funcallv(a,
'+', 1, &b);
4069 return rb_int_minus(a, b);
4071 else if (RB_FLOAT_TYPE_P(a)) {
4072 return rb_float_minus(a, b);
4075 return rb_rational_minus(a, b);
4078 return rb_funcallv(a,
'-', 1, &b);
4086 return rb_int_mul(a, b);
4088 else if (RB_FLOAT_TYPE_P(a)) {
4089 return rb_float_mul(a, b);
4092 return rb_rational_mul(a, b);
4095 return rb_funcallv(a,
'*', 1, &b);
4104 q = rb_int_idiv(a, b);
4106 else if (RB_FLOAT_TYPE_P(a)) {
4107 q = rb_float_div(a, b);
4110 q = rb_rational_div(a, b);
4113 q = rb_funcallv(a, idDiv, 1, &b);
4119 else if (RB_FLOAT_TYPE_P(q)) {
4120 return rb_float_floor(q, 0);
4123 return rb_rational_floor(q, 0);
4126 return rb_funcall(q, rb_intern(
"floor"), 0);
4139arith_seq_last(
int argc,
VALUE *argv,
VALUE self)
4141 VALUE b, e, s, len_1, len, last, nv, ary;
4142 int last_is_adjusted;
4145 e = arith_seq_end(self);
4148 "cannot get the last element of endless arithmetic sequence");
4151 b = arith_seq_begin(self);
4152 s = arith_seq_step(self);
4154 len_1 = num_idiv(num_minus(e, b), s);
4155 if (rb_num_negative_int_p(len_1)) {
4159 return rb_ary_new_capa(0);
4162 last = num_plus(b, num_mul(s, len_1));
4163 if ((last_is_adjusted = arith_seq_exclude_end_p(self) &&
rb_equal(last, e))) {
4164 last = num_minus(last, s);
4171 if (last_is_adjusted) {
4175 len = rb_int_plus(len_1,
INT2FIX(1));
4178 rb_scan_args(argc, argv,
"1", &nv);
4182 if (
RTEST(rb_int_gt(nv, len))) {
4190 ary = rb_ary_new_capa(n);
4191 b = rb_int_minus(last, rb_int_mul(s, nv));
4193 b = rb_int_plus(b, s);
4194 rb_ary_push(ary, b);
4208arith_seq_inspect(
VALUE self)
4211 VALUE eobj, str, eargs;
4222 str =
rb_sprintf(
"(%s%"PRIsVALUE
"%s.", range_p ?
"(" :
"", eobj, range_p ?
")" :
"");
4239 if (RB_TYPE_P(argv[argc-1],
T_HASH)) {
4241 rb_hash_foreach(argv[argc-1], key_symbol_p, (
VALUE)&all_key);
4242 if (all_key) kwds = argv[--argc];
4246 VALUE arg = *argv++;
4252 rb_hash_foreach(kwds, kwd_append, str);
4278 if (!
rb_equal(arith_seq_begin(self), arith_seq_begin(other))) {
4282 if (!
rb_equal(arith_seq_end(self), arith_seq_end(other))) {
4286 if (!
rb_equal(arith_seq_step(self), arith_seq_step(other))) {
4290 if (arith_seq_exclude_end_p(self) != arith_seq_exclude_end_p(other)) {
4308arith_seq_hash(
VALUE self)
4314 v = rb_hash(arith_seq_begin(self));
4316 v = rb_hash(arith_seq_end(self));
4318 v = rb_hash(arith_seq_step(self));
4325#define NUM_GE(x, y) RTEST(rb_num_coerce_relop((x), (y), idGE))
4340arith_seq_each(
VALUE self)
4342 VALUE c, e, s, len_1, last;
4347 c = arith_seq_begin(self);
4348 e = arith_seq_end(self);
4349 s = arith_seq_step(self);
4350 x = arith_seq_exclude_end_p(self);
4352 if (!RB_TYPE_P(s,
T_COMPLEX) && ruby_float_step(c, e, s, x, TRUE)) {
4359 c = rb_int_plus(c, s);
4373 len_1 = num_idiv(num_minus(e, c), s);
4374 last = num_plus(c, num_mul(s, len_1));
4376 last = num_minus(last, s);
4379 if (rb_num_negative_int_p(s)) {
4380 while (NUM_GE(c, last)) {
4386 while (NUM_GE(last, c)) {
4403arith_seq_size(
VALUE self)
4405 VALUE b, e, s, len_1, len, last;
4408 b = arith_seq_begin(self);
4409 e = arith_seq_end(self);
4410 s = arith_seq_step(self);
4411 x = arith_seq_exclude_end_p(self);
4413 if (RB_FLOAT_TYPE_P(b) || RB_FLOAT_TYPE_P(e) || RB_FLOAT_TYPE_P(s)) {
4417 if (rb_num_negative_int_p(s)) {
4429 if (isinf(n))
return DBL2NUM(n);
4431 return rb_dbl2big(n);
4446 len_1 = rb_int_idiv(rb_int_minus(e, b), s);
4447 if (rb_num_negative_int_p(len_1)) {
4451 last = rb_int_plus(b, rb_int_mul(s, len_1));
4456 len = rb_int_plus(len_1,
INT2FIX(1));
4462#define sym(name) ID2SYM(rb_intern_const(name))
4464InitVM_Enumerator(
void)
4466 ID id_private = rb_intern_const(
"private");
4500 rb_define_alias(rb_cLazy,
"_enumerable_collect_concat",
"collect_concat");
4516 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_map"));
4517 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_collect"));
4518 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_flat_map"));
4519 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_collect_concat"));
4520 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_select"));
4521 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_find_all"));
4522 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_filter"));
4523 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_filter_map"));
4524 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_reject"));
4525 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_grep"));
4526 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_grep_v"));
4527 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_zip"));
4528 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_take"));
4529 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_take_while"));
4530 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_drop"));
4531 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_drop_while"));
4532 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_uniq"));
4564 lazy_use_super_method = rb_hash_new_with_size(18);
4565 rb_hash_aset(lazy_use_super_method, sym(
"map"), sym(
"_enumerable_map"));
4566 rb_hash_aset(lazy_use_super_method, sym(
"collect"), sym(
"_enumerable_collect"));
4567 rb_hash_aset(lazy_use_super_method, sym(
"flat_map"), sym(
"_enumerable_flat_map"));
4568 rb_hash_aset(lazy_use_super_method, sym(
"collect_concat"), sym(
"_enumerable_collect_concat"));
4569 rb_hash_aset(lazy_use_super_method, sym(
"select"), sym(
"_enumerable_select"));
4570 rb_hash_aset(lazy_use_super_method, sym(
"find_all"), sym(
"_enumerable_find_all"));
4571 rb_hash_aset(lazy_use_super_method, sym(
"filter"), sym(
"_enumerable_filter"));
4572 rb_hash_aset(lazy_use_super_method, sym(
"filter_map"), sym(
"_enumerable_filter_map"));
4573 rb_hash_aset(lazy_use_super_method, sym(
"reject"), sym(
"_enumerable_reject"));
4574 rb_hash_aset(lazy_use_super_method, sym(
"grep"), sym(
"_enumerable_grep"));
4575 rb_hash_aset(lazy_use_super_method, sym(
"grep_v"), sym(
"_enumerable_grep_v"));
4576 rb_hash_aset(lazy_use_super_method, sym(
"zip"), sym(
"_enumerable_zip"));
4577 rb_hash_aset(lazy_use_super_method, sym(
"take"), sym(
"_enumerable_take"));
4578 rb_hash_aset(lazy_use_super_method, sym(
"take_while"), sym(
"_enumerable_take_while"));
4579 rb_hash_aset(lazy_use_super_method, sym(
"drop"), sym(
"_enumerable_drop"));
4580 rb_hash_aset(lazy_use_super_method, sym(
"drop_while"), sym(
"_enumerable_drop_while"));
4581 rb_hash_aset(lazy_use_super_method, sym(
"uniq"), sym(
"_enumerable_uniq"));
4582 rb_hash_aset(lazy_use_super_method, sym(
"with_index"), sym(
"_enumerable_with_index"));
4584 rb_gc_register_mark_object(lazy_use_super_method);
4604 rb_define_method(rb_cGenerator,
"initialize_copy", generator_init_copy, 1);
4625 rb_define_method(rb_cEnumChain,
"initialize_copy", enum_chain_init_copy, 1);
4639 rb_define_method(rb_cEnumProduct,
"initialize", enum_product_initialize, -1);
4640 rb_define_method(rb_cEnumProduct,
"initialize_copy", enum_product_init_copy, 1);
4675Init_Enumerator(
void)
4677 id_rewind = rb_intern_const(
"rewind");
4678 id_new = rb_intern_const(
"new");
4679 id_next = rb_intern_const(
"next");
4680 id_result = rb_intern_const(
"result");
4681 id_receiver = rb_intern_const(
"receiver");
4682 id_arguments = rb_intern_const(
"arguments");
4683 id_memo = rb_intern_const(
"memo");
4684 id_method = rb_intern_const(
"method");
4685 id_force = rb_intern_const(
"force");
4686 id_to_enum = rb_intern_const(
"to_enum");
4687 id_each_entry = rb_intern_const(
"each_entry");
4688 id_begin = rb_intern_const(
"begin");
4689 id_end = rb_intern_const(
"end");
4690 id_step = rb_intern_const(
"step");
4691 id_exclude_end = rb_intern_const(
"exclude_end");
4692 sym_each =
ID2SYM(id_each);
4693 sym_cycle =
ID2SYM(rb_intern_const(
"cycle"));
4694 sym_yield =
ID2SYM(rb_intern_const(
"yield"));
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
void rb_need_block(void)
Declares that the current method needs a block.
void rb_undef_method(VALUE klass, const char *name)
Defines an undef of a method.
int rb_keyword_given_p(void)
Determines if the current method is given a keyword argument.
int rb_block_given_p(void)
Determines if the current method is given a block.
#define T_COMPLEX
Old name of RUBY_T_COMPLEX.
#define RB_INTEGER_TYPE_P
Old name of rb_integer_type_p.
#define rb_str_buf_cat2
Old name of rb_usascii_str_new_cstr.
#define OBJ_INIT_COPY(obj, orig)
Old name of RB_OBJ_INIT_COPY.
#define RFLOAT_VALUE
Old name of rb_float_value.
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
#define T_FLOAT
Old name of RUBY_T_FLOAT.
#define ID2SYM
Old name of RB_ID2SYM.
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
#define CLASS_OF
Old name of rb_class_of.
#define rb_ary_new4
Old name of rb_ary_new_from_values.
#define FIXABLE
Old name of RB_FIXABLE.
#define rb_exc_new2
Old name of rb_exc_new_cstr.
#define LONG2FIX
Old name of RB_INT2FIX.
#define T_RATIONAL
Old name of RUBY_T_RATIONAL.
#define T_HASH
Old name of RUBY_T_HASH.
#define NUM2DBL
Old name of rb_num2dbl.
#define rb_ary_new3
Old name of rb_ary_new_from_args.
#define LONG2NUM
Old name of RB_LONG2NUM.
#define Qtrue
Old name of RUBY_Qtrue.
#define ST2FIX
Old name of RB_ST2FIX.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define FIX2LONG
Old name of RB_FIX2LONG.
#define T_ARRAY
Old name of RUBY_T_ARRAY.
#define NIL_P
Old name of RB_NIL_P.
#define ALLOCV_N
Old name of RB_ALLOCV_N.
#define POSFIXABLE
Old name of RB_POSFIXABLE.
#define T_SYMBOL
Old name of RUBY_T_SYMBOL.
#define DBL2NUM
Old name of rb_float_new.
#define NUM2LONG
Old name of RB_NUM2LONG.
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define rb_ary_new2
Old name of rb_ary_new_capa.
#define ALLOCV_END
Old name of RB_ALLOCV_END.
#define SYMBOL_P
Old name of RB_SYMBOL_P.
void rb_raise(VALUE exc, const char *fmt,...)
Exception entry point.
VALUE rb_rescue2(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2,...)
An equivalent of rescue clause.
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
void rb_iter_break(void)
Breaks from a block.
VALUE rb_eRangeError
RangeError exception.
VALUE rb_eTypeError
TypeError exception.
VALUE rb_eRuntimeError
RuntimeError exception.
VALUE rb_eStopIteration
StopIteration exception.
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports always regardless of runtime -W flag.
VALUE rb_eArgError
ArgumentError exception.
VALUE rb_eIndexError
IndexError exception.
VALUE rb_mKernel
Kernel module.
VALUE rb_mEnumerable
Enumerable module.
VALUE rb_cEnumerator
Enumerator class.
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_cNumeric
Numeric class.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_obj_dup(VALUE obj)
Duplicates the given object.
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
VALUE rb_cRange
Range class.
VALUE rb_equal(VALUE lhs, VALUE rhs)
This function is an optimised version of calling #==.
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass)
Queries if the given object is an instance (of possibly descendants) of the given class.
VALUE rb_obj_freeze(VALUE obj)
Just calls rb_obj_freeze_inline() inside.
VALUE rb_to_int(VALUE val)
Identical to rb_check_to_int(), except it raises in case of conversion mismatch.
VALUE rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE procval)
Identical to rb_funcallv_public(), except you can pass a block.
VALUE rb_call_super(int argc, const VALUE *argv)
This resembles ruby's super.
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
This roughly resembles return enum_for(__callee__) unless block_given?.
VALUE rb_enumerator_size_func(VALUE recv, VALUE argv, VALUE eobj)
This is the type of functions that rb_enumeratorize_with_size() expects.
#define rb_check_frozen
Just another name of rb_check_frozen.
void rb_provide(const char *feature)
Declares that the given feature is already provided by someone else.
VALUE rb_num_coerce_cmp(VALUE lhs, VALUE rhs, ID op)
Identical to rb_num_coerce_bin(), except for return values.
VALUE rb_obj_method(VALUE recv, VALUE mid)
Creates a method object.
VALUE rb_block_proc(void)
Constructs a Proc object from implicitly passed components.
VALUE rb_proc_call_with_block(VALUE recv, int argc, const VALUE *argv, VALUE proc)
Identical to rb_proc_call(), except you can additionally pass another proc object,...
VALUE rb_proc_call_kw(VALUE recv, VALUE args, int kw_splat)
Identical to rb_proc_call(), except you can specify how to handle the last element of the given array...
VALUE rb_obj_is_proc(VALUE recv)
Queries if the given object is a proc.
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
Deconstructs a range into its components.
#define rb_hash_uint(h, i)
Just another name of st_hash_uint.
#define rb_hash_end(h)
Just another name of st_hash_end.
VALUE rb_str_append(VALUE dst, VALUE src)
Identical to rb_str_buf_append(), except it converts the right hand side before concatenating.
VALUE rb_str_buf_append(VALUE dst, VALUE src)
Identical to rb_str_cat_cstr(), except it takes Ruby's string instead of C's.
void rb_str_set_len(VALUE str, long len)
Overwrites the length of the string.
st_index_t rb_hash_start(st_index_t i)
Starts a series of hashing.
VALUE rb_exec_recursive(VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h)
"Recursion" API entry point.
VALUE rb_attr_get(VALUE obj, ID name)
Identical to rb_ivar_get()
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val)
Identical to rb_iv_set(), except it accepts the name as an ID instead of a C string.
VALUE rb_ivar_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
VALUE rb_class_path(VALUE mod)
Identical to rb_mod_name(), except it returns #<Class: ...> style inspection for anonymous modules.
int rb_respond_to(VALUE obj, ID mid)
Queries if the object responds to the method.
void rb_undef_alloc_func(VALUE klass)
Deletes the allocator function of a class.
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcallv(), except it returns RUBY_Qundef instead of raising rb_eNoMethodError.
VALUE rb_check_funcall_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
Identical to rb_check_funcall(), except you can specify how to handle the last element of the given a...
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func)
Sets the allocator function of a class.
VALUE rb_sym2str(VALUE id)
Identical to rb_id2str(), except it takes an instance of rb_cSymbol rather than an ID.
ID rb_to_id(VALUE str)
Identical to rb_intern(), except it takes an instance of rb_cString.
VALUE rb_sprintf(const char *fmt,...)
Ruby's extended sprintf(3).
VALUE rb_str_catf(VALUE dst, const char *fmt,...)
Identical to rb_sprintf(), except it renders the output to the specified object rather than creating ...
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Shim for block function parameters.
VALUE rb_yield_values2(int n, const VALUE *argv)
Identical to rb_yield_values(), except it takes the parameters as a C array instead of variadic argum...
VALUE rb_yield(VALUE val)
Yields the block.
VALUE rb_yield_values_kw(int n, const VALUE *argv, int kw_splat)
Identical to rb_yield_values2(), except you can specify how to handle the last element of the given a...
VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
This is the type of a function that the interpreter expect for C-backended blocks.
VALUE rb_block_call_kw(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2, int kw_splat)
Identical to rb_funcallv_kw(), except it additionally passes a function as a block.
#define rb_long2int
Just another name of rb_long2int_inline.
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
#define ALLOCA_N(type, n)
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
VALUE rb_proc_new(type *q, VALUE w)
Creates a rb_cProc instance.
#define RARRAY_LEN
Just another name of rb_array_len.
#define RARRAY_AREF(a, i)
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
#define DATA_PTR(obj)
Convenient getter macro.
#define RHASH_EMPTY_P(h)
Checks if the hash is empty.
#define TypedData_Get_Struct(obj, type, data_type, sval)
Obtains a C struct from inside of a wrapper Ruby object.
#define TypedData_Make_Struct(klass, type, data_type, sval)
Identical to TypedData_Wrap_Struct, except it allocates a new data region internally instead of takin...
#define InitVM(ext)
This macro is for internal use.
#define RB_PASS_CALLED_KEYWORDS
Pass keywords if current method is called with keywords, useful for argument delegation.
#define RB_NO_KEYWORDS
Do not pass keywords.
#define RTEST
This is an old name of RB_TEST.
#define _(args)
This was a transition path from K&R to ANSI.
Decomposed Enumerator::ArithmeicSequence.
int exclude_end
Whether the endpoint is open or closed.
VALUE end
"Right" or "highest" endpoint of the sequence.
VALUE step
Step between a sequence.
VALUE begin
"Left" or "lowest" endpoint of the sequence.
uintptr_t VALUE
Type that represents a Ruby object.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.