summaryrefslogtreecommitdiff
path: root/set.c
diff options
context:
space:
mode:
-rw-r--r--set.c132
1 files changed, 63 insertions, 69 deletions
@@ -843,66 +843,72 @@ set_i_classify(VALUE set)
return args[0];
}
-struct set_divide_args {
- VALUE self;
- VALUE set_class;
- VALUE final_set;
- VALUE hash;
- VALUE current_set;
- VALUE current_item;
- unsigned long ni;
- unsigned long nj;
-};
-static VALUE
-set_divide_block0(RB_BLOCK_CALL_FUNC_ARGLIST(j, arg))
-{
- struct set_divide_args *args = (struct set_divide_args *)arg;
- if (args->nj > args->ni) {
- VALUE i = args->current_item;
- if (RTEST(rb_yield_values(2, i, j)) && RTEST(rb_yield_values(2, j, i))) {
- VALUE hash = args->hash;
- if (args->current_set == Qnil) {
- VALUE set = rb_hash_aref(hash, j);
- if (set == Qnil) {
- VALUE both[2] = {i, j};
- set = set_s_create(2, both, args->set_class);
- rb_hash_aset(hash, i, set);
- rb_hash_aset(hash, j, set);
- set_i_add(args->final_set, set);
- }
- else {
- set_i_add(set, i);
- rb_hash_aset(hash, i, set);
- }
- args->current_set = set;
- }
- else {
- set_i_add(args->current_set, j);
- rb_hash_aset(hash, j, args->current_set);
}
}
}
- args->nj++;
- return j;
-}
-
-static VALUE
-set_divide_block(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
-{
- struct set_divide_args *args = (struct set_divide_args *)arg;
- VALUE hash = args->hash;
- args->current_set = rb_hash_aref(hash, i);
- args->current_item = i;
- args->nj = 0;
- rb_block_call(args->self, id_each, 0, 0, set_divide_block0, arg);
- if (args->current_set == Qnil) {
- VALUE set = set_s_create(1, &i, args->set_class);
- rb_hash_aset(hash, i, set);
- set_i_add(args->final_set, set);
- }
- args->ni++;
- return i;
}
static void set_merge_enum_into(VALUE set, VALUE arg);
@@ -936,19 +942,7 @@ set_i_divide(VALUE set)
RETURN_SIZED_ENUMERATOR(set, 0, 0, set_enum_size);
if (rb_block_arity() == 2) {
- VALUE final_set = set_s_create(0, 0, rb_cSet);
- struct set_divide_args args = {
- .self = set,
- .set_class = rb_obj_class(set),
- .final_set = final_set,
- .hash = rb_hash_new(),
- .current_set = 0,
- .current_item = 0,
- .ni = 0,
- .nj = 0
- };
- rb_block_call(set, id_each, 0, 0, set_divide_block, (VALUE)&args);
- return final_set;
}
VALUE values = rb_hash_values(set_i_classify(set));