32 #define ARY_DEFAULT_SIZE 16
33 #define ARY_MAX_SIZE (LONG_MAX / (int)sizeof(VALUE))
34 #define SMALL_ARRAY_LEN 16
37 should_be_T_ARRAY(
VALUE ary)
43 should_not_be_shared_and_embedded(
VALUE ary)
48 #define ARY_SHARED_P(ary) \
49 (assert(should_be_T_ARRAY((VALUE)(ary))), \
50 assert(should_not_be_shared_and_embedded((VALUE)ary)), \
51 FL_TEST_RAW((ary),ELTS_SHARED)!=0)
53 #define ARY_EMBED_P(ary) \
54 (assert(should_be_T_ARRAY((VALUE)(ary))), \
55 assert(should_not_be_shared_and_embedded((VALUE)ary)), \
56 FL_TEST_RAW((ary), RARRAY_EMBED_FLAG) != 0)
58 #define ARY_HEAP_PTR(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr)
59 #define ARY_HEAP_LEN(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len)
60 #define ARY_HEAP_CAPA(a) (assert(!ARY_EMBED_P(a)), assert(!ARY_SHARED_ROOT_P(a)), \
61 RARRAY(a)->as.heap.aux.capa)
63 #define ARY_EMBED_PTR(a) (assert(ARY_EMBED_P(a)), RARRAY(a)->as.ary)
64 #define ARY_EMBED_LEN(a) \
65 (assert(ARY_EMBED_P(a)), \
66 (long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
67 (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)))
68 #define ARY_HEAP_SIZE(a) (assert(!ARY_EMBED_P(a)), assert(ARY_OWNS_HEAP_P(a)), ARY_CAPA(a) * sizeof(VALUE))
70 #define ARY_OWNS_HEAP_P(a) (assert(should_be_T_ARRAY((VALUE)(a))), \
71 !FL_TEST_RAW((a), ELTS_SHARED|RARRAY_EMBED_FLAG))
73 #define FL_SET_EMBED(a) do { \
74 assert(!ARY_SHARED_P(a)); \
75 FL_SET((a), RARRAY_EMBED_FLAG); \
76 RARY_TRANSIENT_UNSET(a); \
80 #define FL_UNSET_EMBED(ary) FL_UNSET((ary), RARRAY_EMBED_FLAG|RARRAY_EMBED_LEN_MASK)
81 #define FL_SET_SHARED(ary) do { \
82 assert(!ARY_EMBED_P(ary)); \
83 FL_SET((ary), ELTS_SHARED); \
85 #define FL_UNSET_SHARED(ary) FL_UNSET((ary), ELTS_SHARED)
87 #define ARY_SET_PTR(ary, p) do { \
88 assert(!ARY_EMBED_P(ary)); \
89 assert(!OBJ_FROZEN(ary)); \
90 RARRAY(ary)->as.heap.ptr = (p); \
92 #define ARY_SET_EMBED_LEN(ary, n) do { \
94 assert(ARY_EMBED_P(ary)); \
95 assert(!OBJ_FROZEN(ary)); \
96 RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK; \
97 RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT; \
99 #define ARY_SET_HEAP_LEN(ary, n) do { \
100 assert(!ARY_EMBED_P(ary)); \
101 RARRAY(ary)->as.heap.len = (n); \
103 #define ARY_SET_LEN(ary, n) do { \
104 if (ARY_EMBED_P(ary)) { \
105 ARY_SET_EMBED_LEN((ary), (n)); \
108 ARY_SET_HEAP_LEN((ary), (n)); \
110 assert(RARRAY_LEN(ary) == (n)); \
112 #define ARY_INCREASE_PTR(ary, n) do { \
113 assert(!ARY_EMBED_P(ary)); \
114 assert(!OBJ_FROZEN(ary)); \
115 RARRAY(ary)->as.heap.ptr += (n); \
117 #define ARY_INCREASE_LEN(ary, n) do { \
118 assert(!OBJ_FROZEN(ary)); \
119 if (ARY_EMBED_P(ary)) { \
120 ARY_SET_EMBED_LEN((ary), RARRAY_LEN(ary)+(n)); \
123 RARRAY(ary)->as.heap.len += (n); \
127 #define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? RARRAY_EMBED_LEN_MAX : \
128 ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : ARY_HEAP_CAPA(ary))
129 #define ARY_SET_CAPA(ary, n) do { \
130 assert(!ARY_EMBED_P(ary)); \
131 assert(!ARY_SHARED_P(ary)); \
132 assert(!OBJ_FROZEN(ary)); \
133 RARRAY(ary)->as.heap.aux.capa = (n); \
136 #define ARY_SHARED_ROOT(ary) (assert(ARY_SHARED_P(ary)), RARRAY(ary)->as.heap.aux.shared_root)
137 #define ARY_SET_SHARED(ary, value) do { \
138 const VALUE _ary_ = (ary); \
139 const VALUE _value_ = (value); \
140 assert(!ARY_EMBED_P(_ary_)); \
141 assert(ARY_SHARED_P(_ary_)); \
142 assert(ARY_SHARED_ROOT_P(_value_)); \
143 RB_OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared_root, _value_); \
145 #define RARRAY_SHARED_ROOT_FLAG FL_USER5
146 #define ARY_SHARED_ROOT_P(ary) (assert(should_be_T_ARRAY((VALUE)(ary))), \
147 FL_TEST_RAW((ary), RARRAY_SHARED_ROOT_FLAG))
148 #define ARY_SHARED_ROOT_REFCNT(ary) \
149 (assert(ARY_SHARED_ROOT_P(ary)), RARRAY(ary)->as.heap.aux.capa)
150 #define ARY_SHARED_ROOT_OCCUPIED(ary) (ARY_SHARED_ROOT_REFCNT(ary) == 1)
151 #define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \
152 assert(ARY_SHARED_ROOT_P(ary)); \
153 RARRAY(ary)->as.heap.aux.capa = (value); \
155 #define FL_SET_SHARED_ROOT(ary) do { \
156 assert(!ARY_EMBED_P(ary)); \
157 assert(!RARRAY_TRANSIENT_P(ary)); \
158 FL_SET((ary), RARRAY_SHARED_ROOT_FLAG); \
173 #define ary_verify(ary) ary_verify_(ary, __FILE__, __LINE__)
176 ary_verify_(
VALUE ary,
const char *file,
int line)
200 for (i=0; i<
len; i++) {
217 rb_ary_verify(
VALUE ary)
222 #define ary_verify(ary) ((void)0)
251 ary_mem_clear(
VALUE ary,
long beg,
long size)
259 memfill(
register VALUE *mem,
register long size,
register VALUE val)
289 for (i=0; i<
argc; i++) {
299 ary_memcpy0(ary, beg,
argc,
argv, ary);
303 ary_heap_alloc(
VALUE ary,
size_t capa)
330 ary_heap_free(
VALUE ary)
341 ary_heap_realloc(
VALUE ary,
size_t new_capa)
346 if (new_capa <= old_capa) {
352 if (new_ptr ==
NULL) {
367 #if USE_TRANSIENT_HEAP
369 rb_ary_transient_heap_evacuate_(
VALUE ary,
int transient,
int promote)
390 new_ptr = ary_heap_alloc(ary, capa);
395 RARRAY(ary)->as.heap.ptr = new_ptr;
411 rb_ary_transient_heap_evacuate_(ary,
TRUE,
TRUE);
422 ary_resize_capa(
VALUE ary,
long capacity)
431 VALUE *
ptr = ary_heap_alloc(ary, capacity);
439 ary_heap_realloc(ary, capacity);
449 if (
len > capacity)
len = capacity;
451 ary_heap_free_ptr(ary,
ptr, old_capa);
462 ary_shrink_capa(
VALUE ary)
467 assert(old_capa >= capacity);
468 if (old_capa > capacity) ary_heap_realloc(ary, capacity);
474 ary_double_capa(
VALUE ary,
long min)
485 ary_resize_capa(ary, new_capa);
491 rb_ary_decrement_share(
VALUE shared_root)
506 rb_ary_unshare(
VALUE ary)
508 VALUE shared_root =
RARRAY(ary)->as.heap.aux.shared_root;
509 rb_ary_decrement_share(shared_root);
514 rb_ary_unshare_safe(
VALUE ary)
522 rb_ary_increment_share(
VALUE shared_root)
532 rb_ary_set_shared(
VALUE ary,
VALUE shared_root)
534 rb_ary_increment_share(shared_root);
541 rb_ary_modify_check(
VALUE ary)
550 rb_ary_modify_check(ary);
562 rb_ary_decrement_share(shared_root);
574 rb_ary_decrement_share(shared_root);
590 ary_ensure_room_for_push(
VALUE ary,
long add_len)
593 long new_len = old_len + add_len;
604 rb_ary_modify_check(ary);
614 if (new_len > capa - (capa >> 6)) {
615 ary_double_capa(ary, new_len);
626 rb_ary_modify_check(ary);
629 if (new_len > capa) {
630 ary_double_capa(ary, new_len);
665 RARRAY(ary1)->as.heap.aux.shared_root ==
RARRAY(ary2)->as.heap.aux.shared_root &&
666 RARRAY(ary1)->as.heap.len ==
RARRAY(ary2)->as.heap.len) {
673 ary_alloc(
VALUE klass)
684 empty_ary_alloc(
VALUE klass)
687 return ary_alloc(klass);
691 ary_new(
VALUE klass,
long capa)
704 ary = ary_alloc(klass);
706 ptr = ary_heap_alloc(ary, capa);
738 for (i=0; i<n; i++) {
739 ARY_SET(ary, i, va_arg(ar,
VALUE));
752 ary = ary_new(klass, n);
754 ary_memcpy(ary, 0, n, elts);
770 VALUE ary = ary_new(0, capa);
778 VALUE ary = ary_new(0, capa);
779 ary_memfill(ary, 0, capa,
Qnil);
827 ary_discard(
VALUE ary)
835 ary_make_shared(
VALUE ary)
848 ary_shrink_capa(ary);
875 return (
VALUE)shared;
880 ary_make_substitution(
VALUE ary)
891 return rb_ary_increment_share(ary_make_shared(ary));
906 #define to_ary rb_to_array_type
1012 rb_ary_unshare_safe(ary);
1039 ary_resize_capa(ary,
len);
1044 rb_warn(
"block supersedes default value argument");
1046 for (i=0; i<
len; i++) {
1052 ary_memfill(ary, 0,
len, val);
1096 ary_double_capa(ary, idx);
1099 ary_mem_clear(ary,
len, idx -
len + 1);
1105 ARY_SET(ary, idx, val);
1109 ary_make_partial(
VALUE ary,
VALUE klass,
long offset,
long len)
1116 VALUE result = ary_alloc(klass);
1122 VALUE shared, result = ary_alloc(klass);
1125 shared = ary_make_shared(ary);
1128 rb_ary_set_shared(result, shared);
1140 ary_make_shared_copy(
VALUE ary)
1175 return ary_make_partial(ary,
rb_cArray, offset, n);
1198 VALUE target_ary = ary_ensure_room_for_push(ary, 1);
1211 VALUE target_ary = ary_ensure_room_for_push(ary,
len);
1212 ary_memcpy0(ary, oldlen,
len,
argv, target_ary);
1244 rb_ary_modify_check(ary);
1246 if (n == 0)
return Qnil;
1251 ary_resize_capa(ary, n * 2);
1286 rb_ary_modify_check(ary);
1299 rb_ary_modify_check(ary);
1313 ARY_SET(ary, 0,
Qnil);
1314 ary_make_shared(ary);
1360 rb_ary_modify_check(ary);
1371 if (n<=0)
return ary;
1373 rb_ary_modify_check(ary);
1376 setup_occupied_shared:
1377 ary_mem_clear(ary, 0, n);
1388 ary_make_shared(ary);
1389 goto setup_occupied_shared;
1399 ary_ensure_room_for_unshift(
VALUE ary,
int argc)
1404 const VALUE *head, *sharedp;
1414 rb_ary_modify_check(ary);
1417 goto makeroom_if_need;
1423 if (capa - (capa >> 6) <= new_len) {
1424 ary_double_capa(ary, new_len);
1433 ary_make_shared(ary);
1438 if (head - sharedp <
argc) {
1441 room = capa - new_len;
1444 head = sharedp +
argc + room;
1483 rb_ary_modify_check(ary);
1487 target_ary = ary_ensure_room_for_unshift(ary,
argc);
1488 ary_memcpy0(ary, 0,
argc,
argv, target_ary);
1496 return rb_ary_unshift_m(1,&item,ary);
1501 rb_ary_elt(
VALUE ary,
long offset)
1505 if (offset < 0 ||
len <= offset) {
1514 return rb_ary_entry_internal(ary, offset);
1523 if (beg > alen)
return Qnil;
1524 if (beg < 0 ||
len < 0)
return Qnil;
1526 if (alen <
len || alen < beg +
len) {
1530 if (
len == 0)
return ary_new(klass, 0);
1532 return ary_make_partial(ary, klass, beg,
len);
1578 return rb_ary_aref2(ary,
argv[0],
argv[1]);
1722 if (block_given &&
argc == 2) {
1723 rb_warn(
"block supersedes default value argument");
1731 if (block_given)
return rb_yield(pos);
1785 rb_warn(
"given block not used");
1839 rb_warn(
"given block not used");
1857 if (!
NIL_P(tmp))
return tmp;
1862 rb_ary_splice(
VALUE ary,
long beg,
long len,
const VALUE *rptr,
long rlen)
1876 if (olen <
len || olen < beg +
len) {
1882 rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1;
1890 target_ary = ary_ensure_room_for_push(ary, rlen-
len);
1892 ary_mem_clear(ary, olen, beg - olen);
1895 ary_memcpy0(ary, beg, rlen, rptr, target_ary);
1906 alen = olen + rlen -
len;
1908 ary_double_capa(ary, alen);
1936 rb_ary_modify_check(ary);
1941 rb_bug(
"probable buffer overflow: %ld for %ld",
len, capa);
1961 if (
len == olen)
return ary;
1967 ary_double_capa(ary,
len);
1969 ary_mem_clear(ary, olen,
len - olen);
1984 ary_heap_realloc(ary,
len);
2031 long offset, beg,
len;
2035 rb_ary_modify_check(ary);
2041 rb_ary_modify_check(ary);
2083 rb_ary_modify_check(ary);
2085 if (
argc == 1)
return ary;
2097 rb_ary_splice(ary, pos, 0,
argv + 1,
argc - 1);
2102 rb_ary_length(
VALUE ary);
2107 return rb_ary_length(ary);
2159 rb_ary_each_index(
VALUE ary)
2186 rb_ary_reverse_each(
VALUE ary)
2214 rb_ary_length(
VALUE ary)
2230 rb_ary_empty_p(
VALUE ary)
2266 VALUE result = arg[2];
2267 int *first = (
int *)arg[3];
2273 ary_join_1(obj, ary, sep, 0, result, first);
2285 for (i=0; i<max; i++) {
2287 if (i > 0 && !
NIL_P(sep))
2299 if (i > 0 && !
NIL_P(sep))
2324 args[3] = (
VALUE)first;
2350 VALUE val, tmp, result;
2362 if (
NIL_P(tmp) || tmp != val) {
2366 ary_join_0(ary, sep, i, result);
2368 ary_join_1(ary, ary, sep, i, result, &first);
2378 ary_join_0(ary, sep,
RARRAY_LEN(ary), result);
2409 rb_warn(
"$, is set to non-nil value");
2446 rb_ary_inspect(
VALUE ary)
2455 return rb_ary_inspect(ary);
2468 rb_ary_to_a(
VALUE ary)
2497 rb_ary_to_h(
VALUE ary)
2504 const VALUE e = rb_ary_elt(ary, i);
2507 if (
NIL_P(key_value_pair)) {
2528 rb_ary_to_ary_m(
VALUE ary)
2553 ary_reverse(p1, p2);
2571 rb_ary_reverse_bang(
VALUE ary)
2587 rb_ary_reverse_m(
VALUE ary)
2595 do *p2-- = *p1++;
while (--
len > 0);
2602 rotate_count(
long cnt,
long len)
2700 sort_reentered(
VALUE ary)
2702 if (
RBASIC(ary)->klass) {
2709 sort_1(
const void *ap,
const void *
bp,
void *dummy)
2712 VALUE retval = sort_reentered(data->
ary);
2721 sort_reentered(data->
ary);
2726 sort_2(
const void *ap,
const void *
bp,
void *dummy)
2729 VALUE retval = sort_reentered(data->
ary);
2734 if ((
long)a > (long)b)
return 1;
2735 if ((
long)a < (long)b)
return -1;
2747 sort_reentered(data->
ary);
2782 VALUE tmp = ary_make_substitution(
ary);
2796 rb_ary_unshare(
ary);
2814 rb_ary_unshare(
ary);
2931 VALUE index_result = rb_ary_bsearch_index(
ary);
2936 return index_result;
2956 int smaller = 0, satisfied = 0;
2960 while (low < high) {
2961 mid = low + ((high - low) / 2);
2968 else if (v ==
Qtrue) {
2979 case 1: smaller = 1;
break;
2980 case -1: smaller = 0;
2985 " (must be numeric, true, false or nil)",
2995 if (!satisfied)
return Qnil;
3109 long beg,
len, i, j;
3111 for (i=0; i<
argc; i++) {
3118 long end = olen < beg+
len ? olen : beg+
len;
3119 for (j = beg; j < end; j++) {
3142 const long end = beg +
len;
3182 for (i = 0; i <
argc; ++i) {
3183 append_values_at_single(result,
ary, olen,
argv[i]);
3234 select_bang_i(
VALUE a)
3248 return (i1 == i2) ?
Qnil :
ary;
3252 select_bang_ensure(
VALUE a)
3257 long i1 = arg->
len[0], i2 = arg->
len[1];
3259 if (i2 <
len && i2 < i1) {
3302 args.len[0] = args.len[1] = 0;
3327 rb_ary_select_bang(
ary);
3339 ary_resize_capa(
ary,
len * 2);
3389 ary_resize_smaller(
ary, i2);
3415 ary_resize_smaller(
ary, i2);
3427 if (pos < 0)
return Qnil;
3486 long pos,
len, orig_len;
3488 rb_ary_modify_check(
ary);
3497 if (pos < 0)
return Qnil;
3499 else if (orig_len < pos)
return Qnil;
3500 if (orig_len < pos +
len) {
3501 len = orig_len - pos;
3506 rb_ary_splice(
ary, pos,
len, 0, 0);
3517 goto delete_pos_len;
3546 reject_bang_i(
VALUE a)
3560 return (i1 == i2) ?
Qnil :
ary;
3567 rb_ary_modify_check(
ary);
3569 args.len[0] = args.len[1] = 0;
3593 return ary_reject_bang(
ary);
3616 ary_reject(
ary, rejected_ary);
3617 return rejected_ary;
3643 ary_reject_bang(
ary);
3659 take_items(
VALUE obj,
long n)
3666 args[0] = result; args[1] = (
VALUE)n;
3705 for (i=0; i<
argc; i++) {
3719 for (j=0; j<
argc; j++) {
3720 tmp[j+1] = rb_ary_elt(
argv[j], i);
3732 for (j=0; j<
argc; j++) {
3742 for (i=0; i<
len; i++) {
3746 for (j=0; j<
argc; j++) {
3772 long elen = -1, alen, i, j;
3773 VALUE tmp, result = 0;
3777 for (i=0; i<alen; i++) {
3782 for (j=0; j<elen; j++) {
3790 for (j=0; j<elen; j++) {
3791 rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
3813 rb_ary_modify_check(copy);
3815 if (copy == orig)
return copy;
3818 VALUE shared_root = 0;
3821 ary_heap_free(copy);
3830 rb_ary_decrement_share(shared_root);
3835 VALUE shared_root = ary_make_shared(orig);
3837 ary_heap_free(copy);
3840 rb_ary_unshare_safe(copy);
3845 rb_ary_set_shared(copy, shared_root);
3864 rb_ary_modify_check(
ary);
3867 rb_ary_unshare(
ary);
3916 long beg = 0, end = 0,
len = 0;
3939 if (beg < 0) beg = 0;
3954 ary_resize_capa(
ary, end);
3964 for (i=beg; i<end; i++) {
3971 ary_memfill(
ary, beg,
len, item);
4003 long len, xlen, ylen;
4050 rb_ary_modify_check(
ary);
4055 else if (
argc > 1) {
4058 for (i = 0; i <
argc; i++) {
4061 ary_append(
ary, args);
4071 return ary_append(x,
to_ary(y));
4122 ary_memcpy(ary2, 0, t,
ptr);
4123 while (t <=
len/2) {
4208 const VALUE *p1, *p2;
4217 for (i = 0; i < len1; i++) {
4255 if (ary1 == ary2)
return Qtrue;
4274 if (!
rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
4291 if (ary1 == ary2)
return Qtrue;
4379 for (i=0; i<
len; i++) {
4380 VALUE e1 = rb_ary_elt(ary1, i), e2 = rb_ary_elt(ary2, i);
4427 if (ary1 == ary2)
return INT2FIX(0);
4429 if (v !=
Qundef)
return v;
4461 VALUE hash = ary_tmp_hash_new(
ary);
4462 return ary_add_hash(hash,
ary);
4480 VALUE hash = ary_tmp_hash_new(
ary);
4481 return ary_add_hash_by(hash,
ary);
4485 ary_recycle_hash(
VALUE hash)
4530 VALUE elt = rb_ary_elt(ary1, i);
4531 if (rb_ary_includes_by_eql(ary2, elt))
continue;
4537 hash = ary_make_hash(ary2);
4542 ary_recycle_hash(hash);
4585 for (i = 0; i <
argc; i++) {
4588 if (is_hash[i])
argv[i] = ary_make_hash(
argv[i]);
4594 for (j = 0; j <
argc; j++) {
4600 if (rb_ary_includes_by_eql(
argv[j], elt))
break;
4631 VALUE hash, ary3, v;
4642 if (!rb_ary_includes_by_eql(ary2, v))
continue;
4643 if (rb_ary_includes_by_eql(ary3, v))
continue;
4649 hash = ary_make_hash(ary2);
4658 ary_recycle_hash(hash);
4686 for (i = 0; i <
argc; i++) {
4687 result = rb_ary_and(result,
argv[i]);
4707 if (rb_ary_includes_by_eql(ary_union, elt))
continue;
4747 rb_ary_union(ary3, ary1);
4748 rb_ary_union(ary3, ary2);
4752 hash = ary_make_hash(ary1);
4753 rb_ary_union_hash(hash, ary2);
4756 ary_recycle_hash(hash);
4781 VALUE hash, ary_union;
4784 for (i = 0; i <
argc; i++) {
4792 rb_ary_union(ary_union,
ary);
4793 for (i = 0; i <
argc; i++) rb_ary_union(ary_union,
argv[i]);
4798 hash = ary_make_hash(
ary);
4799 for (i = 0; i <
argc; i++) rb_ary_union_hash(hash,
argv[i]);
4802 ary_recycle_hash(hash);
4924 rb_ary_minmax(
VALUE ary)
4929 return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));
4967 rb_ary_uniq_bang(
VALUE ary)
4972 rb_ary_modify_check(ary);
4976 hash = ary_make_hash_by(ary);
4978 hash = ary_make_hash(ary);
4984 rb_ary_modify_check(ary);
4987 rb_ary_unshare(ary);
4990 ary_resize_capa(ary, hash_size);
4992 ary_recycle_hash(hash);
5019 rb_ary_uniq(
VALUE ary)
5028 hash = ary_make_hash_by(ary);
5032 hash = ary_make_hash(ary);
5037 ary_recycle_hash(hash);
5056 rb_ary_compact_bang(
VALUE ary)
5073 ary_resize_smaller(ary, n);
5089 rb_ary_compact(
VALUE ary)
5092 rb_ary_compact_bang(ary);
5137 rb_warn(
"given block not used");
5148 flatten(
VALUE ary,
int level)
5151 VALUE stack, result, tmp, elt, vmemo;
5164 }
else if (tmp == ary) {
5189 if (level >= 0 &&
RARRAY_LEN(stack) / 2 >= level) {
5194 if (
RBASIC(result)->klass) {
5254 int mod = 0, level = -1;
5258 rb_ary_modify_check(ary);
5260 if (level == 0)
return Qnil;
5262 result = flatten(ary, level);
5263 if (result == ary) {
5303 if (level == 0)
return ary_make_shared_copy(ary);
5306 result = flatten(ary, level);
5307 if (result == ary) {
5308 result = ary_make_shared_copy(ary);
5314 #define OPTHASH_GIVEN_P(opts) \
5315 (argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
5316 static ID id_random;
5318 #define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)
5346 keyword_ids[0] = id_random;
5391 rb_ary_shuffle_bang(
argc,
argv, ary);
5428 long n,
len, i, j, k, idx[10];
5430 long memo_threshold;
5436 keyword_ids[0] = id_random;
5449 return rb_ary_elt(ary, i);
5456 for (i = 0; i < n; ++i) {
5463 for (i = 0; i < n; ++i) {
5485 if (j >= i) l = i, g = ++j;
5486 if (k >= l && (++k >= g)) ++k;
5497 sorted[0] = idx[0] = rnds[0];
5498 for (i=1; i<n; i++) {
5500 for (j = 0; j < i; ++j) {
5501 if (k < sorted[j])
break;
5504 memmove(&sorted[j+1], &sorted[j],
sizeof(sorted[0])*(i-j));
5505 sorted[j] = idx[i] = k;
5509 for (i=0; i<n; i++) {
5514 else if (n <= memo_threshold / 2) {
5516 #undef RUBY_UNTYPED_DATA_WARNING
5517 #define RUBY_UNTYPED_DATA_WARNING 0
5523 for (i=0; i<n; i++) {
5526 if (r > max_idx) max_idx = r;
5529 if (
len <= max_idx) n = 0;
5530 else if (n >
len) n =
len;
5532 for (i=0; i<n; i++) {
5533 long j2 = j = ptr_result[i];
5539 ptr_result[i] = ptr_ary[j2];
5551 for (i=0; i<n; i++) {
5554 ptr_result[j] = ptr_result[i];
5578 return rb_fix_mul_fix(rb_ary_length(
self), n);
5614 if (n <= 0)
return Qnil;
5617 while (
RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
5625 #define tmpary(n) rb_ary_tmp_new(n)
5626 #define tmpary_discard(a) (ary_discard(a), RBASIC_SET_CLASS_RAW(a, rb_cArray))
5634 yield_indexed_values(
const VALUE values,
const long r,
const long *
const p)
5639 for (i = 0; i < r; i++) ARY_SET(result, i,
RARRAY_AREF(values, p[i]));
5642 return !
RBASIC(values)->klass;
5658 permute0(
const long n,
const long r,
long *
const p,
char *
const used,
const VALUE values)
5660 long i = 0, index = 0;
5663 const char *
const unused = memchr(&used[i], 0, n-i);
5678 for (i = 0; i < n; ++i) {
5679 if (used[i])
continue;
5681 if (!yield_indexed_values(values, r, p)) {
5697 descending_factorial(
long from,
long how_many)
5702 while (--how_many > 0) {
5714 binomial_coefficient(
long comb,
long size)
5718 if (comb >
size-comb) {
5724 else if (comb == 0) {
5728 for (i = 1; i < comb; ++i) {
5741 return descending_factorial(n, k);
5783 if (r < 0 || n < r) {
5797 char *used = (
char*)(p + r);
5798 VALUE ary0 = ary_make_shared_copy(ary);
5803 permute0(n, r, p, used, ary0);
5811 combinate0(
const long len,
const long n,
long *
const stack,
const VALUE values)
5818 for (lev++; lev < n; lev++) {
5819 stack[lev+1] = stack[lev]+1;
5821 if (!yield_indexed_values(values, n, stack+1)) {
5825 if (lev == 0)
return;
5827 }
while (stack[lev+1]+n ==
len+lev+1);
5837 return binomial_coefficient(k, n);
5873 if (n < 0 ||
len < n) {
5885 VALUE ary0 = ary_make_shared_copy(ary);
5887 long *stack =
ALLOCV_N(
long, t0, n+1);
5890 combinate0(
len, n, stack, ary0);
5910 rpermute0(
const long n,
const long r,
long *
const p,
const VALUE values)
5912 long i = 0, index = 0;
5916 if (++index < r-1) {
5920 for (i = 0; i < n; ++i) {
5922 if (!yield_indexed_values(values, r, p)) {
5927 if (index <= 0)
return;
5928 }
while ((i = ++p[--index]) >= n);
5971 rb_ary_repeated_permutation(
VALUE ary,
VALUE num)
5993 VALUE ary0 = ary_make_shared_copy(ary);
5996 rpermute0(n, r, p, ary0);
6004 rcombinate0(
const long n,
const long r,
long *
const p,
const long rest,
const VALUE values)
6006 long i = 0, index = 0;
6010 if (++index < r-1) {
6014 for (; i < n; ++i) {
6016 if (!yield_indexed_values(values, r, p)) {
6021 if (index <= 0)
return;
6022 }
while ((i = ++p[--index]) >= n);
6034 return binomial_coefficient(k, n + k - 1);
6065 rb_ary_repeated_combination(
VALUE ary,
VALUE num)
6083 else if (
len == 0) {
6089 VALUE ary0 = ary_make_shared_copy(ary);
6092 rcombinate0(
len, n, p, n, ary0);
6127 int *counters =
ALLOCV_N(
int, t1, n);
6137 for (i = 1; i < n; i++) arrays[i] =
Qnil;
6138 for (i = 1; i < n; i++) arrays[i] =
to_ary(
argv[i-1]);
6141 for (i = 0; i < n; i++) counters[i] = 0;
6146 for (i = 0; i < n; i++) {
6148 arrays[i] = ary_make_shared_copy(arrays[i]);
6153 for (i = 0; i < n; i++) {
6169 for (j = 0; j < n; j++) {
6174 if (
NIL_P(result)) {
6194 while (counters[m] ==
RARRAY_LEN(arrays[m])) {
6197 if (--m < 0)
goto done;
6205 return NIL_P(result) ? ary : result;
6251 rb_ary_take_while(
VALUE ary)
6259 return rb_ary_take(ary,
LONG2FIX(i));
6311 rb_ary_drop_while(
VALUE ary)
6319 return rb_ary_drop(ary,
LONG2FIX(i));
6339 rb_warn(
"given block not used");
6346 for (i = 0; i <
len; ++i) {
6375 rb_warn(
"given block not used");
6382 for (i = 0; i <
len; ++i) {
6411 rb_warn(
"given block not used");
6418 for (i = 0; i <
len; ++i) {
6448 rb_warn(
"given block not used");
6452 if (result)
return Qfalse;
6458 for (i = 0; i <
len; ++i) {
6460 if (result)
return Qfalse;
6468 if (result)
return Qfalse;
6497 if (!--
argc)
return self;
6503 finish_exact_sum(
long n,
VALUE r,
VALUE v,
int z)
6602 v = finish_exact_sum(n, r, v,
argc!=0);
6606 v = finish_exact_sum(n, r, v, i!=0);
6618 goto has_float_value;
6650 if (fabs(
f) >= fabs(x))
6663 goto has_some_value;
6675 rb_ary_deconstruct(
VALUE ary)
6922 #define rb_intern(str) rb_intern_const(str)