dynamic_array.h v0.3.1
Reference-counted dynamic arrays for C
Loading...
Searching...
No Matches
Classes | Macros | Typedefs | Functions
dynamic_array.h File Reference

reference-counted (optionally atomic) dynamic arrays with ArrayBuffer-style builder More...

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdatomic.h>
Include dependency graph for dynamic_array.h:

Go to the source code of this file.

Classes

struct  da_array_t
 Reference-counted dynamic array structure. More...
 
struct  da_builder_t
 ArrayBuffer-style builder for efficient array construction. More...
 
struct  da_sort_context
 

Macros

#define DA_MALLOC   malloc
 Custom memory allocator (default: malloc)
 
#define DA_REALLOC   realloc
 Custom memory reallocator (default: realloc)
 
#define DA_FREE   free
 Custom memory deallocator (default: free)
 
#define DA_ASSERT   assert
 Custom assertion macro (default: assert)
 
#define DA_DEF   extern
 
#define DA_ATOMIC_INT   _Atomic int
 Enable atomic reference counting (default: 0)
 
#define DA_ATOMIC_FETCH_ADD(ptr, val)   atomic_fetch_add(ptr, val)
 
#define DA_ATOMIC_FETCH_SUB(ptr, val)   atomic_fetch_sub(ptr, val)
 
#define DA_ATOMIC_LOAD(ptr)   atomic_load(ptr)
 
#define DA_ATOMIC_STORE(ptr, val)   atomic_store(ptr, val)
 
#define DA_HAS_TYPEOF   0
 
#define DA_HAS_AUTO   0
 
#define DA_HAS_GENERIC   0
 
#define DA_SUPPORT_TYPE_INFERENCE   0
 
#define DA_NEW(T)   da_new(sizeof(T))
 
#define DA_CREATE(T, cap, retain_fn, release_fn)   da_create(sizeof(T), cap, retain_fn, release_fn)
 Type-safe array creation.
 
#define DA_PUSH_TYPED(arr, val, T)   do { T _temp = (val); da_push(arr, (void*)&_temp); } while(0)
 Type-safe element append with explicit type parameter.
 
#define DA_PUT_TYPED(arr, i, val, T)   do { T _temp = (val); da_set(arr, i, (void*)&_temp); } while(0)
 Type-safe element assignment with explicit type parameter.
 
#define DA_INSERT_TYPED(arr, i, val, T)   do { T _temp = (val); da_insert(arr, i, (void*)&_temp); } while(0)
 Type-safe element insert with explicit type parameter.
 
#define DA_PUSH(arr, val, T)   DA_PUSH_TYPED(arr, val, T)
 Type-safe element append (adaptive macro)
 
#define DA_PUT(arr, i, val, T)   DA_PUT_TYPED(arr, i, val, T)
 Type-safe element assignment (adaptive macro)
 
#define DA_INSERT(arr, i, val, T)   DA_INSERT_TYPED(arr, i, val, T)
 Type-safe element insert (adaptive macro)
 
#define DA_LENGTH(arr)   da_length(arr)
 Get array length (shorthand for da_length)
 
#define DA_CAPACITY(arr)   da_capacity(arr)
 Get array capacity (shorthand for da_capacity)
 
#define DA_AT(arr, i, T)   (*(T*)da_get(arr, i))
 Type-safe element access by value.
 
#define DA_POP(arr, out_ptr)   da_pop(arr, out_ptr)
 Pop last element (shorthand for da_pop)
 
#define DA_REMOVE(arr, i, out_ptr)   da_remove(arr, i, out_ptr)
 Remove element at index (shorthand for da_remove)
 
#define DA_CLEAR(arr)   da_clear(arr)
 Clear array (shorthand for da_clear)
 
#define DA_RESERVE(arr, cap)   da_reserve(arr, cap)
 Reserve capacity (shorthand for da_reserve)
 
#define DA_RESIZE(arr, len)   da_resize(arr, len)
 Resize array (shorthand for da_resize)
 
#define DA_TRIM(arr, cap)   da_trim(arr, cap)
 
#define DA_SHRINK_TO_FIT(arr)   da_trim(arr, da_length(arr))
 
#define DA_PEEK(arr, T)   (*(T*)da_peek(arr))
 
#define DA_PEEK_FIRST(arr, T)   (*(T*)da_peek_first(arr))
 
#define DA_BUILDER_CREATE(T)   da_builder_create(sizeof(T))
 Type-safe builder creation.
 
#define DA_BUILDER_APPEND_TYPED(builder, val, T)   do { T _temp = (val); da_builder_append(builder, (void*)&_temp); } while(0)
 Type-safe element append to builder with explicit type parameter.
 
#define DA_BUILDER_PUT_TYPED(builder, i, val, T)   do { T _temp = (val); da_builder_set(builder, i, (void*)&_temp); } while(0)
 Type-safe element assignment in builder with explicit type parameter.
 
