Skip to content
This repository has been archived by the owner on Oct 4, 2024. It is now read-only.

vector: introduce generic vector type #8

Merged
merged 2 commits into from
Jul 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__/
29 changes: 29 additions & 0 deletions include/libtrx/vector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

typedef struct VECTOR {
int32_t count;
int32_t capacity;
size_t item_size;
void **items;
} VECTOR;

VECTOR *Vector_Create(size_t item_size);
VECTOR *Vector_CreateAtCapacity(size_t item_size, int32_t capacity);
void Vector_Free(VECTOR *vector);

int32_t Vector_IndexOf(const VECTOR *vector, const void *item);
int32_t Vector_LastIndexOf(const VECTOR *vector, const void *item);
bool Vector_Contains(const VECTOR *vector, const void *item);

void Vector_Add(VECTOR *vector, void *item);
void Vector_Insert(VECTOR *vector, int32_t index, void *item);

bool Vector_Remove(VECTOR *vector, const void *item);
void Vector_RemoveAt(VECTOR *vector, int32_t index);

void Vector_Reverse(VECTOR *vector);
void Vector_Clear(VECTOR *vector);
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ sources = [
'src/log.c',
'src/memory.c',
'src/strings.c',
'src/vector.c',
]

dependencies = [
Expand Down
138 changes: 138 additions & 0 deletions src/vector.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#include "vector.h"

#include "memory.h"

#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#define VECTOR_DEFAULT_CAPACITY 4
#define VECTOR_GROWTH_RATE 2

static void Vector_EnsureCapacity(VECTOR *vector);

VECTOR *Vector_Create(const size_t item_size)
{
return Vector_CreateAtCapacity(item_size, VECTOR_DEFAULT_CAPACITY);
}

VECTOR *Vector_CreateAtCapacity(const size_t item_size, const int32_t capacity)
{
VECTOR *const vector = Memory_Alloc(sizeof(VECTOR));
vector->count = 0;
vector->capacity = capacity;
vector->item_size = item_size;
vector->items = Memory_Alloc(item_size * capacity);

return vector;
}

void Vector_Free(VECTOR *vector)
{
Memory_FreePointer(&vector->items);
Memory_FreePointer(&vector);
}

static void Vector_EnsureCapacity(VECTOR *vector)
{
if (vector->count + 1 <= vector->capacity) {
return;
}

vector->capacity *= VECTOR_GROWTH_RATE;
vector->items =
Memory_Realloc(vector->items, vector->item_size * vector->capacity);
}

int32_t Vector_IndexOf(const VECTOR *vector, const void *item)
{
for (int32_t i = 0; i < vector->count; i++) {
if (vector->items[i] == item) {
return i;
}
}
return -1;
}

int32_t Vector_LastIndexOf(const VECTOR *vector, const void *item)
{
for (int32_t i = vector->count - 1; i >= 0; i--) {
if (vector->items[i] == item) {
return i;
}
}
return -1;
}

bool Vector_Contains(const VECTOR *vector, const void *item)
{
return Vector_IndexOf(vector, item) != -1;
}

void Vector_Add(VECTOR *vector, void *item)
{
Vector_EnsureCapacity(vector);
vector->items[vector->count++] = item;
}

void Vector_Insert(VECTOR *vector, const int32_t index, void *item)
{
assert(index >= 0 && index <= vector->count);

Vector_EnsureCapacity(vector);

for (int32_t i = vector->count - 1; i >= index; i--) {
vector->items[i + 1] = vector->items[i];
}

vector->items[index] = item;
vector->count++;
}

bool Vector_Remove(VECTOR *vector, const void *item)
{
const int32_t index = Vector_IndexOf(vector, item);
if (index == -1) {
return false;
}

Vector_RemoveAt(vector, index);
return true;
}

void Vector_RemoveAt(VECTOR *vector, const int32_t index)
{
assert(index >= 0 && index < vector->count);

vector->items[index] = NULL;
for (int32_t i = index + 1; i < vector->count; i++) {
vector->items[i - 1] = vector->items[i];
vector->items[i] = NULL;
}

vector->count--;
}

void Vector_Reverse(VECTOR *vector)
{
int32_t i = 0;
int32_t j = vector->count - 1;
for (; i < j; i++, j--) {
void *temp = vector->items[i];
vector->items[i] = vector->items[j];
vector->items[j] = temp;
}
}

void Vector_Clear(VECTOR *vector)
{
for (int32_t i = 0; i < vector->count; i++) {
vector->items[i] = NULL;
}

vector->count = 0;
vector->capacity = VECTOR_DEFAULT_CAPACITY;
vector->items =
Memory_Realloc(vector->items, vector->item_size * vector->capacity);
}