fx.collections: update fx_array to support storing fx_values
This commit is contained in:
+90
-110
@@ -2,6 +2,7 @@
|
||||
#include <fx/iterator.h>
|
||||
#include <fx/stream.h>
|
||||
#include <fx/string.h>
|
||||
#include <fx/value.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -12,7 +13,7 @@ struct fx_array_p {
|
||||
size_t ar_len;
|
||||
/* maximum number of items that can currently be stored in array */
|
||||
size_t ar_cap;
|
||||
fx_object **ar_data;
|
||||
fx_value *ar_data;
|
||||
};
|
||||
|
||||
struct fx_array_iterator_p {
|
||||
@@ -22,7 +23,7 @@ struct fx_array_iterator_p {
|
||||
/** The index of the current value */
|
||||
size_t i;
|
||||
/** The current value */
|
||||
fx_object *value;
|
||||
fx_value *value;
|
||||
};
|
||||
|
||||
/*** PRIVATE FUNCTIONS ********************************************************/
|
||||
@@ -32,7 +33,7 @@ static fx_status resize_array(struct fx_array_p *array, size_t new_capacity)
|
||||
if (array->ar_cap < new_capacity) {
|
||||
void *new_data = realloc(
|
||||
array->ar_data,
|
||||
new_capacity * sizeof(struct fx_dsref *));
|
||||
new_capacity * sizeof(fx_value));
|
||||
if (!new_data) {
|
||||
return FX_ERR_NO_MEMORY;
|
||||
}
|
||||
@@ -40,12 +41,12 @@ static fx_status resize_array(struct fx_array_p *array, size_t new_capacity)
|
||||
array->ar_data = new_data;
|
||||
} else {
|
||||
for (size_t i = new_capacity; i < array->ar_len; i++) {
|
||||
fx_object_unref(array->ar_data[i]);
|
||||
fx_value_unset(&array->ar_data[i]);
|
||||
}
|
||||
|
||||
void *new_data = realloc(
|
||||
array->ar_data,
|
||||
new_capacity * sizeof(struct fx_dsref *));
|
||||
new_capacity * sizeof(fx_value));
|
||||
if (!new_data) {
|
||||
return FX_ERR_NO_MEMORY;
|
||||
}
|
||||
@@ -63,7 +64,7 @@ static fx_status resize_array(struct fx_array_p *array, size_t new_capacity)
|
||||
|
||||
static fx_status array_insert(
|
||||
struct fx_array_p *array,
|
||||
fx_object *value,
|
||||
fx_value value,
|
||||
size_t at)
|
||||
{
|
||||
if (at == FX_NPOS) {
|
||||
@@ -84,13 +85,13 @@ static fx_status array_insert(
|
||||
}
|
||||
}
|
||||
|
||||
fx_object **src = array->ar_data + at;
|
||||
fx_object **dest = src + 1;
|
||||
size_t move_len = (array->ar_len - at) * sizeof(struct fx_dsref *);
|
||||
fx_value *src = array->ar_data + at;
|
||||
fx_value *dest = src + 1;
|
||||
size_t move_len = (array->ar_len - at) * sizeof(fx_value);
|
||||
|
||||
memmove(dest, src, move_len);
|
||||
|
||||
array->ar_data[at] = fx_object_ref(value);
|
||||
fx_value_copy(&array->ar_data[at], &value);
|
||||
array->ar_len++;
|
||||
|
||||
return FX_SUCCESS;
|
||||
@@ -102,11 +103,11 @@ static fx_status array_remove(struct fx_array_p *array, size_t at)
|
||||
return FX_ERR_OUT_OF_BOUNDS;
|
||||
}
|
||||
|
||||
fx_object **src = array->ar_data + at;
|
||||
fx_object **dest = src + 1;
|
||||
size_t move_len = array->ar_len * sizeof(struct fx_dsref *);
|
||||
fx_value *src = array->ar_data + at;
|
||||
fx_value *dest = src + 1;
|
||||
size_t move_len = array->ar_len * sizeof(fx_value);
|
||||
|
||||
fx_object_unref(array->ar_data[at]);
|
||||
fx_value_unset(&array->ar_data[at]);
|
||||
|
||||
memmove(dest, src, move_len);
|
||||
|
||||
@@ -125,17 +126,17 @@ static fx_status array_remove_back(struct fx_array_p *array)
|
||||
return array_remove(array, array->ar_len - 1);
|
||||
}
|
||||
|
||||
static fx_object *array_pop(struct fx_array_p *array, size_t at)
|
||||
static fx_value array_pop(struct fx_array_p *array, size_t at)
|
||||
{
|
||||
if (at >= array->ar_len) {
|
||||
return NULL;
|
||||
return FX_VALUE_EMPTY;
|
||||
}
|
||||
|
||||
fx_object **src = array->ar_data + at;
|
||||
fx_object **dest = src + 1;
|
||||
size_t move_len = array->ar_len * sizeof(struct fx_dsref *);
|
||||
fx_value *dest = array->ar_data + at;
|
||||
fx_value *src = dest + 1;
|
||||
size_t move_len = array->ar_len * sizeof(fx_value);
|
||||
|
||||
fx_object *out = array->ar_data[at];
|
||||
fx_value out = array->ar_data[at];
|
||||
|
||||
memmove(dest, src, move_len);
|
||||
|
||||
@@ -144,40 +145,42 @@ static fx_object *array_pop(struct fx_array_p *array, size_t at)
|
||||
return out;
|
||||
}
|
||||
|
||||
static fx_object *array_pop_front(struct fx_array_p *array)
|
||||
static fx_value array_pop_front(struct fx_array_p *array)
|
||||
{
|
||||
return array_pop(array, 0);
|
||||
}
|
||||
|
||||
static fx_object *array_pop_back(struct fx_array_p *array)
|
||||
static fx_value array_pop_back(struct fx_array_p *array)
|
||||
{
|
||||
return array_pop(array, array->ar_len - 1);
|
||||
}
|
||||
|
||||
static fx_object *array_at(const struct fx_array_p *array, size_t at)
|
||||
static fx_value *array_get_ref(const struct fx_array_p *array, size_t at)
|
||||
{
|
||||
if (at >= array->ar_len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return array->ar_data[at];
|
||||
return &array->ar_data[at];
|
||||
}
|
||||
|
||||
static fx_object *array_get(struct fx_array_p *array, size_t at)
|
||||
static fx_value array_get(struct fx_array_p *array, size_t at)
|
||||
{
|
||||
if (at >= array->ar_len) {
|
||||
return NULL;
|
||||
return FX_VALUE_EMPTY;
|
||||
}
|
||||
|
||||
return fx_object_ref(array->ar_data[at]);
|
||||
fx_value result;
|
||||
fx_value_copy(&result, &array->ar_data[at]);
|
||||
return result;
|
||||
}
|
||||
|
||||
static size_t array_size(const struct fx_array_p *array)
|
||||
static size_t array_get_size(const struct fx_array_p *array)
|
||||
{
|
||||
return array->ar_len;
|
||||
}
|
||||
|
||||
static size_t array_capacity(const struct fx_array_p *array)
|
||||
static size_t array_get_capacity(const struct fx_array_p *array)
|
||||
{
|
||||
return array->ar_cap;
|
||||
}
|
||||
@@ -189,18 +192,16 @@ static void array_clear(struct fx_array_p *array)
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < array->ar_len; i++) {
|
||||
fx_object_unref(array->ar_data[i]);
|
||||
fx_value_unset(&array->ar_data[i]);
|
||||
}
|
||||
|
||||
memset(array->ar_data, 0x0, array->ar_cap * sizeof(fx_object *));
|
||||
memset(array->ar_data, 0x0, array->ar_cap * sizeof(fx_value));
|
||||
array->ar_len = 0;
|
||||
}
|
||||
|
||||
/*** PUBLIC FUNCTIONS *********************************************************/
|
||||
|
||||
fx_array *fx_array_create_with_values(
|
||||
fx_object *const *values,
|
||||
size_t nr_values)
|
||||
fx_array *fx_array_create_with_values(const fx_value *values, size_t nr_values)
|
||||
{
|
||||
fx_array *array = fx_array_create();
|
||||
if (!array) {
|
||||
@@ -211,14 +212,14 @@ fx_array *fx_array_create_with_values(
|
||||
|
||||
size_t real_nr_values = 0;
|
||||
for (size_t i = 0; i < nr_values; i++) {
|
||||
if (values[i]) {
|
||||
if (fx_value_is_set(&values[i])) {
|
||||
real_nr_values++;
|
||||
}
|
||||
}
|
||||
|
||||
p->ar_len = real_nr_values;
|
||||
p->ar_cap = real_nr_values;
|
||||
p->ar_data = calloc(real_nr_values, sizeof(struct fx_dsref *));
|
||||
p->ar_data = calloc(real_nr_values, sizeof(fx_value));
|
||||
if (!p->ar_data) {
|
||||
fx_array_unref(array);
|
||||
return NULL;
|
||||
@@ -226,13 +227,13 @@ fx_array *fx_array_create_with_values(
|
||||
|
||||
size_t index = 0;
|
||||
for (size_t i = 0; i < nr_values; i++) {
|
||||
p->ar_data[index++] = fx_object_ref(values[i]);
|
||||
fx_value_copy(&p->ar_data[index++], &values[i]);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
fx_status fx_array_insert(fx_array *array, fx_object *value, size_t at)
|
||||
fx_status fx_array_insert(fx_array *array, fx_value value, size_t at)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC(FX_TYPE_ARRAY, array_insert, array, value, at);
|
||||
}
|
||||
@@ -252,39 +253,39 @@ fx_status fx_array_remove_back(fx_array *array)
|
||||
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_ARRAY, array_remove_back, array);
|
||||
}
|
||||
|
||||
fx_object *fx_array_pop(fx_array *array, size_t at)
|
||||
fx_value fx_array_pop(fx_array *array, size_t at)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC(FX_TYPE_ARRAY, array_pop, array, at);
|
||||
}
|
||||
|
||||
fx_object *fx_array_pop_front(fx_array *array)
|
||||
fx_value fx_array_pop_front(fx_array *array)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_ARRAY, array_pop_front, array);
|
||||
}
|
||||
|
||||
fx_object *fx_array_pop_back(fx_array *array)
|
||||
fx_value fx_array_pop_back(fx_array *array)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_ARRAY, array_pop_back, array);
|
||||
}
|
||||
|
||||
fx_object *fx_array_at(const fx_array *array, size_t at)
|
||||
fx_value *fx_array_get_ref(const fx_array *array, size_t at)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC(FX_TYPE_ARRAY, array_at, array, at);
|
||||
FX_CLASS_DISPATCH_STATIC(FX_TYPE_ARRAY, array_get_ref, array, at);
|
||||
}
|
||||
|
||||
fx_object *fx_array_get(fx_array *array, size_t at)
|
||||
fx_value fx_array_get(const fx_array *array, size_t at)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC(FX_TYPE_ARRAY, array_get, array, at);
|
||||
}
|
||||
|
||||
size_t fx_array_size(const fx_array *array)
|
||||
size_t fx_array_get_size(const fx_array *array)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_ARRAY, array_size, array);
|
||||
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_ARRAY, array_get_size, array);
|
||||
}
|
||||
|
||||
size_t fx_array_capacity(const fx_array *array)
|
||||
size_t fx_array_get_capacity(const fx_array *array)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_ARRAY, array_capacity, array);
|
||||
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_ARRAY, array_get_capacity, array);
|
||||
}
|
||||
|
||||
void fx_array_clear(fx_array *array)
|
||||
@@ -294,12 +295,12 @@ void fx_array_clear(fx_array *array)
|
||||
|
||||
/*** PUBLIC ALIAS FUNCTIONS ***************************************************/
|
||||
|
||||
fx_status fx_array_append(fx_array *array, fx_object *value)
|
||||
fx_status fx_array_push_back(fx_array *array, fx_value value)
|
||||
{
|
||||
return fx_array_insert(array, value, FX_NPOS);
|
||||
}
|
||||
|
||||
fx_status fx_array_prepend(fx_array *array, fx_object *value)
|
||||
fx_status fx_array_push_front(fx_array *array, fx_value value)
|
||||
{
|
||||
return fx_array_insert(array, value, 0);
|
||||
}
|
||||
@@ -317,7 +318,7 @@ static void array_fini(fx_object *obj, void *priv)
|
||||
|
||||
if (array->ar_data) {
|
||||
for (size_t i = 0; i < array->ar_len; i++) {
|
||||
fx_object_unref(array->ar_data[i]);
|
||||
fx_value_unset(&array->ar_data[i]);
|
||||
}
|
||||
|
||||
free(array->ar_data);
|
||||
@@ -325,29 +326,34 @@ static void array_fini(fx_object *obj, void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
static void array_to_string(const fx_object *obj, fx_stream *out)
|
||||
static fx_status array_to_string(
|
||||
const fx_value *obj,
|
||||
fx_stream *out,
|
||||
const char *format)
|
||||
{
|
||||
struct fx_array_p *array = fx_object_get_private(obj, FX_TYPE_ARRAY);
|
||||
struct fx_array_p *array = fx_object_get_private(
|
||||
obj->v_object,
|
||||
FX_TYPE_ARRAY);
|
||||
|
||||
if (!array->ar_len) {
|
||||
fx_stream_write_cstr(out, "[]", NULL);
|
||||
return;
|
||||
return FX_SUCCESS;
|
||||
}
|
||||
|
||||
fx_stream_write_cstr(out, "[\n", NULL);
|
||||
|
||||
fx_stream_push_indent(out, 1);
|
||||
size_t len = array_size(array);
|
||||
size_t len = array_get_size(array);
|
||||
|
||||
for (size_t i = 0; i < array->ar_len; i++) {
|
||||
fx_object *value = array->ar_data[i];
|
||||
bool is_string = fx_object_is_type(value, FX_TYPE_STRING);
|
||||
fx_value *value = &array->ar_data[i];
|
||||
bool is_string = fx_value_is_type(value, FX_TYPE_STRING);
|
||||
|
||||
if (is_string) {
|
||||
fx_stream_write_char(out, '"');
|
||||
}
|
||||
|
||||
fx_object_to_string(value, out);
|
||||
fx_value_to_string(value, out, NULL);
|
||||
|
||||
if (is_string) {
|
||||
fx_stream_write_char(out, '"');
|
||||
@@ -362,6 +368,7 @@ static void array_to_string(const fx_object *obj, fx_stream *out)
|
||||
|
||||
fx_stream_pop_indent(out);
|
||||
fx_stream_write_char(out, ']');
|
||||
return FX_SUCCESS;
|
||||
}
|
||||
|
||||
/*** ITERATOR FUNCTIONS *******************************************************/
|
||||
@@ -369,33 +376,15 @@ static void array_to_string(const fx_object *obj, fx_stream *out)
|
||||
static fx_iterator *iterable_begin(fx_object *obj)
|
||||
{
|
||||
fx_array_iterator *it_obj = fx_object_create(FX_TYPE_ARRAY_ITERATOR);
|
||||
struct fx_array_iterator_p *it
|
||||
= fx_object_get_private(it_obj, FX_TYPE_ARRAY_ITERATOR);
|
||||
struct fx_array_iterator_p *it = fx_object_get_private(
|
||||
it_obj,
|
||||
FX_TYPE_ARRAY_ITERATOR);
|
||||
it->_a = obj;
|
||||
it->_a_p = fx_object_get_private(obj, FX_TYPE_ARRAY);
|
||||
it->i = 0;
|
||||
|
||||
if (it->_a_p->ar_len > 0) {
|
||||
it->value = it->_a_p->ar_data[0];
|
||||
} else {
|
||||
fx_iterator_set_status(it_obj, FX_ERR_NO_DATA);
|
||||
it->value = NULL;
|
||||
}
|
||||
|
||||
return it_obj;
|
||||
}
|
||||
|
||||
static const fx_iterator *iterable_cbegin(const fx_object *obj)
|
||||
{
|
||||
fx_array_iterator *it_obj = fx_object_create(FX_TYPE_ARRAY_ITERATOR);
|
||||
struct fx_array_iterator_p *it
|
||||
= fx_object_get_private(it_obj, FX_TYPE_ARRAY_ITERATOR);
|
||||
it->_a = (fx_array *)obj;
|
||||
it->_a_p = fx_object_get_private(obj, FX_TYPE_ARRAY);
|
||||
it->i = 0;
|
||||
|
||||
if (it->_a_p->ar_len > 0) {
|
||||
it->value = it->_a_p->ar_data[0];
|
||||
it->value = &it->_a_p->ar_data[0];
|
||||
} else {
|
||||
fx_iterator_set_status(it_obj, FX_ERR_NO_DATA);
|
||||
it->value = NULL;
|
||||
@@ -406,12 +395,13 @@ static const fx_iterator *iterable_cbegin(const fx_object *obj)
|
||||
|
||||
static enum fx_status iterator_move_next(const fx_iterator *obj)
|
||||
{
|
||||
struct fx_array_iterator_p *it
|
||||
= fx_object_get_private(obj, FX_TYPE_ARRAY_ITERATOR);
|
||||
struct fx_array_iterator_p *it = fx_object_get_private(
|
||||
obj,
|
||||
FX_TYPE_ARRAY_ITERATOR);
|
||||
struct fx_array_p *array = it->_a_p;
|
||||
|
||||
if (it->value == NULL || it->i >= array->ar_len) {
|
||||
return false;
|
||||
return FX_ERR_NO_DATA;
|
||||
}
|
||||
|
||||
it->i++;
|
||||
@@ -419,7 +409,7 @@ static enum fx_status iterator_move_next(const fx_iterator *obj)
|
||||
if (it->i >= array->ar_len) {
|
||||
it->value = NULL;
|
||||
} else {
|
||||
it->value = array->ar_data[it->i];
|
||||
it->value = &array->ar_data[it->i];
|
||||
}
|
||||
|
||||
return (it->value != NULL) ? FX_SUCCESS : FX_ERR_NO_DATA;
|
||||
@@ -427,22 +417,19 @@ static enum fx_status iterator_move_next(const fx_iterator *obj)
|
||||
|
||||
static enum fx_status iterator_erase(fx_iterator *obj)
|
||||
{
|
||||
struct fx_array_iterator_p *it
|
||||
= fx_object_get_private(obj, FX_TYPE_ARRAY_ITERATOR);
|
||||
struct fx_array_iterator_p *it = fx_object_get_private(
|
||||
obj,
|
||||
FX_TYPE_ARRAY_ITERATOR);
|
||||
struct fx_array_p *array = it->_a_p;
|
||||
|
||||
if (it->i >= array->ar_len) {
|
||||
return FX_ERR_OUT_OF_BOUNDS;
|
||||
}
|
||||
|
||||
if (array->ar_data[it->i] != it->value) {
|
||||
return FX_ERR_BAD_STATE;
|
||||
}
|
||||
|
||||
array_remove(array, it->i);
|
||||
|
||||
if (it->i < array->ar_len) {
|
||||
it->value = array->ar_data[it->i];
|
||||
it->value = &array->ar_data[it->i];
|
||||
} else {
|
||||
it->value = NULL;
|
||||
}
|
||||
@@ -450,36 +437,31 @@ static enum fx_status iterator_erase(fx_iterator *obj)
|
||||
return FX_SUCCESS;
|
||||
}
|
||||
|
||||
static fx_iterator_value iterator_get_value(fx_iterator *obj)
|
||||
static fx_value iterator_get_value(const fx_iterator *obj)
|
||||
{
|
||||
struct fx_array_iterator_p *it
|
||||
= fx_object_get_private(obj, FX_TYPE_ARRAY_ITERATOR);
|
||||
struct fx_array_iterator_p *it = fx_object_get_private(
|
||||
obj,
|
||||
FX_TYPE_ARRAY_ITERATOR);
|
||||
struct fx_array_p *array = it->_a_p;
|
||||
|
||||
return FX_ITERATOR_VALUE_PTR(it->value);
|
||||
}
|
||||
if (it->i >= array->ar_len) {
|
||||
return FX_VALUE_EMPTY;
|
||||
}
|
||||
|
||||
static const fx_iterator_value iterator_get_cvalue(const fx_iterator *obj)
|
||||
{
|
||||
struct fx_array_iterator_p *it
|
||||
= fx_object_get_private(obj, FX_TYPE_ARRAY_ITERATOR);
|
||||
|
||||
return FX_ITERATOR_VALUE_CPTR(it->value);
|
||||
return *it->value;
|
||||
}
|
||||
|
||||
static enum fx_status iterator_is_valid(const fx_iterator *obj)
|
||||
{
|
||||
struct fx_array_iterator_p *it
|
||||
= fx_object_get_private(obj, FX_TYPE_ARRAY_ITERATOR);
|
||||
struct fx_array_iterator_p *it = fx_object_get_private(
|
||||
obj,
|
||||
FX_TYPE_ARRAY_ITERATOR);
|
||||
struct fx_array_p *array = it->_a_p;
|
||||
|
||||
if (it->i >= array->ar_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (array->ar_data[it->i] != it->value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (it->value != NULL) ? FX_SUCCESS : FX_ERR_NO_DATA;
|
||||
}
|
||||
|
||||
@@ -493,7 +475,6 @@ FX_TYPE_CLASS_BEGIN(fx_array)
|
||||
|
||||
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_iterable, FX_TYPE_ITERABLE)
|
||||
FX_INTERFACE_ENTRY(it_begin) = iterable_begin;
|
||||
FX_INTERFACE_ENTRY(it_cbegin) = iterable_cbegin;
|
||||
FX_TYPE_VTABLE_INTERFACE_END(fx_iterable, FX_TYPE_ITERABLE)
|
||||
FX_TYPE_CLASS_END(fx_array)
|
||||
|
||||
@@ -516,7 +497,6 @@ FX_TYPE_CLASS_BEGIN(fx_array_iterator)
|
||||
FX_INTERFACE_ENTRY(it_move_next) = iterator_move_next;
|
||||
FX_INTERFACE_ENTRY(it_erase) = iterator_erase;
|
||||
FX_INTERFACE_ENTRY(it_get_value) = iterator_get_value;
|
||||
FX_INTERFACE_ENTRY(it_get_cvalue) = iterator_get_cvalue;
|
||||
FX_TYPE_VTABLE_INTERFACE_END(fx_iterator, FX_TYPE_ITERATOR)
|
||||
FX_TYPE_CLASS_END(fx_array_iterator)
|
||||
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
/**
|
||||
* A heterogeneous array of objects. fx_array only stores references
|
||||
* to the objects that it contains, not the object data itself.
|
||||
*
|
||||
* fx_array stores pointers to objects in a single contiguous array,
|
||||
* but this is an implementation detail that may change in the future.
|
||||
* Users of fx_array should not rely on this being the case.
|
||||
*/
|
||||
#ifndef FX_DS_ARRAY_H_
|
||||
#define FX_DS_ARRAY_H_
|
||||
#ifndef FX_COLLECTIONS_ARRAY_H_
|
||||
#define FX_COLLECTIONS_ARRAY_H_
|
||||
|
||||
#include <fx/iterator.h>
|
||||
#include <fx/macros.h>
|
||||
@@ -35,187 +27,37 @@ FX_API fx_type_id fx_array_iterator_get_type(void);
|
||||
|
||||
FX_TYPE_DEFAULT_CONSTRUCTOR(fx_array, FX_TYPE_ARRAY);
|
||||
|
||||
/**
|
||||
* Creates an fx_array initialised with the contents of the provided
|
||||
* fx_object pointer array. The fx_array will take a reference to each
|
||||
* object specified in `values`, and will increment the reference count.
|
||||
* The order of objects in the new fx_array will be the same as the order
|
||||
* of objects in `values`. Any NULL pointers in the `values` array will
|
||||
* be ignored, and will not result in gaps in the created fx_array.
|
||||
* However, `nr_values` should be large enough to cover the final
|
||||
* non-NULL pointer in `values`, including any NULL pointers in-between.
|
||||
*
|
||||
* @param values The list of object pointers which should make up the
|
||||
* contents of the new fx_array.
|
||||
* @param nr_values The size of the `values` array.
|
||||
* @return A pointer to the new fx_array, or NULL if an error occurred.
|
||||
*/
|
||||
FX_API fx_array *fx_array_create_with_values(
|
||||
fx_object *const *values,
|
||||
const fx_value *values,
|
||||
size_t nr_values);
|
||||
|
||||
/**
|
||||
* Remove all object references from an fx_array, resetting the size of the
|
||||
* array to zero. The reference counts of all objects in the array will be
|
||||
* decremented.
|
||||
*
|
||||
* @param array The fx_array to clear.
|
||||
*/
|
||||
FX_API void fx_array_clear(fx_array *array);
|
||||
|
||||
/**
|
||||
* Inserts an object at the end of an fx_array. The reference count of
|
||||
* the object will be incremented.
|
||||
*
|
||||
* @param array The fx_array to append the object to.
|
||||
* @param value The object to append.
|
||||
* @return FX_SUCCESS if the object was appended successfully, or an
|
||||
* error code if an error occurred.
|
||||
*/
|
||||
FX_API fx_status fx_array_append(fx_array *array, fx_object *value);
|
||||
FX_API fx_status fx_array_push_back(fx_array *array, fx_value value);
|
||||
|
||||
/**
|
||||
* Inserts an object at the beginning of an fx_array. The reference count
|
||||
* of the object will be incremented. All other objects in the array
|
||||
* will be moved to make space for the object being pre-pended.
|
||||
*
|
||||
* @param array The fx_array to prepend the object to.
|
||||
* @param value The object to prepend.
|
||||
* @return FX_SUCCESS if the object was prepended successfully, or an
|
||||
* error code if an error occurred.
|
||||
*/
|
||||
FX_API fx_status fx_array_prepend(fx_array *array, fx_object *value);
|
||||
FX_API fx_status fx_array_push_front(fx_array *array, fx_value value);
|
||||
|
||||
/**
|
||||
* Inserts an object into an fx_array at a given index. The reference
|
||||
* count of the object will be incremented. If the specified index is at
|
||||
* the beginning or mid-way through the array (i.e. not at the end),
|
||||
* some or all of the objects already in the array will be moved to make
|
||||
* space for the object being inserted.
|
||||
*
|
||||
* @param array The fx_array to insert the object into.
|
||||
* @param value The object to insert.
|
||||
* @param at The index to insert the object at. If the index is
|
||||
* `FX_NPOS`, the object will be inserted at the end of the fx_array.
|
||||
* @return FX_SUCCESS if the object was inserted, or a status code
|
||||
* describing any error that occurred.
|
||||
*/
|
||||
FX_API fx_status fx_array_insert(fx_array *array, fx_object *value, size_t at);
|
||||
FX_API fx_status fx_array_insert(fx_array *array, fx_value value, size_t at);
|
||||
|
||||
/**
|
||||
* Removes the object at the specified index from an fx_array. The
|
||||
* reference count of the removed object will be decremented. If the
|
||||
* specified index is at the beginning or mid-way through the array
|
||||
* (i.e. not at the end), the remaining objects will be moved to fill
|
||||
* the empty space created by the object's removal.
|
||||
*
|
||||
* @param array The fx_array to remove the object from.
|
||||
* @param at The index of the object to be removed.
|
||||
* @return FX_SUCCESS if the object was removed, or a status code
|
||||
* describing any error that occurred.
|
||||
*/
|
||||
FX_API fx_status fx_array_remove(fx_array *array, size_t at);
|
||||
|
||||
/**
|
||||
* Removes the object at the beginning of an fx_array. The reference count
|
||||
* of the removed object will be decremented. The remaining objects will be
|
||||
* moved to fill the empty space created by the object's removal.
|
||||
*
|
||||
* @param array The fx_array to remove the object from.
|
||||
* @return FX_SUCCESS if the object was removed, or a status code describing any
|
||||
* error that occurred.
|
||||
*/
|
||||
FX_API fx_status fx_array_remove_front(fx_array *array);
|
||||
|
||||
/**
|
||||
* Removes the object at the end of an fx_array. The reference count
|
||||
* of the removed object will be decremented.
|
||||
*
|
||||
* @param array The fx_array to remove the object from.
|
||||
* @return FX_SUCCESS if the object was removed, or a status code describing any
|
||||
* error that occurred.
|
||||
*/
|
||||
FX_API fx_status fx_array_remove_back(fx_array *array);
|
||||
|
||||
/**
|
||||
* Removes the object at the specified index of an fx_array, and returns
|
||||
* a pointer to it. The reference count of the removed object will NOT
|
||||
* be decremented. The caller becomes the owner of the array's reference
|
||||
* to the object. If the specified index is at the beginning or mid-way
|
||||
* through the array (i.e. not at the end), the remaining objects will
|
||||
* be moved to fill the empty space created by the object's removal.
|
||||
*
|
||||
* @param array The fx_array to remove the object from.
|
||||
* @param at The index of the object to be removed.
|
||||
* @return An pointer to the removed object. This pointer is owned by
|
||||
* the caller. Returns NULL if an error occurred.
|
||||
*/
|
||||
FX_API fx_object *fx_array_pop(fx_array *array, size_t at);
|
||||
FX_API fx_value fx_array_pop(fx_array *array, size_t at);
|
||||
|
||||
/**
|
||||
* Removes the object at the beginning of an fx_array, and returns a
|
||||
* pointer to it. The reference count of the removed object will NOT be
|
||||
* decremented. The caller becomes the owner of the array's reference to
|
||||
* the object. The remaining objects in the fx_array will be moved to
|
||||
* fill the empty space left by the removed object.
|
||||
*
|
||||
* @param array The fx_array to remove the object from.
|
||||
* @return An pointer to the removed object. This pointer is owned by
|
||||
* the caller. Returns NULL if an error occurred.
|
||||
*/
|
||||
FX_API fx_object *fx_array_pop_front(fx_array *array);
|
||||
FX_API fx_value fx_array_pop_front(fx_array *array);
|
||||
|
||||
/**
|
||||
* Removes the object at the end of an fx_array, and returns a pointer to it.
|
||||
* The reference count of the removed object will NOT be decremented. The caller
|
||||
* becomes the owner of the array's reference to the object.
|
||||
*
|
||||
* @param array The fx_array to remove the object from.
|
||||
* @return An pointer to the removed object. This pointer is owned by the
|
||||
* caller. Returns NULL if an error occurred.
|
||||
*/
|
||||
FX_API fx_object *fx_array_pop_back(fx_array *array);
|
||||
FX_API fx_value fx_array_pop_back(fx_array *array);
|
||||
|
||||
/**
|
||||
* Returns an unowned pointer to the object at the given index of an fx_array.
|
||||
* The caller does not own the returned pointer, and MUST NOT release it.
|
||||
*
|
||||
* @param array The fx_array.
|
||||
* @param at The index of the object to return.
|
||||
* @return A pointer to the object at the given index. This pointer is NOT owned
|
||||
* by the caller. Returns NULL if an error occurred.
|
||||
*/
|
||||
FX_API fx_object *fx_array_at(const fx_array *array, size_t at);
|
||||
FX_API fx_value *fx_array_get_ref(const fx_array *array, size_t at);
|
||||
|
||||
/**
|
||||
* Returns an owned pointer to the object at the given index of an
|
||||
* fx_array. The caller owns the returned pointer, and must release it
|
||||
* when they are finished with it.
|
||||
*
|
||||
* @param array The fx_array.
|
||||
* @param at The index of the object to return.
|
||||
* @return A pointer to the object at the given index. This pointer is
|
||||
* owned by the caller. Returns NULL if an error occurred.
|
||||
*/
|
||||
FX_API fx_object *fx_array_get(fx_array *array, size_t at);
|
||||
FX_API fx_value fx_array_get(const fx_array *array, size_t at);
|
||||
|
||||
/**
|
||||
* Returns the number of objects contained in an fx_array.
|
||||
*
|
||||
* @param array The fx_array.
|
||||
* @return The number of objects contained in the fx_array.
|
||||
*/
|
||||
FX_API size_t fx_array_size(const fx_array *array);
|
||||
FX_API size_t fx_array_get_size(const fx_array *array);
|
||||
|
||||
/**
|
||||
* Returns the current maximum capacity of an fx_array. This represents
|
||||
* the number of objects that can be stored in an fx_array before its
|
||||
* internal buffer would need to be re-sized.
|
||||
*
|
||||
* @param array The fx_array.
|
||||
* @return The maximum capacity of the fx_array.
|
||||
*/
|
||||
FX_API size_t fx_array_capacity(const fx_array *array);
|
||||
FX_API size_t fx_array_get_capacity(const fx_array *array);
|
||||
|
||||
FX_DECLS_END;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
int main(void)
|
||||
{
|
||||
#if 0
|
||||
fx_array *array = fx_array_create();
|
||||
fx_array_append(array, fx_int_create(32));
|
||||
fx_array_append(array, fx_int_create(64));
|
||||
@@ -17,5 +18,6 @@ int main(void)
|
||||
fx_iterator_unref(it);
|
||||
|
||||
fx_array_unref(array);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user