ds: array: convert to new object system

This commit is contained in:
2025-10-19 11:02:59 +01:00
parent 3eebdddc21
commit 0a9eb4a085
3 changed files with 301 additions and 256 deletions

View File

@@ -1,67 +1,22 @@
#include "array.h"
#include <blue/core/iterator.h> #include <blue/core/iterator.h>
#include <blue/core/stream.h> #include <blue/core/stream.h>
#include <blue/ds/array.h> #include <blue/ds/array.h>
#include <blue/ds/type.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static void array_release(struct b_dsref *obj); /*** PRIVATE DATA *************************************************************/
static void array_to_string(const struct b_dsref *obj, struct b_stream *out);
static struct b_dsref_type array_type = { struct b_array_p {
.t_flags = B_DSREF_FUNDAMENTAL, /* number of items in array */
.t_id = B_DSREF_TYPE_ARRAY, size_t ar_len;
.t_name = "corelib::array", /* maximum number of items that can currently be stored in array */
.t_instance_size = sizeof(struct b_array), size_t ar_cap;
.t_release = array_release, b_object **ar_data;
.t_to_string = array_to_string,
}; };
struct b_array *b_array_create(void) /*** PRIVATE FUNCTIONS ********************************************************/
{
struct b_array *array
= (struct b_array *)b_dsref_type_instantiate(&array_type);
if (!array) {
return NULL;
}
return array; static b_status resize_array(struct b_array_p *array, size_t new_capacity)
}
struct b_array *b_array_create_with_values(
struct b_dsref *const *values, size_t nr_values)
{
struct b_array *array = b_array_create();
if (!array) {
return NULL;
}
size_t real_nr_values = 0;
for (size_t i = 0; i < nr_values; i++) {
if (values[i]) {
real_nr_values++;
}
}
array->ar_len = real_nr_values;
array->ar_cap = real_nr_values;
array->ar_data = calloc(real_nr_values, sizeof(struct b_dsref *));
if (!array->ar_data) {
b_array_release(array);
return NULL;
}
size_t index = 0;
for (size_t i = 0; i < nr_values; i++) {
array->ar_data[index++] = b_retain(values[i]);
}
return array;
}
static b_status resize_array(struct b_array *array, size_t new_capacity)
{ {
if (array->ar_cap < new_capacity) { if (array->ar_cap < new_capacity) {
void *new_data = realloc( void *new_data = realloc(
@@ -73,7 +28,7 @@ static b_status resize_array(struct b_array *array, size_t new_capacity)
array->ar_data = new_data; array->ar_data = new_data;
} else { } else {
for (size_t i = new_capacity; i < array->ar_len; i++) { for (size_t i = new_capacity; i < array->ar_len; i++) {
b_release(array->ar_data[i]); b_object_unref(array->ar_data[i]);
} }
void *new_data = realloc( void *new_data = realloc(
@@ -93,17 +48,7 @@ static b_status resize_array(struct b_array *array, size_t new_capacity)
return B_SUCCESS; return B_SUCCESS;
} }
b_status b_array_append(struct b_array *array, struct b_dsref *value) static b_status array_insert(struct b_array_p *array, b_object *value, size_t at)
{
return b_array_insert(array, value, B_NPOS);
}
b_status b_array_prepend(struct b_array *array, struct b_dsref *value)
{
return b_array_insert(array, value, 0);
}
b_status b_array_insert(struct b_array *array, struct b_dsref *value, size_t at)
{ {
if (at == B_NPOS) { if (at == B_NPOS) {
at = array->ar_len; at = array->ar_len;
@@ -123,29 +68,29 @@ b_status b_array_insert(struct b_array *array, struct b_dsref *value, size_t at)
} }
} }
struct b_dsref **src = array->ar_data + at; b_object **src = array->ar_data + at;
struct b_dsref **dest = src + 1; b_object **dest = src + 1;
size_t move_len = (array->ar_len - at) * sizeof(struct b_dsref *); size_t move_len = (array->ar_len - at) * sizeof(struct b_dsref *);
memmove(dest, src, move_len); memmove(dest, src, move_len);
array->ar_data[at] = b_retain(value); array->ar_data[at] = b_object_ref(value);
array->ar_len++; array->ar_len++;
return B_SUCCESS; return B_SUCCESS;
} }
b_status b_array_remove(struct b_array *array, size_t at) static b_status array_remove(struct b_array_p *array, size_t at)
{ {
if (at >= array->ar_len) { if (at >= array->ar_len) {
return B_ERR_OUT_OF_BOUNDS; return B_ERR_OUT_OF_BOUNDS;
} }
struct b_dsref **src = array->ar_data + at; b_object **src = array->ar_data + at;
struct b_dsref **dest = src + 1; b_object **dest = src + 1;
size_t move_len = array->ar_len * sizeof(struct b_dsref *); size_t move_len = array->ar_len * sizeof(struct b_dsref *);
b_release(array->ar_data[at]); b_object_unref(array->ar_data[at]);
memmove(dest, src, move_len); memmove(dest, src, move_len);
@@ -154,27 +99,27 @@ b_status b_array_remove(struct b_array *array, size_t at)
return B_SUCCESS; return B_SUCCESS;
} }
b_status b_array_remove_front(struct b_array *array) static b_status array_remove_front(struct b_array_p *array)
{ {
return b_array_remove(array, 0); return array_remove(array, 0);
} }
b_status b_array_remove_back(struct b_array *array) static b_status array_remove_back(struct b_array_p *array)
{ {
return b_array_remove(array, array->ar_len - 1); return array_remove(array, array->ar_len - 1);
} }
struct b_dsref *b_array_pop(b_array *array, size_t at) static b_object *array_pop(struct b_array_p *array, size_t at)
{ {
if (at >= array->ar_len) { if (at >= array->ar_len) {
return NULL; return NULL;
} }
struct b_dsref **src = array->ar_data + at; b_object **src = array->ar_data + at;
struct b_dsref **dest = src + 1; b_object **dest = src + 1;
size_t move_len = array->ar_len * sizeof(struct b_dsref *); size_t move_len = array->ar_len * sizeof(struct b_dsref *);
struct b_dsref *out = array->ar_data[at]; b_object *out = array->ar_data[at];
memmove(dest, src, move_len); memmove(dest, src, move_len);
@@ -183,17 +128,17 @@ struct b_dsref *b_array_pop(b_array *array, size_t at)
return out; return out;
} }
struct b_dsref *b_array_pop_front(struct b_array *array) static b_object *array_pop_front(struct b_array_p *array)
{ {
return b_array_pop(array, 0); return array_pop(array, 0);
} }
struct b_dsref *b_array_pop_back(struct b_array *array) static b_object *array_pop_back(struct b_array_p *array)
{ {
return b_array_pop(array, array->ar_len - 1); return array_pop(array, array->ar_len - 1);
} }
struct b_dsref *b_array_at(const struct b_array *array, size_t at) static b_object *array_at(const struct b_array_p *array, size_t at)
{ {
if (at >= array->ar_len) { if (at >= array->ar_len) {
return NULL; return NULL;
@@ -202,28 +147,169 @@ struct b_dsref *b_array_at(const struct b_array *array, size_t at)
return array->ar_data[at]; return array->ar_data[at];
} }
struct b_dsref *b_array_get(struct b_array *array, size_t at) static b_object *array_get(struct b_array_p *array, size_t at)
{ {
if (at >= array->ar_len) { if (at >= array->ar_len) {
return NULL; return NULL;
} }
return b_retain(array->ar_data[at]); return b_object_ref(array->ar_data[at]);
} }
size_t b_array_size(const struct b_array *array) static size_t array_size(const struct b_array_p *array)
{ {
return array->ar_len; return array->ar_len;
} }
size_t b_array_capacity(const struct b_array *array) static size_t array_capacity(const struct b_array_p *array)
{ {
return array->ar_cap; return array->ar_cap;
} }
static void array_to_string(const struct b_dsref *obj, struct b_stream *out) static void array_clear(struct b_array_p *array)
{ {
struct b_array *array = B_ARRAY(obj); if (!array->ar_len) {
return;
}
for (size_t i = 0; i < array->ar_len; i++) {
b_object_unref(array->ar_data[i]);
}
memset(array->ar_data, 0x0, array->ar_cap * sizeof(b_object *));
array->ar_len = 0;
}
/*** PUBLIC FUNCTIONS *********************************************************/
b_array *b_array_create_with_values(b_object *const *values, size_t nr_values)
{
b_array *array = b_array_create();
if (!array) {
return NULL;
}
struct b_array_p *p = b_object_get_private(array, B_TYPE_ARRAY);
size_t real_nr_values = 0;
for (size_t i = 0; i < nr_values; i++) {
if (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 b_dsref *));
if (!p->ar_data) {
b_array_unref(array);
return NULL;
}
size_t index = 0;
for (size_t i = 0; i < nr_values; i++) {
p->ar_data[index++] = b_object_ref(values[i]);
}
return array;
}
b_status b_array_insert(b_array *array, b_object *value, size_t at)
{
B_CLASS_DISPATCH_STATIC(B_TYPE_ARRAY, array_insert, array, value, at);
}
b_status b_array_remove(b_array *array, size_t at)
{
B_CLASS_DISPATCH_STATIC(B_TYPE_ARRAY, array_remove, array, at);
}
b_status b_array_remove_front(b_array *array)
{
B_CLASS_DISPATCH_STATIC_0(B_TYPE_ARRAY, array_remove_front, array);
}
b_status b_array_remove_back(b_array *array)
{
B_CLASS_DISPATCH_STATIC_0(B_TYPE_ARRAY, array_remove_back, array);
}
b_object *b_array_pop(b_array *array, size_t at)
{
B_CLASS_DISPATCH_STATIC(B_TYPE_ARRAY, array_pop, array, at);
}
b_object *b_array_pop_front(b_array *array)
{
B_CLASS_DISPATCH_STATIC_0(B_TYPE_ARRAY, array_pop_front, array);
}
b_object *b_array_pop_back(b_array *array)
{
B_CLASS_DISPATCH_STATIC_0(B_TYPE_ARRAY, array_pop_back, array);
}
b_object *b_array_at(const b_array *array, size_t at)
{
B_CLASS_DISPATCH_STATIC(B_TYPE_ARRAY, array_at, array, at);
}
b_object *b_array_get(b_array *array, size_t at)
{
B_CLASS_DISPATCH_STATIC(B_TYPE_ARRAY, array_get, array, at);
}
size_t b_array_size(const b_array *array)
{
B_CLASS_DISPATCH_STATIC_0(B_TYPE_ARRAY, array_size, array);
}
size_t b_array_capacity(const b_array *array)
{
B_CLASS_DISPATCH_STATIC_0(B_TYPE_ARRAY, array_capacity, array);
}
void b_array_clear(b_array *array)
{
B_CLASS_DISPATCH_STATIC_0(B_TYPE_ARRAY, array_clear, array);
}
/*** PUBLIC ALIAS FUNCTIONS ***************************************************/
b_status b_array_append(b_array *array, b_object *value)
{
return b_array_insert(array, value, B_NPOS);
}
b_status b_array_prepend(b_array *array, b_object *value)
{
return b_array_insert(array, value, 0);
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void array_init(b_object *obj, void *priv)
{
struct b_array_p *array = priv;
}
static void array_fini(b_object *obj, void *priv)
{
struct b_array_p *array = priv;
if (array->ar_data) {
for (size_t i = 0; i < array->ar_len; i++) {
b_object_unref(array->ar_data[i]);
}
free(array->ar_data);
array->ar_data = NULL;
}
}
static void array_to_string(const b_object *obj, struct b_stream *out)
{
struct b_array_p *array = b_object_get_private(obj, B_TYPE_ARRAY);
if (!array->ar_len) { if (!array->ar_len) {
b_stream_write_string(out, "[]", NULL); b_stream_write_string(out, "[]", NULL);
@@ -233,24 +319,24 @@ static void array_to_string(const struct b_dsref *obj, struct b_stream *out)
b_stream_write_string(out, "[\n", NULL); b_stream_write_string(out, "[\n", NULL);
b_stream_push_indent(out, 1); b_stream_push_indent(out, 1);
size_t len = b_array_size(array); size_t len = array_size(array);
b_array_iterator it; for (size_t i = 0; i < array->ar_len; i++) {
b_array_foreach(&it, array) b_object *value = array->ar_data[i];
{ bool is_string
bool is_string = b_typeid(it.value) == B_DSREF_TYPE_STRING; = false; // b_object_is_type(value, B_TYPE_STRING);
if (is_string) { if (is_string) {
b_stream_write_char(out, '"'); b_stream_write_char(out, '"');
} }
b_to_string(it.value, out); b_object_to_string(value, out);
if (is_string) { if (is_string) {
b_stream_write_char(out, '"'); b_stream_write_char(out, '"');
} }
if (it.i < len - 1) { if (i < len - 1) {
b_stream_write_string(out, ",", NULL); b_stream_write_string(out, ",", NULL);
} }
@@ -261,26 +347,22 @@ static void array_to_string(const struct b_dsref *obj, struct b_stream *out)
b_stream_write_char(out, ']'); b_stream_write_char(out, ']');
} }
static void array_release(struct b_dsref *obj) /*** CLASS DEFINITION *********************************************************/
{
struct b_array *array = B_ARRAY(obj);
if (array->ar_data) { B_TYPE_CLASS_DEFINITION_BEGIN(b_array)
for (size_t i = 0; i < array->ar_len; i++) { B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
b_release(array->ar_data[i]); B_INTERFACE_ENTRY(to_string) = array_to_string;
} B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
B_TYPE_CLASS_DEFINITION_END(b_array)
free(array->ar_data); B_TYPE_DEFINITION_BEGIN(b_array)
array->ar_data = NULL; B_TYPE_ID(0xe3c46da1, 0x5f37, 0x4e44, 0xb53b, 0xff5a6200191b);
} B_TYPE_CLASS(b_array_class);
} B_TYPE_INSTANCE_INIT(array_init);
B_TYPE_INSTANCE_INIT(array_fini);
B_TYPE_DEFINITION_END(b_array)
void b_array_clear(struct b_array *array) /*** ITERATOR FUNCTIONS *******************************************************/
{
while (array->ar_len) {
b_array_remove_back(array);
}
}
static bool array_iterator_next(struct b_iterator *it) static bool array_iterator_next(struct b_iterator *it)
{ {
@@ -304,14 +386,15 @@ static b_iterator_ops it_ops = {
.it_is_valid = array_iterator_is_valid, .it_is_valid = array_iterator_is_valid,
}; };
int b_array_iterator_begin(struct b_array *array, struct b_array_iterator *it) int b_array_iterator_begin(b_array *array, struct b_array_iterator *it)
{ {
it->_a = array; it->_a = array;
it->_a_p = b_object_get_private(array, B_TYPE_ARRAY);
it->i = 0; it->i = 0;
it->_base.it_ops = &it_ops; it->_base.it_ops = &it_ops;
if (array->ar_len > 0) { if (it->_a_p->ar_len > 0) {
it->value = array->ar_data[0]; it->value = it->_a_p->ar_data[0];
} else { } else {
it->value = NULL; it->value = NULL;
} }
@@ -321,7 +404,7 @@ int b_array_iterator_begin(struct b_array *array, struct b_array_iterator *it)
bool b_array_iterator_next(struct b_array_iterator *it) bool b_array_iterator_next(struct b_array_iterator *it)
{ {
struct b_array *array = it->_a; struct b_array_p *array = it->_a_p;
if (it->value == NULL || it->i >= array->ar_len) { if (it->value == NULL || it->i >= array->ar_len) {
return false; return false;
@@ -340,7 +423,7 @@ bool b_array_iterator_next(struct b_array_iterator *it)
b_status b_array_iterator_erase(struct b_array_iterator *it) b_status b_array_iterator_erase(struct b_array_iterator *it)
{ {
struct b_array *array = it->_a; struct b_array_p *array = it->_a_p;
if (it->i >= array->ar_len) { if (it->i >= array->ar_len) {
return B_ERR_OUT_OF_BOUNDS; return B_ERR_OUT_OF_BOUNDS;
} }
@@ -349,7 +432,7 @@ b_status b_array_iterator_erase(struct b_array_iterator *it)
return B_ERR_BAD_STATE; return B_ERR_BAD_STATE;
} }
b_array_remove(array, it->i); array_remove(array, it->i);
if (it->i < array->ar_len) { if (it->i < array->ar_len) {
it->value = array->ar_data[it->i]; it->value = array->ar_data[it->i];
@@ -362,7 +445,7 @@ b_status b_array_iterator_erase(struct b_array_iterator *it)
bool b_array_iterator_is_valid(const struct b_array_iterator *it) bool b_array_iterator_is_valid(const struct b_array_iterator *it)
{ {
struct b_array *array = it->_a; struct b_array_p *array = it->_a_p;
if (it->i >= array->ar_len) { if (it->i >= array->ar_len) {
return false; return false;
} }
@@ -373,8 +456,3 @@ bool b_array_iterator_is_valid(const struct b_array_iterator *it)
return it->value != NULL; return it->value != NULL;
} }
b_dsref_type_id b_array_type_id(void)
{
return (b_dsref_type_id)&array_type;
}

View File

@@ -1,15 +0,0 @@
#ifndef _BLUELIB_ARRAY_H_
#define _BLUELIB_ARRAY_H_
#include "../object.h"
struct b_array {
struct b_dsref ar_base;
/* number of items in array */
unsigned int ar_len;
/* maximum number of items that can currently be stored in array */
unsigned int ar_cap;
struct b_dsref **ar_data;
};
#endif

View File

@@ -1,16 +1,29 @@
#ifndef BLUELIB_ARRAY_H_ /**
#define BLUELIB_ARRAY_H_ * A heterogeneous array of objects. b_array only stores references
* to the objects that it contains, not the object data itself.
*
* b_array stores pointers to objects in a single contiguous array,
* but this is an implementation detail that may change in the future.
* Users of b_array should not rely on this being the case.
*/
#ifndef BLUE_DS_ARRAY_H_
#define BLUE_DS_ARRAY_H_
#include <blue/core/iterator.h> #include <blue/core/iterator.h>
#include <blue/core/macros.h>
#include <blue/core/misc.h> #include <blue/core/misc.h>
#include <blue/core/status.h> #include <blue/core/status.h>
#include <blue/ds/object.h>
#include <blue/ds/type.h>
/** B_DECLS_BEGIN;
* Cast a generic b_dsref pointer to an b_array pointer.
*/ #define B_TYPE_ARRAY (b_array_get_type())
#define B_ARRAY(p) ((b_array *)(p))
struct b_array_p;
B_DECLARE_TYPE(b_array);
B_TYPE_CLASS_DECLARATION_BEGIN(b_array)
B_TYPE_CLASS_DECLARATION_END(b_array)
/** /**
* Iterate through each object in an b_array. * Iterate through each object in an b_array.
@@ -26,24 +39,10 @@
for (int z__b_unique_name() = b_array_iterator_begin(array, it); \ for (int z__b_unique_name() = b_array_iterator_begin(array, it); \
(it)->value != NULL; b_array_iterator_next(it)) (it)->value != NULL; b_array_iterator_next(it))
#ifdef __cplusplus
extern "C" {
#endif
/**
* A heterogeneous array of objects. b_array only stores references
* to the objects that it contains, not the object data itself.
*
* b_array stores pointers to objects in a single contiguous array,
* but this is an implementation detail that may change in the future.
* Users of b_array should not rely on this being the case.
*/
typedef struct b_array b_array;
/** /**
* Iterator for traversing the contents of an b_array. * Iterator for traversing the contents of an b_array.
* *
* The iterator provides the current b_dsref `value`, as well * The iterator provides the current b_object `value`, as well
* as the index `i` of that value within the array. * as the index `i` of that value within the array.
* *
* Any members whose names begin with _ (underscore) are reserved * Any members whose names begin with _ (underscore) are reserved
@@ -52,57 +51,35 @@ typedef struct b_array b_array;
typedef struct b_array_iterator { typedef struct b_array_iterator {
b_iterator _base; b_iterator _base;
b_array *_a; b_array *_a;
struct b_array_p *_a_p;
/** The index of the current value */ /** The index of the current value */
size_t i; size_t i;
/** The current value */ /** The current value */
b_dsref *value; b_object *value;
} b_array_iterator; } b_array_iterator;
/** BLUE_API b_type b_array_get_type(void);
* Creates an empty b_array.
* B_TYPE_DEFAULT_CONSTRUCTOR(b_array, B_TYPE_ARRAY);
* @return A pointer to the new array, or NULL if an error occurred.
*/
BLUE_API b_array *b_array_create(void);
/** /**
* Creates an b_array initialised with the contents of the provided b_dsref * Creates an b_array initialised with the contents of the provided
* pointer array. The b_array will take a reference to each object specified in * b_object pointer array. The b_array will take a reference to each
* `values`, and will increment the reference count. The order of objects in the * object specified in `values`, and will increment the reference count.
* new b_array will be the same as the order of objects in `values`. Any NULL * The order of objects in the new b_array will be the same as the order
* pointers in the `values` array will be ignored, and will not result in gaps * of objects in `values`. Any NULL pointers in the `values` array will
* in the created b_array. However, `nr_values` should be large enough to cover * be ignored, and will not result in gaps in the created b_array.
* the final non-NULL pointer in `values`, including any NULL pointers * However, `nr_values` should be large enough to cover the final
* in-between. * non-NULL pointer in `values`, including any NULL pointers in-between.
* *
* @param values The list of object pointers which should make up the contents * @param values The list of object pointers which should make up the
* of the new b_array. * contents of the new b_array.
* @param nr_values The size of the `values` array. * @param nr_values The size of the `values` array.
* @return A pointer to the new b_array, or NULL if an error occurred. * @return A pointer to the new b_array, or NULL if an error occurred.
*/ */
BLUE_API b_array *b_array_create_with_values( BLUE_API b_array *b_array_create_with_values(
b_dsref *const *values, size_t nr_values); b_object *const *values, size_t nr_values);
/**
* Increment the reference counter of an b_array.
*
* @param array The b_array to reference.
* @return The b_array pointer that was passed to the function.
*/
static inline b_array *b_array_retain(b_array *array)
{
return B_ARRAY(b_retain(B_DSREF(array)));
}
/**
* Decrement the reference counter of an b_array, destroying the array if it reaches zero.
* @param array The b_array reference to release.
*/
static inline void b_array_release(b_array *array)
{
b_release(B_DSREF(array));
}
/** /**
* Remove all object references from an b_array, resetting the size of the array to zero. * Remove all object references from an b_array, resetting the size of the array to zero.
@@ -113,49 +90,55 @@ static inline void b_array_release(b_array *array)
BLUE_API void b_array_clear(b_array *array); BLUE_API void b_array_clear(b_array *array);
/** /**
* Inserts an object at the end of an b_array. The reference count of the object * Inserts an object at the end of an b_array. The reference count of
* will be incremented. * the object will be incremented.
* *
* @param array The b_array to append the object to. * @param array The b_array to append the object to.
* @param value The object to append. * @param value The object to append.
* @return B_SUCCESS if the object was appended successfully, or an error code if an error occurred. * @return B_SUCCESS if the object was appended successfully, or an
* error code if an error occurred.
*/ */
BLUE_API b_status b_array_append(b_array *array, b_dsref *value); BLUE_API b_status b_array_append(b_array *array, b_object *value);
/** /**
* Inserts an object at the beginning of an b_array. The reference count of the object * Inserts an object at the beginning of an b_array. The reference count
* will be incremented. All other objects in the array will be moved to make space * of the object will be incremented. All other objects in the array
* for the object being pre-pended. * will be moved to make space for the object being pre-pended.
* *
* @param array The b_array to prepend the object to. * @param array The b_array to prepend the object to.
* @param value The object to prepend. * @param value The object to prepend.
* @return B_SUCCESS if the object was prepended successfully, or an error code if an error occurred. * @return B_SUCCESS if the object was prepended successfully, or an
* error code if an error occurred.
*/ */
BLUE_API b_status b_array_prepend(b_array *array, b_dsref *value); BLUE_API b_status b_array_prepend(b_array *array, b_object *value);
/** /**
* Inserts an object into an b_array at a given index. The reference count of the object * Inserts an object into an b_array at a given index. The reference
* will be incremented. If the specified index is at the beginning or mid-way through * count of the object will be incremented. If the specified index is at
* the array (i.e. not at the end), some or all of the objects already in the array will * the beginning or mid-way through the array (i.e. not at the end),
* be moved to make space for the object being inserted. * some or all of the objects already in the array will be moved to make
* space for the object being inserted.
* *
* @param array The b_array to insert the object into. * @param array The b_array to insert the object into.
* @param value The object to insert. * @param value The object to insert.
* @param at The index to insert the object at. If the index is `B_NPOS`, the object will * @param at The index to insert the object at. If the index is
* be inserted at the end of the b_array. * `B_NPOS`, the object will be inserted at the end of the b_array.
* @return B_SUCCESS if the object was inserted, or a status code describing any error that occurred. * @return B_SUCCESS if the object was inserted, or a status code
* describing any error that occurred.
*/ */
BLUE_API b_status b_array_insert(b_array *array, b_dsref *value, size_t at); BLUE_API b_status b_array_insert(b_array *array, b_object *value, size_t at);
/** /**
* Removes the object at the specified index from an b_array. The reference count * Removes the object at the specified index from an b_array. The
* of the removed object will be decremented. If the specified index is at the beginning * reference count of the removed object will be decremented. If the
* or mid-way through the array (i.e. not at the end), the remaining objects will be moved * specified index is at the beginning or mid-way through the array
* to fill the empty space created by the object's removal. * (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 b_array to remove the object from. * @param array The b_array to remove the object from.
* @param at The index of the object to be removed. * @param at The index of the object to be removed.
* @return B_SUCCESS if the object was removed, or a status code describing any error that occurred. * @return B_SUCCESS if the object was removed, or a status code
* describing any error that occurred.
*/ */
BLUE_API b_status b_array_remove(b_array *array, size_t at); BLUE_API b_status b_array_remove(b_array *array, size_t at);
@@ -179,32 +162,32 @@ BLUE_API b_status b_array_remove_front(b_array *array);
BLUE_API b_status b_array_remove_back(b_array *array); BLUE_API b_status b_array_remove_back(b_array *array);
/** /**
* Removes the object at the specified index of an b_array, and returns a * Removes the object at the specified index of an b_array, and returns
* pointer to it. The reference count of the removed object will NOT be * a pointer to it. The reference count of the removed object will NOT
* decremented. The caller becomes the owner of the array's reference to the * be decremented. The caller becomes the owner of the array's reference
* object. If the specified index is at the beginning or mid-way through the * to the object. If the specified index is at the beginning or mid-way
* array (i.e. not at the end), the remaining objects will be moved to fill the * through the array (i.e. not at the end), the remaining objects will
* empty space created by the object's removal. * be moved to fill the empty space created by the object's removal.
* *
* @param array The b_array to remove the object from. * @param array The b_array to remove the object from.
* @param at The index of the object to be removed. * @param at The index of the object to be removed.
* @return An pointer to the removed object. This pointer is owned by the * @return An pointer to the removed object. This pointer is owned by
* caller. Returns NULL if an error occurred. * the caller. Returns NULL if an error occurred.
*/ */
BLUE_API b_dsref *b_array_pop(b_array *array, size_t at); BLUE_API b_object *b_array_pop(b_array *array, size_t at);
/** /**
* Removes the object at the beginning of an b_array, and returns a pointer to * Removes the object at the beginning of an b_array, and returns a
* it. The reference count of the removed object will NOT be decremented. The * pointer to it. The reference count of the removed object will NOT be
* caller becomes the owner of the array's reference to the object. The * decremented. The caller becomes the owner of the array's reference to
* remaining objects in the b_array will be moved to fill the empty space left * the object. The remaining objects in the b_array will be moved to
* by the removed object. * fill the empty space left by the removed object.
* *
* @param array The b_array to remove the object from. * @param array The b_array to remove the object from.
* @return An pointer to the removed object. This pointer is owned by the * @return An pointer to the removed object. This pointer is owned by
* caller. Returns NULL if an error occurred. * the caller. Returns NULL if an error occurred.
*/ */
BLUE_API b_dsref *b_array_pop_front(b_array *array); BLUE_API b_object *b_array_pop_front(b_array *array);
/** /**
* Removes the object at the end of an b_array, and returns a pointer to it. The * Removes the object at the end of an b_array, and returns a pointer to it. The
@@ -215,7 +198,7 @@ BLUE_API b_dsref *b_array_pop_front(b_array *array);
* @return An pointer to the removed object. This pointer is owned by the * @return An pointer to the removed object. This pointer is owned by the
* caller. Returns NULL if an error occurred. * caller. Returns NULL if an error occurred.
*/ */
BLUE_API b_dsref *b_array_pop_back(b_array *array); BLUE_API b_object *b_array_pop_back(b_array *array);
/** /**
* Returns an unowned pointer to the object at the given index of an b_array. * Returns an unowned pointer to the object at the given index of an b_array.
@@ -226,18 +209,19 @@ BLUE_API b_dsref *b_array_pop_back(b_array *array);
* @return A pointer to the object at the given index. This pointer is NOT owned * @return A pointer to the object at the given index. This pointer is NOT owned
* by the caller. Returns NULL if an error occurred. * by the caller. Returns NULL if an error occurred.
*/ */
BLUE_API b_dsref *b_array_at(const b_array *array, size_t at); BLUE_API b_object *b_array_at(const b_array *array, size_t at);
/** /**
* Returns an owned pointer to the object at the given index of an b_array. The caller owns * Returns an owned pointer to the object at the given index of an
* the returned pointer, and must release it when they are finished with it. * b_array. The caller owns the returned pointer, and must release it
* when they are finished with it.
* *
* @param array The b_array. * @param array The b_array.
* @param at The index of the object to return. * @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. * @return A pointer to the object at the given index. This pointer is
* Returns NULL if an error occurred. * owned by the caller. Returns NULL if an error occurred.
*/ */
BLUE_API b_dsref *b_array_get(b_array *array, size_t at); BLUE_API b_object *b_array_get(b_array *array, size_t at);
/** /**
* Returns the number of objects contained in an b_array. * Returns the number of objects contained in an b_array.
@@ -248,9 +232,9 @@ BLUE_API b_dsref *b_array_get(b_array *array, size_t at);
BLUE_API size_t b_array_size(const b_array *array); BLUE_API size_t b_array_size(const b_array *array);
/** /**
* Returns the current maximum capacity of an b_array. This represents the * Returns the current maximum capacity of an b_array. This represents
* number of objects that can be stored in an b_array before its internal buffer * the number of objects that can be stored in an b_array before its
* would need to be re-sized. * internal buffer would need to be re-sized.
* *
* @param array The b_array. * @param array The b_array.
* @return The maximum capacity of the b_array. * @return The maximum capacity of the b_array.
@@ -297,8 +281,6 @@ BLUE_API b_status b_array_iterator_erase(b_array_iterator *it);
*/ */
BLUE_API bool b_array_iterator_is_valid(const b_array_iterator *it); BLUE_API bool b_array_iterator_is_valid(const b_array_iterator *it);
#ifdef __cplusplus B_DECLS_END;
}
#endif
#endif #endif