/*
Copyright (C) 2001-2008, The Perl Foundation.
$Id: /mirror/trunk/src/pmc/fixedfloatarray.pmc 29983 2008-08-02T22:45:13.271765Z allison  $

=head1 NAME

src/pmc/fixedfloatarray.pmc - fixed size array for floating point numbers only

=head1 DESCRIPTION

This class, FixedFloatArray, implements an array of fixed size which
stored FLOATVALs.  It uses Float PMCs to do all necessary conversions.

=head2 Functions

=over 4

=cut

*/

#include "parrot/parrot.h"

pmclass FixedFloatArray need_ext provides array {

/*

=back

=head2 Methods

=over 4

=item C<void init()>

Initializes the array.

=cut

*/

    VTABLE void init() {
        PMC_int_val(SELF) = 0;
        PMC_data(SELF)    = NULL;
    }

/*

=item C<void destroy()>

Destroys the array.

=cut

*/

    VTABLE void destroy() {
        if (PMC_data(SELF))
            mem_sys_free(PMC_data(SELF));

        PMC_data(SELF)    = NULL;
        PMC_int_val(SELF) = 0;
    }

/*

=item C<PMC *clone()>

Creates and returns a copy of the array.

=cut

*/

    VTABLE PMC *clone() {
        INTVAL size;
        size_t mem_size;
        PMC   * const dest = pmc_new(INTERP, SELF->vtable->base_type);

        if (!PMC_data(SELF))
            return dest;

        size              = PMC_int_val(SELF);
        PMC_int_val(dest) = size;
        mem_size          = size * sizeof (FLOATVAL);

        PMC_data(dest)    = mem_sys_allocate(mem_size);
        mem_sys_memcopy(PMC_data(dest), PMC_data(SELF), mem_size);
        PObj_active_destroy_SET(dest);

        return dest;
    }

/*

=item C<INTVAL get_bool()>

Returns whether the array has any elements (meaning been initialized, for a
fixed sized array).

=cut

*/
    VTABLE INTVAL get_bool() {
        const INTVAL size = SELF.elements();
        return (INTVAL)(size != 0);
    }

/*

=item C<INTVAL elements()>

=cut

*/

    VTABLE INTVAL elements() {
        return PMC_int_val(SELF);
    }

/*

=item C<INTVAL get_integer()>

Returns the number of elements in the array.

=cut

*/

    VTABLE INTVAL get_integer() {
        return SELF.elements();
    }


/*

=item C<INTVAL get_integer_keyed_int(INTVAL key)>

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

=cut

*/

    VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
        const FLOATVAL f = SELF.get_number_keyed_int(key);
        return (INTVAL)f;
    }

/*

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

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

=cut

*/

    VTABLE INTVAL get_integer_keyed(PMC *key) {
        /* simple int keys only */
        const INTVAL k = key_integer(INTERP, key);
        return SELF.get_integer_keyed_int(k);
    }


/*

=item C<FLOATVAL get_number_keyed_int(INTVAL key)>

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

=cut

*/

    VTABLE FLOATVAL get_number_keyed_int(INTVAL key) {
        FLOATVAL *data;

        if (key < 0 || key >= PMC_int_val(SELF))
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
                "FixedFloatArray: index out of bounds!");

        data = (FLOATVAL *)PMC_data(SELF);
        return data[key];
    }

/*

=item C<FLOATVAL get_number_keyed(PMC *key)>

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

=cut

*/

    VTABLE FLOATVAL get_number_keyed(PMC *key) {
        const INTVAL k = key_integer(INTERP, key);
        return SELF.get_number_keyed_int(k);
    }

/*

=item C<STRING *get_string_keyed_int(INTVAL key)>

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

=cut

*/

    VTABLE STRING *get_string_keyed_int(INTVAL key) {
        PMC * const e = SELF.get_pmc_keyed_int(key);
        return VTABLE_get_string(INTERP, e);
    }

