00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "ruby.h"
00016 #include "util.h"
00017 #include "st.h"
00018
00019 VALUE rb_cArray;
00020 static ID id_cmp;
00021
00022 #define ARY_DEFAULT_SIZE 16
00023
00024 void
00025 rb_mem_clear(mem, size)
00026 register VALUE *mem;
00027 register long size;
00028 {
00029 while (size--) {
00030 *mem++ = Qnil;
00031 }
00032 }
00033
00034 static inline void
00035 memfill(mem, size, val)
00036 register VALUE *mem;
00037 register long size;
00038 register VALUE val;
00039 {
00040 while (size--) {
00041 *mem++ = val;
00042 }
00043 }
00044
00045 #define ARY_TMPLOCK FL_USER1
00046
00047 static inline void
00048 rb_ary_modify_check(ary)
00049 VALUE ary;
00050 {
00051 if (OBJ_FROZEN(ary)) rb_error_frozen("array");
00052 if (FL_TEST(ary, ARY_TMPLOCK))
00053 rb_raise(rb_eRuntimeError, "can't modify array during iteration");
00054 if (!OBJ_TAINTED(ary) && rb_safe_level() >= 4)
00055 rb_raise(rb_eSecurityError, "Insecure: can't modify array");
00056 }
00057
00058 static void
00059 rb_ary_modify(ary)
00060 VALUE ary;
00061 {
00062 VALUE *ptr;
00063
00064 rb_ary_modify_check(ary);
00065 if (FL_TEST(ary, ELTS_SHARED)) {
00066 ptr = ALLOC_N(VALUE, RARRAY(ary)->len);
00067 FL_UNSET(ary, ELTS_SHARED);
00068 RARRAY(ary)->aux.capa = RARRAY(ary)->len;
00069 MEMCPY(ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
00070 RARRAY(ary)->ptr = ptr;
00071 }
00072 }
00073
00074 VALUE
00075 rb_ary_freeze(ary)
00076 VALUE ary;
00077 {
00078 return rb_obj_freeze(ary);
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 static VALUE
00090 rb_ary_frozen_p(ary)
00091 VALUE ary;
00092 {
00093 if (OBJ_FROZEN(ary)) return Qtrue;
00094 if (FL_TEST(ary, ARY_TMPLOCK)) return Qtrue;
00095 return Qfalse;
00096 }
00097
00098 static VALUE ary_alloc (VALUE);
00099 static VALUE
00100 ary_alloc(klass)
00101 VALUE klass;
00102 {
00103 NEWOBJ(ary, struct RArray);
00104 OBJSETUP(ary, klass, T_ARRAY);
00105
00106 ary->len = 0;
00107 ary->ptr = 0;
00108 ary->aux.capa = 0;
00109
00110 return (VALUE)ary;
00111 }
00112
00113 static VALUE
00114 ary_new(klass, len)
00115 VALUE klass;
00116 long len;
00117 {
00118 VALUE ary = ary_alloc(klass);
00119
00120 if (len < 0) {
00121 rb_raise(rb_eArgError, "negative array size (or size too big)");
00122 }
00123 if (len > 0 && len * sizeof(VALUE) <= len) {
00124 rb_raise(rb_eArgError, "array size too big");
00125 }
00126 if (len == 0) len++;
00127 RARRAY(ary)->ptr = ALLOC_N(VALUE, len);
00128 RARRAY(ary)->aux.capa = len;
00129
00130 return ary;
00131 }
00132
00133 VALUE
00134 rb_ary_new2(len)
00135 long len;
00136 {
00137 return ary_new(rb_cArray, len);
00138 }
00139
00140
00141 VALUE
00142 rb_ary_new()
00143 {
00144 return rb_ary_new2(ARY_DEFAULT_SIZE);
00145 }
00146
00147 #ifdef HAVE_STDARG_PROTOTYPES
00148 #include <stdarg.h>
00149 #define va_init_list(a,b) va_start(a,b)
00150 #else
00151 #include <varargs.h>
00152 #define va_init_list(a,b) va_start(a)
00153 #endif
00154
00155 VALUE
00156 #ifdef HAVE_STDARG_PROTOTYPES
00157 rb_ary_new3(long n, ...)
00158 #else
00159 rb_ary_new3(n, va_alist)
00160 long n;
00161 va_dcl
00162 #endif
00163 {
00164 va_list ar;
00165 VALUE ary;
00166 long i;
00167
00168 ary = rb_ary_new2(n);
00169
00170 va_init_list(ar, n);
00171 for (i=0; i<n; i++) {
00172 RARRAY(ary)->ptr[i] = va_arg(ar, VALUE);
00173 }
00174 va_end(ar);
00175
00176 RARRAY(ary)->len = n;
00177 return ary;
00178 }
00179
00180 VALUE
00181 rb_ary_new4(n, elts)
00182 long n;
00183 const VALUE *elts;
00184 {
00185 VALUE ary;
00186
00187 ary = rb_ary_new2(n);
00188 if (n > 0 && elts) {
00189 MEMCPY(RARRAY(ary)->ptr, elts, VALUE, n);
00190 }
00191 RARRAY(ary)->len = n;
00192
00193 return ary;
00194 }
00195
00196 VALUE
00197 rb_assoc_new(car, cdr)
00198 VALUE car, cdr;
00199 {
00200 VALUE ary;
00201
00202 ary = rb_ary_new2(2);
00203 RARRAY(ary)->ptr[0] = car;
00204 RARRAY(ary)->ptr[1] = cdr;
00205 RARRAY(ary)->len = 2;
00206
00207 return ary;
00208 }
00209
00210 static VALUE
00211 to_ary(ary)
00212 VALUE ary;
00213 {
00214 return rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
00215 }
00216
00217 VALUE
00218 rb_check_array_type(ary)
00219 VALUE ary;
00220 {
00221 return rb_check_convert_type(ary, T_ARRAY, "Array", "to_ary");
00222 }
00223
00224 static VALUE rb_ary_replace (VALUE, VALUE);
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 static VALUE
00265 rb_ary_initialize(argc, argv, ary)
00266 int argc;
00267 VALUE *argv;
00268 VALUE ary;
00269 {
00270 long len;
00271 VALUE size, val;
00272
00273 if (rb_scan_args(argc, argv, "02", &size, &val) == 0) {
00274 RARRAY(ary)->len = 0;
00275 if (rb_block_given_p()) {
00276 rb_warning("given block not used");
00277 }
00278 return ary;
00279 }
00280
00281 if (argc == 1 && !FIXNUM_P(size)) {
00282 val = rb_check_array_type(size);
00283 if (!NIL_P(val)) {
00284 rb_ary_replace(ary, val);
00285 return ary;
00286 }
00287 }
00288
00289 len = NUM2LONG(size);
00290 if (len < 0) {
00291 rb_raise(rb_eArgError, "negative array size");
00292 }
00293 if (len > 0 && len * (long)sizeof(VALUE) <= len) {
00294 rb_raise(rb_eArgError, "array size too big");
00295 }
00296 rb_ary_modify(ary);
00297 if (len > RARRAY(ary)->aux.capa) {
00298 REALLOC_N(RARRAY(ary)->ptr, VALUE, len);
00299 RARRAY(ary)->aux.capa = len;
00300 }
00301 if (rb_block_given_p()) {
00302 long i;
00303
00304 if (argc == 2) {
00305 rb_warn("block supersedes default value argument");
00306 }
00307 for (i=0; i<len; i++) {
00308 rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
00309 RARRAY(ary)->len = i + 1;
00310 }
00311 }
00312 else {
00313 memfill(RARRAY(ary)->ptr, len, val);
00314 RARRAY(ary)->len = len;
00315 }
00316
00317 return ary;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 static VALUE
00330 rb_ary_s_create(argc, argv, klass)
00331 int argc;
00332 VALUE *argv;
00333 VALUE klass;
00334 {
00335 VALUE ary = ary_alloc(klass);
00336
00337 if (argc > 0) {
00338 RARRAY(ary)->ptr = ALLOC_N(VALUE, argc);
00339 MEMCPY(RARRAY(ary)->ptr, argv, VALUE, argc);
00340 }
00341 RARRAY(ary)->len = RARRAY(ary)->aux.capa = argc;
00342
00343 return ary;
00344 }
00345
00346 void
00347 rb_ary_store(ary, idx, val)
00348 VALUE ary;
00349 long idx;
00350 VALUE val;
00351 {
00352 if (idx < 0) {
00353 idx += RARRAY(ary)->len;
00354 if (idx < 0) {
00355 rb_raise(rb_eIndexError, "index %ld out of array",
00356 idx - RARRAY(ary)->len);
00357 }
00358 }
00359
00360 rb_ary_modify(ary);
00361 if (idx >= RARRAY(ary)->aux.capa) {
00362 long new_capa = RARRAY(ary)->aux.capa / 2;
00363
00364 if (new_capa < ARY_DEFAULT_SIZE) {
00365 new_capa = ARY_DEFAULT_SIZE;
00366 }
00367 new_capa += idx;
00368 if (new_capa * (long)sizeof(VALUE) <= new_capa) {
00369 rb_raise(rb_eArgError, "index too big");
00370 }
00371 REALLOC_N(RARRAY(ary)->ptr, VALUE, new_capa);
00372 RARRAY(ary)->aux.capa = new_capa;
00373 }
00374 if (idx > RARRAY(ary)->len) {
00375 rb_mem_clear(RARRAY(ary)->ptr + RARRAY(ary)->len,
00376 idx-RARRAY(ary)->len + 1);
00377 }
00378
00379 if (idx >= RARRAY(ary)->len) {
00380 RARRAY(ary)->len = idx + 1;
00381 }
00382 RARRAY(ary)->ptr[idx] = val;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 VALUE
00399 rb_ary_push(ary, item)
00400 VALUE ary;
00401 VALUE item;
00402 {
00403 rb_ary_store(ary, RARRAY(ary)->len, item);
00404 return ary;
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 static VALUE
00421 rb_ary_push_m(argc, argv, ary)
00422 int argc;
00423 VALUE *argv;
00424 VALUE ary;
00425 {
00426 while (argc--) {
00427 rb_ary_push(ary, *argv++);
00428 }
00429 return ary;
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 VALUE
00445 rb_ary_pop(ary)
00446 VALUE ary;
00447 {
00448 rb_ary_modify_check(ary);
00449 if (RARRAY(ary)->len == 0) return Qnil;
00450 if (!FL_TEST(ary, ELTS_SHARED) &&
00451 RARRAY(ary)->len * 2 < RARRAY(ary)->aux.capa &&
00452 RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) {
00453 RARRAY(ary)->aux.capa = RARRAY(ary)->len * 2;
00454 REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
00455 }
00456 return RARRAY(ary)->ptr[--RARRAY(ary)->len];
00457 }
00458
00459 static VALUE
00460 ary_make_shared(ary)
00461 VALUE ary;
00462 {
00463 if (!FL_TEST(ary, ELTS_SHARED)) {
00464 NEWOBJ(shared, struct RArray);
00465 OBJSETUP(shared, rb_cArray, T_ARRAY);
00466
00467 shared->len = RARRAY(ary)->len;
00468 shared->ptr = RARRAY(ary)->ptr;
00469 shared->aux.capa = RARRAY(ary)->aux.capa;
00470 RARRAY(ary)->aux.shared = (VALUE)shared;
00471 FL_SET(ary, ELTS_SHARED);
00472 OBJ_FREEZE(shared);
00473 return (VALUE)shared;
00474 }
00475 else {
00476 return RARRAY(ary)->aux.shared;
00477 }
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 VALUE
00494 rb_ary_shift(ary)
00495 VALUE ary;
00496 {
00497 VALUE top;
00498
00499 rb_ary_modify_check(ary);
00500 if (RARRAY(ary)->len == 0) return Qnil;
00501 top = RARRAY(ary)->ptr[0];
00502 ary_make_shared(ary);
00503 RARRAY(ary)->ptr++;
00504 RARRAY(ary)->len--;
00505
00506 return top;
00507 }
00508
00509 VALUE
00510 rb_ary_unshift(ary, item)
00511 VALUE ary, item;
00512 {
00513 rb_ary_modify(ary);
00514 if (RARRAY(ary)->len == RARRAY(ary)->aux.capa) {
00515 long capa_inc = RARRAY(ary)->aux.capa / 2;
00516 if (capa_inc < ARY_DEFAULT_SIZE) {
00517 capa_inc = ARY_DEFAULT_SIZE;
00518 }
00519 RARRAY(ary)->aux.capa += capa_inc;
00520 REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
00521 }
00522
00523
00524 MEMMOVE(RARRAY(ary)->ptr + 1, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
00525
00526 RARRAY(ary)->len++;
00527 RARRAY(ary)->ptr[0] = item;
00528
00529 return ary;
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 static VALUE
00545 rb_ary_unshift_m(argc, argv, ary)
00546 int argc;
00547 VALUE *argv;
00548 VALUE ary;
00549 {
00550 long len = RARRAY(ary)->len;
00551
00552 if (argc == 0) return ary;
00553
00554
00555 rb_ary_store(ary, len + argc - 1, Qnil);
00556
00557
00558 MEMMOVE(RARRAY(ary)->ptr + argc, RARRAY(ary)->ptr, VALUE, len);
00559 MEMCPY(RARRAY(ary)->ptr, argv, VALUE, argc);
00560
00561 return ary;
00562 }
00563
00564
00565 static inline VALUE
00566 rb_ary_elt(ary, offset)
00567 VALUE ary;
00568 long offset;
00569 {
00570 if (RARRAY(ary)->len == 0) return Qnil;
00571 if (offset < 0 || RARRAY(ary)->len <= offset) {
00572 return Qnil;
00573 }
00574 return RARRAY(ary)->ptr[offset];
00575 }
00576
00577 VALUE
00578 rb_ary_entry(ary, offset)
00579 VALUE ary;
00580 long offset;
00581 {
00582 if (offset < 0) {
00583 offset += RARRAY(ary)->len;
00584 }
00585 return rb_ary_elt(ary, offset);
00586 }
00587
00588 static VALUE
00589 rb_ary_subseq(ary, beg, len)
00590 VALUE ary;
00591 long beg, len;
00592 {
00593 VALUE klass, ary2, shared;
00594 VALUE *ptr;
00595
00596 if (beg > RARRAY(ary)->len) return Qnil;
00597 if (beg < 0 || len < 0) return Qnil;
00598
00599 if (beg + len > RARRAY(ary)->len) {
00600 len = RARRAY(ary)->len - beg;
00601 if (len < 0)
00602 len = 0;
00603 }
00604 klass = rb_obj_class(ary);
00605 if (len == 0) return ary_new(klass, 0);
00606
00607 shared = ary_make_shared(ary);
00608 ptr = RARRAY(ary)->ptr;
00609 ary2 = ary_alloc(klass);
00610 RARRAY(ary2)->ptr = ptr + beg;
00611 RARRAY(ary2)->len = len;
00612 RARRAY(ary2)->aux.shared = shared;
00613 FL_SET(ary2, ELTS_SHARED);
00614
00615 return ary2;
00616 }
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 VALUE
00651 rb_ary_aref(argc, argv, ary)
00652 int argc;
00653 VALUE *argv;
00654 VALUE ary;
00655 {
00656 VALUE arg;
00657 long beg, len;
00658
00659 if (argc == 2) {
00660 if (SYMBOL_P(argv[0])) {
00661 rb_raise(rb_eTypeError, "Symbol as array index");
00662 }
00663 beg = NUM2LONG(argv[0]);
00664 len = NUM2LONG(argv[1]);
00665 if (beg < 0) {
00666 beg += RARRAY(ary)->len;
00667 }
00668 return rb_ary_subseq(ary, beg, len);
00669 }
00670 if (argc != 1) {
00671 rb_scan_args(argc, argv, "11", 0, 0);
00672 }
00673 arg = argv[0];
00674
00675 if (FIXNUM_P(arg)) {
00676 return rb_ary_entry(ary, FIX2LONG(arg));
00677 }
00678 if (SYMBOL_P(arg)) {
00679 rb_raise(rb_eTypeError, "Symbol as array index");
00680 }
00681
00682 switch (rb_range_beg_len(arg, &beg, &len, RARRAY(ary)->len, 0)) {
00683 case Qfalse:
00684 break;
00685 case Qnil:
00686 return Qnil;
00687 default:
00688 return rb_ary_subseq(ary, beg, len);
00689 }
00690 return rb_ary_entry(ary, NUM2LONG(arg));
00691 }
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 static VALUE
00709 rb_ary_at(ary, pos)
00710 VALUE ary, pos;
00711 {
00712 return rb_ary_entry(ary, NUM2LONG(pos));
00713 }
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 static VALUE
00731 rb_ary_first(argc, argv, ary)
00732 int argc;
00733 VALUE *argv;
00734 VALUE ary;
00735 {
00736 if (argc == 0) {
00737 if (RARRAY(ary)->len == 0) return Qnil;
00738 return RARRAY(ary)->ptr[0];
00739 }
00740 else {
00741 VALUE nv, result;
00742 long n, i;
00743
00744 rb_scan_args(argc, argv, "01", &nv);
00745 n = NUM2LONG(nv);
00746 if (n > RARRAY(ary)->len) n = RARRAY(ary)->len;
00747 result = rb_ary_new2(n);
00748 for (i=0; i<n; i++) {
00749 rb_ary_push(result, RARRAY(ary)->ptr[i]);
00750 }
00751 return result;
00752 }
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 static VALUE
00767 rb_ary_last(argc, argv, ary)
00768 int argc;
00769 VALUE *argv;
00770 VALUE ary;
00771 {
00772 if (argc == 0) {
00773 if (RARRAY(ary)->len == 0) return Qnil;
00774 return RARRAY(ary)->ptr[RARRAY(ary)->len-1];
00775 }
00776 else {
00777 VALUE nv, result;
00778 long n, i;
00779
00780 rb_scan_args(argc, argv, "01", &nv);
00781 n = NUM2LONG(nv);
00782 if (n > RARRAY(ary)->len) n = RARRAY(ary)->len;
00783 result = rb_ary_new2(n);
00784 for (i=RARRAY(ary)->len-n; n--; i++) {
00785 rb_ary_push(result, RARRAY(ary)->ptr[i]);
00786 }
00787 return result;
00788 }
00789 }
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 static VALUE
00812 rb_ary_fetch(argc, argv, ary)
00813 int argc;
00814 VALUE *argv;
00815 VALUE ary;
00816 {
00817 VALUE pos, ifnone;
00818 long block_given;
00819 long idx;
00820
00821 rb_scan_args(argc, argv, "11", &pos, &ifnone);
00822 block_given = rb_block_given_p();
00823 if (block_given && argc == 2) {
00824 rb_warn("block supersedes default value argument");
00825 }
00826 idx = NUM2LONG(pos);
00827
00828 if (idx < 0) {
00829 idx += RARRAY(ary)->len;
00830 }
00831 if (idx < 0 || RARRAY(ary)->len <= idx) {
00832 if (block_given) return rb_yield(pos);
00833 if (argc == 1) {
00834 rb_raise(rb_eIndexError, "index %ld out of array", idx);
00835 }
00836 return ifnone;
00837 }
00838 return RARRAY(ary)->ptr[idx];
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854 static VALUE
00855 rb_ary_index(ary, val)
00856 VALUE ary;
00857 VALUE val;
00858 {
00859 long i;
00860
00861 for (i=0; i<RARRAY(ary)->len; i++) {
00862 if (rb_equal(RARRAY(ary)->ptr[i], val))
00863 return LONG2NUM(i);
00864 }
00865 return Qnil;
00866 }
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881 static VALUE
00882 rb_ary_rindex(ary, val)
00883 VALUE ary;
00884 VALUE val;
00885 {
00886 long i = RARRAY(ary)->len;
00887
00888 while (i--) {
00889 if (i > RARRAY(ary)->len) {
00890 i = RARRAY(ary)->len;
00891 continue;
00892 }
00893 if (rb_equal(RARRAY(ary)->ptr[i], val))
00894 return LONG2NUM(i);
00895 }
00896 return Qnil;
00897 }
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907 static VALUE
00908 rb_ary_indexes(argc, argv, ary)
00909 int argc;
00910 VALUE *argv;
00911 VALUE ary;
00912 {
00913 VALUE new_ary;
00914 long i;
00915
00916 rb_warn("Array#%s is deprecated; use Array#values_at", rb_id2name(rb_frame_last_func()));
00917 new_ary = rb_ary_new2(argc);
00918 for (i=0; i<argc; i++) {
00919 rb_ary_push(new_ary, rb_ary_aref(1, argv+i, ary));
00920 }
00921
00922 return new_ary;
00923 }
00924
00925 VALUE
00926 rb_ary_to_ary(obj)
00927 VALUE obj;
00928 {
00929 if (TYPE(obj) == T_ARRAY) {
00930 return obj;
00931 }
00932 if (rb_respond_to(obj, rb_intern("to_ary"))) {
00933 return rb_convert_type(obj, T_ARRAY, "Array", "to_ary");
00934 }
00935 return rb_ary_new3(1, obj);
00936 }
00937
00938 static void
00939 rb_ary_splice(ary, beg, len, rpl)
00940 VALUE ary;
00941 long beg, len;
00942 VALUE rpl;
00943 {
00944 long rlen;
00945
00946 if (len < 0) rb_raise(rb_eIndexError, "negative length (%ld)", len);
00947 if (beg < 0) {
00948 beg += RARRAY(ary)->len;
00949 if (beg < 0) {
00950 beg -= RARRAY(ary)->len;
00951 rb_raise(rb_eIndexError, "index %ld out of array", beg);
00952 }
00953 }
00954 if (beg + len > RARRAY(ary)->len) {
00955 len = RARRAY(ary)->len - beg;
00956 }
00957
00958 if (NIL_P(rpl)) {
00959 rlen = 0;
00960 }
00961 else {
00962 rpl = rb_ary_to_ary(rpl);
00963 rlen = RARRAY(rpl)->len;
00964 }
00965 rb_ary_modify(ary);
00966
00967 if (beg >= RARRAY(ary)->len) {
00968 len = beg + rlen;
00969 if (len >= RARRAY(ary)->aux.capa) {
00970 REALLOC_N(RARRAY(ary)->ptr, VALUE, len);
00971 RARRAY(ary)->aux.capa = len;
00972 }
00973 rb_mem_clear(RARRAY(ary)->ptr + RARRAY(ary)->len, beg - RARRAY(ary)->len);
00974 if (rlen > 0) {
00975 MEMCPY(RARRAY(ary)->ptr + beg, RARRAY(rpl)->ptr, VALUE, rlen);
00976 }
00977 RARRAY(ary)->len = len;
00978 }
00979 else {
00980 long alen;
00981
00982 if (beg + len > RARRAY(ary)->len) {
00983 len = RARRAY(ary)->len - beg;
00984 }
00985
00986 alen = RARRAY(ary)->len + rlen - len;
00987 if (alen >= RARRAY(ary)->aux.capa) {
00988 REALLOC_N(RARRAY(ary)->ptr, VALUE, alen);
00989 RARRAY(ary)->aux.capa = alen;
00990 }
00991
00992 if (len != rlen) {
00993 MEMMOVE(RARRAY(ary)->ptr + beg + rlen, RARRAY(ary)->ptr + beg + len,
00994 VALUE, RARRAY(ary)->len - (beg + len));
00995 RARRAY(ary)->len = alen;
00996 }
00997 if (rlen > 0) {
00998 MEMMOVE(RARRAY(ary)->ptr + beg, RARRAY(rpl)->ptr, VALUE, rlen);
00999 }
01000 }
01001 }
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031 static VALUE
01032 rb_ary_aset(argc, argv, ary)
01033 int argc;
01034 VALUE *argv;
01035 VALUE ary;
01036 {
01037 long offset, beg, len;
01038
01039 if (argc == 3) {
01040 if (SYMBOL_P(argv[0])) {
01041 rb_raise(rb_eTypeError, "Symbol as array index");
01042 }
01043 if (SYMBOL_P(argv[1])) {
01044 rb_raise(rb_eTypeError, "Symbol as subarray length");
01045 }
01046 rb_ary_splice(ary, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]);
01047 return argv[2];
01048 }
01049 if (argc != 2) {
01050 rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
01051 }
01052 if (FIXNUM_P(argv[0])) {
01053 offset = FIX2LONG(argv[0]);
01054 goto fixnum;
01055 }
01056 if (SYMBOL_P(argv[0])) {
01057 rb_raise(rb_eTypeError, "Symbol as array index");
01058 }
01059 if (rb_range_beg_len(argv[0], &beg, &len, RARRAY(ary)->len, 1)) {
01060
01061 rb_ary_splice(ary, beg, len, argv[1]);
01062 return argv[1];
01063 }
01064
01065 offset = NUM2LONG(argv[0]);
01066 fixnum:
01067 rb_ary_store(ary, offset, argv[1]);
01068 return argv[1];
01069 }
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083 static VALUE
01084 rb_ary_insert(argc, argv, ary)
01085 int argc;
01086 VALUE *argv;
01087 VALUE ary;
01088 {
01089 long pos;
01090
01091 if (argc == 1) return ary;
01092 if (argc < 1) {
01093 rb_raise(rb_eArgError, "wrong number of arguments (at least 1)");
01094 }
01095 pos = NUM2LONG(argv[0]);
01096 if (pos == -1) {
01097 pos = RARRAY(ary)->len;
01098 }
01099 if (pos < 0) {
01100 pos++;
01101 }
01102 rb_ary_splice(ary, pos, 0, rb_ary_new4(argc - 1, argv + 1));
01103 return ary;
01104 }
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121 VALUE
01122 rb_ary_each(ary)
01123 VALUE ary;
01124 {
01125 long i;
01126
01127 for (i=0; i<RARRAY(ary)->len; i++) {
01128 rb_yield(RARRAY(ary)->ptr[i]);
01129 }
01130 return ary;
01131 }
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 static VALUE
01149 rb_ary_each_index(ary)
01150 VALUE ary;
01151 {
01152 long i;
01153
01154 for (i=0; i<RARRAY(ary)->len; i++) {
01155 rb_yield(LONG2NUM(i));
01156 }
01157 return ary;
01158 }
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175 static VALUE
01176 rb_ary_reverse_each(ary)
01177 VALUE ary;
01178 {
01179 long len = RARRAY(ary)->len;
01180
01181 while (len--) {
01182 rb_yield(RARRAY(ary)->ptr[len]);
01183 if (RARRAY(ary)->len < len) {
01184 len = RARRAY(ary)->len;
01185 }
01186 }
01187 return ary;
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199 static VALUE
01200 rb_ary_length(ary)
01201 VALUE ary;
01202 {
01203 return LONG2NUM(RARRAY(ary)->len);
01204 }
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215 static VALUE
01216 rb_ary_empty_p(ary)
01217 VALUE ary;
01218 {
01219 if (RARRAY(ary)->len == 0)
01220 return Qtrue;
01221 return Qfalse;
01222 }
01223
01224 VALUE
01225 rb_ary_dup(ary)
01226 VALUE ary;
01227 {
01228 VALUE dup = rb_ary_new2(RARRAY(ary)->len);
01229
01230 DUPSETUP(dup, ary);
01231 MEMCPY(RARRAY(dup)->ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
01232 RARRAY(dup)->len = RARRAY(ary)->len;
01233 return dup;
01234 }
01235
01236 extern VALUE rb_output_fs;
01237
01238 static VALUE
01239 inspect_join(ary, arg)
01240 VALUE ary;
01241 VALUE *arg;
01242 {
01243 return rb_ary_join(arg[0], arg[1]);
01244 }
01245
01246 VALUE
01247 rb_ary_join(ary, sep)
01248 VALUE ary, sep;
01249 {
01250 long len = 1, i;
01251 int taint = Qfalse;
01252 VALUE result, tmp;
01253
01254 if (RARRAY(ary)->len == 0) return rb_str_new(0, 0);
01255 if (OBJ_TAINTED(ary) || OBJ_TAINTED(sep)) taint = Qtrue;
01256
01257 for (i=0; i<RARRAY(ary)->len; i++) {
01258 tmp = rb_check_string_type(RARRAY(ary)->ptr[i]);
01259 len += NIL_P(tmp) ? 10 : RSTRING(tmp)->len;
01260 }
01261 if (!NIL_P(sep)) {
01262 StringValue(sep);
01263 len += RSTRING(sep)->len * (RARRAY(ary)->len - 1);
01264 }
01265 result = rb_str_buf_new(len);
01266 for (i=0; i<RARRAY(ary)->len; i++) {
01267 tmp = RARRAY(ary)->ptr[i];
01268 switch (TYPE(tmp)) {
01269 case T_STRING:
01270 break;
01271 case T_ARRAY:
01272 if (rb_inspecting_p(tmp)) {
01273 tmp = rb_str_new2("[...]");
01274 }
01275 else {
01276 VALUE args[2];
01277
01278 args[0] = tmp;
01279 args[1] = sep;
01280 tmp = rb_protect_inspect(inspect_join, ary, (VALUE)args);
01281 }
01282 break;
01283 default:
01284 tmp = rb_obj_as_string(tmp);
01285 }
01286 if (i > 0 && !NIL_P(sep))
01287 rb_str_buf_append(result, sep);
01288 rb_str_buf_append(result, tmp);
01289 if (OBJ_TAINTED(tmp)) taint = Qtrue;
01290 }
01291
01292 if (taint) OBJ_TAINT(result);
01293 return result;
01294 }
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307 static VALUE
01308 rb_ary_join_m(argc, argv, ary)
01309 int argc;
01310 VALUE *argv;
01311 VALUE ary;
01312 {
01313 VALUE sep;
01314
01315 rb_scan_args(argc, argv, "01", &sep);
01316 if (NIL_P(sep)) sep = rb_output_fs;
01317
01318 return rb_ary_join(ary, sep);
01319 }
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331 VALUE
01332 rb_ary_to_s(ary)
01333 VALUE ary;
01334 {
01335 if (RARRAY(ary)->len == 0) return rb_str_new(0, 0);
01336
01337 return rb_ary_join(ary, rb_output_fs);
01338 }
01339
01340 static ID inspect_key;
01341
01342 struct inspect_arg {
01343 VALUE (*func)();
01344 VALUE arg1, arg2;
01345 };
01346
01347 static VALUE
01348 inspect_call(arg)
01349 struct inspect_arg *arg;
01350 {
01351 return (*arg->func)(arg->arg1, arg->arg2);
01352 }
01353
01354 static VALUE
01355 get_inspect_tbl(create)
01356 int create;
01357 {
01358 VALUE inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key);
01359
01360 if (NIL_P(inspect_tbl)) {
01361 if (create) {
01362 tbl_init:
01363 inspect_tbl = rb_ary_new();
01364 rb_thread_local_aset(rb_thread_current(), inspect_key, inspect_tbl);
01365 }
01366 }
01367 else if (TYPE(inspect_tbl) != T_ARRAY) {
01368 rb_warn("invalid inspect_tbl value");
01369 if (create) goto tbl_init;
01370 rb_thread_local_aset(rb_thread_current(), inspect_key, Qnil);
01371 return Qnil;
01372 }
01373 return inspect_tbl;
01374 }
01375
01376 static VALUE
01377 inspect_ensure(obj)
01378 VALUE obj;
01379 {
01380 VALUE inspect_tbl;
01381
01382 inspect_tbl = get_inspect_tbl(Qfalse);
01383 if (!NIL_P(inspect_tbl)) {
01384 rb_ary_pop(inspect_tbl);
01385 }
01386 return 0;
01387 }
01388
01389 VALUE
01390 rb_protect_inspect(func, obj, arg)
01391 VALUE (*func)(ANYARGS);
01392 VALUE obj, arg;
01393 {
01394 struct inspect_arg iarg;
01395 VALUE inspect_tbl;
01396 VALUE id;
01397
01398 inspect_tbl = get_inspect_tbl(Qtrue);
01399 id = rb_obj_id(obj);
01400 if (rb_ary_includes(inspect_tbl, id)) {
01401 return (*func)(obj, arg);
01402 }
01403 rb_ary_push(inspect_tbl, id);
01404 iarg.func = func;
01405 iarg.arg1 = obj;
01406 iarg.arg2 = arg;
01407
01408 return rb_ensure(inspect_call, (VALUE)&iarg, inspect_ensure, obj);
01409 }
01410
01411 VALUE
01412 rb_inspecting_p(obj)
01413 VALUE obj;
01414 {
01415 VALUE inspect_tbl;
01416
01417 inspect_tbl = get_inspect_tbl(Qfalse);
01418 if (NIL_P(inspect_tbl)) return Qfalse;
01419 return rb_ary_includes(inspect_tbl, rb_obj_id(obj));
01420 }
01421
01422 static VALUE
01423 inspect_ary(ary)
01424 VALUE ary;
01425 {
01426 int tainted = OBJ_TAINTED(ary);
01427 long i;
01428 VALUE s, str;
01429
01430 str = rb_str_buf_new2("[");
01431 for (i=0; i<RARRAY(ary)->len; i++) {
01432 s = rb_inspect(RARRAY(ary)->ptr[i]);
01433 if (OBJ_TAINTED(s)) tainted = Qtrue;
01434 if (i > 0) rb_str_buf_cat2(str, ", ");
01435 rb_str_buf_append(str, s);
01436 }
01437 rb_str_buf_cat2(str, "]");
01438 if (tainted) OBJ_TAINT(str);
01439 return str;
01440 }
01441
01442
01443
01444
01445
01446
01447
01448
01449 static VALUE
01450 rb_ary_inspect(ary)
01451 VALUE ary;
01452 {
01453 if (RARRAY(ary)->len == 0) return rb_str_new2("[]");
01454 if (rb_inspecting_p(ary)) return rb_str_new2("[...]");
01455 return rb_protect_inspect(inspect_ary, ary, 0);
01456 }
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466 static VALUE
01467 rb_ary_to_a(ary)
01468 VALUE ary;
01469 {
01470 if (rb_obj_class(ary) != rb_cArray) {
01471 VALUE dup = rb_ary_new2(RARRAY(ary)->len);
01472 rb_ary_replace(dup, ary);
01473 return dup;
01474 }
01475 return ary;
01476 }
01477
01478
01479
01480
01481
01482
01483
01484
01485 static VALUE
01486 rb_ary_to_ary_m(ary)
01487 VALUE ary;
01488 {
01489 return ary;
01490 }
01491
01492 VALUE
01493 rb_ary_reverse(ary)
01494 VALUE ary;
01495 {
01496 VALUE *p1, *p2;
01497 VALUE tmp;
01498
01499 rb_ary_modify(ary);
01500 if (RARRAY(ary)->len > 1) {
01501 p1 = RARRAY(ary)->ptr;
01502 p2 = p1 + RARRAY(ary)->len - 1;
01503
01504 while (p1 < p2) {
01505 tmp = *p1;
01506 *p1++ = *p2;
01507 *p2-- = tmp;
01508 }
01509 }
01510 return ary;
01511 }
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524 static VALUE
01525 rb_ary_reverse_bang(ary)
01526 VALUE ary;
01527 {
01528 return rb_ary_reverse(ary);
01529 }
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541 static VALUE
01542 rb_ary_reverse_m(ary)
01543 VALUE ary;
01544 {
01545 return rb_ary_reverse(rb_ary_dup(ary));
01546 }
01547
01548 struct ary_sort_data {
01549 VALUE ary;
01550 VALUE *ptr;
01551 long len;
01552 };
01553
01554 static void
01555 ary_sort_check(data)
01556 struct ary_sort_data *data;
01557 {
01558 if (RARRAY(data->ary)->ptr != data->ptr || RARRAY(data->ary)->len != data->len) {
01559 rb_raise(rb_eArgError, "array modified during sort");
01560 }
01561 }
01562
01563 static int
01564 sort_1(a, b, data)
01565 VALUE *a, *b;
01566 struct ary_sort_data *data;
01567 {
01568 VALUE retval = rb_yield_values(2, *a, *b);
01569 int n;
01570
01571 n = rb_cmpint(retval, *a, *b);
01572 ary_sort_check(data);
01573 return n;
01574 }
01575
01576 static int
01577 sort_2(ap, bp, data)
01578 VALUE *ap, *bp;
01579 struct ary_sort_data *data;
01580 {
01581 VALUE retval;
01582 VALUE a = *ap, b = *bp;
01583 int n;
01584
01585 if (FIXNUM_P(a) && FIXNUM_P(b)) {
01586 if ((long)a > (long)b) return 1;
01587 if ((long)a < (long)b) return -1;
01588 return 0;
01589 }
01590 if (TYPE(a) == T_STRING) {
01591 if (TYPE(b) == T_STRING) return rb_str_cmp(a, b);
01592 }
01593
01594 retval = rb_funcall(a, id_cmp, 1, b);
01595 n = rb_cmpint(retval, a, b);
01596 ary_sort_check(data);
01597
01598 return n;
01599 }
01600
01601 static VALUE
01602 sort_internal(ary)
01603 VALUE ary;
01604 {
01605 struct ary_sort_data data;
01606
01607 data.ary = ary;
01608 data.ptr = RARRAY(ary)->ptr; data.len = RARRAY(ary)->len;
01609 qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE),
01610 rb_block_given_p()?sort_1:sort_2, &data);
01611 return ary;
01612 }
01613
01614 static VALUE
01615 sort_unlock(ary)
01616 VALUE ary;
01617 {
01618 FL_UNSET(ary, ARY_TMPLOCK);
01619 return ary;
01620 }
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638 VALUE
01639 rb_ary_sort_bang(ary)
01640 VALUE ary;
01641 {
01642 rb_ary_modify(ary);
01643 if (RARRAY(ary)->len > 1) {
01644 FL_SET(ary, ARY_TMPLOCK);
01645 rb_ensure(sort_internal, ary, sort_unlock, ary);
01646 }
01647 return ary;
01648 }
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666 VALUE
01667 rb_ary_sort(ary)
01668 VALUE ary;
01669 {
01670 ary = rb_ary_dup(ary);
01671 rb_ary_sort_bang(ary);
01672 return ary;
01673 }
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689 static VALUE
01690 rb_ary_collect(ary)
01691 VALUE ary;
01692 {
01693 long i;
01694 VALUE collect;
01695
01696 if (!rb_block_given_p()) {
01697 return rb_ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr);
01698 }
01699
01700 collect = rb_ary_new2(RARRAY(ary)->len);
01701 for (i = 0; i < RARRAY(ary)->len; i++) {
01702 rb_ary_push(collect, rb_yield(RARRAY(ary)->ptr[i]));
01703 }
01704 return collect;
01705 }
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721 static VALUE
01722 rb_ary_collect_bang(ary)
01723 VALUE ary;
01724 {
01725 long i;
01726
01727 rb_ary_modify(ary);
01728 for (i = 0; i < RARRAY(ary)->len; i++) {
01729 rb_ary_store(ary, i, rb_yield(RARRAY(ary)->ptr[i]));
01730 }
01731 return ary;
01732 }
01733
01734 VALUE
01735 rb_values_at(obj, olen, argc, argv, func)
01736 VALUE obj;
01737 long olen;
01738 int argc;
01739 VALUE *argv;
01740 VALUE (*func) (VALUE,long);
01741 {
01742 VALUE result = rb_ary_new2(argc);
01743 long beg, len, i, j;
01744
01745 for (i=0; i<argc; i++) {
01746 if (FIXNUM_P(argv[i])) {
01747 rb_ary_push(result, (*func)(obj, FIX2LONG(argv[i])));
01748 continue;
01749 }
01750
01751 switch (rb_range_beg_len(argv[i], &beg, &len, olen, 0)) {
01752 case Qfalse:
01753 break;
01754 case Qnil:
01755 continue;
01756 default:
01757 for (j=0; j<len; j++) {
01758 rb_ary_push(result, (*func)(obj, j+beg));
01759 }
01760 continue;
01761 }
01762 rb_ary_push(result, (*func)(obj, NUM2LONG(argv[i])));
01763 }
01764 return result;
01765 }
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783 static VALUE
01784 rb_ary_values_at(argc, argv, ary)
01785 int argc;
01786 VALUE *argv;
01787 VALUE ary;
01788 {
01789 return rb_values_at(ary, RARRAY(ary)->len, argc, argv, rb_ary_entry);
01790 }
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804 static VALUE
01805 rb_ary_select(ary)
01806 VALUE ary;
01807 {
01808 VALUE result;
01809 long i;
01810
01811 result = rb_ary_new2(RARRAY(ary)->len);
01812 for (i = 0; i < RARRAY(ary)->len; i++) {
01813 if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) {
01814 rb_ary_push(result, rb_ary_elt(ary, i));
01815 }
01816 }
01817 return result;
01818 }
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837 VALUE
01838 rb_ary_delete(ary, item)
01839 VALUE ary;
01840 VALUE item;
01841 {
01842 long i1, i2;
01843
01844 for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
01845 VALUE e = RARRAY(ary)->ptr[i1];
01846
01847 if (rb_equal(e, item)) continue;
01848 if (i1 != i2) {
01849 rb_ary_store(ary, i2, e);
01850 }
01851 i2++;
01852 }
01853 if (RARRAY(ary)->len == i2) {
01854 if (rb_block_given_p()) {
01855 return rb_yield(item);
01856 }
01857 return Qnil;
01858 }
01859
01860 rb_ary_modify(ary);
01861 if (RARRAY(ary)->len > i2) {
01862 RARRAY(ary)->len = i2;
01863 if (i2 * 2 < RARRAY(ary)->aux.capa &&
01864 RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) {
01865 REALLOC_N(RARRAY(ary)->ptr, VALUE, i2 * 2);
01866 RARRAY(ary)->aux.capa = i2 * 2;
01867 }
01868 }
01869
01870 return item;
01871 }
01872
01873 VALUE
01874 rb_ary_delete_at(ary, pos)
01875 VALUE ary;
01876 long pos;
01877 {
01878 long i, len = RARRAY(ary)->len;
01879 VALUE del;
01880
01881 if (pos >= len) return Qnil;
01882 if (pos < 0) {
01883 pos += len;
01884 if (pos < 0) return Qnil;
01885 }
01886
01887 rb_ary_modify(ary);
01888 del = RARRAY(ary)->ptr[pos];
01889 for (i = pos + 1; i < len; i++, pos++) {
01890 RARRAY(ary)->ptr[pos] = RARRAY(ary)->ptr[i];
01891 }
01892 RARRAY(ary)->len = pos;
01893
01894 return del;
01895 }
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911 static VALUE
01912 rb_ary_delete_at_m(ary, pos)
01913 VALUE ary, pos;
01914 {
01915 return rb_ary_delete_at(ary, NUM2LONG(pos));
01916 }
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943 static VALUE
01944 rb_ary_slice_bang(argc, argv, ary)
01945 int argc;
01946 VALUE *argv;
01947 VALUE ary;
01948 {
01949 VALUE arg1, arg2;
01950 long pos, len;
01951
01952 if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) {
01953 pos = NUM2LONG(arg1);
01954 len = NUM2LONG(arg2);
01955 delete_pos_len:
01956 if (pos < 0) {
01957 pos = RARRAY(ary)->len + pos;
01958 }
01959 arg2 = rb_ary_subseq(ary, pos, len);
01960 rb_ary_splice(ary, pos, len, Qnil);
01961 return arg2;
01962 }
01963
01964 if (!FIXNUM_P(arg1) && rb_range_beg_len(arg1, &pos, &len, RARRAY(ary)->len, 1)) {
01965 goto delete_pos_len;
01966 }
01967
01968 return rb_ary_delete_at(ary, NUM2LONG(arg1));
01969 }
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981 static VALUE
01982 rb_ary_reject_bang(ary)
01983 VALUE ary;
01984 {
01985 long i1, i2;
01986
01987 rb_ary_modify(ary);
01988 for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
01989 VALUE v = RARRAY(ary)->ptr[i1];
01990 if (RTEST(rb_yield(v))) continue;
01991 if (i1 != i2) {
01992 rb_ary_store(ary, i2, v);
01993 }
01994 i2++;
01995 }
01996 if (RARRAY(ary)->len == i2) return Qnil;
01997 if (i2 < RARRAY(ary)->len)
01998 RARRAY(ary)->len = i2;
01999
02000 return ary;
02001 }
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011 static VALUE
02012 rb_ary_reject(ary)
02013 VALUE ary;
02014 {
02015 ary = rb_ary_dup(ary);
02016 rb_ary_reject_bang(ary);
02017 return ary;
02018 }
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031 static VALUE
02032 rb_ary_delete_if(ary)
02033 VALUE ary;
02034 {
02035 rb_ary_reject_bang(ary);
02036 return ary;
02037 }
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061 static VALUE
02062 rb_ary_zip(argc, argv, ary)
02063 int argc;
02064 VALUE *argv;
02065 VALUE ary;
02066 {
02067 int i, j;
02068 long len;
02069 VALUE result;
02070
02071 for (i=0; i<argc; i++) {
02072 argv[i] = to_ary(argv[i]);
02073 }
02074 if (rb_block_given_p()) {
02075 for (i=0; i<RARRAY(ary)->len; i++) {
02076 VALUE tmp = rb_ary_new2(argc+1);
02077
02078 rb_ary_push(tmp, rb_ary_elt(ary, i));
02079 for (j=0; j<argc; j++) {
02080 rb_ary_push(tmp, rb_ary_elt(argv[j], i));
02081 }
02082 rb_yield(tmp);
02083 }
02084 return Qnil;
02085 }
02086 len = RARRAY(ary)->len;
02087 result = rb_ary_new2(len);
02088 for (i=0; i<len; i++) {
02089 VALUE tmp = rb_ary_new2(argc+1);
02090
02091 rb_ary_push(tmp, rb_ary_elt(ary, i));
02092 for (j=0; j<argc; j++) {
02093 rb_ary_push(tmp, rb_ary_elt(argv[j], i));
02094 }
02095 rb_ary_push(result, tmp);
02096 }
02097 return result;
02098 }
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111 static VALUE
02112 rb_ary_transpose(ary)
02113 VALUE ary;
02114 {
02115 long elen = -1, alen, i, j;
02116 VALUE tmp, result = 0;
02117
02118 alen = RARRAY(ary)->len;
02119 if (alen == 0) return rb_ary_dup(ary);
02120 for (i=0; i<alen; i++) {
02121 tmp = to_ary(rb_ary_elt(ary, i));
02122 if (elen < 0) {
02123 elen = RARRAY(tmp)->len;
02124 result = rb_ary_new2(elen);
02125 for (j=0; j<elen; j++) {
02126 rb_ary_store(result, j, rb_ary_new2(alen));
02127 }
02128 }
02129 else if (elen != RARRAY(tmp)->len) {
02130 rb_raise(rb_eIndexError, "element size differs (%d should be %d)",
02131 RARRAY(tmp)->len, elen);
02132 }
02133 for (j=0; j<elen; j++) {
02134 rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
02135 }
02136 }
02137 return result;
02138 }
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152 static VALUE
02153 rb_ary_replace(copy, orig)
02154 VALUE copy, orig;
02155 {
02156 VALUE shared;
02157
02158 rb_ary_modify(copy);
02159 orig = to_ary(orig);
02160 if (copy == orig) return copy;
02161 shared = ary_make_shared(orig);
02162 if (RARRAY(copy)->ptr && !FL_TEST(copy, ELTS_SHARED))
02163 free(RARRAY(copy)->ptr);
02164 RARRAY(copy)->ptr = RARRAY(orig)->ptr;
02165 RARRAY(copy)->len = RARRAY(orig)->len;
02166 RARRAY(copy)->aux.shared = shared;
02167 FL_SET(copy, ELTS_SHARED);
02168
02169 return copy;
02170 }
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182 VALUE
02183 rb_ary_clear(ary)
02184 VALUE ary;
02185 {
02186 rb_ary_modify(ary);
02187 RARRAY(ary)->len = 0;
02188 if (ARY_DEFAULT_SIZE * 2 < RARRAY(ary)->aux.capa) {
02189 REALLOC_N(RARRAY(ary)->ptr, VALUE, ARY_DEFAULT_SIZE * 2);
02190 RARRAY(ary)->aux.capa = ARY_DEFAULT_SIZE * 2;
02191 }
02192 return ary;
02193 }
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219 static VALUE
02220 rb_ary_fill(argc, argv, ary)
02221 int argc;
02222 VALUE *argv;
02223 VALUE ary;
02224 {
02225 VALUE item, arg1, arg2;
02226 long beg, end, len;
02227 VALUE *p, *pend;
02228 int block_p = Qfalse;
02229
02230 if (rb_block_given_p()) {
02231 block_p = Qtrue;
02232 rb_scan_args(argc, argv, "02", &arg1, &arg2);
02233 argc += 1;
02234 }
02235 else {
02236 rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
02237 }
02238 switch (argc) {
02239 case 1:
02240 beg = 0;
02241 len = RARRAY(ary)->len;
02242 break;
02243 case 2:
02244 if (rb_range_beg_len(arg1, &beg, &len, RARRAY(ary)->len, 1)) {
02245 break;
02246 }
02247
02248 case 3:
02249 beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
02250 if (beg < 0) {
02251 beg = RARRAY(ary)->len + beg;
02252 if (beg < 0) beg = 0;
02253 }
02254 len = NIL_P(arg2) ? RARRAY(ary)->len - beg : NUM2LONG(arg2);
02255 break;
02256 }
02257 rb_ary_modify(ary);
02258 end = beg + len;
02259 if (end > RARRAY(ary)->len) {
02260 if (end >= RARRAY(ary)->aux.capa) {
02261 REALLOC_N(RARRAY(ary)->ptr, VALUE, end);
02262 RARRAY(ary)->aux.capa = end;
02263 }
02264 rb_mem_clear(RARRAY(ary)->ptr + RARRAY(ary)->len, end - RARRAY(ary)->len);
02265 RARRAY(ary)->len = end;
02266 }
02267
02268 if (block_p) {
02269 VALUE v;
02270 long i;
02271
02272 for (i=beg; i<end; i++) {
02273 v = rb_yield(LONG2NUM(i));
02274 if (i>=RARRAY(ary)->len) break;
02275 RARRAY(ary)->ptr[i] = v;
02276 }
02277 }
02278 else {
02279 p = RARRAY(ary)->ptr + beg;
02280 pend = p + len;
02281 while (p < pend) {
02282 *p++ = item;
02283 }
02284 }
02285 return ary;
02286 }
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298 VALUE
02299 rb_ary_plus(x, y)
02300 VALUE x, y;
02301 {
02302 VALUE z;
02303 long len;
02304
02305 y = to_ary(y);
02306 len = RARRAY(x)->len + RARRAY(y)->len;
02307 z = rb_ary_new2(len);
02308 MEMCPY(RARRAY(z)->ptr, RARRAY(x)->ptr, VALUE, RARRAY(x)->len);
02309 MEMCPY(RARRAY(z)->ptr + RARRAY(x)->len, RARRAY(y)->ptr, VALUE, RARRAY(y)->len);
02310 RARRAY(z)->len = len;
02311 return z;
02312 }
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324 VALUE
02325 rb_ary_concat(x, y)
02326 VALUE x, y;
02327 {
02328 y = to_ary(y);
02329 if (RARRAY(y)->len > 0) {
02330 rb_ary_splice(x, RARRAY(x)->len, 0, y);
02331 }
02332 return x;
02333 }
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351 static VALUE
02352 rb_ary_times(ary, times)
02353 VALUE ary, times;
02354 {
02355 VALUE ary2, tmp;
02356 long i, len;
02357
02358 tmp = rb_check_string_type(times);
02359 if (!NIL_P(tmp)) {
02360 return rb_ary_join(ary, tmp);
02361 }
02362
02363 len = NUM2LONG(times);
02364 if (len == 0) return ary_new(rb_obj_class(ary), 0);
02365 if (len < 0) {
02366 rb_raise(rb_eArgError, "negative argument");
02367 }
02368 if (LONG_MAX/len < RARRAY(ary)->len) {
02369 rb_raise(rb_eArgError, "argument too big");
02370 }
02371 len *= RARRAY(ary)->len;
02372
02373 ary2 = ary_new(rb_obj_class(ary), len);
02374 RARRAY(ary2)->len = len;
02375
02376 for (i=0; i<len; i+=RARRAY(ary)->len) {
02377 MEMCPY(RARRAY(ary2)->ptr+i, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
02378 }
02379 OBJ_INFECT(ary2, ary);
02380
02381 return ary2;
02382 }
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404 VALUE
02405 rb_ary_assoc(ary, key)
02406 VALUE ary, key;
02407 {
02408 long i;
02409 VALUE v;
02410
02411 for (i = 0; i < RARRAY(ary)->len; ++i) {
02412 v = RARRAY(ary)->ptr[i];
02413 if (TYPE(v) == T_ARRAY &&
02414 RARRAY(v)->len > 0 &&
02415 rb_equal(RARRAY(v)->ptr[0], key))
02416 return v;
02417 }
02418 return Qnil;
02419 }
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435 VALUE
02436 rb_ary_rassoc(ary, value)
02437 VALUE ary, value;
02438 {
02439 long i;
02440 VALUE v;
02441
02442 for (i = 0; i < RARRAY(ary)->len; ++i) {
02443 v = RARRAY(ary)->ptr[i];
02444 if (TYPE(v) == T_ARRAY &&
02445 RARRAY(v)->len > 1 &&
02446 rb_equal(RARRAY(v)->ptr[1], value))
02447 return v;
02448 }
02449 return Qnil;
02450 }
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466 static VALUE
02467 rb_ary_equal(ary1, ary2)
02468 VALUE ary1, ary2;
02469 {
02470 long i;
02471
02472 if (ary1 == ary2) return Qtrue;
02473 if (TYPE(ary2) != T_ARRAY) {
02474 if (!rb_respond_to(ary2, rb_intern("to_ary"))) {
02475 return Qfalse;
02476 }
02477 return rb_equal(ary2, ary1);
02478 }
02479 if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse;
02480 for (i=0; i<RARRAY(ary1)->len; i++) {
02481 if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
02482 return Qfalse;
02483 }
02484 return Qtrue;
02485 }
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495 static VALUE
02496 rb_ary_eql(ary1, ary2)
02497 VALUE ary1, ary2;
02498 {
02499 long i;
02500
02501 if (ary1 == ary2) return Qtrue;
02502 if (TYPE(ary2) != T_ARRAY) return Qfalse;
02503 if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse;
02504 for (i=0; i<RARRAY(ary1)->len; i++) {
02505 if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
02506 return Qfalse;
02507 }
02508 return Qtrue;
02509 }
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519 static VALUE
02520 rb_ary_hash(ary)
02521 VALUE ary;
02522 {
02523 long i, h;
02524 VALUE n;
02525
02526 h = RARRAY(ary)->len;
02527 for (i=0; i<RARRAY(ary)->len; i++) {
02528 h = (h << 1) | (h<0 ? 1 : 0);
02529 n = rb_hash(RARRAY(ary)->ptr[i]);
02530 h ^= NUM2LONG(n);
02531 }
02532 return LONG2FIX(h);
02533 }
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548 VALUE
02549 rb_ary_includes(ary, item)
02550 VALUE ary;
02551 VALUE item;
02552 {
02553 long i;
02554
02555 for (i=0; i<RARRAY(ary)->len; i++) {
02556 if (rb_equal(RARRAY(ary)->ptr[i], item)) {
02557 return Qtrue;
02558 }
02559 }
02560 return Qfalse;
02561 }
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584 VALUE
02585 rb_ary_cmp(ary1, ary2)
02586 VALUE ary1, ary2;
02587 {
02588 long i, len;
02589
02590 ary2 = to_ary(ary2);
02591 len = RARRAY(ary1)->len;
02592 if (len > RARRAY(ary2)->len) {
02593 len = RARRAY(ary2)->len;
02594 }
02595 for (i=0; i<len; i++) {
02596 VALUE v = rb_funcall(rb_ary_elt(ary1, i), id_cmp, 1, rb_ary_elt(ary2, i));
02597 if (v != INT2FIX(0)) {
02598 return v;
02599 }
02600 }
02601 len = RARRAY(ary1)->len - RARRAY(ary2)->len;
02602 if (len == 0) return INT2FIX(0);
02603 if (len > 0) return INT2FIX(1);
02604 return INT2FIX(-1);
02605 }
02606
02607 static VALUE
02608 ary_make_hash(ary1, ary2)
02609 VALUE ary1, ary2;
02610 {
02611 VALUE hash = rb_hash_new();
02612 long i;
02613
02614 for (i=0; i<RARRAY(ary1)->len; i++) {
02615 rb_hash_aset(hash, RARRAY(ary1)->ptr[i], Qtrue);
02616 }
02617 if (ary2) {
02618 for (i=0; i<RARRAY(ary2)->len; i++) {
02619 rb_hash_aset(hash, RARRAY(ary2)->ptr[i], Qtrue);
02620 }
02621 }
02622 return hash;
02623 }
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637 static VALUE
02638 rb_ary_diff(ary1, ary2)
02639 VALUE ary1, ary2;
02640 {
02641 VALUE ary3;
02642 volatile VALUE hash;
02643 long i;
02644
02645 hash = ary_make_hash(to_ary(ary2), 0);
02646 ary3 = rb_ary_new();
02647
02648 for (i=0; i<RARRAY(ary1)->len; i++) {
02649 if (st_lookup(RHASH(hash)->tbl, RARRAY(ary1)->ptr[i], 0)) continue;
02650 rb_ary_push(ary3, rb_ary_elt(ary1, i));
02651 }
02652 return ary3;
02653 }
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666 static VALUE
02667 rb_ary_and(ary1, ary2)
02668 VALUE ary1, ary2;
02669 {
02670 VALUE hash, ary3, v, vv;
02671 long i;
02672
02673 ary2 = to_ary(ary2);
02674 ary3 = rb_ary_new2(RARRAY(ary1)->len < RARRAY(ary2)->len ?
02675 RARRAY(ary1)->len : RARRAY(ary2)->len);
02676 hash = ary_make_hash(ary2, 0);
02677
02678 for (i=0; i<RARRAY(ary1)->len; i++) {
02679 v = vv = rb_ary_elt(ary1, i);
02680 if (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {
02681 rb_ary_push(ary3, v);
02682 }
02683 }
02684
02685 return ary3;
02686 }
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699 static VALUE
02700 rb_ary_or(ary1, ary2)
02701 VALUE ary1, ary2;
02702 {
02703 VALUE hash, ary3;
02704 VALUE v, vv;
02705 long i;
02706
02707 ary2 = to_ary(ary2);
02708 ary3 = rb_ary_new2(RARRAY(ary1)->len+RARRAY(ary2)->len);
02709 hash = ary_make_hash(ary1, ary2);
02710
02711 for (i=0; i<RARRAY(ary1)->len; i++) {
02712 v = vv = rb_ary_elt(ary1, i);
02713 if (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {
02714 rb_ary_push(ary3, v);
02715 }
02716 }
02717 for (i=0; i<RARRAY(ary2)->len; i++) {
02718 v = vv = rb_ary_elt(ary2, i);
02719 if (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {
02720 rb_ary_push(ary3, v);
02721 }
02722 }
02723 return ary3;
02724 }
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740 static VALUE
02741 rb_ary_uniq_bang(ary)
02742 VALUE ary;
02743 {
02744 VALUE hash, v, vv;
02745 long i, j;
02746
02747 hash = ary_make_hash(ary, 0);
02748
02749 if (RARRAY(ary)->len == RHASH(hash)->tbl->num_entries) {
02750 return Qnil;
02751 }
02752 for (i=j=0; i<RARRAY(ary)->len; i++) {
02753 v = vv = rb_ary_elt(ary, i);
02754 if (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {
02755 rb_ary_store(ary, j++, v);
02756 }
02757 }
02758 RARRAY(ary)->len = j;
02759
02760 return ary;
02761 }
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773 static VALUE
02774 rb_ary_uniq(ary)
02775 VALUE ary;
02776 {
02777 ary = rb_ary_dup(ary);
02778 rb_ary_uniq_bang(ary);
02779 return ary;
02780 }
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793 static VALUE
02794 rb_ary_compact_bang(ary)
02795 VALUE ary;
02796 {
02797 VALUE *p, *t, *end;
02798
02799 rb_ary_modify(ary);
02800 p = t = RARRAY(ary)->ptr;
02801 end = p + RARRAY(ary)->len;
02802
02803 while (t < end) {
02804 if (NIL_P(*t)) t++;
02805 else *p++ = *t++;
02806 }
02807 if (RARRAY(ary)->len == (p - RARRAY(ary)->ptr)) {
02808 return Qnil;
02809 }
02810 RARRAY(ary)->len = RARRAY(ary)->aux.capa = (p - RARRAY(ary)->ptr);
02811 REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
02812
02813 return ary;
02814 }
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826 static VALUE
02827 rb_ary_compact(ary)
02828 VALUE ary;
02829 {
02830 ary = rb_ary_dup(ary);
02831 rb_ary_compact_bang(ary);
02832 return ary;
02833 }
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845 static VALUE
02846 rb_ary_nitems(ary)
02847 VALUE ary;
02848 {
02849 long n = 0;
02850 VALUE *p, *pend;
02851
02852 p = RARRAY(ary)->ptr;
02853 pend = p + RARRAY(ary)->len;
02854
02855 while (p < pend) {
02856 if (!NIL_P(*p)) n++;
02857 p++;
02858 }
02859 return LONG2NUM(n);
02860 }
02861
02862 static long
02863 flatten(ary, idx, ary2, memo)
02864 VALUE ary;
02865 long idx;
02866 VALUE ary2, memo;
02867 {
02868 VALUE id;
02869 long i = idx;
02870 long n, lim = idx + RARRAY(ary2)->len;
02871
02872 id = rb_obj_id(ary2);
02873 if (rb_ary_includes(memo, id)) {
02874 rb_raise(rb_eArgError, "tried to flatten recursive array");
02875 }
02876 rb_ary_push(memo, id);
02877 rb_ary_splice(ary, idx, 1, ary2);
02878 while (i < lim) {
02879 VALUE tmp;
02880
02881 tmp = rb_check_array_type(rb_ary_elt(ary, i));
02882 if (!NIL_P(tmp)) {
02883 n = flatten(ary, i, tmp, memo);
02884 i += n; lim += n;
02885 }
02886 i++;
02887 }
02888 rb_ary_pop(memo);
02889
02890 return lim - idx - 1;
02891 }
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907 static VALUE
02908 rb_ary_flatten_bang(ary)
02909 VALUE ary;
02910 {
02911 long i = 0;
02912 int mod = 0;
02913 VALUE memo = Qnil;
02914
02915 while (i<RARRAY(ary)->len) {
02916 VALUE ary2 = RARRAY(ary)->ptr[i];
02917 VALUE tmp;
02918
02919 tmp = rb_check_array_type(ary2);
02920 if (!NIL_P(tmp)) {
02921 if (NIL_P(memo)) {
02922 memo = rb_ary_new();
02923 }
02924 i += flatten(ary, i, tmp, memo);
02925 mod = 1;
02926 }
02927 i++;
02928 }
02929 if (mod == 0) return Qnil;
02930 return ary;
02931 }
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947 static VALUE
02948 rb_ary_flatten(ary)
02949 VALUE ary;
02950 {
02951 ary = rb_ary_dup(ary);
02952 rb_ary_flatten_bang(ary);
02953 return ary;
02954 }
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964 void
02965 Init_Array()
02966 {
02967 rb_cArray = rb_define_class("Array", rb_cObject);
02968 rb_include_module(rb_cArray, rb_mEnumerable);
02969
02970 rb_define_alloc_func(rb_cArray, ary_alloc);
02971 rb_define_singleton_method(rb_cArray, "[]", rb_ary_s_create, -1);
02972 rb_define_method(rb_cArray, "initialize", rb_ary_initialize, -1);
02973 rb_define_method(rb_cArray, "initialize_copy", rb_ary_replace, 1);
02974
02975 rb_define_method(rb_cArray, "to_s", rb_ary_to_s, 0);
02976 rb_define_method(rb_cArray, "inspect", rb_ary_inspect, 0);
02977 rb_define_method(rb_cArray, "to_a", rb_ary_to_a, 0);
02978 rb_define_method(rb_cArray, "to_ary", rb_ary_to_ary_m, 0);
02979 rb_define_method(rb_cArray, "frozen?", rb_ary_frozen_p, 0);
02980
02981 rb_define_method(rb_cArray, "==", rb_ary_equal, 1);
02982 rb_define_method(rb_cArray, "eql?", rb_ary_eql, 1);
02983 rb_define_method(rb_cArray, "hash", rb_ary_hash, 0);
02984
02985 rb_define_method(rb_cArray, "[]", rb_ary_aref, -1);
02986 rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1);
02987 rb_define_method(rb_cArray, "at", rb_ary_at, 1);
02988 rb_define_method(rb_cArray, "fetch", rb_ary_fetch, -1);
02989 rb_define_method(rb_cArray, "first", rb_ary_first, -1);
02990 rb_define_method(rb_cArray, "last", rb_ary_last, -1);
02991 rb_define_method(rb_cArray, "concat", rb_ary_concat, 1);
02992 rb_define_method(rb_cArray, "<<", rb_ary_push, 1);
02993 rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);
02994 rb_define_method(rb_cArray, "pop", rb_ary_pop, 0);
02995 rb_define_method(rb_cArray, "shift", rb_ary_shift, 0);
02996 rb_define_method(rb_cArray, "unshift", rb_ary_unshift_m, -1);
02997 rb_define_method(rb_cArray, "insert", rb_ary_insert, -1);
02998 rb_define_method(rb_cArray, "each", rb_ary_each, 0);
02999 rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0);
03000 rb_define_method(rb_cArray, "reverse_each", rb_ary_reverse_each, 0);
03001 rb_define_method(rb_cArray, "length", rb_ary_length, 0);
03002 rb_define_alias(rb_cArray, "size", "length");
03003 rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0);
03004 rb_define_method(rb_cArray, "index", rb_ary_index, 1);
03005 rb_define_method(rb_cArray, "rindex", rb_ary_rindex, 1);
03006 rb_define_method(rb_cArray, "indexes", rb_ary_indexes, -1);
03007 rb_define_method(rb_cArray, "indices", rb_ary_indexes, -1);
03008 rb_define_method(rb_cArray, "join", rb_ary_join_m, -1);
03009 rb_define_method(rb_cArray, "reverse", rb_ary_reverse_m, 0);
03010 rb_define_method(rb_cArray, "reverse!", rb_ary_reverse_bang, 0);
03011 rb_define_method(rb_cArray, "sort", rb_ary_sort, 0);
03012 rb_define_method(rb_cArray, "sort!", rb_ary_sort_bang, 0);
03013 rb_define_method(rb_cArray, "collect", rb_ary_collect, 0);
03014 rb_define_method(rb_cArray, "collect!", rb_ary_collect_bang, 0);
03015 rb_define_method(rb_cArray, "map", rb_ary_collect, 0);
03016 rb_define_method(rb_cArray, "map!", rb_ary_collect_bang, 0);
03017 rb_define_method(rb_cArray, "select", rb_ary_select, 0);
03018 rb_define_method(rb_cArray, "values_at", rb_ary_values_at, -1);
03019 rb_define_method(rb_cArray, "delete", rb_ary_delete, 1);
03020 rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at_m, 1);
03021 rb_define_method(rb_cArray, "delete_if", rb_ary_delete_if, 0);
03022 rb_define_method(rb_cArray, "reject", rb_ary_reject, 0);
03023 rb_define_method(rb_cArray, "reject!", rb_ary_reject_bang, 0);
03024 rb_define_method(rb_cArray, "zip", rb_ary_zip, -1);
03025 rb_define_method(rb_cArray, "transpose", rb_ary_transpose, 0);
03026 rb_define_method(rb_cArray, "replace", rb_ary_replace, 1);
03027 rb_define_method(rb_cArray, "clear", rb_ary_clear, 0);
03028 rb_define_method(rb_cArray, "fill", rb_ary_fill, -1);
03029 rb_define_method(rb_cArray, "include?", rb_ary_includes, 1);
03030 rb_define_method(rb_cArray, "<=>", rb_ary_cmp, 1);
03031
03032 rb_define_method(rb_cArray, "slice", rb_ary_aref, -1);
03033 rb_define_method(rb_cArray, "slice!", rb_ary_slice_bang, -1);
03034
03035 rb_define_method(rb_cArray, "assoc", rb_ary_assoc, 1);
03036 rb_define_method(rb_cArray, "rassoc", rb_ary_rassoc, 1);
03037
03038 rb_define_method(rb_cArray, "+", rb_ary_plus, 1);
03039 rb_define_method(rb_cArray, "*", rb_ary_times, 1);
03040
03041 rb_define_method(rb_cArray, "-", rb_ary_diff, 1);
03042 rb_define_method(rb_cArray, "&", rb_ary_and, 1);
03043 rb_define_method(rb_cArray, "|", rb_ary_or, 1);
03044
03045 rb_define_method(rb_cArray, "uniq", rb_ary_uniq, 0);
03046 rb_define_method(rb_cArray, "uniq!", rb_ary_uniq_bang, 0);
03047 rb_define_method(rb_cArray, "compact", rb_ary_compact, 0);
03048 rb_define_method(rb_cArray, "compact!", rb_ary_compact_bang, 0);
03049 rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0);
03050 rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, 0);
03051 rb_define_method(rb_cArray, "nitems", rb_ary_nitems, 0);
03052
03053 id_cmp = rb_intern("<=>");
03054 inspect_key = rb_intern("__inspect_key__");
03055 }
03056