class List

Constants

VERSION

Public Class Methods

[](*args) click to toggle source
static VALUE
list_s_create(int argc, VALUE *argv, VALUE klass)
{
        VALUE list;

        list = rb_obj_alloc(klass);
        return list_push_m(argc, argv, list);
}
new(p1 = v1, p2 = v2) click to toggle source
static VALUE
list_initialize(int argc, VALUE *argv, VALUE self)
{
        VALUE size, val;
        long len;
        long i;

        list_modify_check(self);
        if (argc == 0) {
                return self;
        }
        if (argc == 1 && !FIXNUM_P(argv[0])) {
                switch (rb_type(argv[0])) {
                case T_ARRAY:
                        return list_push_ary(self, argv[0]);
                case T_DATA:
                        return list_replace(self, argv[0]);
                default:
                        break;
                }
        }

        rb_scan_args(argc, argv, "02", &size, &val);

        len = NUM2LONG(size);
        if (len < 0) {
                rb_raise(rb_eArgError, "negative size");
        }
        if (LIST_MAX_SIZE < len) {
                rb_raise(rb_eArgError, "size too big");
        }

        if (rb_block_given_p()) {
                if (argc == 2) {
                        rb_warn("block supersedes default value argument");
                }
                for (i = 0; i < len; i++) {
                        list_push(self, rb_yield(LONG2NUM(i)));
                }
        } else {
                for (i = 0; i < len; i++) {
                        list_push(self, val);
                }
        }
        return self;
}
try_convert(p1) click to toggle source
static VALUE
list_s_try_convert(VALUE dummy, VALUE obj)
{
        return check_list_type(obj);
}

Public Instance Methods

