public API solo dev done, awaiting other ideas

This commit is contained in:
2026-05-20 19:44:04 -05:00
parent 06da081893
commit aaad35adc5

View File

@@ -1,44 +1,86 @@
#ifndef MARIGOLD_DYNAMIC_ARRAY_H #ifndef MARIGOLD_DYNAMIC_ARRAY_H
#define MARIGOLD_DYNAMIC_ARRAY_H #define MARIGOLD_DYNAMIC_ARRAY_H
#include <pthread.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <pthread.h>
typedef struct dynamic_array_struct typedef enum
dynamic_array_flag_enum
{
dynamic_array_multithread_safe = 1 << 0,
dynamic_array_read_only = 1 << 1,
dynamic_array_certainly_sorted = 1 << 2,
dynamic_array_marked_for_free = 1 << 3,
dynamic_array_debug_has_function_call_rolled_over = 1 << 4,
dynamic_array_debug_has_owner_count_rolled_over = 1 << 5,
dynamic_array_debug_has_been_resized = 1 << 6,
dynamic_array_debug_has_been_resized_rolled_over = 1 << 7
}
dynamic_array_flag_enum;
typedef enum
dynamic_array_growth_rate_enum
{
dynamic_array_growth_static = 0,
dynamic_array_growth_linear = 1,
dynamic_array_growth_double = 2,
dynamic_array_growth_triple = 3,
dynamic_array_growth_quadruple = 4,
dynamic_array_growth_quintuple = 5
}
dynamic_array_growth_rate_enum;
typedef struct
dynamic_array_struct
{ {
size_t item_size; size_t item_size;
size_t current_capacity; size_t current_capacity;
size_t current_occupancy; size_t current_occupancy;
void* data_pointer; void* data_pointer;
int (*comparator)(const void*, const void*); int (*comparator)(const void *, const void *);
void (*item_free)(const void *);
pthread_mutex_t* mutex_lock; pthread_mutex_t* mutex_lock;
unsigned short owner_count; unsigned short owner_count;
unsigned short function_call_count; uint8_t growth_strategy;
unsigned short growth_steps; uint8_t flags;
unsigned char growth_factor; #ifdef MARIGOLD_DEBUG
uint8_t flags; // is_multithread_safe, is_read_only, is_certainly_sorted, has_owner_count_rolled_over, has_function_call_count_rolled_over, has_growth_steps_rolled_over, has_been_resized, is_array_full (occupancy == capacity) uint8_t debug_flags;
} dynamic_array_struct; uint32_t debug_resize_count;
uint32_t debug_function_call_count;
uint32_t debug_last_error_code;
uint32_t debug_allocation_failures;
#endif // MARIGOLD_DEBUG.
}
dynamic_array_struct;
/** /**
* @brief Create a new dynamic array, it then internally does all the initalization. * @brief Create a new dynamic array, it then internally does all the
* initialization.
* *
* Creates a dynamic array with the specified item size and starting capacity. * Creates a dynamic array with the specified item size and starting capacity.
* The growth_factor determines how the array expands when capacity is exceeded. * The growth_strategy determines how the array expands when capacity is
* exceeded.
*
* If is_multithread_safe is true, the internal mutex is created and initialized
* here.
* *
* @param item_size Size of each element in bytes. * @param item_size Size of each element in bytes.
* @param starting_capacity Initial number of elements to allocate space for. * @param starting_capacity Initial number of elements to allocate space for.
* @param growth_factor Growth strategy: 0 = no growth. 1 = linear (+starting_capacity), * @param growth_strategy Growth strategy enum.
* 2+ = multiplier (2 = 2x, 3 = 3x, etc.) * @param comparator Function to compare two elements. May be NULL if not
* @param comparator Function to compare two elements. May be NULL if not needed. * needed.
* @param is_multithread_safe If true, enables thread-safe operations. * @param is_multithread_safe If true, enables thread-safe operations.
* @return Pointer to the initialized dynamic_array, or NULL on failure. * @return Pointer to the initialized dynamic_array, or NULL on failure.
*/ */
dynamic_array_struct* dynamic_array_create(size_t item_size, dynamic_array_struct*
dynamic_array_create(size_t item_size,
size_t starting_capacity, size_t starting_capacity,
unsigned char growth_factor, dynamic_array_growth_rate_enum growth_rate,
int (*comparator)(const void*, const void*), int (*comparator)(const void*, const void*),
void (*item_free)(const void *),
bool is_multithread_safe); bool is_multithread_safe);
/** /**
@@ -48,10 +90,37 @@ dynamic_array_struct* dynamic_array_create(size_t item_size,
* and the struct itself. Use this for explicit cleanup. For reference-counted * and the struct itself. Use this for explicit cleanup. For reference-counted
* shared ownership, prefer dynamic_array_release(). * shared ownership, prefer dynamic_array_release().
* *
* If the array is thread-safe, the internal mutex is destroyed and freed here.
*
* @param array_to_destroy is the dynamic array being deallocated/destroyed. * @param array_to_destroy is the dynamic array being deallocated/destroyed.
* @return true on successful destory, false on failure. * @return true on successful destroy, false on failure.
*/ */
bool dynamic_array_destroy(dynamic_array_struct* array_to_destroy); bool
dynamic_array_destroy(dynamic_array_struct* array_to_destroy);
/**
* @brief Set or clear a specific flag on the dynamic array.
*
* @param array Pointer to the dynamic_array.
* @param flag The flag to modify.
* @param value true to set the flag, false to clear it.
*/
void
dynamic_array_set_flag(dynamic_array_struct* array,
dynamic_array_flag_enum flag,
bool value);
/**
* @brief Get a specific flag on the dynamic array.
*
* @param array Pointer to the dynamic_array.
* @param flag The flag to get.
*
* @return value of flag as bool (true or false)
*/
bool
dynamic_array_get_flag_value(const dynamic_array_struct* array,
dynamic_array_flag_enum flag);
/** /**
* @brief Get the number of elements currently in the array. * @brief Get the number of elements currently in the array.
@@ -59,7 +128,8 @@ bool dynamic_array_destroy(dynamic_array_struct* array_to_destroy);
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @return Number of elements (current_occupancy). * @return Number of elements (current_occupancy).
*/ */
size_t dynamic_array_get_occupancy(const dynamic_array_struct* array); size_t
dynamic_array_get_occupancy(const dynamic_array_struct* array);
/** /**
* @brief Get the total capacity of the array. * @brief Get the total capacity of the array.
@@ -67,7 +137,8 @@ size_t dynamic_array_get_occupancy(const dynamic_array_struct* array);
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @return Total capacity (current_capacity). * @return Total capacity (current_capacity).
*/ */
size_t dynamic_array_get_capacity(const dynamic_array_struct* array); size_t
dynamic_array_get_capacity(const dynamic_array_struct* array);
/** /**
* @brief Get a pointer to the element at the specified index. * @brief Get a pointer to the element at the specified index.
@@ -76,7 +147,8 @@ size_t dynamic_array_get_capacity(const dynamic_array_struct* array);
* @param index Index of the element to access. * @param index Index of the element to access.
* @return Pointer to the element, or NULL if index is out of bounds. * @return Pointer to the element, or NULL if index is out of bounds.
*/ */
void* dynamic_array_get_pointer_to_index(dynamic_array_struct* array, void*
dynamic_array_get_pointer_to_index(dynamic_array_struct* array,
size_t index); size_t index);
/** /**
@@ -86,7 +158,8 @@ void* dynamic_array_get_pointer_to_index(dynamic_array_struct* array,
* @param index Index of the element to access. * @param index Index of the element to access.
* @return Const pointer to the element, or NULL if index is out of bounds. * @return Const pointer to the element, or NULL if index is out of bounds.
*/ */
const void* dynamic_array_get_const_pointer_to_index(const dynamic_array_struct* array, const void*
dynamic_array_get_const_pointer_to_index(const dynamic_array_struct* array,
size_t index); size_t index);
/** /**
@@ -98,7 +171,8 @@ const void* dynamic_array_get_const_pointer_to_index(const dynamic_array_struct*
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @return Pointer to the raw memory block, or NULL if empty. * @return Pointer to the raw memory block, or NULL if empty.
*/ */
void* dynamic_array_get_raw_data_pointer(const dynamic_array_struct* array); void*
dynamic_array_get_raw_data_pointer(const dynamic_array_struct* array);
/** /**
* @brief Append an element to the end of the array. * @brief Append an element to the end of the array.
@@ -109,8 +183,8 @@ void* dynamic_array_get_raw_data_pointer(const dynamic_array_struct* array);
* @param element Pointer to the element to append. * @param element Pointer to the element to append.
* @return true on success, false on allocation failure. * @return true on success, false on allocation failure.
*/ */
bool dynamic_array_append(dynamic_array_struct* array, bool
const void* element); dynamic_array_append(dynamic_array_struct* array, const void* element);
/** /**
* @brief Insert an element at the specified index. * @brief Insert an element at the specified index.
@@ -123,7 +197,8 @@ bool dynamic_array_append(dynamic_array_struct* array,
* @param element Pointer to the element to insert. * @param element Pointer to the element to insert.
* @return true on success, false if index is out of bounds or allocation fails. * @return true on success, false if index is out of bounds or allocation fails.
*/ */
bool dynamic_array_insert_at(dynamic_array_struct* array, bool
dynamic_array_insert_at(dynamic_array_struct* array,
size_t index, size_t index,
const void* element); const void* element);
@@ -135,7 +210,8 @@ bool dynamic_array_insert_at(dynamic_array_struct* array,
* @param new_element Pointer to the new element data. * @param new_element Pointer to the new element data.
* @return true on success, false if index is out of bounds. * @return true on success, false if index is out of bounds.
*/ */
bool dynamic_array_set_item(dynamic_array_struct* array, bool
dynamic_array_set_item(dynamic_array_struct* array,
size_t index, size_t index,
const void* new_element); const void* new_element);
@@ -147,7 +223,8 @@ bool dynamic_array_set_item(dynamic_array_struct* array,
* @param index_b Second index. * @param index_b Second index.
* @return true on success, false if either index is out of bounds. * @return true on success, false if either index is out of bounds.
*/ */
bool dynamic_array_swap(dynamic_array_struct* array, bool
dynamic_array_swap(dynamic_array_struct* array,
size_t index_a, size_t index_a,
size_t index_b); size_t index_b);
@@ -155,32 +232,38 @@ bool dynamic_array_swap(dynamic_array_struct* array,
* @brief Remove the last element from the array. * @brief Remove the last element from the array.
* *
* Decrements current_occupancy. Does not free the memory block. * Decrements current_occupancy. Does not free the memory block.
* If item_free is set, it will be called on the removed element.
* *
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @return true on success, false if array is empty. * @return true on success, false if array is empty.
*/ */
bool dynamic_array_pop(dynamic_array_struct* array); bool
dynamic_array_pop(dynamic_array_struct* array);
/** /**
* @brief Remove an element at the specified index. * @brief Remove an element at the specified index.
* *
* Shifts subsequent elements down to fill the gap. * Shifts subsequent elements down to fill the gap.
* If item_free is set, it will be called on the removed element.
* *
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @param index Index of the element to remove. * @param index Index of the element to remove.
* @return true on success, false if index is out of bounds. * @return true on success, false if index is out of bounds.
*/ */
bool dynamic_array_remove(dynamic_array_struct* array, bool
dynamic_array_remove(dynamic_array_struct* array,
size_t index); size_t index);
/** /**
* @brief Clear all elements from the array. * @brief Clear all elements from the array.
* *
* Sets current_occupancy to 0. Does not free the memory block. * Sets current_occupancy to 0. Does not free the memory block.
* If item_free is set, it will be called on all removed elements.
* *
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
*/ */
void dynamic_array_clear(dynamic_array_struct* array); void
dynamic_array_clear(dynamic_array_struct* array);
/** /**
* @brief Check if the array is empty. * @brief Check if the array is empty.
@@ -188,28 +271,18 @@ void dynamic_array_clear(dynamic_array_struct* array);
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @return true if current_occupancy is 0, false otherwise. * @return true if current_occupancy is 0, false otherwise.
*/ */
bool dynamic_array_is_empty(const dynamic_array_struct* array); bool
dynamic_array_is_empty(const dynamic_array_struct* array);
/** /**
* @brief Reserve additional capacity without changing size. * @brief Reserve additional capacity without changing elements.
* *
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @param new_capacity Desired capacity. * @param new_capacity Desired capacity.
* @return true on success, false on allocation failure. * @return true on success, false on allocation failure.
*/ */
bool dynamic_array_increase_capacity(dynamic_array_struct* array, bool
size_t new_capacity); dynamic_array_increase_capacity(dynamic_array_struct* array,
/**
* @brief Resize the array capacity to the specified value.
*
* Can grow or shrink the underlying allocation. Occupancy remains unchanged.
*
* @param array Pointer to the dynamic_array.
* @param new_capacity Desired capacity.
* @return true on success, false on allocation failure or if new_capacity < occupancy.
*/
bool dynamic_array_resize(dynamic_array_struct* array,
size_t new_capacity); size_t new_capacity);
/** /**
@@ -220,7 +293,8 @@ bool dynamic_array_resize(dynamic_array_struct* array,
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @return true on success, false on allocation failure. * @return true on success, false on allocation failure.
*/ */
bool dynamic_array_shrink_to_fit(dynamic_array_struct* array); bool
dynamic_array_shrink_to_fit(dynamic_array_struct* array);
/** /**
* @brief Increment the owner count for shared ownership. * @brief Increment the owner count for shared ownership.
@@ -228,7 +302,8 @@ bool dynamic_array_shrink_to_fit(dynamic_array_struct* array);
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @return true on success, false if owner_count would overflow. * @return true on success, false if owner_count would overflow.
*/ */
bool dynamic_array_acquire(dynamic_array_struct* array); bool
dynamic_array_acquire(dynamic_array_struct* array);
/** /**
* @brief Decrement the owner count for shared ownership. * @brief Decrement the owner count for shared ownership.
@@ -238,7 +313,8 @@ bool dynamic_array_acquire(dynamic_array_struct* array);
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @return true if owner_count > 0 after decrement, false if destroyed. * @return true if owner_count > 0 after decrement, false if destroyed.
*/ */
bool dynamic_array_release(dynamic_array_struct* array); bool
dynamic_array_release(dynamic_array_struct* array);
/** /**
* @brief Get the current owner count. * @brief Get the current owner count.
@@ -246,7 +322,8 @@ bool dynamic_array_release(dynamic_array_struct* array);
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @return Current owner_count value. * @return Current owner_count value.
*/ */
unsigned short dynamic_array_get_owner_count(const dynamic_array_struct* array); unsigned short
dynamic_array_get_owner_count(const dynamic_array_struct* array);
/** /**
* @brief Check if the array is thread-safe. * @brief Check if the array is thread-safe.
@@ -254,27 +331,71 @@ unsigned short dynamic_array_get_owner_count(const dynamic_array_struct* array);
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @return true if is_multithread_safe is set, false otherwise. * @return true if is_multithread_safe is set, false otherwise.
*/ */
bool dynamic_array_is_thread_safe(const dynamic_array_struct* array); bool
dynamic_array_is_thread_safe(const dynamic_array_struct* array);
/**
* @brief Creates a shallow copy of the array.
*
* The new array will have the same capacity and occupancy, but the elements
* themselves are not copied (pointers are copied).
*
* @param array_to_copy Pointer to the array being copied.
* @return Pointer to the new shallow copy, or NULL on failure.
*/
dynamic_array_struct*
dynamic_array_shallow_copy(const dynamic_array_struct* array_to_copy);
/** /**
* @brief Creates a deep copy of the array. * @brief Creates a deep copy of the array.
* *
* Uses the provided item_copy function to duplicate each element.
*
* @param array_to_copy Pointer to the array being copied. * @param array_to_copy Pointer to the array being copied.
* @param item_copy Function pointer to copy a single element.
* @return Pointer to the new deep copy, or NULL on failure. * @return Pointer to the new deep copy, or NULL on failure.
*/ */
dynamic_array_struct* dynamic_array_clone(const dynamic_array_struct* array_to_copy); dynamic_array_struct*
dynamic_array_deep_copy(const dynamic_array_struct* array_to_copy,
void* (*item_copy)(const void* item));
/** /**
* @brief Creates a deep copy of a slice of an array. * @brief Creates a shallow copy of a slice of an array.
* *
* @param array_to_copy Pointer to the array being copied/sliced. * @param array_to_copy Pointer to the array being copied/sliced.
* @param starting_point Index to start the slice at. * @param starting_point Index to start the slice at.
* @param ending_point Index to end the slice at. * @param ending_point Index to end the slice at.
* @param is_start_inclusive Boolean indicator of if the starting index should be included. * @param is_start_inclusive Boolean indicator of if the starting index should
* @param is_end_inclusive Boolean indicator of if the ending index should be included. * be included.
* @param is_end_inclusive Boolean indicator of if the ending index should
* be included.
* @return Pointer to the new shallow copy of the slice, or NULL on failure.
*/
dynamic_array_struct*
dynamic_array_shallow_copy_slice(const dynamic_array_struct* array_to_copy,
size_t starting_point,
size_t ending_point,
bool is_start_inclusive,
bool is_end_inclusive);
/**
* @brief Creates a deep copy of a slice of an array.
*
* Uses the provided item_copy function to duplicate each element in the slice.
*
* @param array_to_copy Pointer to the array being copied/sliced.
* @param item_copy Function pointer to copy a single element.
* @param starting_point Index to start the slice at.
* @param ending_point Index to end the slice at.
* @param is_start_inclusive Boolean indicator of if the starting index should
* be included.
* @param is_end_inclusive Boolean indicator of if the ending index should
* be included.
* @return Pointer to the new deep copy of the slice, or NULL on failure. * @return Pointer to the new deep copy of the slice, or NULL on failure.
*/ */
dynamic_array_struct* dynamic_array_clone_slice(const dynamic_array_struct* array_to_copy, dynamic_array_struct*
dynamic_array_deep_copy_slice(const dynamic_array_struct* array_to_copy,
void* (*item_copy)(const void* item),
size_t starting_point, size_t starting_point,
size_t ending_point, size_t ending_point,
bool is_start_inclusive, bool is_start_inclusive,
@@ -286,7 +407,8 @@ dynamic_array_struct* dynamic_array_clone_slice(const dynamic_array_struct* arra
* @param array_to_sort Pointer to the array to be sorted. * @param array_to_sort Pointer to the array to be sorted.
* @param should_reverse_sort If true, inverts the order of the array. * @param should_reverse_sort If true, inverts the order of the array.
*/ */
void dynamic_array_sort_in_place(dynamic_array_struct* array_to_sort, void
dynamic_array_sort_in_place(dynamic_array_struct* array_to_sort,
bool should_reverse_sort); bool should_reverse_sort);
/** /**
@@ -295,11 +417,14 @@ void dynamic_array_sort_in_place(dynamic_array_struct* array_to_sort,
* @param array_to_sort Pointer to the array to be sorted. * @param array_to_sort Pointer to the array to be sorted.
* @param starting_point Index to start the slice at. * @param starting_point Index to start the slice at.
* @param ending_point Index to end the slice at. * @param ending_point Index to end the slice at.
* @param is_start_inclusive Boolean indicator of if the starting index should be included. * @param is_start_inclusive Boolean indicator of if the starting index should
* @param is_end_inclusive Boolean indicator of if the ending index should be included. * be included.
* @param is_end_inclusive Boolean indicator of if the ending index should
* be included.
* @param should_reverse_sort If true, inverts the order of the slice. * @param should_reverse_sort If true, inverts the order of the slice.
*/ */
void dynamic_array_sort_slice(dynamic_array_struct* array_to_sort, void
dynamic_array_sort_slice(dynamic_array_struct* array_to_sort,
size_t starting_point, size_t starting_point,
size_t ending_point, size_t ending_point,
bool is_start_inclusive, bool is_start_inclusive,
@@ -307,13 +432,14 @@ void dynamic_array_sort_slice(dynamic_array_struct* array_to_sort,
bool should_reverse_sort); bool should_reverse_sort);
/** /**
* @brief Creates a new sorted copy of the array without modifying the original. * @brief Creates a new sorted shallow copy of the array without modifying the original.
* *
* @param array_to_sort Pointer to the array to be sorted. * @param array_to_sort Pointer to the array to be sorted.
* @param should_reverse_sort If true, inverts the order of the copy. * @param should_reverse_sort If true, inverts the order of the copy.
* @return Pointer to the new sorted array, or NULL on failure. * @return Pointer to the new sorted array, or NULL on failure.
*/ */
dynamic_array_struct* dynamic_array_get_sorted_copy(dynamic_array_struct* array_to_sort, dynamic_array_struct*
dynamic_array_get_sorted_copy(const dynamic_array_struct* array,
bool should_reverse_sort); bool should_reverse_sort);
/** /**
@@ -321,7 +447,8 @@ dynamic_array_struct* dynamic_array_get_sorted_copy(dynamic_array_struct* array_
* *
* @param array_to_reverse Pointer to the array to be reversed. * @param array_to_reverse Pointer to the array to be reversed.
*/ */
void dynamic_array_reverse(dynamic_array_struct* array_to_reverse); void
dynamic_array_reverse(dynamic_array_struct* array_to_reverse);
/** /**
* @brief Check if the array contains a specific value. * @brief Check if the array contains a specific value.
@@ -332,8 +459,9 @@ void dynamic_array_reverse(dynamic_array_struct* array_to_reverse);
* @param pointer_of_value_to_find Pointer to the value to find. * @param pointer_of_value_to_find Pointer to the value to find.
* @return true if the value is found, false otherwise. * @return true if the value is found, false otherwise.
*/ */
bool dynamic_array_contains(dynamic_array_struct* array_to_search, bool
void* pointer_of_value_to_find); dynamic_array_contains(const dynamic_array_struct* array_to_search,
const void* pointer_of_value_to_find);
/** /**
* @brief Find the first index of a value in the array. * @brief Find the first index of a value in the array.
@@ -344,8 +472,9 @@ bool dynamic_array_contains(dynamic_array_struct* array_to_search,
* @param pointer_of_value_to_find Pointer to the value to find. * @param pointer_of_value_to_find Pointer to the value to find.
* @return Index of the first occurrence, or SIZE_MAX if not found. * @return Index of the first occurrence, or SIZE_MAX if not found.
*/ */
size_t dynamic_array_find_first_index_of(dynamic_array_struct* array_to_search, size_t
void* pointer_of_value_to_find); dynamic_array_find_first_index_of(const dynamic_array_struct* array_to_search,
const void* pointer_of_value_to_find);
/** /**
* @brief Find the last index of a value in the array. * @brief Find the last index of a value in the array.
@@ -356,8 +485,9 @@ size_t dynamic_array_find_first_index_of(dynamic_array_struct* array_to_search,
* @param pointer_of_value_to_find Pointer to the value to find. * @param pointer_of_value_to_find Pointer to the value to find.
* @return Index of the last occurrence, or SIZE_MAX if not found. * @return Index of the last occurrence, or SIZE_MAX if not found.
*/ */
size_t dynamic_array_find_final_index_of(dynamic_array_struct* array_to_search, size_t
void* pointer_of_value_to_find); dynamic_array_find_final_index_of(const dynamic_array_struct* array_to_search,
const void* pointer_of_value_to_find);
/** /**
* @brief Set or change the comparator function used for sorting and searching. * @brief Set or change the comparator function used for sorting and searching.
@@ -365,22 +495,100 @@ size_t dynamic_array_find_final_index_of(dynamic_array_struct* array_to_search,
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @param comparator Function to compare two elements. * @param comparator Function to compare two elements.
*/ */
void dynamic_array_set_comparator_function(dynamic_array_struct* array, void
dynamic_array_set_comparator_function(dynamic_array_struct *array,
int (*comparator)(const void*, const void*)); int (*comparator)(const void*, const void*));
/** /**
* @brief Copies the element at the specified index into a user-provided buffer. * @brief Copies the element at the specified index into a user-provided buffer.
* *
* Performs bounds checking and uses memcpy to safely extract the element's data. * Performs bounds checking and uses memcpy to safely extract the element's
* Useful when you need a standalone copy of an element rather than a temporary pointer. * data. Useful when you need a standalone copy of an element rather than a
* temporary pointer.
* *
* @param array Pointer to the dynamic_array. * @param array Pointer to the dynamic_array.
* @param index Index of the element to retrieve. * @param index Index of the element to retrieve.
* @param out_buffer Pointer to a buffer large enough to hold one element (at least item_size bytes). * @param out_buffer Pointer to a buffer large enough to hold one element (at
* @return true on success, false if index is out of bounds or out_buffer is NULL. * least item_size bytes).
* @return true on success, false if index is out of bounds or out_buffer is
* NULL.
*/ */
bool dynamic_array_get_item(const dynamic_array_struct* array, bool
dynamic_array_get_item(const dynamic_array_struct* array,
size_t index, size_t index,
void* out_buffer); void* out_buffer);
/**
* @brief Iterates over a specific range of the array.
*
* Calls the callback function for each element in the specified range.
*
* @param array Pointer to the dynamic_array.
* @param callback Function to call for each element.
* @param starting_index Index to start iteration from.
* @param ending_index Index to end iteration at.
* @param is_start_inclusive If true, includes the starting_index in iteration.
* @param is_end_inclusive If true, includes the ending_index in iteration.
*/
void
dynamic_array_iterate_over(dynamic_array_struct* array,
void (*callback)(void* element, void* user_data),
size_t starting_index,
size_t ending_index,
bool is_start_inclusive,
bool is_end_inclusive);
/**
* @brief Iterates over every element in the array.
*
* Calls the callback function for each element in the array.
*
* @param array Pointer to the dynamic_array.
* @param callback Function to call for each element.
*/
void
dynamic_array_foreach(dynamic_array_struct* array,
void (*callback)(void* element, void* user_data));
/**
* @brief Performs a binary search on the array.
*
* If the array is not marked as sorted, a temporary sorted copy is created.
* For repeated searches on unsorted data, sort the array in-place first for
* better performance.
*
* @param array Pointer to the dynamic_array.
* @param value Pointer to the value to search for.
* @return Index of the element if found, or SIZE_MAX if not found.
*/
size_t
dynamic_array_binary_search(const dynamic_array_struct* array,
const void* value);
#ifdef MARIGOLD_DEBUG
/**
* @brief Prints debug statistics about the array to stdout.
*
* @param array Pointer to the dynamic_array.
*/
void dynamic_array_debug_print_stats(const dynamic_array_struct* array);
/**
* @brief Dumps the contents of the array to stdout.
*
* @param array Pointer to the dynamic_array.
*/
void dynamic_array_debug_dump_array(const dynamic_array_struct* array);
/**
* @brief Validates the internal integrity of the array.
*
* Checks for consistency in capacity, occupancy, and pointers.
*
* @param array Pointer to the dynamic_array.
* @return true if the array is valid, false otherwise.
*/
bool dynamic_array_validate_integrity(const dynamic_array_struct* array);
#endif /* MARIGOLD_DEBUG */
#endif /* MARIGOLD_DYNAMIC_ARRAY_H */ #endif /* MARIGOLD_DYNAMIC_ARRAY_H */