clay/src/clay-list.h
Gwendolyn d89ef83551 Reworked property system completely.
Properties can now have values of different types, and they are registered with their name, either to a layout class or globally.
Layout classes are also registered with their name.
2023-02-08 01:09:21 +01:00

93 lines
3.6 KiB
C

#ifndef CLAY_CLAY_LIST_H
#define CLAY_CLAY_LIST_H
#ifndef __GNUC__
#error "this requires GCC" // todo: make clang-compatible if possible
#endif
#include <stddef.h>
#include <malloc.h>
#include <assert.h>
#include <memory.h>
#ifndef CLAY_LIST_DEFAULT_INITIAL_SIZE
# define CLAY_LIST_DEFAULT_INITIAL_SIZE 16
#endif
#define CLAY_LIST_TYPE(list$name, list$element_type) \
typedef struct { \
list$element_type *elements; \
size_t length; \
size_t size;\
} list$name ## _s, * list$name; \
typedef const list$name ## _s * list$name ## _const;
#define CLAY_LIST_FOREACH(foreach$list, foreach$elptr, foreach$idx) \
for (int list_foreach$next = 1; list_foreach$next; (list_foreach$next = 0)) \
for (size_t foreach$idx = 0; list_foreach$next && foreach$idx < (foreach$list)->length; ++foreach$idx) \
for (typeof((foreach$list)->elements) foreach$elptr = &(foreach$list)->elements[foreach$idx]; list_foreach$next;) \
for (; !(list_foreach$next = 0); ({list_foreach$next = 1;break;}))
#define clay_list_create_1(list_create_1$type) clay_list_create_2(list_create_1$type, CLAY_LIST_DEFAULT_INITIAL_SIZE)
#define clay_list_create_2(list_create_2$type, list_create_2$initial_size) ({ \
assert((list_create_2$initial_size) > 0); \
list_create_2$type list_create_2$list = malloc(sizeof(*list_create_2$list)); \
assert(list_create_2$list != NULL); \
clay_list_init(list_create_2$list, (list_create_2$initial_size)); \
list_create_2$list; \
})
#define clay_list_create(...) CMOBALL(clay_list_create, __VA_ARGS__)
#define clay_list_init(list_init$list, list_init$initial_size) ({ \
(list_init$list)->length = 0; \
(list_init$list)->size = (list_init$initial_size); \
(list_init$list)->elements = malloc(sizeof(*(list_init$list)->elements) * (list_init$list)->size); \
assert((list_init$list)->elements != NULL); \
})
#define clay_list_append(list_append$list, list_append$el) ({ \
assert((list_append$list)->length <= (list_append$list)->size); \
if ((list_append$list)->length == (list_append$list)->size) { \
size_t list_append$new_size = (list_append$list)->size * 2; \
(list_append$list)->elements = realloc((list_append$list)->elements, sizeof(*(list_append$list)->elements) * list_append$new_size); \
(list_append$list)->size = list_append$new_size; \
assert((list_append$list)->elements != NULL); \
} \
(list_append$list)->length += 1; \
(list_append$list)->elements[(list_append$list)->length - 1] = (list_append$el); \
})
#define clay_list_remove(list_remove$list, list_remove$idx) ({ \
assert((list_remove$idx) < (list_remove$list)->length); \
if ((list_remove$idx) < (list_remove$list)->length - 1) { \
memmove((list_remove$list)->elements + (list_remove$idx), (list_remove$list)->elements + (list_remove$idx) + 1, ((list_remove$list)->length - (list_remove$idx) - 1) * sizeof(*(list_remove$list)->elements)); \
} \
(list_remove$list)->length -= 1; \
})
#define clay_list_destroy(list_destroy$list) ({ \
clay_list_empty(list_destroy$list); \
free(list_destroy$list); \
})
#define clay_list_empty(list_empty$list) ({ \
free((list_empty$list)->elements); \
(list_empty$list)->elements = NULL; \
})
#define clay_list_clone(list_clone$list) ({ \
typeof(list_clone$list) list_clone$new = clay_list_create(typeof(list_clone$list), (list_clone$list)->length); \
memcpy(list_clone$new->elements, (list_clone$list)->elements, (list_clone$list)->length); \
list_clone$new->length = (list_clone$list)->length; \
list_clone$new; \
})
#endif //CLAY_CLAY_LIST_H