&(p1) click to toggle source
static VALUE
list_and(VALUE list1, VALUE list2)
{
        VALUE list3, hash;
        st_table *table;
        st_data_t vv;
        item_t *c1;

        list2 = to_list(list2);
        list3 = list_new();
        if (LIST_LEN(list2) == 0) return list3;
        hash = list_make_hash(list2);
        table = RHASH_TBL(hash);

        LIST_FOR(list1, c1) {
                vv = (st_data_t) c1->value;
                if (st_delete(table, &vv, 0)) {
                        list_push(list3, c1->value);
                }
        }

        return list3;
}
*(p1) click to toggle source
static VALUE
list_times(VALUE self, VALUE times)
{
        VALUE result;
        VALUE tmp;
        long i, len;
        item_t *c;

        tmp = rb_check_string_type(times);
        if (!NIL_P(tmp)) {
                return list_join(self, tmp);
        }

        len = NUM2LONG(times);
        if (len == 0) {
                return rb_obj_alloc(rb_obj_class(self));
        }
        if (len < 0) {
                rb_raise(rb_eArgError, "negative argument");
        }

        if (LIST_MAX_SIZE / len < LIST_LEN(self)) {
                rb_raise(rb_eArgError, "argument too big");
        }

        result = rb_obj_alloc(rb_obj_class(self));
        if (0 < LIST_LEN(self)) {
                for (i = 0; i < len; i++) {
                        LIST_FOR(self, c) {
                                list_push(result, c->value);
                        }
                }
        }
        return result;
}
+(p1) click to toggle source
static VALUE
list_plus(VALUE x, VALUE y)
{
        item_t *cx, *cy;
        long len;
        VALUE result;

        Check_Type(y, T_DATA);
        len = LIST_LEN(x) + LIST_LEN(y);

        result = list_new();
        LIST_FOR(x,cx) {
                list_push(result, cx->value);
        }
        LIST_FOR(y,cy) {
                list_push(result, cy->value);
        }
        return result;
}
-(p1) click to toggle source
static VALUE
list_diff(VALUE list1, VALUE list2)
{
        VALUE list3;
        volatile VALUE hash;
        item_t *c;

        hash = list_make_hash(to_list(list2));
        list3 = list_new();

        LIST_FOR(list1, c) {
                if (st_lookup(RHASH_TBL(hash), c->value, 0)) continue;
                list_push(list3, c->value);
        }
        return list3;
}
<<(p1) click to toggle source
static VALUE
list_push(VALUE self, VALUE obj)
{
        list_t *ptr;
        item_t *next;

        list_modify_check(self);
        if (self == obj) {
                rb_raise(rb_eArgError, "`List' cannot set recursive");
        }

        next = item_alloc(obj, NULL);

        Data_Get_Struct(self, list_t, ptr);
        if (ptr->first == NULL) {
                ptr->first = next;
                ptr->last = next;
                ptr->last->next = NULL;
        } else {
                ptr->last->next = next;
                ptr->last = next;
        }
        LIST_LEN(self)++;
        return self;
}
<=>(p1) click to toggle source
static VALUE
list_cmp(VALUE list1, VALUE list2)
{
        VALUE v;
        long len;

        if (rb_type(list2) != T_DATA) return Qnil;
        if (list1 == list2) return INT2FIX(0);
        v = rb_exec_recursive_paired(recursive_cmp, list1, list2, list2);
        if (v != Qundef) return v;
        len = LIST_LEN(list1) - LIST_LEN(list2);
        if (len == 0) return INT2FIX(0);
        if (0 < len) return INT2FIX(1);
        return INT2FIX(-1);
}
==(p1) click to toggle source
static VALUE
list_equal(VALUE self, VALUE obj)
{
        if (self == obj)
                return Qtrue;

        if (!rb_obj_is_kind_of(obj, cList)) {
                if (rb_type(obj) == T_ARRAY) {
                        return Qfalse;
                }
                if (!rb_respond_to(obj, id_to_list)) {
                        return Qfalse;
                }
                return rb_equal(obj, self);
        }
        return rb_exec_recursive_paired(recursive_equal, self, obj, obj);

}
[](p1, p2 = v2) click to toggle source
static VALUE
list_aref(int argc, VALUE *argv, VALUE self)
{
        VALUE arg;
        long beg, len;
        list_t *ptr;

        Data_Get_Struct(self, list_t, ptr);
        if (argc == 2) {
                beg = NUM2LONG(argv[0]);
                len = NUM2LONG(argv[1]);
                if (beg < 0) {
                        beg += LIST_LEN(self);
                }
                return list_subseq(self, beg, len);
        }
        if (argc != 1) {
                rb_scan_args(argc, argv, "11", NULL, NULL);
        }
        arg = argv[0];

        /* special case - speeding up */
        if (FIXNUM_P(arg)) {
                return list_entry(self, FIX2LONG(arg));
        }
        /* check if idx is Range */
        switch (rb_range_beg_len(arg, &beg, &len, LIST_LEN(self), 0)) {
        case Qfalse:
                break;
        case Qnil:
                return Qnil;
        default:
                return list_subseq(self, beg, len);
        }
        return list_entry(self, NUM2LONG(arg));
}
Also aliased as: slice
[]=(*args) click to toggle source
static VALUE
list_aset(int argc, VALUE *argv, VALUE self)
{
        long offset, beg, len;
        list_t *ptr;

        Data_Get_Struct(self, list_t, ptr);
        if (argc == 3) {
                list_modify_check(self);
                beg = NUM2LONG(argv[0]);
                len = NUM2LONG(argv[1]);
                list_splice(self, beg, len, argv[2]);
                return argv[2];
        }
        rb_check_arity(argc, 2, 2);
        list_modify_check(self);
        if (FIXNUM_P(argv[0])) {
                offset = FIX2LONG(argv[0]);
                goto fixnum;
        }
        if (rb_range_beg_len(argv[0], &beg, &len, LIST_LEN(self), 1)) {
                /* check if idx is Range */
                list_splice(self, beg, len, argv[1]);
                return argv[1];
        }

        offset = NUM2LONG(argv[0]);
fixnum:
        list_store(self, offset, argv[1]);
        return argv[1];
}
assoc(p1) click to toggle source
static VALUE
list_assoc(VALUE self, VALUE key)
{
        VALUE v;
        item_t *c;

        if (list_empty_p(self)) return Qnil;
        LIST_FOR(self, c) {
                v = check_list_type(c->value);
                if (!NIL_P(v)) {
                        if (0 < LIST_LEN(v) && rb_equal(list_first(0,NULL,v), key)) {
                                return v;
                        }
                }
        }
        return Qnil;
}
at(p1) click to toggle source
static VALUE
list_at(VALUE self, VALUE pos)
{
        return list_entry(self, NUM2LONG(pos));
}
bsearch() click to toggle source

from CRuby rb_ary_bsearch

