more functions implemented, and updated LICENSES

This commit is contained in:
2026-05-28 18:23:10 -05:00
parent df76edc97a
commit e142468c81
5 changed files with 238 additions and 16 deletions

View File

@@ -0,0 +1,9 @@
#ifndef INTERNAL_MARIGOLD_MACROS_H
#define INTERNAL_MARIGOLD_MACROS_H
#define SINGLE_ELEMENT 1
#define INDEX_ZERO 0
#define BIT_FALSE 0
#define EMPTY 0
#endif /* INTERNAL_MARIGOLD_MACROS_H */

View File

@@ -1,5 +1,7 @@
#include "marigold_vector.h"
#include "internal/internal_marigold_macros.h"
#include <pthread.h>
#include <stdio.h>
#include <string.h>
@@ -11,7 +13,8 @@ vector_create(size_t item_size,
void (*item_free)(const void *),
bool is_multithread_safe)
{
vector_struct* new_vector = calloc(1, sizeof(vector_struct));
vector_struct* new_vector = calloc(SINGLE_ELEMENT,
sizeof(vector_struct));
if (!new_vector)
{
@@ -55,7 +58,7 @@ bool
vector_get_flag_value(const vector_struct* vector,
vector_flag_enum flag)
{
if ((vector->flags & flag) != 0) // Checks if the existing bit is equal to 1.
if ((vector->flags & flag) != BIT_FALSE)
{
return true;
}
@@ -112,7 +115,7 @@ vector_append(vector_struct* vector,
if (!vector_grow(vector))
{ /* failed to grow vector (probably out of memory)*/
if (is_thread_safe)
{ /* unlocking mutex during fail case if it is locked. */
{ /* unlocking mutex during fail case (if it is locked.) */
pthread_mutex_unlock(vector->mutex_lock);
}
return false; /* returns false to show append failed. */
@@ -143,15 +146,87 @@ vector_insert_at(vector_struct* vector,
pthread_mutex_lock(vector->mutex_lock);
}
if (index > vector->current_occupancy)
{ /* index out of bounds for insertion. */
if (is_thread_safe)
{ /* unlocking mutex during fail case (if it is locked.) */
pthread_mutex_unlock(vector->mutex_lock);
}
return false; /* returns false to show insert failed. */
}
if (vector->current_occupancy == vector->current_capacity)
{
if (!vector_grow(vector))
{ /* failed to grow vector (probably out of memory). */
if (is_thread_safe)
{ /* unlocking mutex during fail case (if it is locked.) */
pthread_mutex_unlock(vector->mutex_lock);
}
return false; /* returns false to show insert failed. */
}
}
char* data = (char*)vector->data_pointer;
const size_t element_size = vector->item_size;
const size_t bytes_to_shift = (vector->current_occupancy - index) * element_size;
const size_t shift_offset = index * element_size;
if (bytes_to_shift > INDEX_ZERO)
{
memmove(data + shift_offset + element_size,
data + shift_offset,
bytes_to_shift);
}
memcpy(data + shift_offset, element, element_size);
vector->current_occupancy++;
if (is_thread_safe)
{ /* unlocking mutex post vector modification if it exists/is locked. */
pthread_mutex_unlock(vector->mutex_lock);
}
return true; /* returns true to show insert success. */
}
bool
vector_set_item(vector_struct* vector,
size_t index,
size_t index_to_set,
const void* new_element)
{
const bool is_thread_safe = vector_is_thread_safe(vector);
if (is_thread_safe)
{ /* if thread safe enabled, locking before vector modification. */
pthread_mutex_lock(vector->mutex_lock);
}
if (index_to_set >= vector->current_occupancy)
{ /* index out of bounds for setting. */
if (is_thread_safe)
{ /* unlocking mutex during fail case if it is locked. */
pthread_mutex_unlock(vector->mutex_lock);
}
return false; /* failed, cannot set a value outside of current values. */
}
char* data = (char*)vector->data_pointer;
const size_t element_size = vector->item_size;
const size_t offset = index_to_set * element_size;
if (vector->item_free != NULL)
{ /* free the old element if item_free callback is set. */
vector->item_free(data + offset);
}
memcpy(data + offset, new_element, element_size);
if (is_thread_safe)
{ /* unlocking mutex post vector modification if it exists/is locked. */
pthread_mutex_unlock(vector->mutex_lock);
}
return true; /* returns true to show set success. */
}
bool
@@ -159,32 +234,137 @@ vector_swap(vector_struct* vector,
size_t index_a,
size_t index_b)
{
const bool is_thread_safe = vector_is_thread_safe(vector);
if (is_thread_safe)
{ /* if thread safe enabled, locking before vector modification. */
pthread_mutex_lock(vector->mutex_lock);
}
}
if (index_a >= vector->current_occupancy || index_b >= vector->current_occupancy)
{ /* index out of bounds for swapping. */
if (is_thread_safe)
{ /* unlocking mutex during fail case if it is locked. */
pthread_mutex_unlock(vector->mutex_lock);
}
return false; /* returns false to show swap failed. */
}
bool
vector_pop(vector_struct* vector)
{
if (index_a == index_b)
{ /* same index, nothing to swap. */
if (is_thread_safe)
{ /* unlocking mutex post vector modification if it exists/is locked. */
pthread_mutex_unlock(vector->mutex_lock);
}
return true; /* returns true to show swap success. */
}
char* data = (char*)vector->data_pointer;
const size_t element_size = vector->item_size;
const size_t offset_a = index_a * element_size;
const size_t offset_b = index_b * element_size;
void* temp = malloc(element_size);
if (!temp)
{ /* failed to allocate temporary buffer. */
if (is_thread_safe)
{ /* unlocking mutex during fail case if it is locked. */
pthread_mutex_unlock(vector->mutex_lock);
}
return false; /* returns false to show swap failed. */
}
memcpy(temp, data + offset_a, element_size);
memcpy(data + offset_a, data + offset_b, element_size);
memcpy(data + offset_b, temp, element_size);
free(temp);
if (is_thread_safe)
{ /* unlocking mutex post vector modification if it exists/is locked. */
pthread_mutex_unlock(vector->mutex_lock);
}
return true; /* returns true to show swap success. */
}
bool
vector_remove(vector_struct* vector,
size_t index)
{
const bool is_thread_safe = vector_is_thread_safe(vector);
if (is_thread_safe)
{ /* if thread safe enabled, locking before vector modification. */
pthread_mutex_lock(vector->mutex_lock);
}
if (index >= vector->current_occupancy)
{ /* index out of bounds for removal. */
if (is_thread_safe)
{ /* unlocking mutex during fail case if it is locked. */
pthread_mutex_unlock(vector->mutex_lock);
}
return false; /* returns false to show remove failed. */
}
char* data = (char*)vector->data_pointer;
const size_t element_size = vector->item_size;
const size_t offset = index * element_size;
const size_t bytes_to_shift = (vector->current_occupancy - index - 1) * element_size;
if (vector->item_free != NULL)
{ /* free the removed element if item_free callback is set. */
vector->item_free(data + offset);
}
if (bytes_to_shift > INDEX_ZERO)
{
memmove(data + offset,
data + offset + element_size,
bytes_to_shift);
}
vector->current_occupancy--;
if (is_thread_safe)
{ /* unlocking mutex post vector modification if it exists/is locked. */
pthread_mutex_unlock(vector->mutex_lock);
}
return true; /* returns true to show remove success. */
}
void
vector_clear(vector_struct* vector)
{
const bool is_thread_safe = vector_is_thread_safe(vector);
if (is_thread_safe)
{ /* if thread safe enabled, locking before vector modification. */
pthread_mutex_lock(vector->mutex_lock);
}
if (vector->item_free != NULL)
{ /* free all elements if item_free callback is set. */
char* data = (char*)vector->data_pointer;
const size_t element_size = vector->item_size;
for (size_t i = 0; i < vector->current_occupancy; i++)
{
vector->item_free(data + (i * element_size));
}
}
vector->current_occupancy = 0;
if (is_thread_safe)
{ /* unlocking mutex post vector modification if it exists/is locked. */
pthread_mutex_unlock(vector->mutex_lock);
}
}
bool
vector_is_empty(const vector_struct* vector)
{
if (vector->current_occupancy == 0)
if (vector->current_occupancy == EMPTY)
{
return true;
}
@@ -228,7 +408,7 @@ vector_get_owner_count(const vector_struct* vector)
bool
vector_is_thread_safe(const vector_struct* vector)
{
if ((vector->flags & vector_multithread_safe) != 0)
if ((vector->flags & vector_multithread_safe) != FALSE)
{
return true;
}

View File

@@ -153,13 +153,13 @@ vector_insert_at(vector_struct* vector,
* @brief Replace the element at the specified index.
*
* @param vector Pointer to the vector.
* @param index Index of the element to replace.
* @param index_to_set Index of the element to replace.
* @param new_element Pointer to the new element data.
* @return true on success, false if index is out of bounds.
*/
bool
vector_set_item(vector_struct* vector,
size_t index,
size_t index_to_set,
const void* new_element);
/**