d89ef83551
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.
93 lines
3.6 KiB
C
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
|