1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
#ifndef ARRAY_H
#define ARRAY_H
#include <stddef.h>
#include <stdbool.h>
/**
* @file
*
* A dynamically growing array, there exist two typical ways to use it:
*
* 1. To hold pointers to externally allocated memory regions.
*
* Use `array_init` for initialization, an element has the size of a
* pointer. Use the functions suffixed with ``_ptr`` to manage your
* pointers. The cleanup function `array_release_full` must only be
* used with this type of array.
*
* 2. To hold arbitrary sized objects.
*
* Use `array_init_sized` to specify the size of a single element.
* Use the regular (i.e. without the ``_ptr`` suffix) functions to
* manage your objects. Functions like `array_add` and `array_set`
* will copy the object into the array, `array_get` will return a
* pointer to the object stored within the array.
*/
/** A dynamically growing array. */
typedef struct {
char *items; /** Data pointer, NULL if empty. */
size_t elem_size; /** Size of one array element. */
size_t len; /** Number of currently stored items. */
size_t count; /** Maximal capacity of the array. */
} Array;
/**
* Initialize an Array object to store pointers.
* @rst
* .. note:: Is equivalent to ``array_init_sized(arr, sizeof(void*))``.
* @endrst
*/
void array_init(Array*);
/**
* Initialize an Array object to store arbitrarily sized objects.
*/
void array_init_sized(Array*, size_t elem_size);
/** Initialize Array by using the same element size as in ``from``. */
void array_init_from(Array*, const Array *from);
/** Release storage space. Reinitializes Array object. */
void array_release(Array*);
/**
* Release storage space and call `free(3)` for each stored pointer.
* @rst
* .. warning:: Assumes array elements to be pointers.
* @endrst
*/
void array_release_full(Array*);
/** Empty array, keep allocated memory. */
void array_clear(Array*);
/** Reserve memory to store at least ``count`` elements. */
bool array_reserve(Array*, size_t count);
/**
* Get array element.
* @rst
* .. warning:: Returns a pointer to the allocated array region.
* Operations which might cause reallocations (e.g. the insertion
* of new elements) might invalidate the pointer.
* @endrst
*/
void *array_get(const Array*, size_t idx);
/**
* Set array element.
* @rst
* .. note:: Copies the ``item`` into the Array. If ``item`` is ``NULL``
* the corresponding memory region will be cleared.
* @endrst
*/
bool array_set(Array*, size_t idx, void *item);
/** Dereference pointer stored in array element. */
void *array_get_ptr(const Array*, size_t idx);
/** Store the address to which ``item`` points to into the array. */
bool array_set_ptr(Array*, size_t idx, void *item);
/** Add element to the end of the array. */
bool array_add(Array*, void *item);
/** Add pointer to the end of the array. */
bool array_add_ptr(Array*, void *item);
/**
* Remove an element by index.
* @rst
* .. note:: Might not shrink underlying memory region.
* @endrst
*/
bool array_remove(Array*, size_t idx);
/** Number of elements currently stored in the array. */
size_t array_length(const Array*);
/** Number of elements which can be stored without enlarging the array. */
size_t array_capacity(const Array*);
/** Remove all elements with index greater or equal to ``length``, keep allocated memory. */
bool array_truncate(Array*, size_t length);
/**
* Change length.
* @rst
* .. note:: Has to be less or equal than the capacity.
* Newly accessible elements preserve their previous values.
* @endrst
*/
bool array_resize(Array*, size_t length);
/**
* Sort array, the comparision function works as for `qsort(3)`.
*/
void array_sort(Array*, int (*compar)(const void*, const void*));
/**
* Push item onto the top of the stack.
* @rst
* .. note:: Is equivalent to ``array_add(arr, item)``.
* @endrst
*/
bool array_push(Array*, void *item);
/**
* Get and remove item at the top of the stack.
* @rst
* .. warning:: The same ownership rules as for ``array_get`` apply.
* @endrst
*/
void *array_pop(Array*);
/**
* Get item at the top of the stack without removing it.
* @rst
* .. warning:: The same ownership rules as for ``array_get`` apply.
* @endrst
*/
void *array_peek(const Array*);
#endif
|