#include c_err_t c_AdjList_Init(c_AdjList_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_AdjList_Destroy(c_AdjList_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_AdjList_Resize(c_AdjList_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_AdjList_Append(c_AdjList_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_AdjList_Resize(self, next_cap); if (err != C_ERR_OK) return err; } self->array[self->size++] = value; return C_ERR_OK; } c_err_t c_AdjList_Set(c_AdjList_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_AdjList_Get(c_AdjList_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_AdjList_Remove(c_AdjList_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_AdjList_Resize(self, self->capacity >> 1); } return C_ERR_OK; }