updated vector to video version, will probably break a lot

This commit is contained in:
herbglitch 2024-08-27 03:23:29 -06:00
parent c1e60a6d2f
commit 93dc0fa053
12 changed files with 461 additions and 97 deletions

View file

@ -1,105 +1,131 @@
#include "arc/std/vector.h"
#include "arc/std/bool.h"
#include "arc/std/errno.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
struct ARC_Vector {
uint32_t currentSize, capacity;
uint32_t currentCapacity;
uint32_t currentSize;
void **data;
ARC_Vector_CompareDataFn compareDataFn;
};
void ARC_Vector_Create(ARC_Vector **vector){
*vector = (ARC_Vector *) malloc(sizeof(ARC_Vector));
(*vector)->currentSize = 0;
(*vector)->capacity = 1;
(*vector)->data = (void **)malloc(sizeof(void *));
//this is a private function used as the default check for removing data from a given pointer
ARC_Bool ARC_Vector_CompareDataDefaultFn(void *dataA, void *dataB){
if(dataA == dataB){
return ARC_True;
}
return ARC_False;
}
void ARC_Vector_Create(ARC_Vector **vector, ARC_Vector_CompareDataFn *compareDataFn){
//create the vector
*vector = (ARC_Vector *)malloc(sizeof(ARC_Vector));
//initialize all the values stored in the vector
(*vector)->data = (void **)malloc(sizeof(void *));
(*vector)->currentCapacity = 1;
(*vector)->currentSize = 0;
//set a default for compareDataFn, then override it if it is passed in through parameters
(*vector)->compareDataFn = ARC_Vector_CompareDataDefaultFn;
if(compareDataFn != NULL){
(*vector)->compareDataFn = *compareDataFn;
}
}
void ARC_Vector_Destroy(ARC_Vector *vector){
//free everything stored in the vector
free(vector->data);
//free the vector
free(vector);
}
void ARC_Vector_Add(ARC_Vector *vector, void *data){
//check to see if the current size is the same as a max uint32_t and if so it will overflow so throw an error
if(vector->currentSize == ~((uint32_t)0)){
arc_errno = ARC_ERRNO_OVERFLOW;
ARC_DEBUG_LOG_ERROR("ARC_Vector_Add(vector, data), vector at max capacity tried adding another value");
return;
}
if(vector->currentSize == vector->capacity){
if(!vector->capacity){
++vector->capacity;
}
vector->capacity <<= 1;
//check if we are at the max of the current capacity
if(vector->currentSize == vector->currentCapacity){
//increase the current capacity by double
vector->currentCapacity <<= 1;
vector->data = (void *)realloc(vector->data, sizeof(void *) * vector->capacity);
//if for some reason the capacity is 0, we should set it to one so we do not error on realloc
if(vector->currentCapacity != 0){
vector->currentCapacity++;
}
//resize the vectors array and copy the contents at the same time
vector->data = (void **)realloc(vector->data, sizeof(void *) * vector->currentCapacity);
}
//add to the vectors array and increase its current size
vector->data[vector->currentSize] = data;
++(vector->currentSize);
vector->currentSize++;
}
//this function removes the redundant checking currentSize and index that would happen if ARC_Vector_Remove called ARC_Vector_RemoveIndex
void ARC_Vector_RemoveIndexNoCheck(ARC_Vector *vector, uint32_t index);
void ARC_Vector_Remove(ARC_Vector *vector, void *data){
//iterate through every item to check to see if it exists
for(uint32_t index = 0; index < vector->currentSize; index++){
//keep the code cleaner by pulling the current index data into a temp variable
void *dataB = vector->data[index];
void ARC_Vector_Remove(ARC_Vector *vector, void *data, ARC_Vector_CompareDataFn compare){
if(!vector->currentSize){
arc_errno = ARC_ERRNO_DATA;
return;
}
for(uint32_t i = 0; i < vector->currentSize; i++){
if(!compare(data, vector->data[i])){
ARC_Vector_RemoveIndexNoCheck(vector, i);
return;
//check if the data matches, and if so remove by index
if(vector->compareDataFn(data, dataB) == ARC_True){
ARC_Vector_RemoveIndex(vector, index);
}
}
//no matching data found in compare function
arc_errno = ARC_ERRNO_DATA;
}
void ARC_Vector_RemoveIndex(ARC_Vector *vector, uint32_t index){
if(!vector->currentSize || index >= vector->currentSize){
//check to make sure the given index is in bounds of the vector
if(index >= vector->currentSize){
arc_errno = ARC_ERRNO_DATA;
ARC_DEBUG_LOG_ERROR("ARC_Vector_Add(vector, data), vector at max capacity tried adding another value");
return;
}
ARC_Vector_RemoveIndexNoCheck(vector, index);
}
void ARC_Vector_RemoveIndexNoCheck(ARC_Vector *vector, uint32_t index){
for(uint32_t i = index; i <= vector->currentSize; i++){
if(i + 1 >= vector->currentSize - 1){
break;
}
vector->data[i] = vector->data[i + 1];
//we will be using index to iterate as we will not use it again, so we can skip the first part of the for loop
for(; index + 1 < vector->currentSize; index++){
//override the data from index to the end by shifting it back one
vector->data[index] = vector->data[index + 1];
}
--vector->currentSize;
//we have removed the item so we can decrease the current size
vector->currentSize--;
if(vector->currentSize != vector->capacity >> 1){
//if the current size is half the current capacity or the current capacity is at the smallest limit, we do not need to do anything else
if(vector->currentSize != vector->currentCapacity >> 1 || vector->currentCapacity == 1){
return;
}
vector->capacity >>= 1;
if(vector->capacity <= 0){
vector->capacity = 1;
}
vector->data = (void *)realloc(vector->data, sizeof(void *) * vector->capacity);
//half the capacity and copy it into a smaller array
vector->currentCapacity >>= 1;
vector->data = (void **)realloc(vector->data, sizeof(void *) * vector->currentCapacity);
}
uint32_t ARC_Vector_Size(ARC_Vector *vector){
uint32_t ARC_Vector_GetSize(ARC_Vector *vector){
return vector->currentSize;
}
void *ARC_Vector_Get(ARC_Vector *vector, uint32_t index){
//check to make sure the given index is in bounds of the vector
if(index >= vector->currentSize){
arc_errno = ARC_ERRNO_DATA;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Vector_Get(vector, %u), null value as the index was out of bounds", index);
return NULL;
}
return vector->data[index];
}
}