#define DA_BUILDER_APPEND(builder, val, T)   DA_BUILDER_APPEND_TYPED(builder, val, T)
 Type-safe element append to builder (adaptive macro)
 
#define DA_BUILDER_PUT(builder, i, val, T)   DA_BUILDER_PUT_TYPED(builder, i, val, T)
 Type-safe element assignment in builder (adaptive macro)
 
#define DA_BUILDER_LEN(builder)   da_builder_length(builder)
 Get builder length (shorthand for da_builder_length)
 
#define DA_BUILDER_CAP(builder)   da_builder_capacity(builder)
 Get builder capacity (shorthand for da_builder_capacity)
 
#define DA_BUILDER_AT(builder, i, T)   (*(T*)da_builder_get(builder, i))
 Type-safe element access by value from builder.
 
#define DA_BUILDER_CLEAR(builder)   da_builder_clear(builder)
 Clear builder (shorthand for da_builder_clear)
 
#define DA_BUILDER_TO_ARRAY(builder)   da_builder_to_array(builder, NULL, NULL)
 Convert builder to array (shorthand for da_builder_to_array)
 
#define DA_BUILDER_TO_ARRAY_MANAGED(builder, retain_fn, release_fn)   da_builder_to_array(builder, retain_fn, release_fn)
 

Typedefs

typedef struct da_array_tda_array
 
typedef struct da_builder_tda_builder
 

Functions

DA_DEF da_array da_new (int element_size)
 Creates a new dynamic array (simple version for general use)
 
DA_DEF da_array da_create (int element_size, int initial_capacity, void(*retain_fn)(void *), void(*release_fn)(void *))
 Creates a new dynamic array with full configuration.
 
DA_DEF void da_release (da_array *arr)
 Releases a reference to an array, potentially freeing it.
 
DA_DEF da_array da_retain (da_array arr)
 Increments reference count for sharing an array.
 
DA_DEF void * da_get (da_array arr, int index)
 Gets a pointer to an element at the specified index.
 
DA_DEF void * da_data (da_array arr)
 Gets direct pointer to the underlying data array.
 
DA_DEF void da_set (da_array arr, int index, const void *element)
 Sets the value of an element at the specified index.
 
DA_DEF void da_push (da_array arr, const void *element)
 Appends an element to the end of the array.
 
DA_DEF void da_insert (da_array arr, int index, const void *element)
 Inserts an element at the specified index.
 
DA_DEF void da_remove (da_array arr, int index, void *out)
 Removes and optionally returns an element at the specified index.
 
DA_DEF void da_pop (da_array arr, void *out)
 Removes and optionally returns the last element.
 
DA_DEF void da_clear (da_array arr)
 Removes all elements from the array.
 
DA_DEF void * da_peek (da_array arr)
 Gets a pointer to the last element without removing it.
 
DA_DEF void * da_peek_first (da_array arr)
 Gets a pointer to the first element without removing it.
 
DA_DEF int da_length (da_array arr)
 Gets the current number of elements in the array.
 
DA_DEF int da_capacity (da_array arr)
 Gets the current allocated capacity of the array.
 
DA_DEF void da_reserve (da_array arr, int new_capacity)
 Ensures the array has at least the specified capacity.
 
DA_DEF void da_resize (da_array arr, int new_length)
 Changes the array length, growing or shrinking as needed.
 
DA_DEF void da_trim (da_array arr, int new_capacity)
 Reduces the array's allocated capacity to a specific size.
 
DA_DEF void da_append_array (da_array dest, da_array src)
 Appends all elements from source array to destination array.
 
DA_DEF da_array da_concat (da_array arr1, da_array arr2)
 Creates a new array by concatenating two arrays.
 
DA_DEF void da_append_raw (da_array arr, const void *data, int count)
 Appends raw C array data to the dynamic array.
 
DA_DEF void da_fill (da_array arr, const void *element, int count)
 Fills the array with multiple copies of an element.
 
DA_DEF da_array da_slice (da_array arr, int start, int end)
 Creates a new array containing elements from a range [start, end)
 
DA_DEF da_array da_copy (da_array arr)
 Creates a complete copy of an existing array.
 
DA_DEF da_array da_filter (da_array arr, int(*predicate)(const void *element, void *context), void *context)
 Creates a new array containing elements that pass a predicate test.
 
DA_DEF da_array da_map (da_array arr, void(*mapper)(const void *src, void *dst, void *context), void *context)
 Creates a new array by transforming each element using a mapper function.
 
DA_DEF void da_reduce (da_array arr, const void *initial, void *result, void(*reducer)(void *accumulator, const void *element, void *context), void *context)
 Reduces array to single value using accumulator function.
 
DA_DEF void da_remove_range (da_array arr, int start, int count)
 Removes multiple consecutive elements from the array.
 
DA_DEF void da_reverse (da_array arr)
 Reverses all elements in the array in place.
 
