feat: add list

This commit is contained in:
2025-08-23 18:23:11 +02:00
parent bdaffdda54
commit 0288983aa7
6 changed files with 267 additions and 5 deletions

View File

@@ -5,11 +5,15 @@ set(CMAKE_C_STANDARD 23)
add_library(tstd STATIC library.c
include/tstd/string.h
string.c)
string.c
list.c
include/tstd/list.h)
add_executable(test_tstd test/test_main.c)
target_link_libraries(test_tstd tstd)
add_executable(test_tstd_string test/test_string.c)
add_executable(test_tstd_list test/test_list.c)
target_link_libraries(test_tstd_string tstd)
target_link_libraries(test_tstd_list tstd)
target_include_directories(tstd
PUBLIC
@@ -18,4 +22,5 @@ target_include_directories(tstd
)
enable_testing()
add_test(NAME tstd_tests COMMAND test_tstd)
add_test(NAME tstd_tests_string COMMAND test_tstd_string)
add_test(NAME tstd_tests_list COMMAND test_tstd_list)

View File

@@ -29,6 +29,5 @@ FetchContent_Declare(
FetchContent_MakeAvailable(tstd)
add_executable(myapp src/main.c)
target_link_libraries(myapp PRIVATE tstd)
```

133
include/tstd/list.h Normal file
View File

@@ -0,0 +1,133 @@
//
// Created by tilok on 23.08.2025.
//
#ifndef TSTD_LIST_H
#define TSTD_LIST_H
#include <stdlib.h>
#include <stdlib.h>
typedef struct {
/**
* @brief Pointer to the list's underlying data storage.
*
* This member variable represents the dynamic array used to store the actual
* elements of the list. Each element is a pointer, allowing the list to
* store arbitrary data types. The size of this array is managed by the
* capacity member, and its content can grow or shrink dynamically when
* elements are added or removed.
*
* The memory for this array is allocated dynamically and should be freed
* appropriately to avoid memory leaks when the list is no longer needed.
*/
void** data;
/**
* @brief Represents the number of elements currently stored in the list.
*
* This member tracks the current count of valid elements within the list. It
* increases when elements are added and decreases when elements are removed.
* It is always less than or equal to the list's capacity.
*/
size_t length;
/**
* @brief Represents the current capacity of the list.
*
* This member defines the maximum number of elements the list can hold
* before needing to reallocate memory for additional space. It dynamically
* increases as needed when elements are added beyond the current capacity.
*/
size_t capacity;
} list;
/**
* @brief Creates a new list with a default initial capacity.
*
* This function initializes a new empty list using a pre-defined default
* capacity. The created list can later hold elements and be resized
* dynamically as needed.
*
* @return A pointer to the newly created list, or NULL if memory allocation fails.
*/
list* list_create();
/**
* @brief Creates a new list with a specified initial capacity.
*
* This function initializes an empty list with the given capacity. The capacity
* determines the maximum number of elements the list can initially hold before
* requiring a resize operation. The list supports dynamic resizing as more
* elements are added beyond its current capacity.
*
* @param capacity The initial number of elements the list can hold.
* @return A pointer to the newly created list, or NULL if memory allocation fails.
*/
list* list_create_with_capacity(size_t capacity);
/**
* @brief Resizes the capacity of the list to accommodate more elements.
*
* This function dynamically increases the capacity of a list when needed.
* A new memory block is allocated, existing elements are copied to the
* new block, and the old memory is freed. The new capacity is determined
* based on a growth factor to optimize memory usage.
*
* @param list A pointer to the list structure to be resized.
*/
void list_resize(list* list);
/**
* @brief Adds a new element to the end of the list.
*
* This function appends the provided element to the list. If the list has
* reached its current capacity, it will automatically resize to ensure
* there is enough space for the new element.
*
* @param list A pointer to the list structure where the element will be added.
* @param element A pointer to the element being inserted into the list.
*/
void list_add_element(list* list, void* element);
/**
* @brief Frees the memory allocated for the list and its elements.
*
* This function releases all resources associated with the provided list.
* It deallocates the memory reserved for the list's data and the list
* structure itself. After calling this function, the list pointer will
* no longer be valid.
*
* @param list A pointer to the list to be freed. Must be a valid pointer
* to a list created with `list_create`, or NULL.
*/
void list_free(list* list);
/**
* @brief Frees all elements and associated memory in the given list.
*
* This function deallocates the memory of each element contained in the list,
* as well as the list's internal data structure and the list itself. After
* calling this function, the given list pointer becomes invalid and should not
* be used further.
*
* @param list A pointer to the list to be freed. Passing a NULL pointer is undefined behavior.
*/
void list_free_elements(list* list);
/**
* @brief Deletes an element from the list at a specified index.
*
* This function removes the element at the given index from the list, reducing
* the list's length by one. The subsequent elements in the list are shifted
* to fill the gap left by the removed element. The memory for the removed
* element is not freed by this function; it is the caller's responsibility to
* manage the memory of the deleted element.
*
* @param list A pointer to the list from which the element will be deleted.
* @param index The index of the element to remove. It must be a valid index
* within the list's current length.
* @return A pointer to the removed element. The caller is responsible for managing
* the returned pointer, including deallocating memory if necessary.
*/
void* list_delete_element(list* list, int index);
#endif //TSTD_LIST_H

62
list.c Normal file
View File

@@ -0,0 +1,62 @@
//
// Created by tilok on 23.08.2025.
//
#include "tstd/list.h"
#include <string.h>
list* list_create() {
return list_create_with_capacity(10);
}
list* list_create_with_capacity(size_t capacity) {
void** data = malloc(capacity * sizeof(void *));
list* new_list = malloc(sizeof(list));
new_list->data = data;
new_list->length = 0;
new_list->capacity = capacity;
return new_list;
}
void list_resize(list* list) {
size_t new_capacity = (list->capacity + 1) * 1.5;
void** new_data = malloc(new_capacity * sizeof(void *));
memcpy(new_data, list->data, list->length * sizeof(void *));
free(list->data);
list->data = new_data;
list->capacity = new_capacity;
}
void list_add_element(list* list, void* element) {
if (list->length == list->capacity) {
list_resize(list);
}
list->data[list->length++] = element;
}
void list_free(list* list) {
free(list->data);
free(list);
}
void list_free_elements(list* list) {
for (int i = 0; i < list->length; i++) {
free(list->data[i]);
}
free(list->data);
free(list);
}
void* list_delete_element(list* list, int index) {
void* element = list->data[index];
list->length--;
for (int i = index; i < list->length; i++) {
list->data[i] = list->data[i + 1];
}
return element;
}

63
test/test_list.c Normal file
View File

@@ -0,0 +1,63 @@
//
// Created by tilok on 23.08.2025.
//
#include <assert.h>
#include <string.h>
#include "tstd/list.h"
int test_list_create() {
list* list = list_create();
assert(list->capacity == 10);
list_free(list);
return 0;
}
int test_list_add_element() {
list* list = list_create();
list_add_element(list, "Hello");
assert(list->length == 1);
assert(strcmp(list->data[0], "Hello") == 0);
list_free(list);
return 0;
}
int test_add_multiple_elements() {
list* list = list_create();
for (int i = 0; i < 1000; i++) {
list_add_element(list, "Hello");
}
assert(list->length == 1000);
assert(list->capacity > 1000);
list_free(list);
return 0;
}
int test_delete_element() {
list* list = list_create();
list_add_element(list, "Hello");
list_add_element(list, "World");
list_add_element(list, "Test");
list_delete_element(list, 1);
assert(list->length == 2);
assert(strcmp(list->data[1], "Test") == 0);
return 0;
}
int main() {
int result = 0;
result += test_list_create();
result += test_list_add_element();
result += test_add_multiple_elements();
result += test_delete_element();
return result;
}