#ifndef COLLECTION_H #define COLLECTION_H #include void array_push( void** data, size_t* capacity, size_t* size, void* elem, size_t elem_size); #define ARRAY_FIELD(TYPE, FIELD_NAME) \ TYPE* FIELD_NAME; \ size_t FIELD_NAME##_cap; \ size_t FIELD_NAME##_size #define ARRAY_FIELD_INIT(FIELD_NAME) \ .FIELD_NAME = nullptr, .FIELD_NAME##_cap = 0, .FIELD_NAME##_size = 0 #define ARRAY_FIELD_PUSH(STRUCT_PTR, FIELD_NAME, ELEM_PTR) \ array_push((void**)&(STRUCT_PTR)->FIELD_NAME, \ &(STRUCT_PTR)->FIELD_NAME##_cap, \ &(STRUCT_PTR)->FIELD_NAME##_size, \ (ELEM_PTR), \ sizeof(*(ELEM_PTR))) #define ARRAY_VAR(TYPE, FIELD_NAME) \ TYPE* FIELD_NAME = nullptr; \ size_t FIELD_NAME##_cap = 0; \ size_t FIELD_NAME##_size = 0; #define ARRAY_VAR_PUSH(VAR_NAME, ELEM_PTR) \ array_push((void**)&VAR_NAME, \ &VAR_NAME##_cap, \ &VAR_NAME##_size, \ (ELEM_PTR), \ sizeof(*(ELEM_PTR))) typedef struct KwPair KwPair; typedef struct { ARRAY_FIELD(KwPair, entries); size_t elem_size; size_t pair_size; } Hashmap; void hashmap_init(Hashmap* m, size_t elem_size); void hashmap_deinit(Hashmap* m); void hashmap_set(Hashmap* m, const char* key, void* val); void* hashmap_get(Hashmap* m, const char* key); void hashmap_for_each( Hashmap* m, void fn(void* self, const char* key, void* val), void* self); typedef struct { unsigned char* data; size_t cap; size_t offset; } ArenaBucket; typedef struct { ArenaBucket* buckets; size_t buckets_cap; size_t buckets_size; size_t default_bucket_cap; } Arena; void arena_init(Arena* a, size_t bucket_cap); void arena_deinit(Arena* a); void* arena_alloc(Arena* a, size_t size); void arena_array_push(Arena* arena, void** data, size_t* capacity, size_t* size, void* elem, size_t elem_size); char* arena_strdup(Arena* a, const char* str); #endif