DA_DEF void da_swap (da_array arr, int i, int j)
 Swaps two elements at the specified indices.
 
DA_DEF int da_is_empty (da_array arr)
 Checks if the array is empty.
 
DA_DEF int da_find_index (da_array arr, int(*predicate)(const void *element, void *context), void *context)
 Find index of first element matching predicate.
 
DA_DEF int da_contains (da_array arr, int(*predicate)(const void *element, void *context), void *context)
 Check if array contains element matching predicate.
 
DA_DEF void da_sort (da_array arr, int(*compare)(const void *a, const void *b, void *context), void *context)
 Sort array elements using comparison function.
 
DA_DEF da_builder da_builder_create (int element_size)
 Creates a new array builder for efficient construction.
 
DA_DEF da_array da_builder_to_array (da_builder *builder, void(*retain_fn)(void *), void(*release_fn)(void *))
 Converts builder to a ref-counted array with exact capacity.
 
DA_DEF void da_builder_clear (da_builder builder)
 Removes all elements from the builder.
 
DA_DEF void da_builder_destroy (da_builder *builder)
 Destroys a builder and frees its memory.
 
DA_DEF void da_builder_append (da_builder builder, const void *element)
 Appends an element to the builder.
 
DA_DEF void da_builder_reserve (da_builder builder, int new_capacity)
 Ensures the builder has at least the specified capacity.
 
DA_DEF void da_builder_append_array (da_builder builder, da_array arr)
 Appends all elements from an array to the builder.
 
DA_DEF int da_builder_length (da_builder builder)
 Gets the current number of elements in the builder.
 
DA_DEF int da_builder_capacity (da_builder builder)
 Gets the current allocated capacity of the builder.
 
DA_DEF void * da_builder_get (da_builder builder, int index)
 Gets a pointer to an element at the specified index.
 
DA_DEF void da_builder_set (da_builder builder, int index, const void *element)
 Sets the value of an element at the specified index.
 

Detailed Description

reference-counted (optionally atomic) dynamic arrays with ArrayBuffer-style builder

Author
dynamic_array.h contributors
Version
0.1.1
Date
August 2025

Single header library for mutable dynamic arrays with reference counting. Includes Scala ArrayBuffer-style builder for efficient construction. Designed for portability across PC and microcontroller targets.

Configuration

Customize the library by defining these macros before including:

#define DA_MALLOC malloc // custom allocator
#define DA_REALLOC realloc // custom reallocator
#define DA_FREE free // custom deallocator
#define DA_ASSERT assert // custom assert macro
#define DA_GROWTH 16 // fixed growth increment (default: doubling)
#define DA_ATOMIC_REFCOUNT 1 // enable atomic reference counting (C11 required)
#define DA_IMPLEMENTATION
#include "dynamic_array.h"
reference-counted (optionally atomic) dynamic arrays with ArrayBuffer-style builder

Basic Usage

Regular Arrays

da_array arr = da_new(sizeof(int), 10);
DA_PUSH(arr, 42);
int val = DA_AT(arr, 0, int);
da_release(&arr); // arr becomes NULL
DA_DEF void da_release(da_array *arr)
Releases a reference to an array, potentially freeing it.
Definition dynamic_array.h:1527
DA_DEF da_array da_new(int element_size)
Creates a new dynamic array (simple version for general use)
Definition dynamic_array.h:1486
#define DA_AT(arr, i, T)
Type-safe element access by value.
Definition dynamic_array.h:1269
#define DA_PUSH(arr, val, T)
Type-safe element append (adaptive macro)
Definition dynamic_array.h:1262
Reference-counted dynamic array structure.
Definition dynamic_array.h:192

Builder Pattern (like Scala's ArrayBuffer)

DA_BUILDER_APPEND(builder, 42);
DA_BUILDER_APPEND(builder, 99);
da_array arr = da_builder_to_array(&builder); // Exact size, builder becomes NULL
da_release(&arr);
DA_DEF da_array da_builder_to_array(da_builder *builder, void(*retain_fn)(void *), void(*release_fn)(void *))
Converts builder to a ref-counted array with exact capacity.
Definition dynamic_array.h:1908
#define DA_BUILDER_APPEND(builder, val, T)
Type-safe element append to builder (adaptive macro)
Definition dynamic_array.h:1439
#define DA_BUILDER_CREATE(T)
Type-safe builder creation.
Definition dynamic_array.h:1423
ArrayBuffer-style builder for efficient array construction.
Definition dynamic_array.h:208

Atomic Reference Counting

When DA_ATOMIC_REFCOUNT=1 (requires C11):

Supported Platforms

Macro Definition Documentation

◆ DA_ATOMIC_INT

#define DA_ATOMIC_INT   _Atomic int

Enable atomic reference counting (default: 0)

Note
Requires C11 and stdatomic.h support
Only reference counting is atomic/thread-safe, not array operations
Warning
Array modifications (push/pop/set) still require external synchronization