Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

624 lines (404 sloc) 12.606 kb
/*
Copyright (C) 2001-2014, Parrot Foundation.
=head1 NAME
src/pmc/fixedfloatarray.pmc - FixedFloatArray PMC
=head1 DESCRIPTION
Fixed size array for floating point numbers only.
This class, FixedFloatArray, implements an array of fixed size which
stores FLOATVALs. It uses Float PMCs to do all necessary conversions.
=head2 Functions
=over 4
=cut
*/
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
PARROT_PURE_FUNCTION
static int auxcmpfunc(ARGIN(const FLOATVAL *i), ARGIN(const FLOATVAL *j))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
#define ASSERT_ARGS_auxcmpfunc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(i) \
, PARROT_ASSERT_ARG(j))
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: static */
pmclass FixedFloatArray auto_attrs provides array {
ATTR INTVAL size;
ATTR FLOATVAL *float_array;
/*
=back
=head2 Methods
=over 4
=item C<PMC *sort()>
Sort the array and return self.
=cut
*/
METHOD sort(PMC *cmp_func :optional) {
UINTVAL n;
INTVAL size;
GET_ATTR_size(INTERP, SELF, size);
n = (UINTVAL)size;
if (n > 1) {
FLOATVAL *float_array;
GET_ATTR_float_array(INTERP, SELF, float_array);
if (PMC_IS_NULL(cmp_func))
qsort(float_array, n, sizeof (FLOATVAL),
(int (*)(const void *, const void*))auxcmpfunc);
else
Parrot_util_quicksort(INTERP, (void**)float_array, n, cmp_func, "NN->N");
}
RETURN(PMC *SELF);
}
/*
=item C<void destroy()>
Destroys the array.
=cut
*/
VTABLE void destroy() :no_wb {
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_noargs(INTERP, EXCEPTION_OUT_OF_BOUNDS,
"illegal argument");
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() :no_wb {
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() :no_wb {
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() :no_wb {
const INTVAL size = SELF.elements();
return (INTVAL)(size != 0);
}
/*
=item C<INTVAL elements()>
=cut
*/
VTABLE INTVAL elements() :no_wb {
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() :no_wb {
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) :no_wb {
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) :no_wb {
/* 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) :no_wb {
FLOATVAL *float_array;
INTVAL size;
GET_ATTR_size(INTERP, SELF, size);
if (key < 0)
key += size;
if (key < 0 || key >= size)
Parrot_ex_throw_from_c_noargs(INTERP, EXCEPTION_OUT_OF_BOUNDS,
"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) :no_wb {
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) :no_wb {
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) :no_wb {
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) :no_wb {
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) :no_wb {
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() :no_wb {
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_noargs(INTERP, EXCEPTION_OUT_OF_BOUNDS,
"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) :manual_wb {
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) :manual_wb {
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;
if (key < 0 || key >= size)
Parrot_ex_throw_from_c_noargs(INTERP, EXCEPTION_OUT_OF_BOUNDS,
"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) :manual_wb {
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) :manual_wb {
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) :manual_wb {
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) :manual_wb {
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) :manual_wb {
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() :no_wb {
return STATICSELF.get_repr();
}
VTABLE STRING *get_repr() :no_wb {
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
=head2 Auxiliary functions
=over 4
=item C<static int auxcmpfunc(const FLOATVAL *i, const FLOATVAL *j)>
FLOATVAL compare function for qsort usage.
=cut
*/
PARROT_PURE_FUNCTION
static int
auxcmpfunc(ARGIN(const FLOATVAL *i), ARGIN(const FLOATVAL *j))
{
ASSERT_ARGS(auxcmpfunc)
return (*i < *j) ? -1 : (*i > *j);
}
/*
=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' :
*/
Jump to Line
Something went wrong with that request. Please try again.