X_ARRAY_VERSION_MAJOR
#define X_ARRAY_VERSION_MAJOR 1
STDX - Generic Hashtable
Part of the STDX General Purpose C Library by marciovmf
License: MIT
https://github.com/marciovmf/stdx
Provides a generic, dynamic array implementation with support for
random access, insertion, deletion, and stack-like operations
(push/pop). Useful for managing homogeneous collections in C with
automatic resizing.
To compile the implementation define X_IMPL_ARRAY
in one source file before including this header.
To customize how this module allocates memory, define
X_ARRAY_ALLOC / X_ARRAY_REALLOC / X_ARRAY_FREE before including.
The array core operates on void* elements and an explicit element size.
For convenience this header also provides macros that generate type-safe
wrappers on top of the generic API.
These macros create:
XArraycreate, push, get, data, count, etc.)This avoids manual casts and makes the API easier and safer to use.
X_ARRAY_TYPE(int)
XArray_int* arr = x_array_int_create(16);
x_array_int_push(arr, 10);
x_array_int_push(arr, 20);
int* value = x_array_int_get(arr, 1);
printf("%d\n", *value);
If the element type is not a valid identifier (for example
unsigned int, const char*, or complex types), use the named version:
X_ARRAY_TYPE_NAMED(unsigned int, uint)
XArray_uint* arr = x_array_uint_create(8);
The second argument defines the suffix used to generate the type and function names.
typedef struct
{
float x;
float y;
} Point;
X_ARRAY_TYPE(Point)
XArray_Point* points = x_array_Point_create(4);
Point p = {1.0f, 2.0f};
x_array_Point_push(points, p);
Internally these wrappers call the generic API, so there is no additional runtime overhead.
stdx_common.h
#define X_ARRAY_VERSION_MAJOR 1
#define X_ARRAY_VERSION_MINOR 0
#define X_ARRAY_VERSION_PATCH 0
#define X_ARRAY_VERSION(X_ARRAY_VERSION_MAJOR *10000+X_ARRAY_VERSION_MINOR *100+X_ARRAY_VERSION_PATCH)
typedef enum{
XARRAY_OK=0,
XARRAY_INVALID_RANGE=1,
XARRAY_MEMORY_ALLOCATION_FAILED=2,
XARRAY_INDEX_OUT_OF_BOUNDS=3,
XARRAY_EMPTY=4
}XArrayError;
typedef struct XArray_t XArray;
Create a new dynamic array.
XArray * x_array_create(
size_t elementSize,
size_t capacity
);
size_t elementSizesize_t capacityPointer to the newly created array, or NULL on failure.
Get a pointer to the element at the given index.
void * x_array_get(
XArray *arr,
unsigned int index
);
XArray *arrunsigned int indexPointer to the element at the given index.
Get a pointer to the underlying data buffer.
void * x_array_data(XArray *arr);
XArray *arrPointer to the internal contiguous data storage.
Append an element to the end of the array.
XArrayError x_array_add(
XArray *arr,
void *data
);
XArray *arrvoid *dataError code indicating success or failure.
Insert an element at the specified index.
XArrayError x_array_insert(
XArray *arr,
void *data,
unsigned int index
);
XArray *arrvoid *dataunsigned int indexError code indicating success or failure.
Delete a range of elements from the array.
XArrayError x_array_delete_range(
XArray *arr,
unsigned int start,
unsigned int end
);
XArray *arrunsigned int startunsigned int endError code indicating success or failure.
Remove all elements from the array without freeing its storage.
void x_array_clear(XArray *arr);
XArray *arrNothing.
Delete the element at the specified index.
void x_array_delete_at(
XArray *arr,
unsigned int index
);
XArray *arrunsigned int indexNothing.
Destroy the array and free all associated memory.
void x_array_destroy(XArray *arr);
XArray *arrNothing.
Get the number of elements currently stored in the array.
uint32_t x_array_count(XArray *arr);
XArray *arrNumber of elements in the array.
Get the current capacity of the array.
uint32_t x_array_capacity(XArray *arr);
XArray *arrMaximum number of elements the array can hold without resizing.
Push an element onto the end of the array.
void x_array_push(
XArray *array,
void *value
);
XArray *arrayvoid *valueNothing.
Remove the last element from the array.
void x_array_pop(XArray *array);
XArray *arrayNothing.
Get a pointer to the last element in the array.
void * x_array_top(XArray *array);
XArray *arrayPointer to the last element.
Check whether the array is empty.
bool x_array_is_empty(XArray *array);
XArray *arrayTrue if the array contains no elements, false otherwise.
#define X_ARRAY_TYPE(T) \
X_ARRAY_TYPE_NAMED(T, T)
#define X_ARRAY_TYPE_NAMED(T, suffix) \
typedef XArray XArray_##suffix;\
static inline XArray_##suffix *x_array_##suffix##_create(size_t capacity)\
{\
return(XArray_##suffix *)x_array_create(sizeof(T), capacity);\
}\
static inline void x_array_##suffix##_destroy(XArray_##suffix *arr)\
{\
x_array_destroy((XArray *)arr);\
}\
static inline XArrayError x_array_##suffix##_add_ptr(XArray_##suffix *arr, const T *value_ptr)\
{\
return x_array_add((XArray *)arr, (void *)value_ptr);\
}\
static inline XArrayError x_array_##suffix##_add(XArray_##suffix *arr, T value)\
{\
T value_copy=value;\
return x_array_add((XArray *)arr,&value_copy);\
}\
static inline XArrayError x_array_##suffix##_insert_ptr(XArray_##suffix *arr, const T *value_ptr, unsigned int index)\
{\
return x_array_insert((XArray *)arr, (void *)value_ptr, index);\
}\
static inline XArrayError x_array_##suffix##_insert(XArray_##suffix *arr, T value, unsigned int index)\
{\
T value_copy=value;\
return x_array_insert((XArray *)arr,&value_copy, index);\
}\
static inline XArrayError x_array_##suffix##_push_ptr(XArray_##suffix *arr, const T *value_ptr)\
{\
return x_array_add((XArray *)arr, (void *)value_ptr);\
}\
static inline XArrayError x_array_##suffix##_push(XArray_##suffix *arr, T value)\
{\
T value_copy=value;\
return x_array_add((XArray *)arr,&value_copy);\
}\
static inline void x_array_##suffix##_pop(XArray_##suffix *arr)\
{\
x_array_pop((XArray *)arr);\
}\
static inline T *x_array_##suffix##_get(XArray_##suffix *arr, unsigned int index)\
{\
return(T *)x_array_get((XArray *)arr, index);\
}\
static inline const T *x_array_##suffix##_get_const(const XArray_##suffix *arr, unsigned int index)\
{\
return(const T *)x_array_get((XArray *)arr, index);\
}\
static inline T *x_array_##suffix##_data(XArray_##suffix *arr)\
{\
return(T *)x_array_data((XArray *)arr);\
}\
static inline const T *x_array_##suffix##_data_const(const XArray_##suffix *arr)\
{\
return(const T *)x_array_data((XArray *)arr);\
}\
static inline T *x_array_##suffix##_top(XArray_##suffix *arr)\
{\
return(T *)x_array_top((XArray *)arr);\
}\
static inline const T *x_array_##suffix##_top_const(const XArray_##suffix *arr)\
{\
return(const T *)x_array_top((XArray *)arr);\
}\
static inline void x_array_##suffix##_clear(XArray_##suffix *arr)\
{\
x_array_clear((XArray *)arr);\
}\
static inline void x_array_##suffix##_delete_at(XArray_##suffix *arr, unsigned int index)\
{\
x_array_delete_at((XArray *)arr, index);\
}\
static inline XArrayError x_array_##suffix##_delete_range(XArray_##suffix *arr, unsigned int start, unsigned int end)\
{\
return x_array_delete_range((XArray *)arr, start, end);\
}\
static inline uint32_t x_array_##suffix##_count(XArray_##suffix *arr)\
{\
return x_array_count((XArray *)arr);\
}\
static inline uint32_t x_array_##suffix##_capacity(XArray_##suffix *arr)\
{\
return x_array_capacity((XArray *)arr);\
}\
static inline bool x_array_##suffix##_is_empty(XArray_##suffix *arr)\
{\
return x_array_is_empty((XArray *)arr);\
}
Internal macro for allocating memory. To override how this header allocates memory, define this macro with a different implementation before including this header.
#define X_ARRAY_ALLOC(sz) malloc(sz)
szInternal macro for resizing memory. To override how this header resizes memory, define this macro with a different implementation before including this header.
#define X_ARRAY_REALLOC(p, sz) realloc((p), (sz))
szInternal macro for freeing memory. To override how this header frees memory, define this macro with a different implementation before including this header.
#define X_ARRAY_FREE(p) free(p)
pstruct XArray_t{
void *array;
size_t size;
size_t capacity;
size_t elementSize;
};