31 #define ARY_DEFAULT_SIZE 16    32 #define ARY_MAX_SIZE (LONG_MAX / (int)sizeof(VALUE))    33 #define SMALL_ARRAY_LEN 16    35 # define ARY_SHARED_P(ary) \    36     (assert(!FL_TEST((ary), ELTS_SHARED) || !FL_TEST((ary), RARRAY_EMBED_FLAG)), \    37      FL_TEST((ary),ELTS_SHARED)!=0)    38 # define ARY_EMBED_P(ary) \    39     (assert(!FL_TEST((ary), ELTS_SHARED) || !FL_TEST((ary), RARRAY_EMBED_FLAG)), \    40      FL_TEST((ary), RARRAY_EMBED_FLAG)!=0)    42 #define ARY_HEAP_PTR(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr)    43 #define ARY_HEAP_LEN(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len)    44 #define ARY_EMBED_PTR(a) (assert(ARY_EMBED_P(a)), RARRAY(a)->as.ary)    45 #define ARY_EMBED_LEN(a) \    46     (assert(ARY_EMBED_P(a)), \    47      (long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \    48          (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)))    49 #define ARY_HEAP_SIZE(a) (assert(!ARY_EMBED_P(a)), assert(ARY_OWNS_HEAP_P(a)), RARRAY(a)->as.heap.aux.capa * sizeof(VALUE))    51 #define ARY_OWNS_HEAP_P(a) (!FL_TEST((a), ELTS_SHARED|RARRAY_EMBED_FLAG))    52 #define FL_SET_EMBED(a) do { \    53     assert(!ARY_SHARED_P(a)); \    54     FL_SET((a), RARRAY_EMBED_FLAG); \    56 #define FL_UNSET_EMBED(ary) FL_UNSET((ary), RARRAY_EMBED_FLAG|RARRAY_EMBED_LEN_MASK)    57 #define FL_SET_SHARED(ary) do { \    58     assert(!ARY_EMBED_P(ary)); \    59     FL_SET((ary), ELTS_SHARED); \    61 #define FL_UNSET_SHARED(ary) FL_UNSET((ary), ELTS_SHARED)    63 #define ARY_SET_PTR(ary, p) do { \    64     assert(!ARY_EMBED_P(ary)); \    65     assert(!OBJ_FROZEN(ary)); \    66     RARRAY(ary)->as.heap.ptr = (p); \    68 #define ARY_SET_EMBED_LEN(ary, n) do { \    70     assert(ARY_EMBED_P(ary)); \    71     assert(!OBJ_FROZEN(ary)); \    72     RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK; \    73     RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT; \    75 #define ARY_SET_HEAP_LEN(ary, n) do { \    76     assert(!ARY_EMBED_P(ary)); \    77     RARRAY(ary)->as.heap.len = (n); \    79 #define ARY_SET_LEN(ary, n) do { \    80     if (ARY_EMBED_P(ary)) { \    81         ARY_SET_EMBED_LEN((ary), (n)); \    84         ARY_SET_HEAP_LEN((ary), (n)); \    86     assert(RARRAY_LEN(ary) == (n)); \    88 #define ARY_INCREASE_PTR(ary, n) do  { \    89     assert(!ARY_EMBED_P(ary)); \    90     assert(!OBJ_FROZEN(ary)); \    91     RARRAY(ary)->as.heap.ptr += (n); \    93 #define ARY_INCREASE_LEN(ary, n) do  { \    94     assert(!OBJ_FROZEN(ary)); \    95     if (ARY_EMBED_P(ary)) { \    96         ARY_SET_EMBED_LEN((ary), RARRAY_LEN(ary)+(n)); \    99         RARRAY(ary)->as.heap.len += (n); \   103 #define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? RARRAY_EMBED_LEN_MAX : \   104                        ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : RARRAY(ary)->as.heap.aux.capa)   105 #define ARY_SET_CAPA(ary, n) do { \   106     assert(!ARY_EMBED_P(ary)); \   107     assert(!ARY_SHARED_P(ary)); \   108     assert(!OBJ_FROZEN(ary)); \   109     RARRAY(ary)->as.heap.aux.capa = (n); \   112 #define ARY_SHARED(ary) (assert(ARY_SHARED_P(ary)), RARRAY(ary)->as.heap.aux.shared)   113 #define ARY_SET_SHARED(ary, value) do { \   114     const VALUE _ary_ = (ary); \   115     const VALUE _value_ = (value); \   116     assert(!ARY_EMBED_P(_ary_)); \   117     assert(ARY_SHARED_P(_ary_)); \   118     assert(ARY_SHARED_ROOT_P(_value_)); \   119     RB_OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared, _value_); \   121 #define RARRAY_SHARED_ROOT_FLAG FL_USER5   122 #define ARY_SHARED_ROOT_P(ary) (FL_TEST((ary), RARRAY_SHARED_ROOT_FLAG))   123 #define ARY_SHARED_NUM(ary) \   124     (assert(ARY_SHARED_ROOT_P(ary)), RARRAY(ary)->as.heap.aux.capa)   125 #define ARY_SHARED_OCCUPIED(ary) (ARY_SHARED_NUM(ary) == 1)   126 #define ARY_SET_SHARED_NUM(ary, value) do { \   127     assert(ARY_SHARED_ROOT_P(ary)); \   128     RARRAY(ary)->as.heap.aux.capa = (value); \   130 #define FL_SET_SHARED_ROOT(ary) do { \   131     assert(!ARY_EMBED_P(ary)); \   132     FL_SET((ary), RARRAY_SHARED_ROOT_FLAG); \   135 #define ARY_SET(a, i, v) RARRAY_ASET((assert(!ARY_SHARED_P(a)), (a)), (i), (v))   146 ary_mem_clear(
VALUE ary, 
long beg, 
long size)
   165         memfill(ptr + beg, 
size, val);
   185             for (i=0; i<
argc; i++) {
   200     ary_memcpy0(ary, beg, 
argc, argv, ary);
   204 ary_resize_capa(
VALUE ary, 
long capacity)
   228             if (len > capacity) len = capacity;
   238 ary_shrink_capa(
VALUE ary)
   241     long old_capa = 
RARRAY(ary)->as.heap.aux.capa;
   243     assert(old_capa >= capacity);
   244     if (old_capa > capacity)
   249 ary_double_capa(
VALUE ary, 
long min)
   260     ary_resize_capa(ary, new_capa);
   264 rb_ary_decrement_share(
VALUE shared)
   279 rb_ary_unshare(
VALUE ary)
   282     rb_ary_decrement_share(shared);
   287 rb_ary_unshare_safe(
VALUE ary)
   295 rb_ary_increment_share(
VALUE shared)
   307     rb_ary_increment_share(shared);
   313 rb_ary_modify_check(
VALUE ary)
   321     rb_ary_modify_check(ary);
   330             rb_ary_decrement_share(shared);
   342             rb_ary_decrement_share(shared);
   357 ary_ensure_room_for_push(
VALUE ary, 
long add_len)
   360     long new_len = old_len + add_len;
   371                     rb_ary_modify_check(ary);
   378                     if (new_len > capa - (capa >> 6)) {
   379                         ary_double_capa(ary, new_len);
   388         rb_ary_modify_check(ary);
   391     if (new_len > capa) {
   392         ary_double_capa(ary, new_len);
   423 rb_ary_frozen_p(
VALUE ary)
   441         RARRAY(ary1)->as.heap.aux.shared == 
RARRAY(ary2)->as.heap.aux.shared &&
   442         RARRAY(ary1)->as.heap.len == 
RARRAY(ary2)->as.heap.len) {
   449 ary_alloc(
VALUE klass)
   460 empty_ary_alloc(
VALUE klass)
   463     return ary_alloc(klass);
   467 ary_new(
VALUE klass, 
long capa)
   480     ary = ary_alloc(klass);
   514     for (i=0; i<n; i++) {
   528     ary = ary_new(klass, n);
   530         ary_memcpy(ary, 0, n, elts);
   546     return ary_new(0, capa);
   552     VALUE ary = ary_new(0, capa);
   553     ary_memfill(ary, 0, capa, 
Qnil);
   582 ary_discard(
VALUE ary)
   590 ary_make_shared(
VALUE ary)
   600         ary_shrink_capa(ary);
   618         return (
VALUE)shared;
   623 ary_make_substitution(
VALUE ary)
   634         return rb_ary_increment_share(ary_make_shared(ary));
   748         rb_ary_unshare_safe(ary);
   775     ary_resize_capa(ary, len);
   780             rb_warn(
"block supersedes default value argument");
   782         for (i=0; i<
len; i++) {
   788         ary_memfill(ary, 0, len, val);
   803 rb_ary_s_create(
int argc, 
VALUE *argv, 
VALUE klass)
   805     VALUE ary = ary_new(klass, argc);
   806     if (argc > 0 && argv) {
   807         ary_memcpy(ary, 0, argc, argv);
   832         ary_double_capa(ary, idx);
   835         ary_mem_clear(ary, len, idx - len + 1);
   845 ary_make_partial(
VALUE ary, 
VALUE klass, 
long offset, 
long len)
   852         VALUE result = ary_alloc(klass);
   858         VALUE shared, result = ary_alloc(klass);
   861         shared = ary_make_shared(ary);
   864         rb_ary_set_shared(result, shared);
   873 ary_make_shared_copy(
VALUE ary)
   904     return ary_make_partial(ary, 
rb_cArray, offset, n);
   927     VALUE target_ary = ary_ensure_room_for_push(ary, 1);
   939     VALUE target_ary = ary_ensure_room_for_push(ary, len);
   940     ary_memcpy0(ary, oldlen, len, argv, target_ary);
   962 rb_ary_push_m(
int argc, 
VALUE *argv, 
VALUE ary)
   971     rb_ary_modify_check(ary);
   973     if (n == 0) 
return Qnil;
   978         ary_resize_capa(ary, n * 2);
  1004 rb_ary_pop_m(
int argc, 
VALUE *argv, 
VALUE ary)
  1012     rb_ary_modify_check(ary);
  1013     result = ary_take_first_or_last(argc, argv, ary, 
ARY_TAKE_LAST);
  1024     rb_ary_modify_check(ary);
  1025     if (len == 0) 
return Qnil;
  1038         ary_make_shared(ary);
  1073 rb_ary_shift_m(
int argc, 
VALUE *argv, 
VALUE ary)
  1082     rb_ary_modify_check(ary);
  1083     result = ary_take_first_or_last(argc, argv, ary, 
ARY_TAKE_FIRST);
  1087           setup_occupied_shared:
  1088             ary_mem_clear(ary, 0, n);
  1099             ary_make_shared(ary);
  1100             goto setup_occupied_shared;
  1109 ary_ensure_room_for_unshift(
VALUE ary, 
int argc)
  1112     long new_len = len + 
argc;
  1114     const VALUE *head, *sharedp;
  1126             goto makeroom_if_need;
  1132     if (capa - (capa >> 6) <= new_len) {
  1133         ary_double_capa(ary, new_len);
  1140         ary_make_shared(ary);
  1145         if (head - sharedp < argc) {
  1148             room = capa - new_len;
  1151             head = sharedp + argc + room;
  1180 rb_ary_unshift_m(
int argc, 
VALUE *argv, 
VALUE ary)
  1186         rb_ary_modify_check(ary);
  1190     target_ary = ary_ensure_room_for_unshift(ary, argc);
  1191     ary_memcpy0(ary, 0, argc, argv, target_ary);
  1199     return rb_ary_unshift_m(1,&item,ary);
  1204 rb_ary_elt(
VALUE ary, 
long offset)
  1207     if (len == 0) 
return Qnil;
  1208     if (offset < 0 || len <= offset) {
  1219     if (len == 0) 
return Qnil;
  1222         if (offset < 0) 
return Qnil;
  1224     else if (len <= offset) {
  1236     if (beg > alen) 
return Qnil;
  1237     if (beg < 0 || len < 0) 
return Qnil;
  1239     if (alen < len || alen < beg + len) {
  1243     if (len == 0) 
return ary_new(klass, 0);
  1245     return ary_make_partial(ary, klass, beg, len);
  1353 rb_ary_first(
int argc, 
VALUE *argv, 
VALUE ary)
  1384         if (len == 0) 
return Qnil;
  1388         return ary_take_first_or_last(argc, argv, ary, 
ARY_TAKE_LAST);
  1417 rb_ary_fetch(
int argc, 
VALUE *argv, 
VALUE ary)
  1425     if (block_given && argc == 2) {
  1426         rb_warn(
"block supersedes default value argument");
  1434         if (block_given) 
return rb_yield(pos);
  1471 rb_ary_index(
int argc, 
VALUE *argv, 
VALUE ary)
  1488         rb_warn(
"given block not used");
  1523 rb_ary_rindex(
int argc, 
VALUE *argv, 
VALUE ary)
  1542         rb_warn(
"given block not used");
  1557     if (!
NIL_P(tmp)) 
return tmp;
  1562 rb_ary_splice(
VALUE ary, 
long beg, 
long len, 
const VALUE *rptr, 
long rlen)
  1576     if (olen < len || olen < beg + len) {
  1582         rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1;
  1590         target_ary = ary_ensure_room_for_push(ary, rlen-len); 
  1592         ary_mem_clear(ary, olen, beg - olen);
  1595             ary_memcpy0(ary, beg, rlen, rptr, target_ary);
  1606         alen = olen + rlen - 
len;
  1608             ary_double_capa(ary, alen);
  1613                            MEMMOVE(ptr + beg + rlen, ptr + beg + len,
  1614                                    VALUE, olen - (beg + len)));
  1629     rb_ary_modify_check(ary);
  1633     if (len > (capa = (
long)
ARY_CAPA(ary))) {
  1634         rb_bug(
"probable buffer overflow: %ld for %ld", len, capa);
  1654     if (len == olen) 
return ary;
  1660             ary_double_capa(ary, len);
  1662         ary_mem_clear(ary, olen, len - olen);
  1721 rb_ary_aset(
int argc, 
VALUE *argv, 
VALUE ary)
  1723     long offset, beg, 
len;
  1727         rb_ary_modify_check(ary);
  1733     rb_ary_modify_check(ary);
  1744         return argv[argc-1];
  1770 rb_ary_insert(
int argc, 
VALUE *argv, 
VALUE ary)
  1775     rb_ary_modify_check(ary);
  1777     if (argc == 1) 
return ary;
  1789     rb_ary_splice(ary, pos, 0, argv + 1, argc - 1);
  1794 rb_ary_length(
VALUE ary);
  1799     return rb_ary_length(ary);
  1851 rb_ary_each_index(
VALUE ary)
  1878 rb_ary_reverse_each(
VALUE ary)
  1906 rb_ary_length(
VALUE ary)
  1922 rb_ary_empty_p(
VALUE ary)
  1955     VALUE result = arg[2];
  1956     int *first = (
int *)arg[3];
  1962         ary_join_1(obj, ary, sep, 0, result, first);
  1974     for (i=0; i<max; i++) {
  1976         if (i > 0 && !
NIL_P(sep))
  1989         if (i > 0 && !
NIL_P(sep))
  2014                 args[3] = (
VALUE)first;
  2054         if (
NIL_P(tmp) || tmp != val) {
  2059             ary_join_0(ary, sep, i, result);
  2061             ary_join_1(ary, ary, sep, i, result, &first);
  2070     ary_join_0(ary, sep, 
RARRAY_LEN(ary), result);
  2094 rb_ary_join_m(
int argc, 
VALUE *argv, 
VALUE ary)
  2105 inspect_ary(
VALUE ary, 
VALUE dummy, 
int recur)
  2136 rb_ary_inspect(
VALUE ary)
  2145     return rb_ary_inspect(ary);
  2158 rb_ary_to_a(
VALUE ary)
  2180 rb_ary_to_h(
VALUE ary)
  2185         const VALUE elt = rb_ary_elt(ary, i);
  2187         if (
NIL_P(key_value_pair)) {
  2208 rb_ary_to_ary_m(
VALUE ary)
  2233             ary_reverse(p1, p2);
  2251 rb_ary_reverse_bang(
VALUE ary)
  2267 rb_ary_reverse_m(
VALUE ary)
  2275         do *p2-- = *p1++; 
while (--len > 0);
  2282 rotate_count(
long cnt, 
long len)
  2284     return (cnt < 0) ? (len - (~cnt % 
len) - 1) : (cnt % 
len);
  2296         if (len > 0 && (cnt = rotate_count(cnt, len)) > 0) {
  2298             if (cnt < len) ary_reverse(ptr + cnt, ptr + len);
  2299             if (--cnt > 0) ary_reverse(ptr, ptr + cnt);
  2300             if (len > 0) ary_reverse(ptr, ptr + len);
  2326 rb_ary_rotate_bang(
int argc, 
VALUE *argv, 
VALUE ary)
  2357 rb_ary_rotate_m(
int argc, 
VALUE *argv, 
VALUE ary)
  2372         cnt = rotate_count(cnt, len);
  2375         ary_memcpy(rotated, 0, len, ptr + cnt);
  2376         ary_memcpy(rotated, len, cnt, ptr);
  2388 sort_reentered(
VALUE ary)
  2390     if (
RBASIC(ary)->klass) {
  2397 sort_1(
const void *ap, 
const void *
bp, 
void *dummy)
  2400     VALUE retval = sort_reentered(data->
ary);
  2409     sort_reentered(data->
ary);
  2414 sort_2(
const void *ap, 
const void *bp, 
void *dummy)
  2417     VALUE retval = sort_reentered(data->
ary);
  2422         if ((
long)a > (long)b) 
return 1;
  2423         if ((
long)a < (long)b) 
return -1;
  2435     sort_reentered(data->
ary);
  2470         VALUE tmp = ary_make_substitution(ary); 
  2485                 rb_ary_unshare(ary);
  2503                     rb_ary_unshare(ary);
  2556 static VALUE rb_ary_bsearch_index(
VALUE ary);
  2612 rb_ary_bsearch(
VALUE ary)
  2614     VALUE index_result = rb_ary_bsearch_index(ary);
  2619     return index_result;
  2636 rb_ary_bsearch_index(
VALUE ary)
  2639     int smaller = 0, satisfied = 0;
  2643     while (low < high) {
  2644         mid = low + ((high - low) / 2);
  2651         else if (v == 
Qtrue) {
  2662               case 1: smaller = 1; 
break;
  2663               case -1: smaller = 0;
  2668                      " (must be numeric, true, false or nil)",
  2678     if (!satisfied) 
return Qnil;
  2706 rb_ary_sort_by_bang(
VALUE ary)
  2740 rb_ary_collect(
VALUE ary)
  2776 rb_ary_collect_bang(
VALUE ary)
  2792     long beg, 
len, i, j;
  2794     for (i=0; i<
argc; i++) {
  2801             long end = olen < beg+len ? olen : beg+
len;
  2802             for (j = beg; j < end; j++) {
  2833 rb_ary_values_at(
int argc, 
VALUE *argv, 
VALUE ary)
  2858 rb_ary_select(
VALUE ary)
  2879 select_bang_i(
VALUE a)
  2885     for (i1 = i2 = 0; i1 < 
RARRAY_LEN(ary); arg->
len[0] = ++i1) {
  2893     return (i1 == i2) ? 
Qnil : 
ary;
  2897 select_bang_ensure(
VALUE a)
  2902     long i1 = arg->
len[0], i2 = arg->
len[1];
  2904     if (i2 < len && i2 < i1) {
  2936 rb_ary_select_bang(
VALUE ary)
  2944     args.
len[0] = args.
len[1] = 0;
  2965 rb_ary_keep_if(
VALUE ary)
  2968     rb_ary_select_bang(ary);
  2973 ary_resize_smaller(
VALUE ary, 
long len)
  2980             ary_resize_capa(ary, len * 2);
  3011     for (i1 = i2 = 0; i1 < 
RARRAY_LEN(ary); i1++) {
  3030     ary_resize_smaller(ary, i2);
  3040     for (i1 = i2 = 0; i1 < 
RARRAY_LEN(ary); i1++) {
  3055     ary_resize_smaller(ary, i2);
  3064     if (pos >= len) 
return Qnil;
  3067         if (pos < 0) 
return Qnil;
  3123 rb_ary_slice_bang(
int argc, 
VALUE *argv, 
VALUE ary)
  3126     long pos, 
len, orig_len;
  3128     rb_ary_modify_check(ary);
  3133         if (len < 0) 
return Qnil;
  3137             if (pos < 0) 
return Qnil;
  3139         else if (orig_len < pos) 
return Qnil;
  3140         if (orig_len < pos + len) {
  3141             len = orig_len - pos;
  3146         rb_ary_splice(ary, pos, len, 0, 0);
  3160             goto delete_pos_len;
  3188 reject_bang_i(
VALUE a)
  3194     for (i1 = i2 = 0; i1 < 
RARRAY_LEN(ary); arg->
len[0] = ++i1) {
  3202     return (i1 == i2) ? 
Qnil : 
ary;
  3206 ary_reject_bang(
VALUE ary)
  3210     rb_ary_modify_check(ary);
  3212     args.
len[0] = args.
len[1] = 0;
  3232 rb_ary_reject_bang(
VALUE ary)
  3235     return ary_reject_bang(ary);
  3252 rb_ary_reject(
VALUE ary)
  3258     ary_reject(ary, rejected_ary);
  3259     return rejected_ary;
  3281 rb_ary_delete_if(
VALUE ary)
  3284     ary_reject_bang(ary);
  3299 take_items(
VALUE obj, 
long n)
  3306     args[0] = result; args[1] = (
VALUE)n;
  3345     for (i=0; i<
argc; i++) {
  3346         argv[i] = take_items(argv[i], len);
  3359                 for (j=0; j<
argc; j++) {
  3360                     tmp[j+1] = rb_ary_elt(argv[j], i);
  3372                 for (j=0; j<
argc; j++) {
  3382         for (i=0; i<
len; i++) {
  3386             for (j=0; j<
argc; j++) {
  3410 rb_ary_transpose(
VALUE ary)
  3412     long elen = -1, alen, i, j;
  3413     VALUE tmp, result = 0;
  3417     for (i=0; i<alen; i++) {
  3418         tmp = to_ary(rb_ary_elt(ary, i));
  3422             for (j=0; j<elen; j++) {
  3430         for (j=0; j<elen; j++) {
  3431             rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
  3453     rb_ary_modify_check(copy);
  3454     orig = to_ary(orig);
  3455     if (copy == orig) 
return copy;
  3470             rb_ary_decrement_share(shared);
  3475         VALUE shared = ary_make_shared(orig);
  3480             rb_ary_unshare_safe(copy);
  3485         rb_ary_set_shared(copy, shared);
  3503     rb_ary_modify_check(ary);
  3507             rb_ary_unshare(ary);
  3548 rb_ary_fill(
int argc, 
VALUE *argv, 
VALUE ary)
  3551     long beg = 0, end = 0, len = 0;
  3574             if (beg < 0) beg = 0;
  3589             ary_resize_capa(ary, end);
  3599         for (i=beg; i<end; i++) {
  3606         ary_memfill(ary, beg, len, item);
  3638     long len, xlen, ylen;
  3683 rb_ary_concat_multi(
int argc, 
VALUE *argv, 
VALUE ary)
  3685     rb_ary_modify_check(ary);
  3690     else if (argc > 1) {
  3693         for (i = 0; i < 
argc; i++) {
  3696         ary_append(ary, args);
  3705     return ary_append(x, to_ary(y));
  3756         ary_memcpy(ary2, 0, t, ptr);
  3757         while (t <= len/2) {
  3841 recursive_equal(
VALUE ary1, 
VALUE ary2, 
int recur)
  3844     const VALUE *p1, *p2;
  3846     if (recur) 
return Qtrue; 
  3852     for (i = 0; i < len1; i++) {
  3890     if (ary1 == ary2) 
return Qtrue;
  3903 recursive_eql(
VALUE ary1, 
VALUE ary2, 
int recur)
  3907     if (recur) 
return Qtrue; 
  3909         if (!
rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
  3926     if (ary1 == ary2) 
return Qtrue;
  3946 rb_ary_hash(
VALUE ary)
  3990 rb_ary_includes_by_eql(
VALUE ary, 
VALUE item)
  4005 recursive_cmp(
VALUE ary1, 
VALUE ary2, 
int recur)
  4009     if (recur) 
return Qundef;   
  4014     for (i=0; i<
len; i++) {
  4015         VALUE e1 = rb_ary_elt(ary1, i), e2 = rb_ary_elt(ary2, i);
  4062     if (ary1 == ary2) 
return INT2FIX(0);
  4064     if (v != 
Qundef) 
return v;
  4066     if (len == 0) 
return INT2FIX(0);
  4067     if (len > 0) 
return INT2FIX(1);
  4084 ary_tmp_hash_new(
VALUE ary)
  4094 ary_make_hash(
VALUE ary)
  4096     VALUE hash = ary_tmp_hash_new(ary);
  4097     return ary_add_hash(hash, ary);
  4113 ary_make_hash_by(
VALUE ary)
  4115     VALUE hash = ary_tmp_hash_new(ary);
  4116     return ary_add_hash_by(hash, ary);
  4120 ary_recycle_hash(
VALUE hash)
  4123     if (
RHASH(hash)->ntbl) {
  4154     ary2 = to_ary(ary2);
  4159             VALUE elt = rb_ary_elt(ary1, i);
  4160             if (rb_ary_includes_by_eql(ary2, elt)) 
continue;
  4166     hash = ary_make_hash(ary2);
  4171     ary_recycle_hash(hash);
  4194     VALUE hash, ary3, v;
  4199     ary2 = to_ary(ary2);
  4206             if (!rb_ary_includes_by_eql(ary2, v)) 
continue;
  4207             if (rb_ary_includes_by_eql(ary3, v)) 
continue;
  4213     hash = ary_make_hash(ary2);
  4223     ary_recycle_hash(hash);
  4232     *key = *value = (
VALUE)arg;
  4257     ary2 = to_ary(ary2);
  4261             VALUE elt = rb_ary_elt(ary1, i);
  4262             if (rb_ary_includes_by_eql(ary3, elt)) 
continue;
  4266             VALUE elt = rb_ary_elt(ary2, i);
  4267             if (rb_ary_includes_by_eql(ary3, elt)) 
continue;
  4273     hash = ary_make_hash(ary1);
  4281     ary_recycle_hash(hash);
  4430 rb_ary_uniq_bang(
VALUE ary)
  4435     rb_ary_modify_check(ary);
  4439         hash = ary_make_hash_by(ary);
  4441         hash = ary_make_hash(ary);
  4447     rb_ary_modify_check(ary);
  4450         rb_ary_unshare(ary);
  4453     ary_resize_capa(ary, hash_size);
  4455     ary_recycle_hash(hash);
  4482 rb_ary_uniq(
VALUE ary)
  4489         hash = ary_make_hash_by(ary);
  4493         hash = ary_make_hash(ary);
  4497     ary_recycle_hash(hash);
  4515 rb_ary_compact_bang(
VALUE ary)
  4532     ary_resize_smaller(ary, n);
  4548 rb_ary_compact(
VALUE ary)
  4551     rb_ary_compact_bang(ary);
  4577 rb_ary_count(
int argc, 
VALUE *argv, 
VALUE ary)
  4597             rb_warn(
"given block not used");
  4611     VALUE stack, result, tmp, elt;
  4624             if (level >= 0 && 
RARRAY_LEN(stack) / 2 >= level) {
  4629             if (
RBASIC(result)->klass) {
  4686 rb_ary_flatten_bang(
int argc, 
VALUE *argv, 
VALUE ary)
  4688     int mod = 0, level = -1;
  4692     rb_ary_modify_check(ary);
  4694     if (level == 0) 
return Qnil;
  4696     result = flatten(ary, level, &mod);
  4698         ary_discard(result);
  4731 rb_ary_flatten(
int argc, 
VALUE *argv, 
VALUE ary)
  4733     int mod = 0, level = -1;
  4738     if (level == 0) 
return ary_make_shared_copy(ary);
  4740     result = flatten(ary, level, &mod);
  4746 #define OPTHASH_GIVEN_P(opts) \  4747     (argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))  4748 static ID id_random;
  4750 #define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)  4769 rb_ary_shuffle_bang(
int argc, 
VALUE *argv, 
VALUE ary)
  4778         keyword_ids[0] = id_random;
  4820 rb_ary_shuffle(
int argc, 
VALUE *argv, 
VALUE ary)
  4823     rb_ary_shuffle_bang(argc, argv, ary);
  4853 rb_ary_sample(
int argc, 
VALUE *argv, 
VALUE ary)
  4857     long n, 
len, i, j, k, idx[10];
  4859     long memo_threshold;
  4865         keyword_ids[0] = id_random;
  4878         return rb_ary_elt(ary, i);
  4883     if (n > len) n = 
len;
  4885         for (i = 0; i < n; ++i) {
  4891     if (len < k && n <= 
numberof(idx)) {
  4892         for (i = 0; i < n; ++i) {
  4896     if (n > len) n = 
len;
  4914             if (j >= i) l = i, g = ++j;
  4915             if (k >= l && (++k >= g)) ++k;
  4920         len < 2560 ? len / 128 :
  4921         len < 5120 ? len / 64 :
  4922         len < 10240 ? len / 32 :
  4926         sorted[0] = idx[0] = rnds[0];
  4927         for (i=1; i<n; i++) {
  4929             for (j = 0; j < i; ++j) {
  4930                 if (k < sorted[j]) 
break;
  4933             memmove(&sorted[j+1], &sorted[j], 
sizeof(sorted[0])*(i-j));
  4934             sorted[j] = idx[i] = k;
  4938             for (i=0; i<n; i++) {
  4943     else if (n <= memo_threshold / 2) {
  4945 #undef RUBY_UNTYPED_DATA_WARNING  4946 #define RUBY_UNTYPED_DATA_WARNING 0  4952             for (i=0; i<n; i++) {
  4955                 if (r > max_idx) max_idx = r;
  4958             if (len <= max_idx) n = 0;
  4959             else if (n > len) n = 
len;
  4961                 for (i=0; i<n; i++) {
  4962                     long j2 = j = ptr_result[i];
  4968                     ptr_result[i] = ptr_ary[j2];
  4980             for (i=0; i<n; i++) {
  4983                 ptr_result[j] = ptr_result[i];
  5005     if (mul <= 0) 
return INT2FIX(0);
  5007     return rb_fix_mul_fix(rb_ary_length(
self), n);
  5031 rb_ary_cycle(
int argc, 
VALUE *argv, 
VALUE ary)
  5044         if (n <= 0) 
return Qnil;
  5047     while (
RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
  5055 #define tmpbuf(n, size) rb_str_tmp_new((n)*(size))  5056 #define tmpbuf_discard(s) (rb_str_resize((s), 0L), RBASIC_SET_CLASS_RAW(s, rb_cString))  5057 #define tmpary(n) rb_ary_tmp_new(n)  5058 #define tmpary_discard(a) (ary_discard(a), RBASIC_SET_CLASS_RAW(a, rb_cArray))  5066 yield_indexed_values(
const VALUE values, 
const long r, 
const long *
const p)
  5073     for (i = 0; i < r; i++) result_array[i] = values_array[p[i]];
  5076     return !
RBASIC(values)->klass;
  5092 permute0(
const long n, 
const long r, 
long *
const p, 
char *
const used, 
const VALUE values)
  5094     long i = 0, index = 0;
  5097         const char *
const unused = memchr(&used[i], 0, n-i);
  5112             for (i = 0; i < n; ++i) {
  5113                 if (used[i]) 
continue;
  5115                 if (!yield_indexed_values(values, r, p)) {
  5131 descending_factorial(
long from, 
long how_many)
  5136         while (--how_many > 0) {
  5148 binomial_coefficient(
long comb, 
long size)
  5152     if (comb > size-comb) {
  5158     else if (comb == 0) {
  5162     for (i = 1; i < comb; ++i) {
  5175     return descending_factorial(n, k);
  5207 rb_ary_permutation(
int argc, 
VALUE *argv, 
VALUE ary)
  5217     if (r < 0 || n < r) {
  5231         char *used = (
char*)(p + r);
  5232         VALUE ary0 = ary_make_shared_copy(ary); 
  5237         permute0(n, r, p, used, ary0); 
  5245 combinate0(
const long len, 
const long n, 
long *
const stack, 
const VALUE values)
  5252         for (lev++; lev < n; lev++) {
  5253             stack[lev+1] = stack[lev]+1;
  5255         if (!yield_indexed_values(values, n, stack+1)) {
  5259             if (lev == 0) 
return;
  5261         } 
while (stack[lev+1]+n == len+lev+1);
  5271     return binomial_coefficient(k, n);
  5307     if (n < 0 || len < n) {
  5319         VALUE ary0 = ary_make_shared_copy(ary); 
  5321         long *stack = 
ALLOCV_N(
long, t0, n+1);
  5324         combinate0(len, n, stack, ary0);
  5344 rpermute0(
const long n, 
const long r, 
long *
const p, 
const VALUE values)
  5346     long i = 0, index = 0;
  5350         if (++index < r-1) {
  5354         for (i = 0; i < n; ++i) {
  5356             if (!yield_indexed_values(values, r, p)) {
  5361             if (index <= 0) 
return;
  5362         } 
while ((i = ++p[--index]) >= n);
  5405 rb_ary_repeated_permutation(
VALUE ary, 
VALUE num)
  5427         VALUE ary0 = ary_make_shared_copy(ary); 
  5430         rpermute0(n, r, p, ary0); 
  5438 rcombinate0(
const long n, 
const long r, 
long *
const p, 
const long rest, 
const VALUE values)
  5440     long i = 0, index = 0;
  5444         if (++index < r-1) {
  5448         for (; i < n; ++i) {
  5450             if (!yield_indexed_values(values, r, p)) {
  5455             if (index <= 0) 
return;
  5456         } 
while ((i = ++p[--index]) >= n);
  5468     return binomial_coefficient(k, n + k - 1);
  5499 rb_ary_repeated_combination(
VALUE ary, 
VALUE num)
  5517     else if (len == 0) {
  5523         VALUE ary0 = ary_make_shared_copy(ary); 
  5526         rcombinate0(len, n, p, n, ary0); 
  5555 rb_ary_product(
int argc, 
VALUE *argv, 
VALUE ary)
  5572     for (i = 1; i < n; i++) arrays[i] = 
Qnil;
  5573     for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);
  5576     for (i = 0; i < n; i++) counters[i] = 0;
  5581         for (i = 0; i < n; i++) {
  5583             arrays[i] = ary_make_shared_copy(arrays[i]);
  5588         for (i = 0; i < n; i++) {
  5604         for (j = 0; j < n; j++) {
  5609         if (
NIL_P(result)) {
  5629         while (counters[m] == 
RARRAY_LEN(arrays[m])) {
  5632             if (--m < 0) 
goto done;
  5640     return NIL_P(result) ? 
ary : result;
  5686 rb_ary_take_while(
VALUE ary)
  5694     return rb_ary_take(ary, 
LONG2FIX(i));
  5746 rb_ary_drop_while(
VALUE ary)
  5754     return rb_ary_drop(ary, 
LONG2FIX(i));
  5765 rb_ary_any_p(
VALUE ary)
  5803     if (!--argc) 
return self;
  5809 finish_exact_sum(
long n, 
VALUE r, 
VALUE v, 
int z)
  5909     v = finish_exact_sum(n, r, v, argc!=0);
  5913     v = finish_exact_sum(n, r, v, i!=0);
  5924         goto has_float_value;
  5943             if (fabs(f) >= fabs(x))
  5956     goto has_some_value;
  6209 #define rb_intern(str) rb_intern_const(str) #define RBASIC_CLEAR_CLASS(obj)
VALUE rb_ary_unshift(VALUE ary, VALUE item)
VALUE rb_ary_last(int argc, const VALUE *argv, VALUE ary)
void rb_warn(const char *fmt,...)
VALUE rb_ary_pop(VALUE ary)
void rb_bug(const char *fmt,...)
VALUE rb_ary_entry(VALUE ary, long offset)
VALUE rb_ary_new_capa(long capa)
void rb_enc_copy(VALUE obj1, VALUE obj2)
VALUE rb_ary_freeze(VALUE ary)
#define ARY_SET_EMBED_LEN(ary, n)
VALUE rb_yield_values(int n,...)
VALUE rb_check_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
#define RB_OBJ_WRITTEN(a, oldv, b)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj. 
int rb_block_given_p(void)
Determines if the current method is given a block. 
VALUE rb_ary_sort(VALUE ary)
int rb_float_cmp(VALUE x, VALUE y)
#define rb_usascii_str_new2
VALUE rb_ary_subseq(VALUE ary, long beg, long len)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_ary_delete_at(VALUE ary, long pos)
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
st_index_t rb_hash_end(st_index_t)
VALUE rb_ary_shift(VALUE ary)
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
#define FL_UNSET_SHARED(ary)
VALUE rb_big_plus(VALUE x, VALUE y)
RUBY_EXTERN VALUE rb_cRandom
VALUE rb_ary_each(VALUE ary)
#define ARY_SET_CAPA(ary, n)
void rb_mem_clear(register VALUE *mem, register long size)
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
VALUE rb_ary_push(VALUE ary, VALUE item)
#define SIZED_REALLOC_N(var, type, n, old_n)
VALUE rb_str_buf_new2(const char *)
#define ARY_OWNS_HEAP_P(a)
VALUE rb_ary_rassoc(VALUE ary, VALUE value)
struct st_table * rb_hash_tbl_raw(VALUE hash)
VALUE rb_ary_tmp_new(long capa)
VALUE rb_ary_shared_with_p(VALUE ary1, VALUE ary2)
void ruby_sized_xfree(void *x, size_t size)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method. 
#define RBASIC_SET_CLASS(obj, cls)
VALUE rb_int_mul(VALUE x, VALUE y)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
VALUE rb_ary_clear(VALUE ary)
#define FL_SET_SHARED_ROOT(ary)
#define MUL_OVERFLOW_LONG_P(a, b)
#define OPTIMIZED_CMP(a, b, data)
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
void rb_include_module(VALUE klass, VALUE module)
#define ARY_SHARED_ROOT_P(ary)
VALUE rb_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
#define ARY_SHARED_NUM(ary)
VALUE rb_range_beg_len(VALUE, long *, long *, long, int)
double rb_big2dbl(VALUE x)
int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg)
int rb_str_cmp(VALUE, VALUE)
VALUE rb_ary_rotate(VALUE ary, long cnt)
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
An equivalent to ensure clause. 
void rb_gc_force_recycle(VALUE obj)
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect. 
VALUE rb_hash_new_with_size(st_index_t size)
#define ARY_SHARED_P(ary)
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
VALUE rb_str_buf_append(VALUE, VALUE)
#define st_init_numtable_with_size
RUBY_EXTERN void * memmove(void *, const void *, size_t)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
#define NEWOBJ_OF(obj, type, klass, flags)
#define Data_Wrap_Struct(klass, mark, free, sval)
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
#define OPTHASH_GIVEN_P(opts)
#define RBASIC_SET_CLASS_RAW(obj, cls)
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class 
#define RB_TYPE_P(obj, type)
VALUE rb_ary_assoc(VALUE ary, VALUE key)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false 
#define MEMZERO(p, type, n)
VALUE rb_int_idiv(VALUE x, VALUE y)
VALUE rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE(*func)(VALUE, long))
#define tmpbuf_discard(s)
void rb_ary_free(VALUE ary)
VALUE rb_equal(VALUE, VALUE)
call-seq: obj === other -> true or false 
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
VALUE rb_convert_type_with_id(VALUE, int, const char *, ID)
RUBY_EXTERN VALUE rb_cObject
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE, VALUE)
VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound)
VALUE rb_ary_at(VALUE ary, VALUE pos)
#define RGENGC_WB_PROTECTED_ARRAY
#define tmpary_discard(a)
VALUE rb_ary_replace(VALUE copy, VALUE orig)
VALUE rb_obj_as_string(VALUE)
VALUE rb_str_buf_cat2(VALUE, const char *)
VALUE rb_ary_to_s(VALUE ary)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class. 
#define FL_SET_SHARED(ary)
void rb_ary_store(VALUE ary, long idx, VALUE val)
VALUE rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
rb_atomic_t cnt[RUBY_NSIG]
#define ALLOCV_N(type, v, n)
#define range(low, item, hi)
#define RUBY_FUNC_EXPORTED
#define MEMCPY(p1, p2, type, n)
VALUE rb_nmin_run(VALUE obj, VALUE num, int by, int rev, int ary)
RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y)
#define RUBY_DTRACE_CREATE_HOOK(name, arg)
VALUE rb_ary_to_ary(VALUE obj)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method. 
#define CMP_OPTIMIZABLE(data, type)
#define RARRAY_CONST_PTR(a)
#define REALLOC_N(var, type, n)
VALUE rb_obj_freeze(VALUE)
call-seq: obj.freeze -> obj 
VALUE rb_ary_dig(int argc, VALUE *argv, VALUE self)
#define RARRAY_PTR_USE(ary, ptr_name, expr)
void rb_ary_modify(VALUE ary)
VALUE rb_ary_delete(VALUE ary, VALUE item)
#define MEMMOVE(p1, p2, type, n)
VALUE rb_hash_values(VALUE hash)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
VALUE rb_assoc_new(VALUE car, VALUE cdr)
VALUE rb_fix_plus(VALUE x, VALUE y)
rb_encoding * rb_usascii_encoding(void)
#define ARY_SET_LEN(ary, n)
void ruby_qsort(void *, const size_t, const size_t, int(*)(const void *, const void *, void *), void *)
#define ARY_SET_PTR(ary, p)
#define FL_UNSET_EMBED(ary)
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
RUBY_FUNC_EXPORTED size_t rb_ary_memsize(VALUE ary)
#define rb_cmpint(cmp, a, b)
RUBY_EXTERN VALUE rb_cNumeric
#define RB_FLOAT_TYPE_P(obj)
int rb_respond_to(VALUE, ID)
register unsigned int len
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
VALUE rb_rational_plus(VALUE self, VALUE other)
#define RB_OBJ_WRITE(a, slot, b)
VALUE rb_ary_resize(VALUE ary, long len)
expands or shrinks ary to len elements. 
#define ARY_SET_HEAP_LEN(ary, n)
VALUE rb_yield_values2(int n, const VALUE *argv)
#define UNLIMITED_ARGUMENTS
#define RARRAY_AREF(a, i)
VALUE rb_ary_plus(VALUE x, VALUE y)
#define RBASIC_CLASS(obj)
VALUE rb_check_array_type(VALUE ary)
VALUE rb_check_string_type(VALUE)
VALUE rb_ary_tmp_new_from_values(VALUE klass, long n, const VALUE *elts)
VALUE rb_ary_includes(VALUE ary, VALUE item)
#define ARY_INCREASE_PTR(ary, n)
void rb_warning(const char *fmt,...)
st_index_t rb_hash_uint(st_index_t, st_index_t)
#define ARY_INCREASE_LEN(ary, n)
VALUE rb_ary_sort_bang(VALUE ary)
VALUE rb_ary_dup(VALUE ary)
VALUE rb_ary_concat(VALUE x, VALUE y)
void rb_gc_writebarrier_remember(VALUE obj)
#define RETURN_ENUMERATOR(obj, argc, argv)
VALUE rb_ary_join(VALUE ary, VALUE sep)
VALUE rb_ary_tmp_new_fill(long capa)
struct cmp_opt_data cmp_opt
double rb_num2dbl(VALUE)
Converts a Numeric object to double. 
#define ARY_SET_SHARED_NUM(ary, value)
#define ARY_SET_SHARED(ary, value)
#define RB_DEBUG_COUNTER_INC(type)
int rb_eql(VALUE, VALUE)
Determines if obj1 and obj2 are equal in terms of Object::eql?. 
VALUE rb_ary_reverse(VALUE ary)
VALUE() rb_ary_new_from_args(long n,...)
#define rb_check_frozen(obj)
VALUE rb_ary_cmp(VALUE ary1, VALUE ary2)
VALUE rb_ary_resurrect(VALUE ary)
VALUE rb_str_buf_new(long)
VALUE rb_usascii_str_new(const char *, long)
#define ARY_SHARED_OCCUPIED(ary)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
void rb_ary_delete_same(VALUE ary, VALUE item)
st_index_t rb_hash_start(st_index_t)
VALUE rb_usascii_str_new_cstr(const char *)
void rb_ary_set_len(VALUE ary, long len)