112 lines
3.7 KiB
C
112 lines
3.7 KiB
C
#include "arc/std/vector.h"
|
|
|
|
#include "arc/std/errno.h"
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
struct ARC_Vector {
|
|
uint32_t *currentSize, *capacity;
|
|
uint32_t *dataSize;
|
|
void *data;
|
|
};
|
|
|
|
void ARC_Vector_Create(ARC_Vector **vector, uint32_t dataSize){
|
|
*vector = (ARC_Vector *) malloc(sizeof(ARC_Vector));
|
|
(*vector)->currentSize = (uint32_t *)malloc(sizeof(uint32_t));
|
|
(*vector)->capacity = (uint32_t *)malloc(sizeof(uint32_t));
|
|
(*vector)->dataSize = (uint32_t *)malloc(sizeof(uint32_t));
|
|
(*vector)->data = (void *)malloc(dataSize);
|
|
|
|
*(*vector)->currentSize = 0;
|
|
*(*vector)->capacity = 1;
|
|
*(*vector)->dataSize = dataSize;
|
|
}
|
|
|
|
void ARC_Vector_Destroy(ARC_Vector *vector){
|
|
free(vector->currentSize);
|
|
free(vector->capacity);
|
|
free(vector->data);
|
|
free(vector->dataSize);
|
|
free(vector);
|
|
}
|
|
|
|
void ARC_Vector_Add(ARC_Vector *vector, void *data){
|
|
if(*vector->currentSize == ~((uint32_t)0)){
|
|
arc_errno = ARC_ERRNO_OVERFLOW;
|
|
return;
|
|
}
|
|
|
|
if(*vector->currentSize == *vector->capacity){
|
|
if(!*vector->capacity){
|
|
++*vector->capacity;
|
|
}
|
|
*vector->capacity <<= 1;
|
|
|
|
vector->data = (void *)realloc(vector->data, *vector->dataSize * *vector->capacity);
|
|
}
|
|
|
|
memcpy(vector->data + (*vector->currentSize * *vector->dataSize), data, *vector->dataSize);
|
|
++*(vector->currentSize);
|
|
}
|
|
|
|
void ARC_Vector_Remove(ARC_Vector *vector, void *data, ARC_Vector_CompareDataFn compare){
|
|
if(!*vector->currentSize){
|
|
arc_errno = ARC_ERRNO_DATA;
|
|
return;
|
|
}
|
|
|
|
--*(vector->currentSize);
|
|
|
|
if(*vector->currentSize != *vector->capacity >> 1){
|
|
for(uint32_t i = 0; i <= *vector->currentSize; i++){
|
|
if(!compare(data, vector->data + (i * *vector->dataSize))){
|
|
memcpy(vector->data + (i * *vector->dataSize), vector->data + ((i + 1) * *vector->dataSize), *(vector->currentSize - i) * *vector->dataSize);
|
|
return;
|
|
}
|
|
}
|
|
|
|
arc_errno = ARC_ERRNO_DATA;
|
|
return;
|
|
}
|
|
|
|
*vector->capacity >>= 1;
|
|
void *temp = (void *) malloc(*vector->dataSize * *vector->capacity);
|
|
|
|
for(uint32_t i = 0; i <= *vector->currentSize; i++){
|
|
if(compare(data, vector->data + (i * *vector->dataSize))){
|
|
memcpy(temp, vector->data, i * *vector->dataSize);
|
|
memcpy(temp + (i * *vector->dataSize), vector->data + ((i + 1) * *vector->dataSize), *(vector->currentSize - i) * *vector->dataSize);
|
|
free(vector->data);
|
|
vector->data = temp;
|
|
return;
|
|
}
|
|
}
|
|
|
|
arc_errno = ARC_ERRNO_DATA;
|
|
}
|
|
|
|
void ARC_Vector_RemoveIndex(ARC_Vector *vector, uint32_t *index){
|
|
if(!*vector->currentSize || *index >= *vector->currentSize){
|
|
arc_errno = ARC_ERRNO_DATA;
|
|
return;
|
|
}
|
|
|
|
--*vector->currentSize;
|
|
if(*vector->currentSize != *vector->capacity >> 1){
|
|
memcpy(vector->data + (*index * *vector->dataSize), vector->data + ((*index + 1) * *vector->dataSize), *(vector->currentSize - *index) * *vector->dataSize);
|
|
return;
|
|
}
|
|
|
|
*vector->capacity >>= 1;
|
|
void **temp = (void **)malloc(sizeof(void *) * (*(vector->capacity)));
|
|
memcpy(temp, vector->data, *index * *vector->dataSize);
|
|
memcpy(temp + (*index * *vector->dataSize), vector->data + ((*index + 1) * *vector->dataSize), *(vector->currentSize - *index) * *vector->dataSize);
|
|
|
|
free(vector->data);
|
|
vector->data = temp;
|
|
}
|
|
|
|
uint32_t *ARC_Vector_Size(ARC_Vector *vector){ return vector->currentSize; }
|
|
|
|
void *ARC_Vector_Get(ARC_Vector *vector, uint32_t *index){ return (void *)(uint8_t (*)[*vector->dataSize]) vector->data + (*index * *vector->dataSize); }
|