static VALUE
list_bsearch(VALUE self)
{
        long low, high, mid;
        int smaller = 0, satisfied = 0;
        VALUE v, val, ary;

        ary = list_to_a(self);
        low = 0;
        high = RARRAY_LEN(ary);

        RETURN_ENUMERATOR(self, 0, 0);
        while (low < high) {
                mid = low + ((high - low) / 2);
                val = rb_ary_entry(ary, mid);
                v = rb_yield(val);
                if (FIXNUM_P(v)) {
                        if (FIX2INT(v) == 0) return val;
                        smaller = FIX2INT(v) < 0;
                }
                else if (v == Qtrue) {
                        satisfied = 1;
                        smaller = 1;
                }
                else if (v == Qfalse || v == Qnil) {
                        smaller = 0;
                }
                else if (rb_obj_is_kind_of(v, rb_cNumeric)) {
                        const VALUE zero = INT2FIX(0);
                        switch (rb_cmpint(rb_funcall(v, id_cmp, 1, zero), v, INT2FIX(0))) {
                                case 0: return val;
                                case 1: smaller = 1; break;
                                case -1: smaller = 0;
                        }
                }
                else {
                        rb_raise(rb_eTypeError, "wrong argument type %s"
                                        " (must be numeric, true, false or nil)",
                                        rb_obj_classname(v));
                }
                if (smaller) {
                        high = mid;
                }
                else {
                        low = mid + 1;
                }
        }
        if (low == RARRAY_LEN(ary)) return Qnil;
        if (!satisfied) return Qnil;
        return rb_ary_entry(ary, low);
}
clear() click to toggle source
static VALUE
list_clear(VALUE self)
{
        list_modify_check(self);
        list_t *ptr;
        Data_Get_Struct(self, list_t, ptr);
        list_free(ptr);
        ptr->first = NULL;
        ptr->last = NULL;
        LIST_LEN(self) = 0;
        return self;
}
collect() click to toggle source
static VALUE
list_collect(VALUE self)
{
        return list_collect_bang(rb_obj_clone(self));
}
Also aliased as: map
collect!() click to toggle source
static VALUE
list_collect_bang(VALUE self)
{
        item_t *c;

        RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
        LIST_FOR(self, c) {
                c->value = rb_yield(c->value);
        }
        return self;
}
Also aliased as: map!
combination(p1) click to toggle source
static VALUE
list_combination(VALUE self, VALUE num)
{
        return list_delegate_rb(1, &num, self, rb_intern("combination"));
}
compact() click to toggle source
static VALUE
list_compact(VALUE self)
{
        self = list_dup(self);
        list_compact_bang(self);
        return self;
}
compact!() click to toggle source
static VALUE
list_compact_bang(VALUE self)
{
        long len;

        list_modify_check(self);
        len = LIST_LEN(self);
        list_delete(self, Qnil);
        if (len == LIST_LEN(self)) {
                return Qnil;
        }
        return self;
}
concat(p1) click to toggle source
static VALUE
list_concat(VALUE self, VALUE obj)
{
        long len;
        enum ruby_value_type type;

        list_modify_check(self);
        type = rb_type(obj);
        if (type == T_DATA) {
                len = LIST_LEN(obj);
        } else if (type == T_ARRAY) {
                len = RARRAY_LEN(obj);
        } else {
                obj = to_list(obj);
                len = LIST_LEN(obj);
        }

        if (0 < len) {
                list_splice(self, LIST_LEN(self), 0, obj);
        }
        return self;
}
count(p1) click to toggle source
static VALUE
list_count(int argc, VALUE *argv, VALUE self)
{
        VALUE obj;
        item_t *c;
        long n = 0;

        if (argc == 0) {
                if (!rb_block_given_p()) {
                        return list_length(self);
                }
                LIST_FOR(self,c) {
                        if (RTEST(rb_yield(c->value))) n++;
                }
        } else {
                rb_scan_args(argc, argv, "1", &obj);
                if (rb_block_given_p()) {
                        rb_warn("given block not used");
                }
                LIST_FOR(self,c) {
                        if (rb_equal(c->value, obj)) n++;
                }
        }
        return LONG2NUM(n);
}
cycle(p1 = v1) click to toggle source
static VALUE
list_cycle(int argc, VALUE *argv, VALUE self)
{
        VALUE nv = Qnil;
        item_t *c;
        long n;

        RETURN_SIZED_ENUMERATOR(self, argc, argv, list_cycle_size);
        rb_scan_args(argc, argv, "01", &nv);

        if (NIL_P(nv)) {
                n = -1;
        } else {
                n = NUM2LONG(nv);
                if (n <= 0) return Qnil;
        }

        while (0 < LIST_LEN(self) && (n < 0 || 0 < n--)) {
                LIST_FOR(self, c) {
                        rb_yield(c->value);
                        if (list_empty_p(self)) break;
                }
        }
        return Qnil;
}
delete(p1) click to toggle source
static VALUE
list_delete(VALUE self, VALUE item)
{
        list_t *ptr;
        item_t *c, *before = NULL, *next;
        long len;

        list_modify_check(self);
        Data_Get_Struct(self, list_t, ptr);
        if (LIST_LEN(self) == 0) return Qnil;

        len = LIST_LEN(self);
        for (c = ptr->first; c; c = next) {
                next = c->next;
                if (rb_equal(c->value, item)) {
                        if (ptr->first == ptr->last) {
                                ptr->first = NULL;
                                ptr->last = NULL;
                        } else if (c == ptr->first) {
                                ptr->first = c->next;
                        } else if (c == ptr->last) {
                                ptr->last = before;
                                ptr->last->next = NULL;
                        } else {
                                before->next = c->next;
                        }
                        xfree(c);
                        LIST_LEN(self)--;
                } else {
                        before = c;
                }
        }

        if (LIST_LEN(self) == len) {
                if (rb_block_given_p()) {
                        return rb_yield(item);
                }
                return Qnil;
        } else {
                return item;
        }
}
delete_at(p1) click to toggle source
static VALUE
list_delete_at_m(VALUE self, VALUE pos)
{
        return list_delete_at(self, NUM2LONG(pos));
}
delete_if() click to toggle source
static VALUE
list_delete_if(VALUE self)
{
        RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
        list_reject_bang(self);
        return self;
}
drop(p1) click to toggle source
static VALUE
list_drop(VALUE self, VALUE n)
{
        VALUE result;
        long pos = NUM2LONG(n);

        if (pos < 0) {
                rb_raise(rb_eArgError, "attempt to drop negative size");
        }
        result = list_subseq(self, pos, LIST_LEN(self));
        if (result == Qnil) result = list_new();
        return result;
}
drop_while() click to toggle source
static VALUE
list_drop_while(VALUE self)
{
        long i = 0;
        item_t *c;

        RETURN_ENUMERATOR(self, 0, 0);
        LIST_FOR(self, c) {
                if (!RTEST(rb_yield(c->value))) break;
                i++;
        }
        return list_drop(self, LONG2FIX(i));
}
each() click to toggle source
static VALUE
list_each(VALUE self)
{
        item_t *c;

        RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);

        LIST_FOR(self, c) {
                rb_yield(c->value);
        }
        return self;
}
each_index() click to toggle source
static VALUE
list_each_index(VALUE self)
{
        item_t *c;
        long index;

        RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);

        index = 0;
        LIST_FOR(self, c) {
                rb_yield(LONG2NUM(index++));
        }
        return self;
}
empty?() click to toggle source
static VALUE
list_empty_p(VALUE self)
{
        list_t *ptr;
        Data_Get_Struct(self, list_t, ptr);
        if (LIST_LEN(self) == 0)
                return Qtrue;
        return Qfalse;
}
fetch(p1, p2 = v2) click to toggle source
static VALUE
list_fetch(int argc, VALUE *argv, VALUE self)
{
        VALUE pos, ifnone;
        long block_given;
        long idx;
        list_t *ptr;

        Data_Get_Struct(self, list_t, ptr);
        rb_scan_args(argc, argv, "11", &pos, &ifnone);
        block_given = rb_block_given_p();
        if (block_given && argc == 2) {
                rb_warn("block supersedes default value argument");
        }
        idx = NUM2LONG(pos);

        if (idx < 0) {
                idx += LIST_LEN(self);
        }
        if (idx < 0 || LIST_LEN(self) <= idx) {
                if (block_given) return rb_yield(pos);
                if (argc == 1) {
                        rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%ld",
                                        idx - (idx < 0 ? LIST_LEN(self) : 0), -LIST_LEN(self), LIST_LEN(self));
                }
                return ifnone;
        }
        return list_entry(self, idx);
}
fill(p1 = v1, p2 = v2) click to toggle source
static VALUE
list_fill(int argc, VALUE *argv, VALUE self)
{
        VALUE item, arg1, arg2;
        long beg = 0, len = 0, end = 0;
        long i;
        int block_p = FALSE;
        item_t *c;

        list_modify_check(self);
        if (rb_block_given_p()) {
                block_p = TRUE;
                rb_scan_args(argc, argv, "02", &arg1, &arg2);
                argc += 1; /* hackish */
        } else {
                rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
        }
        switch (argc) {
        case 1:
                beg = 0;
                len = LIST_LEN(self);
                break;
        case 2:
                if (rb_range_beg_len(arg1, &beg, &len, LIST_LEN(self), 1)) {
                        break;
                }
                /* fall through */
        case 3:
                beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
                if (beg < 0) {
                        beg = LIST_LEN(self) + beg;
                        if (beg < 0) beg = 0;
                }
                len = NIL_P(arg2) ? LIST_LEN(self) - beg : NUM2LONG(arg2);
                break;
        }
        if (len < 0) {
                return self;
        }
        if (LIST_MAX_SIZE <= beg || LIST_MAX_SIZE - beg < len) {
                rb_raise(rb_eArgError, "argument too big");
        }
        end = beg + len;
        if (LIST_LEN(self) < end) {
                for (i = 0; i < end - LIST_LEN(self); i++) {
                        list_push(self, Qnil);
                }
        }

        i = -1;
        LIST_FOR(self, c) {
                i++;
                if (i < beg) continue;
                if ((end - 1) < i) break;
                if (block_p) {
                        c->value = rb_yield(LONG2NUM(i));
                } else {
                        c->value = item;
                }
        }
        return self;
}
first(*args) click to toggle source
static VALUE
list_first(int argc, VALUE *argv, VALUE self)
{
        list_t *ptr;
        Data_Get_Struct(self, list_t, ptr);
        if (argc == 0) {
                if (ptr->first == NULL) return Qnil;
                return ptr->first->value;
        } else {
                return list_take_first_or_last(argc, argv, self, LIST_TAKE_FIRST);
        }
}
flatten(p1 = v1) click to toggle source
static VALUE
list_flatten(int argc, VALUE *argv, VALUE self)
{
        int mod = 0, level = -1;
        VALUE result, lv;

        rb_scan_args(argc, argv, "01", &lv);
        if (!NIL_P(lv)) level = NUM2INT(lv);
        if (level == 0) return list_make_shared_copy(self);

        result = flatten(self, level, &mod);
        OBJ_INFECT(result, self);

        return result;
}
flatten!(p1 = v1) click to toggle source
static VALUE
list_flatten_bang(int argc, VALUE *argv, VALUE self)
{
        int mod = 0, level = -1;
        VALUE result, lv;

        rb_scan_args(argc, argv, "01", &lv);
        list_modify_check(self);
        if (!NIL_P(lv)) level = NUM2INT(lv);
        if (level == 0) return Qnil;

        result = flatten(self, level, &mod);
        if (mod == 0) {
                return Qnil;
        }
        list_replace(self, result);
        return self;
}
frozen?() click to toggle source
static VALUE
list_frozen_p(VALUE self)
{
        if (OBJ_FROZEN(self)) return Qtrue;
        return Qfalse;
}
hash() click to toggle source
static VALUE
list_hash(VALUE self)
{
        item_t *c;
        st_index_t h;
        VALUE n;

        h = rb_hash_start(LIST_LEN(self));
        h = rb_hash_uint(h, (st_index_t)list_hash);
        LIST_FOR(self, c) {
                n = rb_hash(c->value);
                h = rb_hash_uint(h, NUM2LONG(n));
        }
        h = rb_hash_end(h);
        return LONG2FIX(h);
}
include?(p1) click to toggle source
static VALUE
list_include_p(VALUE self, VALUE item)
{
        item_t *c;

        LIST_FOR(self, c) {
                if (rb_equal(c->value, item)) {
                        return Qtrue;
                }
        }
        return Qfalse;
}
initialize_copy(p1) click to toggle source
static VALUE
list_replace(VALUE copy, VALUE orig)
{
        item_t *c_orig;
        item_t *c_copy;
        long olen;

        list_modify_check(copy);
        if (copy == orig) return copy;

        switch (rb_type(orig)) {
        case T_ARRAY:
                return list_replace_ary(copy, orig);
        case T_DATA:
                break;
        default:
                rb_raise(rb_eTypeError, "cannot convert to list");
        }
        orig = to_list(orig);
        olen = LIST_LEN(orig);
        if (olen == 0) {
                return list_clear(copy);
        }
        if (olen == LIST_LEN(copy)) {
                LIST_FOR_DOUBLE(orig, c_orig, copy, c_copy, {
                        c_copy->value = c_orig->value;
                });
        } else {
                list_clear(copy);
                LIST_FOR(orig, c_orig) {
                        list_push(copy, c_orig->value);
                }
        }

        return copy;
}
Also aliased as: replace
insert(*args) click to toggle source
static VALUE
list_insert(int argc, VALUE *argv, VALUE self)
{
        list_t *ptr;
        long pos;

        Data_Get_Struct(self, list_t, ptr);
        rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
        list_modify_check(self);
        if (argc == 1) return self;
        pos = NUM2LONG(argv[0]);
        if (pos == -1) {
                pos = LIST_LEN(self);
        }
        if (pos < 0) {
                pos++;
        }
        list_splice(self, pos, 0, rb_ary_new4(argc - 1, argv + 1));
        return self;
}
inspect() click to toggle source
static VALUE
list_inspect(VALUE self)
{
        if (LIST_LEN(self) == 0)
                return rb_sprintf("#<%s: []>", rb_obj_classname(self));
        return rb_exec_recursive(inspect_list, self, 0);
}
Also aliased as: to_s
join(p1 = v1) click to toggle source
static VALUE
list_join_m(int argc, VALUE *argv, VALUE self)
{
        VALUE sep;

        rb_scan_args(argc, argv, "01", &sep);
        if (NIL_P(sep)) sep = rb_output_fs;

        return list_join(self, sep);
}
keep_if() click to toggle source
static VALUE
list_keep_if(VALUE self)
{
        RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
        list_select_bang(self);
        return self;
}
last(*args) click to toggle source
static VALUE
list_last(int argc, VALUE *argv, VALUE self)
{
        list_t *ptr;
        long len;

        Data_Get_Struct(self, list_t, ptr);
        if (argc == 0) {
                len = LIST_LEN(self);
                if (len == 0) return Qnil;
                return list_elt(self, len - 1);
        } else {
                return list_take_first_or_last(argc, argv, self, LIST_TAKE_LAST);
        }
}
length() click to toggle source
static VALUE
list_length(VALUE self)
{
        list_t *ptr;
        Data_Get_Struct(self, list_t, ptr);
        return LONG2NUM(LIST_LEN(self));
}
Also aliased as: size
map()
Alias for: collect
map!()
Alias for: collect!
pack(p1) click to toggle source
static VALUE
list_pack(VALUE self, VALUE str)
{
        return list_delegate_rb(1, &str, self, rb_intern("pack"));
}
permutation(*args) click to toggle source
static VALUE
list_permutation(int argc, VALUE *argv, VALUE self)
{
        return list_delegate_rb(argc, argv, self, rb_intern("permutation"));
}
pop(*args) click to toggle source
static VALUE
list_pop_m(int argc, VALUE *argv, VALUE self)
{
        VALUE result;
        long n;

        if (argc == 0) {
                return list_pop(self);
        }

        list_modify_check(self);
        result = list_take_first_or_last(argc, argv, self, LIST_TAKE_LAST);
        n = NUM2LONG(argv[0]);
        list_mem_clear(self, LIST_LEN(self) - n, n);
        return result;
}
product(*args) click to toggle source
static VALUE
list_product(int argc, VALUE *argv, VALUE self)
{
        return list_delegate_rb(argc, argv, self, rb_intern("product"));
}
push(*args) click to toggle source
static VALUE
list_push_m(int argc, VALUE *argv, VALUE self)
{
        long i;

        list_modify_check(self);
        if (argc == 0) return self;
        for (i = 0; i < argc; i++) {
                list_push(self, argv[i]);
        }
        return self;
}
rassoc(p1) click to toggle source
static VALUE
list_rassoc(VALUE self, VALUE value)
{
        VALUE v;
        item_t *c;

        if (list_empty_p(self)) return Qnil;
        LIST_FOR(self, c) {
                v = check_list_type(c->value);
                if (!NIL_P(v)) {
                        if (1 < LIST_LEN(v) && rb_equal(list_elt(v,1), value)) {
                                return v;
                        }
                }
        }
        return Qnil;
}
reject() click to toggle source
static VALUE
list_reject(VALUE self)
{
        VALUE rejected_list;

        RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
        rejected_list = list_new();
        reject(self, rejected_list);
        return rejected_list;
}
reject!() click to toggle source
static VALUE
list_reject_bang(VALUE self)
{
        RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
        return reject_bang(self);
}
repeated_combination(p1) click to toggle source
static VALUE
list_repeated_combination(VALUE self, VALUE num)
{
        return list_delegate_rb(1, &num, self, rb_intern("repeated_combination"));
}
repeated_permutation(p1) click to toggle source
static VALUE
list_repeated_permutation(VALUE self, VALUE num)
{
        return list_delegate_rb(1, &num, self, rb_intern("repeated_permutation"));
}
replace(p1)
Alias for: initialize_copy
reverse() click to toggle source
static VALUE
list_reverse_m(VALUE self)
{
        VALUE result;
        item_t *c;

        result = list_new();
        if (LIST_LEN(self) == 0) return result;
        LIST_FOR(self, c) {
                list_unshift(result, c->value);
        }
        return result;
}
reverse!() click to toggle source
static VALUE
list_reverse_bang(VALUE self)
{
        VALUE tmp;
        item_t *c;
        long len;

        if (LIST_LEN(self) == 0) return self;
        tmp = list_to_a(self);
        len = LIST_LEN(self);
        LIST_FOR(self, c) {
                c->value = rb_ary_entry(tmp, --len);
        }
        return self;
}
rindex(*args) click to toggle source
static VALUE
list_rindex(int argc, VALUE *argv, VALUE self)
{
        long i;
        long len;
        VALUE val;

        i = LIST_LEN(self);
        if (argc == 0) {
                RETURN_ENUMERATOR(self, 0, 0);
                while (i--) {
                        if (RTEST(rb_yield(list_elt(self, i))))
                                return LONG2NUM(i);
                        if (LIST_LEN(self) < i) {
                                i = LIST_LEN(self);
                        }
                }
                return Qnil;
        }
        rb_check_arity(argc, 0, 1);
        val = argv[0];
        if (rb_block_given_p())
                rb_warn("given block not used");
        while (i--) {
                if (rb_equal(list_elt(self, i), val)) {
                        return LONG2NUM(i);
                }
                len = LIST_LEN(self);
                if (len < i) {
                        i = len;
                }
        }
        return Qnil;
}
ring() click to toggle source
static VALUE
list_ring(VALUE self)
{
        VALUE clone = rb_obj_clone(self);
        return list_ring_bang(clone);
}
ring!() click to toggle source
static VALUE
list_ring_bang(VALUE self)
{
        list_t *ptr;

        Data_Get_Struct(self, list_t, ptr);
        if (ptr->first == NULL)
                rb_raise(rb_eRuntimeError, "length is zero list cannot to change ring");
        rb_obj_freeze(self);
        ptr->last->next = ptr->first;
        return self;
}
ring?() click to toggle source
static VALUE
list_ring_p(VALUE self)
{
        list_t *ptr;

        Data_Get_Struct(self, list_t, ptr);
        if (ptr->first == NULL)
                return Qfalse;
        if (ptr->first == ptr->last->next)
                return Qtrue;
        return Qfalse;
}
rotate(*args) click to toggle source
static VALUE
list_rotate_m(int argc, VALUE *argv, VALUE self)
{
        VALUE clone = rb_obj_clone(self);
        return list_rotate_bang(argc, argv, clone);
}
rotate!(p1 = v1) click to toggle source
static VALUE
list_rotate_bang(int argc, VALUE *argv, VALUE self)
{
        list_t *ptr;
        item_t *c;
        long cnt = 1;
        long i = 0;

        switch (argc) {
        case 1: cnt = NUM2LONG(argv[0]);
        case 0: break;
        default: rb_scan_args(argc, argv, "01", NULL);
        }

        if (LIST_LEN(self) == 0) return self;
        cnt = (cnt < 0) ? (LIST_LEN(self) - (~cnt % LIST_LEN(self)) - 1) : (cnt & LIST_LEN(self));
        Data_Get_Struct(self, list_t, ptr);
        LIST_FOR(self, c) {
                if (cnt == ++i) break;
        }

        ptr->last->next = ptr->first;
        ptr->first = c->next;
        ptr->last = c;
        ptr->last->next = NULL;
        return self;
}
sample(*args) click to toggle source
static VALUE
list_sample(int argc, VALUE *argv, VALUE self)
{
        return list_delegate_rb(argc, argv, self, rb_intern("sample"));
}
select() click to toggle source
static VALUE
list_select(VALUE self)
{
        VALUE result;
        item_t *c;

        RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
        result = list_new();
        LIST_FOR(self, c) {
                if (RTEST(rb_yield(c->value))) {
                        list_push(result, c->value);
                }
        }
        return result;
}
select!() click to toggle source
static VALUE
list_select_bang(VALUE self)
{
        VALUE result;
        item_t *c;
        long i = 0;

        RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
        result = list_new();
        LIST_FOR(self, c) {
                if (RTEST(rb_yield(c->value))) {
                        i++;
                        list_push(result, c->value);
                }
        }

        if (i == LIST_LEN(self)) return Qnil;
        return list_replace(self, result);
}
shift(*args) click to toggle source
static VALUE
list_shift_m(int argc, VALUE *argv, VALUE self)
{
        VALUE result;
        long i;
        list_t *ptr;

        if (argc == 0) {
                return list_shift(self);
        }

        list_modify_check(self);
        result = list_take_first_or_last(argc, argv, self, LIST_TAKE_FIRST);
        Data_Get_Struct(result, list_t, ptr);
        for (i = 0; i < LIST_LEN(self); i++) {
                list_shift(self);
        }
        return result;
}
shuffle(*args) click to toggle source
static VALUE
list_shuffle(int argc, VALUE *argv, VALUE self)
{
        return list_delegate_rb(argc, argv, self, rb_intern("shuffle"));
}
shuffle!(*args) click to toggle source
static VALUE
list_shuffle_bang(int argc, VALUE *argv, VALUE self)
{
        return list_replace(self, list_shuffle(argc, argv, self));
}
size()
Alias for: length
slice(p1, p2 = v2)
Alias for: []
slice!(p1, p2 = v2) click to toggle source
static VALUE
list_slice_bang(int argc, VALUE *argv, VALUE self)
{
        long pos = 0, len = 0;

        list_modify_check(self);
        if (argc == 1) {
                if (FIXNUM_P(argv[0])) {
                        return list_delete_at(self, NUM2LONG(argv[0]));
                } else {
                        switch (rb_range_beg_len(argv[0], &pos, &len, LIST_LEN(self), 0)) {
                        case Qtrue: /* valid range */
                                break;
                        case Qnil: /* invalid range */
                                return Qnil;
                        default: /* not a range */
                                return list_delete_at(self, NUM2LONG(argv[0]));
                        }
                }
        } else if (argc == 2) {
                pos = NUM2LONG(argv[0]);
                len = NUM2LONG(argv[1]);
        } else {
                rb_scan_args(argc, argv, "11", NULL, NULL);
        }
        if (len < 0) return Qnil;
        if (pos < 0) {
                pos += LIST_LEN(self);
                if (pos < 0) return Qnil;
        } else if (LIST_LEN(self) < pos) {
                return Qnil;
        }
        if (LIST_LEN(self) < pos + len) {
                len = LIST_LEN(self) - pos;
        }
        if (len == 0) return list_new();
        VALUE list2 = list_subseq(self, pos, len);
        list_mem_clear(self, pos, len);
        return list2;
}
sort() click to toggle source
static VALUE
list_sort(VALUE self)
{
        VALUE clone = rb_obj_clone(self);
        return list_sort_bang(clone);
}
sort!() click to toggle source
static VALUE
list_sort_bang(VALUE self)
{
        item_t *c;
        long i = 0;

        VALUE ary = list_to_a(self);
        rb_ary_sort_bang(ary);
        LIST_FOR(self, c) {
                c->value = rb_ary_entry(ary, i++);
        }
        return self;
}
sort_by() click to toggle source
static VALUE
list_sort_by(VALUE self)
{
        VALUE ary;

        RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
        ary = rb_block_call(list_to_a(self), rb_intern("sort_by"), 0, 0, sort_by_i, 0);
        return to_list(ary);
}
sort_by!() click to toggle source
static VALUE
list_sort_by_bang(VALUE self)
{
        VALUE sorted;

        sorted = list_sort_by(self);
        return list_replace(self, sorted);
}
take(p1) click to toggle source
static VALUE
list_take(VALUE self, VALUE n)
{
        int len = NUM2LONG(n);

        if (len < 0) {
                rb_raise(rb_eArgError, "attempt to take negative size");
        }
        return list_subseq(self, 0, len);
}
take_while() click to toggle source
static VALUE
list_take_while(VALUE self)
{
        item_t *c;
        long i = 0;

        RETURN_ENUMERATOR(self, 0, 0);
        LIST_FOR(self, c) {
                if (!RTEST(rb_yield(c->value))) break;
                i++;
        }
        return list_take(self, LONG2FIX(i));
}
to_a() click to toggle source
static VALUE
list_to_a(VALUE self)
{
        item_t *c;
        VALUE ary;
        long i = 0;

        ary = rb_ary_new2(LIST_LEN(self));
        LIST_FOR(self, c) {
                rb_ary_store(ary, i++, c->value);
        }
        return ary;
}
Also aliased as: to_ary
to_ary()
Alias for: to_a
to_list() click to toggle source
static VALUE
list_to_list(VALUE self)
{
        return self;
}
to_s()
Alias for: inspect
transpose() click to toggle source
static VALUE
list_transpose(VALUE self)
{
        return list_delegate_rb(0, NULL, self, rb_intern("transpose"));
}
uniq() click to toggle source
static VALUE
list_uniq(VALUE self)
{
        VALUE hash, uniq;

        if (LIST_LEN(self) <= 1)
                return list_dup(self);

        if (rb_block_given_p()) {
                hash = list_make_hash_by(self);
        } else {
                hash = list_make_hash(self);
        }
        uniq = list_hash_values(hash);
        return uniq;
}
uniq!() click to toggle source
static VALUE
list_uniq_bang(VALUE self)
{
        long len;

        list_modify_check(self);
        len = LIST_LEN(self);
        if (len <= 1)
                return Qnil;

        list_replace(self, list_uniq(self));
        if (len == LIST_LEN(self)) {
                return Qnil;
        }

        return self;
}
unshift(*args) click to toggle source
static VALUE
list_unshift_m(int argc, VALUE *argv, VALUE self)
{
        long i;

        list_modify_check(self);
        if (argc == 0) return self;
        for (i = argc - 1; 0 <= i; i--) {
                list_unshift(self, argv[i]);
        }
        return self;
}
values_at(*args) click to toggle source
static VALUE
list_values_at(int argc, VALUE *argv, VALUE self)
{
        VALUE result = list_new();
        long beg, len;
        long i, j;
        list_t *ptr;

        Data_Get_Struct(self, list_t, ptr);
        for (i = 0; i < argc; i++) {
                if (FIXNUM_P(argv[i])) {
                        list_push(result, list_entry(self, FIX2LONG(argv[i])));
                } else if (rb_range_beg_len(argv[i], &beg, &len, LIST_LEN(self), 1)) {
                        for (j = beg; j < beg + len; j++) {
                                if (LIST_LEN(self) < j) {
                                        list_push(result, Qnil);
                                } else {
                                        list_push(result, list_elt(self, j));
                                }
                        }
                } else {
                        list_push(result, list_entry(self, NUM2LONG(argv[i])));
                }
        }
        return result;
}
zip(*args) click to toggle source
static VALUE
list_zip(int argc, VALUE *argv, VALUE self)
{
        VALUE ary;
        long i;

        ary = rb_funcall2(list_to_a(self), rb_intern("zip"), argc, argv);
        if (rb_block_given_p()) {
                for (i = 0; i < RARRAY_LEN(ary); i++) {
                        rb_yield(rb_ary_entry(ary, i));
                }
                return Qnil;
        } else {
                return to_list(ary);
        }
}
|(p1) click to toggle source
static VALUE
list_or(VALUE list1, VALUE list2)
{
        VALUE hash, list3;
        st_data_t vv;
        item_t *c1, *c2;

        list2 = to_list(list2);
        list3 = list_new();
        hash = list_add_hash(list_make_hash(list1), list2);

        LIST_FOR(list1,c1) {
                vv = (st_data_t)c1->value;
                if (st_delete(RHASH_TBL(hash), &vv, 0)) {
                        list_push(list3, c1->value);
                }
        }
        LIST_FOR(list2,c2) {
                vv = (st_data_t)c2->value;
                if (st_delete(RHASH_TBL(hash), &vv, 0)) {
                        list_push(list3, c2->value);
                }
        }
        return list3;
}