#ifndef APFL_INTERNAL_H #define APFL_INTERNAL_H #ifdef __cplusplus extern "C" { #endif #include #include #define DEINIT_CAP_LIST(allocator, items, len, cap, item_deinit) \ do { \ if ((items) == NULL) { \ break; \ } \ for (size_t i = 0; i < (len); i++) { \ item_deinit(allocator, &((items)[i])); \ } \ FREE_LIST(allocator, items, cap); \ len = 0; \ cap = 0; \ (items) = NULL; \ } while(0) #define DEINIT_LIST(allocator, items, len, item_deinit) \ do { \ if ((items) == NULL) { \ break; \ } \ for (size_t i = 0; i < (len); i++) { \ item_deinit(allocator, &((items)[i])); \ } \ FREE_LIST(allocator, items, len); \ len = 0; \ (items) = NULL; \ } while(0) #define DEINIT_LIST_WITH_ARGS(allocator, items, len, item_deinit, ...) \ do { \ if ((items) == NULL) { \ break; \ } \ for (size_t i = 0; i < (len); i++) { \ item_deinit(__VA_ARGS__, &((items)[i])); \ } \ FREE_LIST(allocator, items, len); \ len = 0; \ (items) = NULL; \ } while(0) #define DEINIT_CAP_LIST_WITH_ARGS(allocator, items, len, cap, item_deinit, ...) \ do { \ if ((items) == NULL) { \ break; \ } \ for (size_t i = 0; i < (len); i++) { \ item_deinit(__VA_ARGS__, &((items)[i])); \ } \ FREE_LIST(allocator, items, cap); \ len = 0; \ cap = 0; \ (items) = NULL; \ } while(0) #define MOVEPTR(out, in) \ do { \ out = in; \ in = NULL; \ } while(0) // DESTROY destroys a dynamically allocated value. // It will first deinit the value using deiniter, // free the memory and then set the variable to NULL. // It is always allowed to destroy an already destroyed // or deinited value. #define DESTROY(allocator, var, deiniter) \ do { \ if ((var) == NULL) { \ break; \ } \ deiniter(allocator, var); \ FREE_OBJ(allocator, var); \ (var) = NULL; \ } while(0) // Internal use only functions void apfl_print_indented(unsigned indent, FILE *, const char* fmt, ...); /* Decrease a refererence count. Returns true, if the object should be freed. */ bool apfl_refcount_dec(unsigned *); #ifdef __cplusplus } #endif #endif