/*
Copyright (C) 2001-2003, The Perl Foundation.
$Id: intlist.pmc 16275 2006-12-28 01:20:44Z particle $

=head1 NAME

src/pmc/intlist.pmc - Array of integers

=head1 DESCRIPTION

C<IntList> provides an integer-only array.

=head2 Methods

=over 4

=cut

*/

#include "parrot/parrot.h"

pmclass IntList does array {

/*

=item C<PMC *clone()>

Creates and returns a clone of the list.

=cut

*/

    PMC* clone() {
        PMC* const dest = pmc_new_noinit(INTERP, SELF->vtable->base_type);
        PObj_custom_mark_SET(dest);
        PMC_struct_val(dest) = intlist_clone(INTERP,
                                             (IntList *) PMC_struct_val(SELF));
        return dest;
    }

/*

=item C<void init()>

Initializes the list.

=cut

*/

    void init() {
        PMC_struct_val(SELF) = intlist_new(INTERP);
        PObj_custom_mark_SET(SELF);
    }

/*

=item C<void mark()>

Marks the list as live.

=cut

*/

    void mark() {
        intlist_mark(INTERP, (IntList *) PMC_struct_val(SELF));
    }

/*

=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>

Sets C<value> at index C<key>.

=cut

*/

    void set_integer_keyed_int(INTVAL key, INTVAL value) {
        intlist_assign(INTERP, (IntList*) PMC_struct_val(SELF), key, value);
    }

    void set_integer_native(INTVAL len) {
        list_set_length(INTERP, (List*) PMC_struct_val(SELF), len);
    }
/*

=item C<void set_integer_keyed(PMC *key, INTVAL value)>

Sets C<value> at index C<*key>.

=cut

*/

    void set_integer_keyed(PMC* key, INTVAL value) {
        INTVAL ix;

        if (!key) return;

        ix = key_integer(INTERP, key);
        intlist_assign(INTERP, (IntList*) PMC_struct_val(SELF), ix, value);
    }

/*

=item C<INTVAL get_integer()>

Returns the number of elements in the list.

=cut

*/

    INTVAL get_integer() {
        return intlist_length(INTERP, (IntList*) PMC_struct_val(SELF));
    }
    INTVAL elements() {
        return intlist_length(INTERP, (IntList*) PMC_struct_val(SELF));
    }

/*

=item C<INTVAL get_integer_keyed_int(INTVAL key)>

Returns the value of the element at index C<key>.

=cut

*/

    INTVAL get_integer_keyed_int(INTVAL key) {
        return intlist_get(INTERP, (IntList*) PMC_struct_val(SELF), key);
    }

/*

=item C<INTVAL get_integer_keyed(PMC *key)>

Returns the value of the element at index C<*key>.

=cut

*/

    INTVAL get_integer_keyed(PMC* key) {
        INTVAL ix;
        if (!key) return 0;
        ix = key_integer(INTERP, key);
        return intlist_get(INTERP, (IntList*) PMC_struct_val(SELF), ix);
    }

/*

=item C<void push_integer(INTVAL value)>

Adds C<value> to the end of the list.

=cut

*/

    void push_integer(INTVAL value) {
        intlist_push(INTERP, (IntList*) PMC_struct_val(SELF), value);
    }

/*

=item C<INTVAL pop_integer()>

Removes and returns the last element in the list.

=cut

*/

    INTVAL pop_integer() {
        return intlist_pop(INTERP, (IntList*) PMC_struct_val(SELF));
    }

/*

=item C<void unshift_integer(INTVAL value)>

Adds C<value> to the start of the list.

=cut

*/

    void unshift_integer(INTVAL value) {
        intlist_unshift(INTERP, (IntList**) &PMC_struct_val(SELF), value);
    }

/*

=item C<INTVAL shift_integer()>

Removes and returns the first element in the list.

=cut

*/

    INTVAL shift_integer() {
        return intlist_shift(INTERP, (IntList**) &PMC_struct_val(SELF));
    }

    void splice(PMC* value, INTVAL offset, INTVAL count) {
        if (SELF->vtable->base_type != value->vtable->base_type)
            real_exception(INTERP, NULL, E_TypeError,
                    "Type mismatch in splice");
        list_splice(INTERP, (List*) PMC_struct_val(SELF),
            (List *)PMC_struct_val(value), offset, count);
    }

    PMC* slice(PMC* key, INTVAL f) {
        switch (f) {
            case 0:
                {
                    PMC * const iter = pmc_new_init(INTERP,
                            enum_class_Iterator, SELF);
                    PMC_struct_val(iter) = key;
                    return iter;
                }
        }
        real_exception(INTERP, NULL, E_IndexError,
                "IntList: Unknown slice type");
        return NULL;
    }

    PMC* get_iter() {
        PMC * const iter = pmc_new_init(INTERP, enum_class_Iterator, SELF);
        PMC * const key =  pmc_new(INTERP, enum_class_Key);

        PMC_struct_val(iter) = key;
        PObj_get_FLAGS(key) |= KEY_integer_FLAG;
        PMC_int_val(key) = 0;
        if (!((List *) PMC_struct_val(SELF))->length)
            PMC_int_val(key) = -1;
        return iter;
    }

}

/*

=back

=cut

*/

/*
 * Local variables:
 *   c-file-style: "parrot"
 * End:
 * vim: expandtab shiftwidth=4:
 */
