Skip to content

Instantly share code, notes, and snippets.

@Hadaward
Last active March 7, 2025 00:53
Show Gist options
  • Select an option

  • Save Hadaward/af7bcbac77ad274fdaadf20fecb9954f to your computer and use it in GitHub Desktop.

Select an option

Save Hadaward/af7bcbac77ad274fdaadf20fecb9954f to your computer and use it in GitHub Desktop.
Curtain Collections List
#include "list.h"
List list_instance(size_t type_size) {
return (List){
.data = malloc(0),
.size = 0,
.type_size = type_size
};
}
int list_aux_push(List *list, void *value) {
list->data = realloc(list->data, list->type_size * (list->size + 1));
if (list->data == NULL) {
perror("Failed to allocate memory for list");
exit(EXIT_FAILURE);
}
memcpy((char*)list->data + list->type_size * list->size, value, list->type_size);
list->size++;
return 0;
}
int list_remove(List *list, size_t index) {
if (index >= list->size) {
return -1;
}
memmove((char*)list->data + index * list->type_size, (char*)list->data + (index + 1) * list->type_size, (list->size - index - 1) * list->type_size);
list->size--;
return 0;
}
void *list_get(List list, size_t index) {
if (index >= list.size) {
return NULL;
}
return (char*)list.data + index * list.type_size;
}
size_t list_find(List list, void *value, ComparatorPtr cmp) {
for (size_t i = 0; i < list.size; i++) {
if (cmp((char*)list.data + i * list.type_size, value)) {
return i;
}
}
return SIZE_MAX;
}
int cmp_pointer(void *a, void *b) {
return *((void **)a) == *((void **)b);
}
int cmp_int(void *a, void *b) {
return *((int *)a) == *((int *)b);
}
int cmp_string(void *a, void *b) {
return strcmp(*(char **)a, *(char **)b) == 0;
}
int cmp_float(void *a, void *b) {
return *((float *)a) == *((float *)b);
}
#ifndef CURTAIN_COLLECTIONS_LIST_H
#define CURTAIN_COLLECTIONS_LIST_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int(*ComparatorPtr)(void *, void *);
typedef struct List {
void *data;
size_t size;
size_t type_size;
} List;
List list_instance(size_t type_size);
int list_aux_push(List *list, void *value);
int list_remove(List *list, size_t index);
void *list_get(List list, size_t index);
size_t list_find(List list, void *value, ComparatorPtr cmp);
int cmp_pointer(void *a, void *b);
int cmp_int(void *a, void *b);
int cmp_string(void *a, void *b);
int cmp_float(void *a, void *b);
// Macros
#define list_of(type) list_instance(sizeof(type))
#define list_push(list, value) ({ \
typeof(value) temp = value; \
list_aux_push(list, &temp); \
})
#define list_get_type(list, type, index) (*((type*)list_get(list, index)))
#endif
curtain> make run all
gcc -Wall -Wextra -g -Iinclude -c -MMD src/main.c -o src/main.o
gcc -Wall -Wextra -g -Iinclude -c -MMD src/curtain/collections/list.c -o src/curtain/collections/list.o
gcc -Wall -Wextra -g -Iinclude -o output\main.exe src/main.o src/curtain/collections/list.o -Llib
Executing 'all' complete!
./output\main.exe
List size: 2
Person 0: John, 25
Person 1: Jane, 30
List size: 1
Person 0: John, 25
Executing 'run: all' complete!
make: 'all' is up to date.
#include "curtain/collections/list.h"
typedef struct Person {
char name[50];
int age;
} Person;
void print_list(List list) {
printf("List size: %zu\n", list.size);
for (size_t i = 0; i < list.size; i++) {
Person p = list_get_type(list, Person, i);
printf("Person %zu: %s, %d\n", i, p.name, p.age);
}
}
int main()
{
Person p1 = {"John", 25};
Person p2 = {"Jane", 30};
List list = list_of(Person);
list_push(&list, p1);
list_push(&list, p2);
print_list(list);
size_t index = list_find(list, &p2, cmp_int);
if (index != SIZE_MAX) {
list_remove(&list, index);
}
print_list(list);
free(list.data);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment