summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-06-14 01:54:33 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-06-14 01:54:33 +0000
commit02725fb682c5653142d7e4b5fca86e12e9359ef5 (patch)
treec830ba38b5e34130094850ccac32514d70914122
parent9729275473b8dc5ec9f8bac313d786b9dc377548 (diff)
array.c: combinate0
* array.c (combinate0): extract. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46425 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--array.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/array.c b/array.c
index 77a0ea6690..7544faa3d0 100644
--- a/array.c
+++ b/array.c
@@ -4884,6 +4884,27 @@ rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
return ary;
}
+static void
+combinate0(const long len, const long n, long *const stack, const VALUE values)
+{
+ long lev = 0;
+
+ MEMZERO(stack+1, long, n);
+ stack[0] = -1;
+ for (;;) {
+ for (lev++; lev < n; lev++) {
+ stack[lev+1] = stack[lev]+1;
+ }
+ if (!yield_indexed_values(values, n, stack+1)) {
+ rb_raise(rb_eRuntimeError, "combination reentered");
+ }
+ do {
+ if (lev == 0) return;
+ stack[lev--]++;
+ } while (stack[lev+1]+n == len+lev+1);
+ }
+}
+
static VALUE
rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
{
@@ -4921,7 +4942,7 @@ rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
static VALUE
rb_ary_combination(VALUE ary, VALUE num)
{
- long n, i, len;
+ long i, n, len;
n = NUM2LONG(num);
RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);
@@ -4941,24 +4962,9 @@ rb_ary_combination(VALUE ary, VALUE num)
VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
volatile VALUE t0;
long *stack = ALLOCV_N(long, t0, n+1);
- long lev = 0;
RBASIC_CLEAR_CLASS(ary0);
- MEMZERO(stack+1, long, n);
- stack[0] = -1;
- for (;;) {
- for (lev++; lev < n; lev++) {
- stack[lev+1] = stack[lev]+1;
- }
- if (!yield_indexed_values(ary0, n, stack+1)) {
- rb_raise(rb_eRuntimeError, "combination reentered");
- }
- do {
- if (lev == 0) goto done;
- stack[lev--]++;
- } while (stack[lev+1]+n == len+lev+1);
- }
- done:
+ combinate0(len, n, stack, ary0);
ALLOCV_END(t0);
RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}