/*
Copyright (C) 2001-2009, Parrot Foundation.
=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
*/
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */
pmclass FixedFloatArray auto_attrs provides array {
ATTR INTVAL size;
ATTR FLOATVAL *float_array;
/*
=back
=head2 Methods
=over 4
=item C<void destroy()>
Destroys the array.
=cut
*/
VTABLE void destroy() {
FLOATVAL *float_array;
GET_ATTR_float_array(INTERP, SELF, float_array);
if (float_array)
mem_gc_free(INTERP, float_array);
}
/*
=item C<void init_int(INTVAL size)>
Initializes the array.
=cut
*/
VTABLE void init_int(INTVAL size) {
if (size < 0)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
_("FixedFloatArray: Cannot set array size to a negative number (%d)"), size);
SET_ATTR_size(INTERP, SELF, size);
SET_ATTR_float_array(INTERP, SELF, mem_gc_allocate_n_typed(INTERP, size, FLOATVAL));
PObj_custom_destroy_SET(SELF);
}
/*
=item C<PMC *clone()>
Creates and returns a copy of the array.
=cut
*/
VTABLE PMC *clone() {
FLOATVAL *self_float_array;
PMC * const dest = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
GET_ATTR_float_array(INTERP, SELF, self_float_array);
if (self_float_array) {
INTVAL size;
GET_ATTR_size(INTERP, SELF, size);
{
FLOATVAL * const dest_float_array = mem_gc_allocate_n_typed(INTERP,
size, FLOATVAL);
mem_copy_n_typed(dest_float_array, self_float_array,
size, FLOATVAL);
SET_ATTR_float_array(INTERP, dest, dest_float_array);
}
SET_ATTR_size(INTERP, dest, size);
PObj_custom_destroy_SET(dest);
}
return dest;
}
/*
=item C<PMC *get_iter()>
Return an Iterator for this PMC.
=cut
*/
VTABLE PMC *get_iter() {
return Parrot_pmc_new_init(INTERP, enum_class_ArrayIterator, SELF);
}
/*
=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() {
INTVAL size;
GET_ATTR_size(INTERP, SELF, size);
return size;
}
/*
=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 = VTABLE_get_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 *float_array;
INTVAL size;
GET_ATTR_size(INTERP, SELF, size);
if (key < 0 || key >= size)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"FixedFloatArray: index out of bounds!");
GET_ATTR_float_array(INTERP, SELF, float_array);
return float_array[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 = VTABLE_get_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 = VTABLE_get_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 = Parrot_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 = VTABLE_get_integer(INTERP, key);
return SELF.get_pmc_keyed_int(k);
}
/*
=item C<void * get_pointer()>
Return a pointer to the underlying data buffer. This is a C C<FLOATVAL*> array
and can be treated like any other array. This array should not be resized or
freed.
=cut
*/
VTABLE void * get_pointer() {
FLOATVAL *float_array;
GET_ATTR_float_array(INTERP, SELF, float_array);
return float_array;
}
/*
=item C<void set_integer_native(INTVAL size)>
Resizes the array to C<size> elements.
=cut
*/
VTABLE void set_integer_native(INTVAL new_size) {
INTVAL old_size;
GET_ATTR_size(INTERP, SELF, old_size);
if (old_size || new_size < 1)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"FixedFloatArray: Can't resize!");
SET_ATTR_size(INTERP, SELF, new_size);
SET_ATTR_float_array(INTERP, SELF,
mem_gc_allocate_n_typed(INTERP, new_size, FLOATVAL));
PObj_custom_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 = VTABLE_get_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 *float_array;
INTVAL size;
GET_ATTR_size(INTERP, SELF, size);
if (key < 0 || key >= size)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"FixedFloatArray: index out of bounds!");
GET_ATTR_float_array(INTERP, SELF, float_array);
float_array[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 = VTABLE_get_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 = Parrot_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 = VTABLE_get_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 = VTABLE_get_integer(INTERP, key);
SELF.set_pmc_keyed_int(k, value);
}
/*
=item C<STRING *get_string()>
=item C<STRING *get_repo()>
Returns the Parrot string representation C<key>
=cut
*/
VTABLE STRING *get_string() {
return STATICSELF.get_repr();
}
VTABLE STRING *get_repr() {
STRING *str = CONST_STRING(INTERP, "[ ");
STRING *comma = CONST_STRING(INTERP, ", ");
UINTVAL i;
const UINTVAL elems = SELF.elements();
if (elems > 0)
str = Parrot_str_concat(INTERP, str,
SELF.get_string_keyed_int(0));
for (i = 1; i < elems; ++i) {
str = Parrot_str_concat(INTERP, str, comma);
str = Parrot_str_concat(INTERP, str,
SELF.get_string_keyed_int((INTVAL)i));
}
str = Parrot_str_concat(INTERP, str, CONST_STRING(INTERP, " ]"));
return str;
}
/*
=item C<METHOD reverse()>
Reverse the contents of the array.
=cut
*/
METHOD reverse() {
INTVAL n;
GET_ATTR_size(INTERP, SELF, n);
if (n > 1) {
FLOATVAL val;
FLOATVAL *data;
INTVAL i;
GET_ATTR_float_array(INTERP, SELF, data);
for (i = 0; i <= --n; i++) {
val = data[i];
data[i] = data[n];
data[n] = val;
}
}
}
}
/*
=back
=head1 SEE ALSO
F<docs/pdds/pdd17_basic_types.pod>.
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/