#include 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; }