/*

=item C<STRING *get_string_keyed(PMC *key)>

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

=cut

*/

    VTABLE STRING *get_string_keyed(PMC *key) {
        const INTVAL k = key_integer(INTERP, key);
        return SELF.get_string_keyed_int(k);
    }


/*

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

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

=cut

*/

    VTABLE PMC *get_pmc_keyed_int(INTVAL key) {
        PMC    * const ret = pmc_new(INTERP, enum_class_Float);
        const FLOATVAL val = SELF.get_number_keyed_int(key);

        VTABLE_set_number_native(INTERP, ret, val);
        return ret;
    }

/*

=item C<PMC *get_pmc_keyed(PMC *key)>

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

=cut

*/

    VTABLE PMC *get_pmc_keyed(PMC *key) {
        const INTVAL k = key_integer(INTERP, key);
        return SELF.get_pmc_keyed_int(k);
    }

/*

=item C<void set_integer_native(INTVAL size)>

Resizes the array to C<size> elements.

=cut

*/

    VTABLE void set_integer_native(INTVAL size) {
        if (PMC_int_val(SELF) || size < 1)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
                    "FixedFloatArray: Can't resize!");

        PMC_int_val(SELF) = size;
        PMC_data(SELF)    = mem_sys_allocate(size * sizeof (FLOATVAL));
        PObj_active_destroy_SET(SELF);
    }

/*

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

Sets the integer value of the element at index C<key> to C<value>.

=cut

*/

    VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
        SELF.set_number_keyed_int(key, (FLOATVAL)value);
    }

/*

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

Sets the integer value of the element at index C<key> to C<value>.

=cut

*/

    VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
        const INTVAL k = key_integer(INTERP, key);
        SELF.set_integer_keyed_int(k, value);
    }

/*

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

Sets the floating-point value of the element at index C<key> to
C<value>.

=cut

*/

    VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
        FLOATVAL *data;
        if (key < 0 || key >= PMC_int_val(SELF))
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
                "FixedFloatArray: index out of bounds!");

        data      = (FLOATVAL *)PMC_data(SELF);
        data[key] = value;
    }

/*

=item C<void set_number_keyed(PMC *key, FLOATVAL value)>

Sets the floating-point value of the element at index C<key> to
C<value>.

=cut

*/

    VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
        const INTVAL k = key_integer(INTERP, key);
        SELF.set_number_keyed_int(k, value);
    }

/*

=item C<void set_string_keyed_int(INTVAL key, STRING *value)>

Sets the Parrot string value of the element at index C<key> to C<value>.

=cut

*/

    VTABLE void set_string_keyed_int(INTVAL key, STRING *value) {
        FLOATVAL tempNum;
        PMC * const tempPMC = pmc_new(INTERP, enum_class_Float);

        VTABLE_set_string_native(INTERP, tempPMC, value);
        tempNum = VTABLE_get_number(INTERP, tempPMC);
        SELF.set_number_keyed_int(key, tempNum);
    }

/*

=item C<void set_string_keyed(PMC *key, STRING *value)>

Sets the string value of the element at index C<key> to
C<value>.

=cut

*/

    VTABLE void set_string_keyed(PMC *key, STRING *value) {
        const INTVAL k = key_integer(INTERP, key);
        SELF.set_string_keyed_int(k, value);
    }

/*

=item C<void set_pmc_keyed_int(INTVAL key, PMC *src)>

Sets the PMC value of the element at index C<key> to C<*src>.

=cut

*/

    VTABLE void set_pmc_keyed_int(INTVAL key, PMC *src) {
        const FLOATVAL tempNum = VTABLE_get_number(INTERP, src);
        SELF.set_number_keyed_int(key, tempNum);
    }

/*

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

Sets the string value of the element at index C<key> to
C<value>.

=cut

*/

    VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
        const INTVAL k = key_integer(INTERP, key);
        SELF.set_pmc_keyed_int(k, value);
    }

}

/*

=back

=head1 SEE ALSO

F<docs/pdds/pdd17_basic_types.pod>.

=cut

*/

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