35#define id_lshift idLTLT
47#define ENUM_WANT_SVALUE() do { \
48 i = rb_enum_values_pack(argc, argv); \
62enum_yield_array(
VALUE ary)
122 else if (RB_TYPE_P(pat,
T_REGEXP) &&
155 return enum_grep0(obj, pat,
Qtrue);
176 return enum_grep0(obj, pat,
Qfalse);
179#define COUNT_BIGNUM IMEMO_FL_USER0
180#define MEMO_V3_SET(m, v) RB_OBJ_WRITE((m), &(m)->u3.value, (v))
183imemo_count_up(
struct MEMO *memo)
188 else if (++memo->
u3.
cnt == 0) {
190 unsigned long buf[2] = {0, 1};
197imemo_count_value(
struct MEMO *memo)
215 imemo_count_up(memo);
226 imemo_count_up(memo);
236 imemo_count_up(memo);
276 rb_warn(
"given block not used");
283 return imemo_count_value(memo);
293 MEMO_V1_SET(memo, i);
339 if (!
NIL_P(if_none)) {
353 MEMO_V1_SET(memo, imemo_count_value(memo));
356 imemo_count_up(memo);
366 MEMO_V1_SET(memo, imemo_count_value(memo));
369 imemo_count_up(memo);
401 func = find_index_iter_i;
406 rb_warn(
"given block not used");
434limit_by_enum_size(
VALUE obj,
long n)
440 return ((
unsigned long)n > limit) ? (
long)limit : n;
444enum_size_over_p(
VALUE obj,
long n)
479enum_find_all(
VALUE obj)
518enum_filter_map(
VALUE obj)
560enum_reject(
VALUE obj)
606enum_collect(
VALUE obj)
609 int min_argc, max_argc;
655enum_flat_map(
VALUE obj)
733 return enum_hashify(obj,
argc,
argv, iter);
744 MEMO_V1_SET(memo, i);
761 MEMO_V1_SET(memo, i);
896 op =
id ?
ID2SYM(
id) : init;
910 if (iter == inject_op_i &&
914 return ary_inject_op(obj, init, op);
956enum_partition(
VALUE obj)
976 group = enum_yield(
argc, i);
978 if (!RB_TYPE_P(values,
T_ARRAY)) {
1004enum_group_by(
VALUE obj)
1008 return enum_hashify(obj, 0, 0, group_by_i);
1019 tally +=
INT2FIX(1) & ~FIXNUM_FLAG;
1047enum_tally(
VALUE obj)
1049 return enum_hashify(obj, 0, 0, tally_i);
1059 MEMO_V1_SET(memo, i);
1090 return enum_take(obj,
argv[0]);
1130#define SORT_BY_BUFSIZE 16
1146 v = enum_yield(
argc, i);
1155 RARRAY_ASET(data->
buf, data->
n*2, v);
1156 RARRAY_ASET(data->
buf, data->
n*2+1, i);
1166sort_by_cmp(
const void *ap,
const void *
bp,
void *data)
1173 if (
RBASIC(ary)->klass) {
1262enum_sort_by(
VALUE obj)
1277 RBASIC_CLEAR_CLASS(
ary);
1295 sort_by_cmp, (
void *)
ary));
1309#define ENUMFUNC(name) argc ? name##_eqq : rb_block_given_p() ? name##_iter_i : name##_i
1311#define MEMO_ENUM_NEW(v1) (rb_check_arity(argc, 0, 1), MEMO_NEW((v1), (argc ? *argv : 0), 0))
1313#define DEFINE_ENUMFUNCS(name) \
1314static VALUE enum_##name##_func(VALUE result, struct MEMO *memo); \
1317name##_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memo)) \
1319 return enum_##name##_func(rb_enum_values_pack(argc, argv), MEMO_CAST(memo)); \
1323name##_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memo)) \
1325 return enum_##name##_func(rb_yield_values2(argc, argv), MEMO_CAST(memo)); \
1329name##_eqq(RB_BLOCK_CALL_FUNC_ARGLIST(i, memo)) \
1331 ENUM_WANT_SVALUE(); \
1332 return enum_##name##_func(rb_funcallv(MEMO_CAST(memo)->v2, id_eqq, 1, &i), MEMO_CAST(memo)); \
1336enum_##name##_func(VALUE result, struct MEMO *memo)
1338#define WARN_UNUSED_BLOCK(argc) do { \
1339 if ((argc) > 0 && rb_block_given_p()) { \
1340 rb_warn("given block not used"); \
1346 if (!
RTEST(result)) {
1347 MEMO_V1_SET(memo,
Qfalse);
1388 if (
RTEST(result)) {
1389 MEMO_V1_SET(memo,
Qtrue);
1430 if (
RTEST(result)) {
1432 MEMO_V1_SET(memo,
Qtrue);
1435 MEMO_V1_SET(memo,
Qfalse);
1458 data->
rev ?
"max" :
"min",
1459 data->
by ?
"_by" :
"");
1465nmin_cmp(
const void *ap,
const void *
bp,
void *_data)
1470#define rb_cmpint(cmp, a, b) rb_cmpint(cmpint_reenter_check(data, (cmp)), a, b)
1476nmin_block_cmp(
const void *ap,
const void *
bp,
void *_data)
1481 cmpint_reenter_check(data, cmp);
1502 beg = RARRAY_PTR(data->
buf);
1503 eltsize = data->
by ? 2 : 1;
1509#define GETPTR(i) (beg+(i)*eltsize)
1511#define SWAP(i, j) do { \
1513 memcpy(tmp, GETPTR(i), sizeof(VALUE)*eltsize); \
1514 memcpy(GETPTR(i), GETPTR(j), sizeof(VALUE)*eltsize); \
1515 memcpy(GETPTR(j), tmp, sizeof(VALUE)*eltsize); \
1519 long pivot_index = left + (right-left)/2;
1520 long num_pivots = 1;
1522 SWAP(pivot_index, right);
1523 pivot_index = right;
1527 while (i <= right-num_pivots) {
1532 SWAP(i, right-num_pivots);
1537 SWAP(i, store_index);
1543 for (i = right; right-num_pivots < i; i--) {
1550 if (store_index <=
n &&
n <= store_index+num_pivots)
1553 if (
n < store_index) {
1554 right = store_index-1;
1557 left = store_index+num_pivots;
1577 cmpv = enum_yield(
argc, i);
1703 if (
RTEST(result)) {
1704 MEMO_V1_SET(memo,
Qfalse);
1981 minmax_i_update(i, j, memo);
2033 minmax_ii_update(i, j, memo);
2054enum_minmax(
VALUE obj)
2066 minmax_ii_update(m->
last, m->
last, m);
2071 minmax_i_update(m->
last, m->
last, m);
2088 v = enum_yield(
argc, i);
2090 MEMO_V1_SET(memo, v);
2091 MEMO_V2_SET(memo, i);
2094 MEMO_V1_SET(memo, v);
2095 MEMO_V2_SET(memo, i);
2150 v = enum_yield(
argc, i);
2152 MEMO_V1_SET(memo, v);
2153 MEMO_V2_SET(memo, i);
2156 MEMO_V1_SET(memo, v);
2157 MEMO_V2_SET(memo, i);
2290 vi = enum_yield(
argc, i);
2316 minmax_by_i_update(vi, vj, i, j, memo);
2337enum_minmax_by(
VALUE obj)
2363 MEMO_V2_SET(memo,
Qtrue);
2397 VALUE n = imemo_count_value(m);
2481 enum_yield(
argc, i);
2523add_int(
VALUE x,
long n)
2531div_int(
VALUE x,
long n)
2538#define dont_recycle_block_arg(arity) ((arity) == 1 || (arity) < 0)
2574 size = enum_size(obj, 0, 0);
2580 n = add_int(
size, slice_size-1);
2581 return div_int(n, slice_size);
2610 size = limit_by_enum_size(obj,
size);
2652 size = enum_size(obj, 0, 0);
2655 n = add_int(
size, 1 - cons_size);
2690 if (enum_size_over_p(obj,
size))
return Qnil;
2731 struct MEMO *memo = (
struct MEMO *)memoval;
2734 long n = memo->
u3.
cnt++;
2750 if (
NIL_P(result)) {
2751 enum_yield_array(tmp);
2779 struct MEMO *memo = (
struct MEMO *)memoval;
2797 RARRAY_ASET(args, i,
Qnil);
2803 if (
NIL_P(result)) {
2804 enum_yield_array(tmp);
2853 argv = RARRAY_PTR(args);
2854 for (i=0; i<
argc; i++) {
2865 for (i=0; i<
argc; i++) {
2948enum_take_while(
VALUE obj)
2962 if (memo->
u3.
cnt == 0) {
3033enum_drop_while(
VALUE obj)
3051 enum_yield(
argc, i);
3067 size = enum_size(self, args, 0);
3112 if (n <= 0)
return Qnil;
3115 RBASIC_CLEAR_CLASS(ary);
3119 while (n < 0 || 0 < --n) {
3120 for (i=0; i<
len; i++) {
3155 else if (
NIL_P(v) || v == separator) {
3296enum_chunk(
VALUE enumerable)
3329 if (
RTEST(header_p)) {
3541#define UPDATE_MEMO ((void)(memo = MEMO_FOR(struct sliceafter_arg, _memo)))
3665#define UPDATE_MEMO ((void)(memo = MEMO_FOR(struct slicewhen_arg, _memo)))
3788enum_slice_when(
VALUE enumerable)
3854enum_chunk_while(
VALUE enumerable)
3885 switch (
TYPE(memo->
r)) {
3943 sum_iter_some_value(i, memo);
3968 if (fabs(
f) >= fabs(x)) {
3989 sum_iter_Kahan_Babuska(i, memo);
3991 else switch (
TYPE(memo->
v)) {
3992 default: sum_iter_some_value(i, memo);
return;
3993 case T_FLOAT: sum_iter_Kahan_Babuska(i, memo);
return;
3998 case T_FIXNUM: sum_iter_fixnum(i, memo);
return;
3999 case T_BIGNUM: sum_iter_bignum(i, memo);
return;
4000 case T_RATIONAL: sum_iter_rational(i, memo);
return;
4002 sum_iter_normalize_memo(memo);
4006 sum_iter_Kahan_Babuska(i, memo);
4009 sum_iter_normalize_memo(memo);
4010 sum_iter_some_value(i, memo);
4118 return int_range_sum(beg, end, excl, memo.
v);
4122 if (RB_TYPE_P(obj,
T_HASH) &&
4124 hash_sum(obj, &memo);
4255 id_next = rb_intern_const(
"next");
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
void rb_ary_store(VALUE ary, long idx, VALUE val)
VALUE rb_ary_reverse(VALUE ary)
VALUE rb_ary_shift(VALUE ary)
VALUE rb_ary_dup(VALUE ary)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_ary_concat(VALUE x, VALUE y)
VALUE rb_check_array_type(VALUE ary)
VALUE rb_ary_resize(VALUE ary, long len)
expands or shrinks ary to len elements.
VALUE rb_ary_tmp_new(long capa)
VALUE rb_ary_clear(VALUE ary)
VALUE rb_ary_sort_bang(VALUE ary)
VALUE rb_assoc_new(VALUE car, VALUE cdr)
#define UNREACHABLE_RETURN
VALUE rb_big_minus(VALUE x, VALUE y)
VALUE rb_big_plus(VALUE x, VALUE y)
VALUE rb_big_unpack(unsigned long *buf, long num_longs)
double rb_big2dbl(VALUE x)
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define MEMO_V3_SET(m, v)
#define rb_cmpint(cmp, a, b)
#define MEMO_ENUM_NEW(v1)
VALUE rb_nmin_run(VALUE obj, VALUE num, int by, int rev, int ary)
#define WARN_UNUSED_BLOCK(argc)
#define DEFINE_ENUMFUNCS(name)
#define ENUM_WANT_SVALUE()
VALUE rb_enum_values_pack(int argc, const VALUE *argv)
void Init_Enumerable(void)
#define dont_recycle_block_arg(arity)
#define RSTRING_PTR(string)
VALUE rb_define_module(const char *name)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
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_rescue2(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2,...)
An equivalent of rescue clause.
void rb_warn(const char *fmt,...)
void rb_warning(const char *fmt,...)
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_obj_class(VALUE)
double rb_num2dbl(VALUE)
Converts a Numeric object to double.
VALUE rb_equal(VALUE, VALUE)
This function is an optimized version of calling #==.
unsigned char match[65280+2]
VALUE rb_hash_values(VALUE hash)
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
VALUE rb_hash_set_pair(VALUE hash, VALUE arg)
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
VALUE rb_hash_aref(VALUE hash, VALUE key)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
VALUE rb_hash_clear(VALUE hash)
IMEMO: Internal memo object.
#define MEMO_NEW(a, b, c)
#define MEMO_FOR(type, value)
#define NEW_MEMO_FOR(type, value)
#define NEW_PARTIAL_MEMO_FOR(type, value, member)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE rb_funcallv_public(VALUE, ID, int, const VALUE *)
Calls a method.
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
#define RETURN_ENUMERATOR(obj, argc, argv)
void rb_error_arity(int, int, int)
VALUE rb_block_proc(void)
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
VALUE rb_check_string_type(VALUE)
VALUE rb_ivar_get(VALUE, ID)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_ivar_set(VALUE, ID, VALUE)
int rb_obj_respond_to(VALUE, ID, int)
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
int rb_respond_to(VALUE, ID)
ID rb_intern(const char *)
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
void ruby_qsort(void *, const size_t, const size_t, int(*)(const void *, const void *, void *), void *)
Internal header for Comparable.
#define NEW_CMP_OPT_MEMO(type, value)
#define OPTIMIZED_CMP(a, b, data)
Internal header for Enumerable.
VALUE rb_f_send(int argc, VALUE *argv, VALUE recv)
Internal header for Hash.
Internal header for Numeric.
VALUE rb_int_ge(VALUE x, VALUE y)
VALUE rb_int_minus(VALUE x, VALUE y)
VALUE rb_fix_plus(VALUE x, VALUE y)
VALUE rb_int_idiv(VALUE x, VALUE y)
VALUE rb_int_plus(VALUE x, VALUE y)
VALUE rb_int_succ(VALUE num)
VALUE rb_int_mul(VALUE x, VALUE y)
Internal header for Object.
Internal header for Proc.
int rb_block_min_max_arity(int *max)
Internal header for Rational.
VALUE rb_rational_plus(VALUE self, VALUE other)
Internal header for Regexp.
VALUE rb_reg_match_p(VALUE re, VALUE str, long pos)
VALUE rb_yield_force_blockarg(VALUE values)
VALUE rb_check_funcall_default(VALUE, ID, int, const VALUE *, VALUE)
VALUE rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t bl_proc, int min_argc, int max_argc, VALUE data2)
#define rb_method_basic_definition_p(...)
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
VALUE rb_block_call_kw(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE, int)
VALUE rb_yield_values(int n,...)
VALUE rb_yield_values2(int n, const VALUE *argv)
rb_block_call_func * rb_block_call_func_t
VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
#define RARRAY_AREF(a, i)
#define RARRAY_PTR_USE(ary, ptr_name, expr)
#define RB_OBJ_WRITE(a, slot, b)
WB for new reference from ‘a’ to ‘b’.
#define RB_INTEGER_TYPE_P(obj)
#define RB_PASS_CALLED_KEYWORDS
struct cmp_opt_data cmp_opt
struct cmp_opt_data cmp_opt
struct cmp_opt_data cmp_opt
int(* cmpfunc)(const void *, const void *, void *)
#define STATIC_ID2SYM(id)