diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1999-01-20 04:59:39 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1999-01-20 04:59:39 +0000 |
commit | 210367ec889f5910e270d6ea2c7ddb8a8d939e61 (patch) | |
tree | feb35473da45947378fbc02defe39bcd79ef600e /array.c | |
parent | 9c5b1986a36c7a700b4c76817e35aa874ba7907c (diff) | |
download | ruby-210367ec889f5910e270d6ea2c7ddb8a8d939e61.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r372,
which included commits to RCS files with non-trunk default branches.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@373 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 1037 |
1 files changed, 675 insertions, 362 deletions
@@ -6,41 +6,55 @@ $Date$ created at: Fri Aug 6 09:46:12 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ #include "ruby.h" +#include "util.h" - -VALUE cArray; +VALUE rb_cArray; #define ARY_DEFAULT_SIZE 16 void -memclear(mem, size) +rb_mem_clear(mem, size) register VALUE *mem; - register int size; + register size_t size; { while (size--) { *mem++ = Qnil; } } +static void +memfill(mem, size, val) + register VALUE *mem; + register size_t size; + register VALUE val; +{ + while (size--) { + *mem++ = val; + } +} + #define ARY_FREEZE FL_USER1 +#define ARY_TMPLOCK FL_USER2 static void -ary_modify(ary) +rb_ary_modify(ary) VALUE ary; { - rb_secure(5); - if (FL_TEST(ary, ARY_FREEZE)) { - TypeError("can't modify frozen array"); - } + if (FL_TEST(ary, ARY_FREEZE)) + rb_raise(rb_eTypeError, "can't modify frozen array"); + if (FL_TEST(ary, ARY_TMPLOCK)) + rb_raise(rb_eTypeError, "can't modify array during sort"); + if (rb_safe_level() >= 4 && !FL_TEST(ary, FL_TAINT)) + rb_raise(rb_eSecurityError, "Insecure: can't modify array"); } VALUE -ary_freeze(ary) +rb_ary_freeze(ary) VALUE ary; { FL_SET(ary, ARY_FREEZE); @@ -48,56 +62,68 @@ ary_freeze(ary) } static VALUE -ary_frozen_p(ary) +rb_ary_frozen_p(ary) VALUE ary; { - if (FL_TEST(ary, ARY_FREEZE)) - return TRUE; - return FALSE; + if (FL_TEST(ary, ARY_FREEZE|ARY_TMPLOCK)) + return Qtrue; + return Qfalse; } VALUE -ary_new2(len) - int len; +rb_ary_new2(len) + size_t len; { NEWOBJ(ary, struct RArray); - OBJSETUP(ary, cArray, T_ARRAY); + OBJSETUP(ary, rb_cArray, T_ARRAY); + if (len < 0) { + rb_raise(rb_eArgError, "negative array size (or size too big)"); + } + if (len > 0 && len*sizeof(VALUE) <= 0) { + rb_raise(rb_eArgError, "array size too big"); + } ary->len = 0; ary->capa = len; - if (len == 0) - ary->ptr = 0; - else { - ary->ptr = ALLOC_N(VALUE, len); - memclear(ary->ptr, len); - } + ary->ptr = 0; + ary->ptr = ALLOC_N(VALUE, len); return (VALUE)ary; } VALUE -ary_new() +rb_ary_new() { - return ary_new2(ARY_DEFAULT_SIZE); + return rb_ary_new2(ARY_DEFAULT_SIZE); } +#ifdef HAVE_STDARG_PROTOTYPES +#include <stdarg.h> +#define va_init_list(a,b) va_start(a,b) +#else #include <varargs.h> +#define va_init_list(a,b) va_start(a) +#endif VALUE -ary_new3(n, va_alist) - int n; +#ifdef HAVE_STDARG_PROTOTYPES +rb_ary_new3(size_t n, ...) +#else +rb_ary_new3(n, va_alist) + size_t n; va_dcl +#endif { va_list ar; VALUE ary; - int i; + size_t i; if (n < 0) { - IndexError("Negative number of items(%d)", n); + rb_raise(rb_eIndexError, "negative number of items(%d)", n); } - ary = ary_new2(n<ARY_DEFAULT_SIZE?ARY_DEFAULT_SIZE:n); + ary = rb_ary_new2(n<ARY_DEFAULT_SIZE?ARY_DEFAULT_SIZE:n); - va_start(ar); + va_init_list(ar, n); for (i=0; i<n; i++) { RARRAY(ary)->ptr[i] = va_arg(ar, VALUE); } @@ -108,26 +134,28 @@ ary_new3(n, va_alist) } VALUE -ary_new4(n, elts) - int n; +rb_ary_new4(n, elts) + size_t n; VALUE *elts; { VALUE ary; - ary = ary_new2(n); - MEMCPY(RARRAY(ary)->ptr, elts, VALUE, n); + ary = rb_ary_new2(n); + if (elts) { + MEMCPY(RARRAY(ary)->ptr, elts, VALUE, n); + } RARRAY(ary)->len = n; return ary; } VALUE -assoc_new(car, cdr) +rb_assoc_new(car, cdr) VALUE car, cdr; { VALUE ary; - ary = ary_new2(2); + ary = rb_ary_new2(2); RARRAY(ary)->ptr[0] = car; RARRAY(ary)->ptr[1] = cdr; RARRAY(ary)->len = 2; @@ -136,32 +164,49 @@ assoc_new(car, cdr) } static VALUE -ary_s_new(argc, argv, class) +rb_ary_s_new(argc, argv, klass) int argc; VALUE *argv; - VALUE class; + VALUE klass; { - VALUE size; + size_t len = 0; + VALUE size, val; NEWOBJ(ary, struct RArray); - OBJSETUP(ary, class, T_ARRAY); + OBJSETUP(ary, klass, T_ARRAY); - rb_scan_args(argc, argv, "01", &size); ary->len = 0; - ary->capa = NIL_P(size)?ARY_DEFAULT_SIZE:NUM2INT(size); + ary->ptr = 0; + if (rb_scan_args(argc, argv, "02", &size, &val) == 0) { + ary->capa = ARY_DEFAULT_SIZE; + } + else { + size_t capa = NUM2UINT(size); + + if (capa < 0) { + rb_raise(rb_eArgError, "negative array size"); + } + if (capa > 0 && capa*sizeof(VALUE) <= 0) { + rb_raise(rb_eArgError, "array size too big"); + } + ary->capa = capa; + len = capa; + } ary->ptr = ALLOC_N(VALUE, ary->capa); - memclear(ary->ptr, ary->capa); + memfill(ary->ptr, len, val); + ary->len = len; + rb_obj_call_init((VALUE)ary); return (VALUE)ary; } static VALUE -ary_s_create(argc, argv, class) +rb_ary_s_create(argc, argv, klass) int argc; VALUE *argv; - VALUE class; + VALUE klass; { NEWOBJ(ary, struct RArray); - OBJSETUP(ary, class, T_ARRAY); + OBJSETUP(ary, klass, T_ARRAY); ary->len = argc; ary->capa = argc; @@ -177,14 +222,17 @@ ary_s_create(argc, argv, class) } void -ary_store(ary, idx, val) +rb_ary_store(ary, idx, val) VALUE ary; - int idx; + size_t idx; VALUE val; { - ary_modify(ary); + rb_ary_modify(ary); if (idx < 0) { - IndexError("negative index for array"); + idx = RARRAY(ary)->len + idx; + if (idx < 0) { + rb_raise(rb_eIndexError, "negative index of array"); + } } if (idx >= RARRAY(ary)->capa) { @@ -192,7 +240,8 @@ ary_store(ary, idx, val) REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa); } if (idx > RARRAY(ary)->len) { - memclear(RARRAY(ary)->ptr+RARRAY(ary)->len, idx-RARRAY(ary)->len+1); + rb_mem_clear(RARRAY(ary)->ptr+RARRAY(ary)->len, + idx-RARRAY(ary)->len+1); } if (idx >= RARRAY(ary)->len) { @@ -202,28 +251,28 @@ ary_store(ary, idx, val) } VALUE -ary_push(ary, item) +rb_ary_push(ary, item) VALUE ary; VALUE item; { - ary_store(ary, RARRAY(ary)->len, item); + rb_ary_store(ary, RARRAY(ary)->len, item); return ary; } static VALUE -ary_push_method(argc, argv, ary) +rb_ary_push_method(argc, argv, ary) int argc; VALUE *argv; VALUE ary; { while (argc--) { - ary_store(ary, RARRAY(ary)->len, *argv++); + rb_ary_store(ary, RARRAY(ary)->len, *argv++); } return ary; } VALUE -ary_pop(ary) +rb_ary_pop(ary) VALUE ary; { if (RARRAY(ary)->len == 0) return Qnil; @@ -235,7 +284,7 @@ ary_pop(ary) } VALUE -ary_shift(ary) +rb_ary_shift(ary) VALUE ary; { VALUE top; @@ -256,10 +305,10 @@ ary_shift(ary) } VALUE -ary_unshift(ary, item) +rb_ary_unshift(ary, item) VALUE ary, item; { - ary_modify(ary); + rb_ary_modify(ary); if (RARRAY(ary)->len >= RARRAY(ary)->capa) { RARRAY(ary)->capa+=ARY_DEFAULT_SIZE; REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa); @@ -269,13 +318,15 @@ ary_unshift(ary, item) MEMMOVE(RARRAY(ary)->ptr+1, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len); RARRAY(ary)->len++; - return RARRAY(ary)->ptr[0] = item; + RARRAY(ary)->ptr[0] = item; + + return ary; } VALUE -ary_entry(ary, offset) +rb_ary_entry(ary, offset) VALUE ary; - int offset; + size_t offset; { if (RARRAY(ary)->len == 0) return Qnil; @@ -290,27 +341,27 @@ ary_entry(ary, offset) } static VALUE -ary_subseq(ary, beg, len) +rb_ary_subseq(ary, beg, len) VALUE ary; - int beg, len; + size_t beg, len; { VALUE ary2; - if (beg < 0) { - beg = RARRAY(ary)->len + beg; - if (beg < 0) beg = 0; - } - if (len < 0) { - IndexError("negative length %d", RARRAY(ary)->len); + if (len <= 0) { + return rb_ary_new2(0); } - if (len == 0) { - return ary_new2(0); + if (beg < 0) { + len += beg; + beg = 0; } if (beg + len > RARRAY(ary)->len) { len = RARRAY(ary)->len - beg; } + if (len < 0) { + len = 0; + } - ary2 = ary_new2(len); + ary2 = rb_ary_new2(len); MEMCPY(RARRAY(ary2)->ptr, RARRAY(ary)->ptr+beg, VALUE, len); RARRAY(ary2)->len = len; @@ -320,80 +371,74 @@ ary_subseq(ary, beg, len) static VALUE beg_len(range, begp, lenp, len) VALUE range; - int *begp, *lenp; - int len; + size_t *begp, *lenp; + size_t len; { - int beg, end; + size_t beg, end; + size_t b, e; - if (!range_beg_end(range, &beg, &end)) return FALSE; - - if ((beg > 0 && end > 0 || beg < 0 && end < 0) && beg > end) { - IndexError("end smaller than beg [%d..%d]", beg, end); - } + if (!rb_range_beg_end(range, &beg, &end)) return Qfalse; + b = beg; e = end; if (beg < 0) { beg = len + beg; - if (beg < 0) beg = 0; } + if (end < 0) { + end = len + end; + } + if (beg > end) { + rb_raise(rb_eIndexError, "end smaller than beg [%d..%d]", b, e); + } + *begp = beg; if (beg > len) { *lenp = 0; } else { - if (end < 0) { - end = len + end; - if (end < 0) end = -1; - } - if (beg > end) { - *lenp = 0; - } - else { - *lenp = end - beg +1; - } + len = end - beg +1; + *lenp = len; } - return TRUE; + return Qtrue; } VALUE -ary_aref(argc, argv, ary) +rb_ary_aref(argc, argv, ary) int argc; VALUE *argv; VALUE ary; { VALUE arg1, arg2; - int beg, len; + size_t beg, len; if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) { - beg = NUM2INT(arg1); - len = NUM2INT(arg2); - if (len <= 0) { - return ary_new(); + beg = NUM2UINT(arg1); + len = NUM2UINT(arg2); + if (beg < 0) { + beg = RARRAY(ary)->len + beg; } - return ary_subseq(ary, beg, len); + return rb_ary_subseq(ary, beg, len); } /* special case - speeding up */ if (FIXNUM_P(arg1)) { - return ary_entry(ary, FIX2INT(arg1)); + return rb_ary_entry(ary, FIX2UINT(arg1)); } - else { - /* check if idx is Range */ - if (beg_len(arg1, &beg, &len, RARRAY(ary)->len)) { - return ary_subseq(ary, beg, len); - } + else if (TYPE(arg1) == T_BIGNUM) { + rb_raise(rb_eIndexError, "index too big"); } - if (TYPE(arg1) == T_BIGNUM) { - IndexError("index too big"); + else if (beg_len(arg1, &beg, &len, RARRAY(ary)->len)) { + /* check if idx is Range */ + return rb_ary_subseq(ary, beg, len); } - return ary_entry(ary, NUM2INT(arg1)); + return rb_ary_entry(ary, NUM2UINT(arg1)); } static VALUE -ary_index(ary, val) +rb_ary_index(ary, val) VALUE ary; VALUE val; { - int i; + size_t i; for (i=0; i<RARRAY(ary)->len; i++) { if (rb_equal(RARRAY(ary)->ptr[i], val)) @@ -403,59 +448,74 @@ ary_index(ary, val) } static VALUE -ary_indexes(ary, args) - VALUE ary, args; +rb_ary_rindex(ary, val) + VALUE ary; + VALUE val; { - VALUE *p, *pend; - VALUE new_ary; - int i = 0; + size_t i = RARRAY(ary)->len; - if (!args || NIL_P(args)) { - return ary_new2(0); + while (i--) { + if (rb_equal(RARRAY(ary)->ptr[i], val)) + return INT2FIX(i); } + return Qnil; +} - new_ary = ary_new2(RARRAY(args)->len); +static VALUE +rb_ary_indexes(argc, argv, ary) + int argc; + VALUE *argv; + VALUE ary; +{ + VALUE new_ary; + size_t i; - p = RARRAY(args)->ptr; pend = p + RARRAY(args)->len; - while (p < pend) { - ary_store(new_ary, i++, ary_entry(ary, NUM2INT(*p))); - p++; + new_ary = rb_ary_new2(argc); + for (i=0; i<argc; i++) { + rb_ary_store(new_ary, i, rb_ary_entry(ary, NUM2UINT(argv[i]))); } + return new_ary; } static void -ary_replace(ary, beg, len, rpl) +rb_ary_replace(ary, beg, len, rpl) VALUE ary, rpl; - int beg, len; + size_t beg, len; { - ary_modify(ary); + if (len < 0) { + rb_raise(rb_eIndexError, "negative length %d", len); + } + if (TYPE(rpl) != T_ARRAY) { rpl = rb_Array(rpl); } + + if (beg + len < 0 || (beg < 0 && beg <= -len)) { + rb_raise(rb_eIndexError, "index %d out of range", beg); + } if (beg < 0) { - beg = RARRAY(ary)->len + beg; - if (beg < 0) beg = 0; + len += beg; + beg = 0; } + + rb_ary_modify(ary); if (beg >= RARRAY(ary)->len) { len = beg + RARRAY(rpl)->len; if (len >= RARRAY(ary)->capa) { RARRAY(ary)->capa=len; REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa); } - memclear(RARRAY(ary)->ptr+RARRAY(ary)->len, beg-RARRAY(ary)->len); + rb_mem_clear(RARRAY(ary)->ptr+RARRAY(ary)->len, beg-RARRAY(ary)->len); MEMCPY(RARRAY(ary)->ptr+beg, RARRAY(rpl)->ptr, VALUE, RARRAY(rpl)->len); RARRAY(ary)->len = len; } else { - int alen; + size_t alen; if (beg + len > RARRAY(ary)->len) { len = RARRAY(ary)->len - beg; } - if (len < 0) { - IndexError("negative length %d", RARRAY(ary)->len); - } alen = RARRAY(ary)->len + RARRAY(rpl)->len - len; if (alen >= RARRAY(ary)->capa) { @@ -473,48 +533,49 @@ ary_replace(ary, beg, len, rpl) } static VALUE -ary_aset(argc, argv, ary) +rb_ary_aset(argc, argv, ary) int argc; VALUE *argv; VALUE ary; { VALUE arg1, arg2, arg3; - int offset; - int beg, len; + size_t offset; + size_t beg, len; if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) { - beg = NUM2INT(arg1); - len = NUM2INT(arg2); - ary_replace(ary, beg, len, arg3); + beg = NUM2UINT(arg1); + len = NUM2UINT(arg2); + + if (beg < 0) { + beg = RARRAY(ary)->len + beg; + } + rb_ary_replace(ary, beg, len, arg3); return arg3; } else if (FIXNUM_P(arg1)) { - offset = FIX2INT(arg1); + offset = FIX2UINT(arg1); goto fixnum; } else if (beg_len(arg1, &beg, &len, RARRAY(ary)->len)) { /* check if idx is Range */ - ary_replace(ary, beg, len, arg2); + rb_ary_replace(ary, beg, len, arg2); return arg2; } if (TYPE(arg1) == T_BIGNUM) { - IndexError("index too big"); + rb_raise(rb_eIndexError, "index too big"); } - offset = NUM2INT(arg1); + offset = NUM2UINT(arg1); fixnum: - if (offset < 0) { - offset = RARRAY(ary)->len + offset; - } - ary_store(ary, offset, arg2); + rb_ary_store(ary, offset, arg2); return arg2; } VALUE -ary_each(ary) +rb_ary_each(ary) VALUE ary; { - int i; + size_t i; for (i=0; i<RARRAY(ary)->len; i++) { rb_yield(RARRAY(ary)->ptr[i]); @@ -523,10 +584,10 @@ ary_each(ary) } static VALUE -ary_each_index(ary) +rb_ary_each_index(ary) VALUE ary; { - int i; + size_t i; for (i=0; i<RARRAY(ary)->len; i++) { rb_yield(INT2FIX(i)); @@ -535,10 +596,10 @@ ary_each_index(ary) } static VALUE -ary_reverse_each(ary) +rb_ary_reverse_each(ary) VALUE ary; { - int len = RARRAY(ary)->len; + size_t len = RARRAY(ary)->len; while (len--) { rb_yield(RARRAY(ary)->ptr[len]); @@ -547,26 +608,26 @@ ary_reverse_each(ary) } static VALUE -ary_length(ary) +rb_ary_length(ary) VALUE ary; { return INT2FIX(RARRAY(ary)->len); } static VALUE -ary_empty_p(ary) +rb_ary_empty_p(ary) VALUE ary; { if (RARRAY(ary)->len == 0) - return TRUE; - return FALSE; + return Qtrue; + return Qfalse; } static VALUE -ary_clone(ary) +rb_ary_clone(ary) VALUE ary; { - VALUE ary2 = ary_new2(RARRAY(ary)->len); + VALUE ary2 = rb_ary_new2(RARRAY(ary)->len); CLONESETUP(ary2, ary); MEMCPY(RARRAY(ary2)->ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len); @@ -575,32 +636,56 @@ ary_clone(ary) } static VALUE -ary_dup(ary) +rb_ary_dup(ary) VALUE ary; { - return ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr); + return rb_ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr); } -extern VALUE OFS; +static VALUE +to_ary(ary) + VALUE ary; +{ + return rb_convert_type(ary, T_ARRAY, "Array", "to_ary"); +} -VALUE -ary_join(ary, sep) +extern VALUE rb_output_fs; + +static VALUE +inspect_join(ary, arg) VALUE ary; - VALUE sep; + VALUE *arg; { - int i; + return rb_ary_join(arg[0], arg[1]); +} + +VALUE +rb_ary_join(ary, sep) + VALUE ary, sep; +{ + size_t i; VALUE result, tmp; - if (RARRAY(ary)->len == 0) return str_new(0, 0); + if (RARRAY(ary)->len == 0) return rb_str_new(0, 0); - switch (TYPE(RARRAY(ary)->ptr[0])) { + tmp = RARRAY(ary)->ptr[0]; + switch (TYPE(tmp)) { case T_STRING: - result = str_dup(RARRAY(ary)->ptr[0]); + result = rb_str_dup(tmp); break; case T_ARRAY: - result = ary_join(RARRAY(ary)->ptr[0], sep); + if (rb_inspecting_p(tmp)) { + result = rb_str_new2("[...]"); + } + else { + VALUE args[2]; + + args[0] = tmp; + args[1] = sep; + result = rb_protect_inspect(inspect_join, ary, (VALUE)args); + } break; default: - result = obj_as_string(RARRAY(ary)->ptr[0]); + result = rb_obj_as_string(tmp); break; } @@ -610,21 +695,30 @@ ary_join(ary, sep) case T_STRING: break; case T_ARRAY: - tmp = ary_join(tmp, sep); + if (rb_inspecting_p(tmp)) { + tmp = rb_str_new2("[...]"); + } + else { + VALUE args[2]; + + args[0] = tmp; + args[1] = sep; + tmp = rb_protect_inspect(inspect_join, ary, (VALUE)args); + } break; default: - tmp = obj_as_string(tmp); + tmp = rb_obj_as_string(tmp); } - if (!NIL_P(sep)) str_cat(result, RSTRING(sep)->ptr, RSTRING(sep)->len); - str_cat(result, RSTRING(tmp)->ptr, RSTRING(tmp)->len); - if (str_tainted(tmp)) str_taint(result); + if (!NIL_P(sep)) rb_str_concat(result, sep); + rb_str_cat(result, RSTRING(tmp)->ptr, RSTRING(tmp)->len); + if (OBJ_TAINTED(tmp)) OBJ_TAINT(result); } return result; } static VALUE -ary_join_method(argc, argv, ary) +rb_ary_join_method(argc, argv, ary) int argc; VALUE *argv; VALUE ary; @@ -632,57 +726,144 @@ ary_join_method(argc, argv, ary) VALUE sep; rb_scan_args(argc, argv, "01", &sep); - if (NIL_P(sep)) sep = OFS; - if (!NIL_P(sep)) Check_Type(sep, T_STRING); - - return ary_join(ary, sep); + if (NIL_P(sep)) sep = rb_output_fs; + return rb_ary_join(ary, sep); } VALUE -ary_to_s(ary) +rb_ary_to_s(ary) VALUE ary; { - VALUE str = ary_join(ary, OFS); - if (NIL_P(str)) return str_new(0, 0); + VALUE str; + + if (RARRAY(ary)->len == 0) return rb_str_new(0, 0); + str = rb_ary_join(ary, rb_output_fs); + if (NIL_P(str)) return rb_str_new(0, 0); return str; } +#ifdef USE_THREAD +static ID inspect_key; +#else +static VALUE inspect_tbl; +#endif + +struct inspect_arg { + VALUE (*func)(); + VALUE arg1, arg2; +}; + +VALUE +inspect_call(arg) + struct inspect_arg *arg; +{ + return (*arg->func)(arg->arg1, arg->arg2); +} + static VALUE -ary_inspect(ary) +inspect_ensure(obj) + VALUE obj; +{ +#ifdef USE_THREAD + VALUE inspect_tbl; + + inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key); +#endif + rb_ary_pop(inspect_tbl); + return 0; +} + +VALUE +rb_protect_inspect(func, obj, arg) + VALUE (*func)(); + VALUE obj, arg; +{ + struct inspect_arg iarg; + +#ifdef USE_THREAD + VALUE inspect_tbl; + + if (!inspect_key) { + inspect_key = rb_intern("__inspect_key__"); + } + inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key); + if (NIL_P(inspect_tbl)) { + inspect_tbl = rb_ary_new(); + rb_thread_local_aset(rb_thread_current(), inspect_key, inspect_tbl); + } +#else + if (!inspect_tbl) { + inspect_tbl = rb_ary_new(); + rb_global_variable(&inspect_tbl); + } +#endif + rb_ary_push(inspect_tbl, obj); + iarg.func = func; + iarg.arg1 = obj; + iarg.arg2 = arg; + return rb_ensure(inspect_call, (VALUE)&iarg, inspect_ensure, obj); +} + +VALUE +rb_inspecting_p(obj) + VALUE obj; +{ +#ifdef USE_THREAD + VALUE inspect_tbl; + + if (!inspect_key) return Qfalse; + inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key); + if (NIL_P(inspect_tbl)) return Qfalse; +#else + if (!inspect_tbl) return Qnil; +#endif + return rb_ary_includes(inspect_tbl, obj); +} + +static VALUE +inspect_ary(ary) VALUE ary; { - int i, len; + size_t i = 0; VALUE s, str; - if (RARRAY(ary)->len == 0) return str_new2("[]"); - str = str_new2("["); - len = 1; + str = rb_str_new2("["); for (i=0; i<RARRAY(ary)->len; i++) { s = rb_inspect(RARRAY(ary)->ptr[i]); - if (i > 0) str_cat(str, ", ", 2); - str_cat(str, RSTRING(s)->ptr, RSTRING(s)->len); - len += RSTRING(s)->len + 2; + if (i > 0) rb_str_cat(str, ", ", 2); + rb_str_cat(str, RSTRING(s)->ptr, RSTRING(s)->len); } - str_cat(str, "]", 1); + rb_str_cat(str, "]", 1); return str; } static VALUE -ary_to_a(ary) +rb_ary_inspect(ary) + VALUE ary; +{ + if (RARRAY(ary)->len == 0) return rb_str_new2("[]"); + if (rb_inspecting_p(ary)) return rb_str_new2("[...]"); + return rb_protect_inspect(inspect_ary, ary, 0); +} + +static VALUE +rb_ary_to_a(ary) VALUE ary; { return ary; } VALUE -ary_reverse(ary) +rb_ary_reverse(ary) VALUE ary; { VALUE *p1, *p2; VALUE tmp; + if (RARRAY(ary)->len == 0) return ary; + p1 = RARRAY(ary)->ptr; p2 = p1 + RARRAY(ary)->len - 1; /* points last item */ @@ -697,10 +878,10 @@ ary_reverse(ary) } static VALUE -ary_reverse_method(ary) +rb_ary_reverse_method(ary) VALUE ary; { - return ary_reverse(ary_clone(ary)); + return rb_ary_reverse(rb_ary_dup(ary)); } static ID cmp; @@ -709,7 +890,7 @@ static int sort_1(a, b) VALUE *a, *b; { - VALUE retval = rb_yield(assoc_new(*a, *b)); + VALUE retval = rb_yield(rb_assoc_new(*a, *b)); return NUM2INT(retval); } @@ -722,38 +903,59 @@ sort_2(a, b) if (FIXNUM_P(*a)) { if (FIXNUM_P(*b)) return *a - *b; } - else if (TYPE(*a) == T_STRING) { - if (TYPE(*b) == T_STRING) return str_cmp(*a, *b); + else if (TYPE(*a) == T_STRING && TYPE(*b) == T_STRING) { + return rb_str_cmp(*a, *b); } retval = rb_funcall(*a, cmp, 1, *b); return NUM2INT(retval); } +static VALUE +sort_internal(ary) + VALUE ary; +{ + qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE), + rb_iterator_p()?sort_1:sort_2); + return ary; +} + +static VALUE +sort_unlock(ary) + VALUE ary; +{ + FL_UNSET(ary, ARY_TMPLOCK); + return ary; +} + VALUE -ary_sort_bang(ary) +rb_ary_sort_bang(ary) VALUE ary; { - ary_modify(ary); - qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE), iterator_p()?sort_1:sort_2); + if (RARRAY(ary)->len <= 1) return ary; + + rb_ary_modify(ary); + FL_SET(ary, ARY_TMPLOCK); /* prohibit modification during sort */ + rb_ensure(sort_internal, ary, sort_unlock, ary); return ary; } VALUE -ary_sort(ary) +rb_ary_sort(ary) VALUE ary; { - return ary_sort_bang(ary_clone(ary)); + if (RARRAY(ary)->len == 0) return ary; + return rb_ary_sort_bang(rb_ary_dup(ary)); } VALUE -ary_delete(ary, item) +rb_ary_delete(ary, item) VALUE ary; VALUE item; { - int i1, i2; + size_t i1, i2; - ary_modify(ary); + rb_ary_modify(ary); for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) { if (rb_equal(RARRAY(ary)->ptr[i1], item)) continue; if (i1 != i2) { @@ -762,7 +964,9 @@ ary_delete(ary, item) i2++; } if (RARRAY(ary)->len == i2) { - if (iterator_p()) rb_yield(item); + if (rb_iterator_p()) { + return rb_yield(item); + } return Qnil; } else { @@ -773,15 +977,15 @@ ary_delete(ary, item) } VALUE -ary_delete_at(ary, at) +rb_ary_delete_at(ary, at) VALUE ary; VALUE at; { - int i1, i2, pos; + size_t i1, i2, pos; VALUE del = Qnil; - ary_modify(ary); - pos = NUM2INT(at); + rb_ary_modify(ary); + pos = NUM2UINT(at); for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) { if (i1 == pos) { del = RARRAY(ary)->ptr[i1]; @@ -798,12 +1002,12 @@ ary_delete_at(ary, at) } static VALUE -ary_delete_if(ary) +rb_ary_delete_if(ary) VALUE ary; { - int i1, i2; + size_t i1, i2; - ary_modify(ary); + rb_ary_modify(ary); for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) { if (rb_yield(RARRAY(ary)->ptr[i1])) continue; if (i1 != i2) { @@ -816,23 +1020,30 @@ ary_delete_if(ary) return ary; } -#if 0 static VALUE -ary_replace(ary) +rb_ary_filter(ary) VALUE ary; { - int i; + size_t i; + rb_ary_modify(ary); for (i = 0; i < RARRAY(ary)->len; i++) { RARRAY(ary)->ptr[i] = rb_yield(RARRAY(ary)->ptr[i]); } + return ary; +} +static VALUE +rb_ary_replace_method(ary, ary2) + VALUE ary, ary2; +{ + ary2 = to_ary(ary2); + rb_ary_replace(ary, 0, RARRAY(ary2)->len, ary2); return ary; } -#endif static VALUE -ary_clear(ary) +rb_ary_clear(ary) VALUE ary; { RARRAY(ary)->len = 0; @@ -844,32 +1055,28 @@ ary_clear(ary) } static VALUE -ary_fill(argc, argv, ary) +rb_ary_fill(argc, argv, ary) int argc; VALUE *argv; VALUE ary; { VALUE item, arg1, arg2; - int beg, len, end; + size_t beg, len, end; VALUE *p, *pend; - rb_scan_args(argc, argv, "12", &item, &arg1, &arg2); - if (NIL_P(arg2) && beg_len(arg1, &beg, &len, RARRAY(ary)->len)) { + if (rb_scan_args(argc, argv, "12", &item, &arg1, &arg2) == 2 && + beg_len(arg1, &beg, &len, RARRAY(ary)->len)) { /* beg and len set already */ } else { - beg = NUM2INT(arg1); + beg = NIL_P(arg1)?0:NUM2UINT(arg1); if (beg < 0) { beg = RARRAY(ary)->len + beg; if (beg < 0) beg = 0; } - if (!NIL_P(arg2)) { - len = NUM2INT(arg2); - } - else { - len = RARRAY(ary)->len - beg; - } + len = NIL_P(arg2)?RARRAY(ary)->len - beg:NUM2UINT(arg2); } + rb_ary_modify(ary); end = beg + len; if (end > RARRAY(ary)->len) { if (end >= RARRAY(ary)->capa) { @@ -877,7 +1084,7 @@ ary_fill(argc, argv, ary) REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa); } if (beg > RARRAY(ary)->len) { - memclear(RARRAY(ary)->ptr+RARRAY(ary)->len, end-RARRAY(ary)->len); + rb_mem_clear(RARRAY(ary)->ptr+RARRAY(ary)->len,end-RARRAY(ary)->len); } RARRAY(ary)->len = end; } @@ -890,16 +1097,16 @@ ary_fill(argc, argv, ary) } VALUE -ary_plus(x, y) +rb_ary_plus(x, y) VALUE x, y; { VALUE z; if (TYPE(y) != T_ARRAY) { - return ary_plus(x, rb_Array(y)); + return rb_ary_plus(x, rb_Array(y)); } - z = ary_new2(RARRAY(x)->len + RARRAY(y)->len); + z = rb_ary_new2(RARRAY(x)->len + RARRAY(y)->len); MEMCPY(RARRAY(z)->ptr, RARRAY(x)->ptr, VALUE, RARRAY(x)->len); MEMCPY(RARRAY(z)->ptr+RARRAY(x)->len, RARRAY(y)->ptr, VALUE, RARRAY(y)->len); RARRAY(z)->len = RARRAY(x)->len + RARRAY(y)->len; @@ -907,43 +1114,44 @@ ary_plus(x, y) } VALUE -ary_concat(x, y) +rb_ary_concat(x, y) VALUE x, y; { VALUE *p, *pend; if (TYPE(y) != T_ARRAY) { - return ary_concat(x, rb_Array(y)); + return rb_ary_concat(x, rb_Array(y)); } p = RARRAY(y)->ptr; pend = p + RARRAY(y)->len; while (p < pend) { - ary_store(x, RARRAY(x)->len, *p); + rb_ary_store(x, RARRAY(x)->len, *p); p++; } return x; } static VALUE -ary_times(ary, times) +rb_ary_times(ary, times) VALUE ary; VALUE times; { VALUE ary2; - int i, len; + size_t i, len; if (TYPE(times) == T_STRING) { - return ary_join(ary, times); + return rb_ary_join(ary, times); } - len = NUM2INT(times) * RARRAY(ary)->len; - ary2 = ary_new2(len); - RARRAY(ary2)->len = len; - + len = NUM2UINT(times); if (len < 0) { - ArgError("negative argument"); + rb_raise(rb_eArgError, "negative argument"); } + len *= RARRAY(ary)->len; + + ary2 = rb_ary_new2(len); + RARRAY(ary2)->len = len; for (i=0; i<len; i+=RARRAY(ary)->len) { MEMCPY(RARRAY(ary2)->ptr+i, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len); @@ -953,7 +1161,7 @@ ary_times(ary, times) } VALUE -ary_assoc(ary, key) +rb_ary_assoc(ary, key) VALUE ary; VALUE key; { @@ -971,7 +1179,7 @@ ary_assoc(ary, key) } VALUE -ary_rassoc(ary, value) +rb_ary_rassoc(ary, value) VALUE ary; VALUE value; { @@ -989,135 +1197,203 @@ ary_rassoc(ary, value) } static VALUE -ary_equal(ary1, ary2) +rb_ary_equal(ary1, ary2) VALUE ary1, ary2; { - int i; + size_t i; - if (TYPE(ary2) != T_ARRAY) return FALSE; - if (RARRAY(ary1)->len != RARRAY(ary2)->len) return FALSE; + if (TYPE(ary2) != T_ARRAY) return Qfalse; + if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse; for (i=0; i<RARRAY(ary1)->len; i++) { if (!rb_equal(RARRAY(ary1)->ptr[i], RARRAY(ary2)->ptr[i])) - return FALSE; + return Qfalse; } - return TRUE; + return Qtrue; } static VALUE -ary_eql(ary1, ary2) +rb_ary_eql(ary1, ary2) VALUE ary1, ary2; { - int i; + size_t i; - if (TYPE(ary2) != T_ARRAY) return FALSE; + if (TYPE(ary2) != T_ARRAY) return Qfalse; if (RARRAY(ary1)->len != RARRAY(ary2)->len) - return FALSE; + return Qfalse; for (i=0; i<RARRAY(ary1)->len; i++) { if (!rb_eql(RARRAY(ary1)->ptr[i], RARRAY(ary2)->ptr[i])) - return FALSE; + return Qfalse; } - return TRUE; + return Qtrue; } static VALUE -ary_hash(ary) +rb_ary_hash(ary) VALUE ary; { - int h, i; + size_t i; + int h; h = RARRAY(ary)->len; for (i=0; i<RARRAY(ary)->len; i++) { - h ^= rb_hash(RARRAY(ary)->ptr[i]); + int n = rb_hash(RARRAY(ary)->ptr[i]); + h ^= NUM2LONG(n); } return INT2FIX(h); } VALUE -ary_includes(ary, item) +rb_ary_includes(ary, item) VALUE ary; VALUE item; { - int i; + size_t i; for (i=0; i<RARRAY(ary)->len; i++) { if (rb_equal(RARRAY(ary)->ptr[i], item)) { - return TRUE; + return Qtrue; + } + } + return Qfalse; +} + +static VALUE +rb_ary_cmp(ary, ary2) + VALUE ary; + VALUE ary2; +{ + size_t i, len; + + ary2 = to_ary(ary2); + len = RARRAY(ary)->len; + if (len > RARRAY(ary2)->len) { + len = RARRAY(ary2)->len; + } + for (i=0; i<len; i++) { + VALUE v = rb_funcall(RARRAY(ary)->ptr[i],cmp,1,RARRAY(ary2)->ptr[i]); + if (v != INT2FIX(0)) { + return v; } } - return FALSE; + len = RARRAY(ary)->len - RARRAY(ary2)->len; + if (len == 0) return INT2FIX(0); + if (len > 0) return INT2FIX(1); + return INT2FIX(-1); } static VALUE -ary_diff(ary1, ary2) +rb_ary_diff(ary1, ary2) VALUE ary1, ary2; { VALUE ary3; - int i; + size_t i; - Check_Type(ary2, T_ARRAY); - ary3 = ary_new(); + ary2 = to_ary(ary2); + ary3 = rb_ary_new(); for (i=0; i<RARRAY(ary1)->len; i++) { - if (ary_includes(ary2, RARRAY(ary1)->ptr[i])) continue; - if (ary_includes(ary3, RARRAY(ary1)->ptr[i])) continue; - ary_push(ary3, RARRAY(ary1)->ptr[i]); + if (rb_ary_includes(ary2, RARRAY(ary1)->ptr[i])) continue; + if (rb_ary_includes(ary3, RARRAY(ary1)->ptr[i])) continue; + rb_ary_push(ary3, RARRAY(ary1)->ptr[i]); } return ary3; } static VALUE -ary_and(ary1, ary2) +rb_ary_and(ary1, ary2) VALUE ary1, ary2; { VALUE ary3; - int i; + size_t i; - Check_Type(ary2, T_ARRAY); - ary3 = ary_new(); + ary2 = to_ary(ary2); + ary3 = rb_ary_new(); for (i=0; i<RARRAY(ary1)->len; i++) { - if (ary_includes(ary2, RARRAY(ary1)->ptr[i]) - && !ary_includes(ary3, RARRAY(ary1)->ptr[i])) { - ary_push(ary3, RARRAY(ary1)->ptr[i]); + if (rb_ary_includes(ary2, RARRAY(ary1)->ptr[i]) + && !rb_ary_includes(ary3, RARRAY(ary1)->ptr[i])) { + rb_ary_push(ary3, RARRAY(ary1)->ptr[i]); } } return ary3; } static VALUE -ary_or(ary1, ary2) +rb_ary_or(ary1, ary2) VALUE ary1, ary2; { VALUE ary3; - int i; + size_t i; if (TYPE(ary2) != T_ARRAY) { - if (ary_includes(ary1, ary2)) return ary1; - else return ary_plus(ary1, ary2); + if (rb_ary_includes(ary1, ary2)) return ary1; + else return rb_ary_plus(ary1, ary2); } - ary3 = ary_new(); + ary3 = rb_ary_new(); for (i=0; i<RARRAY(ary1)->len; i++) { - if (!ary_includes(ary3, RARRAY(ary1)->ptr[i])) - ary_push(ary3, RARRAY(ary1)->ptr[i]); + if (!rb_ary_includes(ary3, RARRAY(ary1)->ptr[i])) + rb_ary_push(ary3, RARRAY(ary1)->ptr[i]); } for (i=0; i<RARRAY(ary2)->len; i++) { - if (!ary_includes(ary3, RARRAY(ary2)->ptr[i])) - ary_push(ary3, RARRAY(ary2)->ptr[i]); + if (!rb_ary_includes(ary3, RARRAY(ary2)->ptr[i])) + rb_ary_push(ary3, RARRAY(ary2)->ptr[i]); } return ary3; } static VALUE -ary_compact_bang(ary) +rb_ary_uniq_bang(ary) + VALUE ary; +{ + VALUE *p, *q, *t, *end; + VALUE v; + + rb_ary_modify(ary); + p = RARRAY(ary)->ptr; + end = p + RARRAY(ary)->len; + + while (p < end) { + v = *p++; + q = t = p; + while (q < end) { + if (rb_equal(*q, v)) q++; + else *t++ = *q++; + } + end = t; + } + if (RARRAY(ary)->len == (end - RARRAY(ary)->ptr)) { + return Qnil; + } + + RARRAY(ary)->len = (end - RARRAY(ary)->ptr); + + return ary; +} + +static VALUE +rb_ary_uniq(ary) + VALUE ary; +{ + VALUE v = rb_ary_uniq_bang(rb_ary_dup(ary)); + + if (NIL_P(v)) return ary; + return v; +} + +static VALUE +rb_ary_compact_bang(ary) VALUE ary; { VALUE *p, *t, *end; - ary_modify(ary); + rb_ary_modify(ary); p = t = RARRAY(ary)->ptr; end = p + RARRAY(ary)->len; while (t < end) { if (NIL_P(*t)) t++; else *p++ = *t++; } + if (RARRAY(ary)->len == (p - RARRAY(ary)->ptr)) { + return Qnil; + } RARRAY(ary)->len = RARRAY(ary)->capa = (p - RARRAY(ary)->ptr); REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len); @@ -1125,17 +1401,20 @@ ary_compact_bang(ary) } static VALUE -ary_compact(ary) +rb_ary_compact(ary) VALUE ary; { - return ary_compact_bang(ary_clone(ary)); + VALUE v = rb_ary_compact_bang(rb_ary_dup(ary)); + + if (NIL_P(v)) return ary; + return v; } static VALUE -ary_nitems(ary) +rb_ary_nitems(ary) VALUE ary; { - int n = 0; + size_t n = 0; VALUE *p, *pend; p = RARRAY(ary)->ptr; @@ -1147,74 +1426,108 @@ ary_nitems(ary) return INT2FIX(n); } -extern VALUE mEnumerable; - -void -Init_Array() +static VALUE +rb_ary_flatten_bang(ary) + VALUE ary; { - cArray = rb_define_class("Array", cObject); - rb_include_module(cArray, mEnumerable); - - rb_define_singleton_method(cArray, "new", ary_s_new, -1); - rb_define_singleton_method(cArray, "[]", ary_s_create, -1); - rb_define_method(cArray, "to_s", ary_to_s, 0); - rb_define_method(cArray, "inspect", ary_inspect, 0); - rb_define_method(cArray, "to_a", ary_to_a, 0); - - rb_define_method(cArray, "freeze", ary_freeze, 0); - rb_define_method(cArray, "frozen?", ary_frozen_p, 0); - - rb_define_method(cArray, "==", ary_equal, 1); - rb_define_method(cArray, "eql?", ary_eql, 1); - rb_define_method(cArray, "hash", ary_hash, 0); - - rb_define_method(cArray, "[]", ary_aref, -1); - rb_define_method(cArray, "[]=", ary_aset, -1); - rb_define_method(cArray, "concat", ary_concat, 1); - rb_define_method(cArray, "<<", ary_push, 1); - rb_define_method(cArray, "push", ary_push_method, -1); - rb_define_method(cArray, "pop", ary_pop, 0); - rb_define_method(cArray, "shift", ary_shift, 0); - rb_define_method(cArray, "unshift", ary_unshift, 1); - rb_define_method(cArray, "each", ary_each, 0); - rb_define_method(cArray, "each_index", ary_each_index, 0); - rb_define_method(cArray, "reverse_each", ary_reverse_each, 0); - rb_define_method(cArray, "length", ary_length, 0); - rb_define_alias(cArray, "size", "length"); - rb_define_method(cArray, "empty?", ary_empty_p, 0); - rb_define_method(cArray, "index", ary_index, 1); - rb_define_method(cArray, "indexes", ary_indexes, -2); - rb_define_method(cArray, "clone", ary_clone, 0); - rb_define_method(cArray, "dup", ary_dup, 0); - rb_define_method(cArray, "join", ary_join_method, -1); - rb_define_method(cArray, "reverse", ary_reverse_method, 0); - rb_define_method(cArray, "reverse!", ary_reverse, 0); - rb_define_method(cArray, "sort", ary_sort, 0); - rb_define_method(cArray, "sort!", ary_sort_bang, 0); - rb_define_method(cArray, "delete", ary_delete, 1); - rb_define_method(cArray, "delete_at", ary_delete_at, 1); - rb_define_method(cArray, "delete_if", ary_delete_if, 0); -#if 0 - rb_define_method(cArray, "replace", ary_replace, 0); -#endif - rb_define_method(cArray, "clear", ary_clear, 0); - rb_define_method(cArray, "fill", ary_fill, -1); - rb_define_method(cArray, "include?", ary_includes, 1); - rb_define_method(cArray, "===", ary_includes, 1); + size_t i; + int mod = 0; - rb_define_method(cArray, "assoc", ary_assoc, 1); - rb_define_method(cArray, "rassoc", ary_rassoc, 1); + rb_ary_modify(ary); + for (i=0; i<RARRAY(ary)->len; i++) { + VALUE ary2 = RARRAY(ary)->ptr[i]; + if (TYPE(ary2) == T_ARRAY) { + rb_ary_replace(ary, i--, 1, ary2); + mod = 1; + } + } + if (mod == 0) return Qnil; + return ary; +} - rb_define_method(cArray, "+", ary_plus, 1); - rb_define_method(cArray, "*", ary_times, 1); +static VALUE +rb_ary_flatten(ary) + VALUE ary; +{ + VALUE v = rb_ary_flatten_bang(rb_ary_dup(ary)); - rb_define_method(cArray, "-", ary_diff, 1); - rb_define_method(cArray, "&", ary_and, 1); - rb_define_method(cArray, "|", ary_or, 1); + if (NIL_P(v)) return ary; + return v; +} - rb_define_method(cArray, "compact", ary_compact, 0); - rb_define_method(cArray, "compact!", ary_compact_bang, 0); - rb_define_method(cArray, "nitems", ary_nitems, 0); +void +Init_Array() +{ + rb_cArray = rb_define_class("Array", rb_cObject); + rb_include_module(rb_cArray, rb_mEnumerable); + + rb_define_singleton_method(rb_cArray, "new", rb_ary_s_new, -1); + rb_define_singleton_method(rb_cArray, "[]", rb_ary_s_create, -1); + rb_define_method(rb_cArray, "to_s", rb_ary_to_s, 0); + rb_define_method(rb_cArray, "inspect", rb_ary_inspect, 0); + rb_define_method(rb_cArray, "to_a", rb_ary_to_a, 0); + rb_define_method(rb_cArray, "to_ary", rb_ary_to_a, 0); + + rb_define_method(rb_cArray, "freeze", rb_ary_freeze, 0); + rb_define_method(rb_cArray, "frozen?", rb_ary_frozen_p, 0); + + rb_define_method(rb_cArray, "==", rb_ary_equal, 1); + rb_define_method(rb_cArray, "eql?", rb_ary_eql, 1); + rb_define_method(rb_cArray, "hash", rb_ary_hash, 0); + rb_define_method(rb_cArray, "===", rb_ary_equal, 1); + + rb_define_method(rb_cArray, "[]", rb_ary_aref, -1); + rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1); + rb_define_method(rb_cArray, "concat", rb_ary_concat, 1); + rb_define_method(rb_cArray, "<<", rb_ary_push, 1); + rb_define_method(rb_cArray, "push", rb_ary_push_method, -1); + rb_define_method(rb_cArray, "pop", rb_ary_pop, 0); + rb_define_method(rb_cArray, "shift", rb_ary_shift, 0); + rb_define_method(rb_cArray, "unshift", rb_ary_unshift, 1); + rb_define_method(rb_cArray, "each", rb_ary_each, 0); + rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0); + rb_define_method(rb_cArray, "reverse_each", rb_ary_reverse_each, 0); + rb_define_method(rb_cArray, "length", rb_ary_length, 0); + rb_define_alias(rb_cArray, "size", "length"); + rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0); + rb_define_method(rb_cArray, "index", rb_ary_index, 1); + rb_define_method(rb_cArray, "rindex", rb_ary_rindex, 1); + rb_define_method(rb_cArray, "indexes", rb_ary_indexes, -1); + rb_define_method(rb_cArray, "indices", rb_ary_indexes, -1); + rb_define_method(rb_cArray, "clone", rb_ary_clone, 0); + rb_define_method(rb_cArray, "dup", rb_ary_dup, 0); + rb_define_method(rb_cArray, "join", rb_ary_join_method, -1); + rb_define_method(rb_cArray, "reverse", rb_ary_reverse_method, 0); + rb_define_method(rb_cArray, "reverse!", rb_ary_reverse, 0); + rb_define_method(rb_cArray, "sort", rb_ary_sort, 0); + rb_define_method(rb_cArray, "sort!", rb_ary_sort_bang, 0); + rb_define_method(rb_cArray, "delete", rb_ary_delete, 1); + rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at, 1); + rb_define_method(rb_cArray, "delete_if", rb_ary_delete_if, 0); + rb_define_method(rb_cArray, "filter", rb_ary_filter, 0); + rb_define_method(rb_cArray, "replace", rb_ary_replace_method, 1); + rb_define_method(rb_cArray, "clear", rb_ary_clear, 0); + rb_define_method(rb_cArray, "fill", rb_ary_fill, -1); + rb_define_method(rb_cArray, "include?", rb_ary_includes, 1); + rb_define_method(rb_cArray, "<=>", rb_ary_cmp, 1); + + rb_define_method(rb_cArray, "assoc", rb_ary_assoc, 1); + rb_define_method(rb_cArray, "rassoc", rb_ary_rassoc, 1); + + rb_define_method(rb_cArray, "+", rb_ary_plus, 1); + rb_define_method(rb_cArray, "*", rb_ary_times, 1); + + rb_define_method(rb_cArray, "-", rb_ary_diff, 1); + rb_define_method(rb_cArray, "&", rb_ary_and, 1); + rb_define_method(rb_cArray, "|", rb_ary_or, 1); + + rb_define_method(rb_cArray, "uniq", rb_ary_uniq, 0); + rb_define_method(rb_cArray, "uniq!", rb_ary_uniq_bang, 0); + rb_define_method(rb_cArray, "compact", rb_ary_compact, 0); + rb_define_method(rb_cArray, "compact!", rb_ary_compact_bang, 0); + rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0); + rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, 0); + rb_define_method(rb_cArray, "nitems", rb_ary_nitems, 0); cmp = rb_intern("<=>"); } |