Graph
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
#include <c_UIntArray.h>
|
||||
|
||||
c_err_t c_UIntArray_Init(c_UIntArray_t* self, c_size_t capacity, c_Allocator_t* allocator) {
|
||||
if (!self ) return C_ERR_PARAM;
|
||||
self->allocator = (allocator!=NULL)?*allocator:c_DefaultAllocator;
|
||||
self->capacity = capacity;
|
||||
self->size = 0;
|
||||
if (capacity > 0) {
|
||||
self->array = c_Allocator_Alloc(&self->allocator, self->capacity * sizeof(*self->array));
|
||||
if (!self->array) {
|
||||
self->capacity = 0;
|
||||
return C_ERR_NOMEM;
|
||||
}
|
||||
}else {
|
||||
self->array = NULL;
|
||||
}
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
void c_UIntArray_Destroy(c_UIntArray_t* self) {
|
||||
if (!self) return;
|
||||
if (self->array && self->allocator.free) {
|
||||
c_Allocator_Free(&self->allocator, self->array);
|
||||
self->array = NULL;
|
||||
}
|
||||
self->size = 0;
|
||||
self->capacity = 0;
|
||||
}
|
||||
|
||||
c_err_t c_UIntArray_Resize(c_UIntArray_t* self, c_size_t new_capacity) {
|
||||
if (!self) return C_ERR_PARAM;
|
||||
if (new_capacity == self->capacity) return C_ERR_OK;
|
||||
|
||||
// Boundary contract protection: Cap cannot compress below active item footprints
|
||||
if (new_capacity < self->size) return C_ERR_PARAM;
|
||||
|
||||
if (new_capacity == 0) {
|
||||
if (self->array) {
|
||||
c_Allocator_Free(&self->allocator, self->array);
|
||||
self->array = NULL;
|
||||
}
|
||||
self->capacity = 0;
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
c_uint_t* new_ptr = NULL;
|
||||
if (self->array) {
|
||||
c_size_t old_size = self->capacity * sizeof(*self->array);
|
||||
c_size_t new_size = new_capacity * sizeof(*self->array);
|
||||
|
||||
new_ptr = c_Allocator_Realloc(&self->allocator, self->array, old_size, new_size);
|
||||
} else {
|
||||
new_ptr = c_Allocator_Alloc(&self->allocator, new_capacity * sizeof(*self->array));
|
||||
}
|
||||
|
||||
if (!new_ptr) return C_ERR_NOMEM;
|
||||
|
||||
self->array = new_ptr;
|
||||
self->capacity = new_capacity;
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
c_err_t c_UIntArray_Append(c_UIntArray_t* self, c_uint_t value) {
|
||||
if (!self) return C_ERR_PARAM;
|
||||
|
||||
// Geometric resizing policy (doubling capacity on saturation)
|
||||
if (self->size >= self->capacity) {
|
||||
c_size_t next_cap = (self->capacity == 0) ? 4 : (self->capacity << 1);
|
||||
c_err_t err = c_UIntArray_Resize(self, next_cap);
|
||||
if (err != C_ERR_OK) return err;
|
||||
}
|
||||
|
||||
self->array[self->size++] = value;
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
c_err_t c_UIntArray_Set(c_UIntArray_t* self, c_size_t index, c_uint_t value) {
|
||||
if (!self || index >= self->size) return C_ERR_PARAM;
|
||||
|
||||
self->array[index] = value;
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
c_err_t c_UIntArray_Get(c_UIntArray_t* self, c_size_t index, c_uint_t* value) {
|
||||
if (!self || !value || index >= self->size) return C_ERR_PARAM;
|
||||
if (value) {
|
||||
*value = self->array[index];
|
||||
}
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
c_err_t c_UIntArray_Remove(c_UIntArray_t* self, c_size_t index) {
|
||||
if (!self || index >= self->size) return C_ERR_PARAM;
|
||||
|
||||
c_size_t elements_to_move = self->size - index - 1;
|
||||
if (elements_to_move > 0) {
|
||||
memmove(&self->array[index], &self->array[index + 1], elements_to_move * sizeof(c_uint_t));
|
||||
}
|
||||
|
||||
self->size--;
|
||||
|
||||
if (self->size <= (self->capacity>>2)) {
|
||||
return c_UIntArray_Resize(self, self->capacity >> 1);
|
||||
}
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
c_err_t c_UIntArray_Copy(c_UIntArray_t* dest, c_UIntArray_t* src) {
|
||||
if (!dest || !src) return C_ERR_PARAM;
|
||||
if (dest == src) return C_SUCCESS; /* Self-copy protection */
|
||||
|
||||
c_size_t src_size = (c_size_t)c_UIntArray_GetSize(src);
|
||||
|
||||
/* 1. If the source is empty, simply reset the destination size to 0 */
|
||||
if (src_size == 0) {
|
||||
/* Assuming your array has a fast Clear or Resize capability to clear bounds */
|
||||
dest->size = 0;
|
||||
return C_SUCCESS;
|
||||
}
|
||||
|
||||
c_size_t new_bytes = src_size * sizeof(c_uint_t);
|
||||
|
||||
/* 2. Check if the destination has enough capacity. If not, resize it. */
|
||||
if (dest->capacity < src_size) {
|
||||
/* Calculate how many bytes are needed */
|
||||
c_size_t old_bytes = dest->capacity * sizeof(c_uint_t);
|
||||
|
||||
/* Reallocate memory via the destination's assigned allocator */
|
||||
c_uint_t* new_data = (c_uint_t*)c_Allocator_Realloc(&dest->allocator, dest->array, old_bytes, new_bytes);
|
||||
if (!new_data) return C_ERR_NOMEM;
|
||||
|
||||
dest->array = new_data;
|
||||
dest->capacity = src_size;
|
||||
}
|
||||
|
||||
/* 3. Execute high-speed raw memory block cloning */
|
||||
memcpy(dest->array, src->array, new_bytes);
|
||||
dest->size = src_size;
|
||||
|
||||
return C_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef INCLUDED_C_UINTARRAY_H
|
||||
#define INCLUDED_C_UINTARRAY_H
|
||||
|
||||
#ifndef INCLUDED_C_TYPES_H
|
||||
#include <c_Types.h>
|
||||
#endif /*INCLUDED_C_TYPES_H*/
|
||||
|
||||
#ifndef INCLUDED_C_ALLOCATOR_H
|
||||
#include <c_Allocator.h>
|
||||
#endif /*INCLUDED_C_ALLOCATOR_H*/
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
typedef struct {
|
||||
c_uint_t* array;
|
||||
c_size_t capacity;
|
||||
c_size_t size;
|
||||
c_Allocator_t allocator;
|
||||
}c_UIntArray_t;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
c_err_t c_UIntArray_Init(c_UIntArray_t* self, c_size_t capacity, c_Allocator_t* allocator);
|
||||
|
||||
void c_UIntArray_Destroy(c_UIntArray_t* self);
|
||||
|
||||
c_err_t c_UIntArray_Resize(c_UIntArray_t* self, c_size_t new_capacity);
|
||||
|
||||
c_err_t c_UIntArray_Append(c_UIntArray_t* self, c_uint_t value);
|
||||
|
||||
c_err_t c_UIntArray_Set(c_UIntArray_t* self, c_size_t index, c_uint_t value);
|
||||
|
||||
c_err_t c_UIntArray_Get(c_UIntArray_t* self, c_size_t index, c_uint_t* value);
|
||||
|
||||
c_err_t c_UIntArray_Remove(c_UIntArray_t* self, c_size_t index);
|
||||
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_bool_t c_UIntArray_IsEmpty(c_UIntArray_t* self) {
|
||||
if (!self) return C_TRUE;
|
||||
return self->size==0;
|
||||
}
|
||||
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_size_t c_UIntArray_GetSize(c_UIntArray_t* self) {
|
||||
if (!self) return 0;
|
||||
return self->size;
|
||||
}
|
||||
|
||||
c_err_t c_UIntArray_Copy(c_UIntArray_t* dest, c_UIntArray_t* src);
|
||||
|
||||
#endif /*INCLUDED_C_UINTARRAY_H*/
|
||||
Reference in New Issue
Block a user