#ifndef sizeof_fam_struct #define sizeof_fam_struct(type, len) (sizeof(type) + (len)*sizeof(((type*)NULL)->data[0])) #endif #ifndef map #include #include #include #define map(arr, fun) __extension__({ \ typeof(arr) map_copy_arr = arr; \ size_t data_len = sizeof(typeof(fun(NULL))); \ void *res = malloc(sizeof(size_t) + map_copy_arr->len*data_len); \ *((size_t*)res) = map_copy_arr->len; \ for(size_t i = 0; i < map_copy_arr->len; i++){ \ *((typeof(fun(NULL))*)(((uint8_t*)res) + sizeof(size_t)) + i) = fun(&(arr->data[i])); \ } \ res; \ }) #endif #ifndef fold #include #define fold(arr,fun, init) __extension__({ \ typeof(arr) fold_copy_arr = arr; \ typeof(init) accu = init; \ for(size_t i = 0; i < fold_copy_arr->len;i++){ \ accu = fun(accu, (fold_copy_arr->data[i]));\ }\ accu;\ }) #endif #ifndef filter #include #include #include #define filter(arr, fun) __extension__({ \ typeof(arr) filter_copy_arr = arr; \ typeof(arr) res = malloc(sizeof_fam_struct(typeof(*arr), filter_copy_arr->len)); \ res->len = 0; \ for(size_t i = 0; i < filter_copy_arr->len; i++){ \ if(fun(filter_copy_arr->data[i])){ \ res->data[(res->len)++] = filter_copy_arr->data[i]; \ } \ } \ res; \ }) #endif #ifndef apply #include #include #include #define apply(arr, fun) __extension__({ \ typeof(arr) apply_copy_arr = arr; \ for(size_t i = 0; i < apply_copy_arr->len; i++){ \ fun(&(apply_copy_arr->data[i])); \ } \ apply_copy_arr; \ }) #endif #ifndef ARR_T_GENERIC_MACROS #define ARR_T_GENERIC_MACROS #include #define arr_t(T) struct ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, s){ \ size_t cap; \ size_t len; \ T data[]; \ }\ #define ARR_T_NOT_EXPOSED__ARR_NAME_COMBINE(T, name) T##_arr_##name #define ARR_T_NOT_EXPOSED__ARR_NAME_EXPAND(T, name) ARR_T_NOT_EXPOSED__ARR_NAME_COMBINE(T, name) #define ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, name) ARR_T_NOT_EXPOSED__ARR_NAME_EXPAND(ARR_T_NOT_EXPOSED__GET_TYPE(T), name) #define ARR_T_NOT_EXPOSED__GET_TYPE_CONTAINS_struct 0, #define ARR_T_NOT_EXPOSED__GET_TYPE_CONTAINS_enum 1, #define ARR_T_NOT_EXPOSED__RETURN_TYPE(T, ...) T #define ARR_T_NOT_EXPOSED__GET_TYPE_EXPAND(maybe_T, _, ...) ARR_T_NOT_EXPOSED__RETURN_TYPE(__VA_OPT__(__VA_ARGS__ ,) maybe_T) #define ARR_T_NOT_EXPOSED__GET_TYPE_EXTRACT_PREFIX(maybe_T, _) ARR_T_NOT_EXPOSED__GET_TYPE_EXPAND(maybe_T, _) #define ARR_T_NOT_EXPOSED__GET_TYPE(T) ARR_T_NOT_EXPOSED__GET_TYPE_EXTRACT_PREFIX(T, ARR_T_NOT_EXPOSED__GET_TYPE_CONTAINS_##T) #endif #ifndef array_of #define array_of(T) ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, t) #endif #ifndef autofree #define autofree_array_of(T) [[gnu::__cleanup__(ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, autofree))]] array_of(T) #endif #ifndef ARRAY_OF #warning "ARRAY_OF not defined. This includes does nothing." #else #include #define arr__stringify_expand(x) #x #define arr__stringify(x) arr__stringify_expand(x) #define arr_init_declare(T) [[maybe_unused]] static array_of(T) *ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, init)(size_t cap) #define arr_init_body(T) [[maybe_unused]] static array_of(T) *ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, init)(size_t cap){ \ array_of(T) *arr = malloc(sizeof_fam_struct(array_of(T), cap)); \ arr->cap = cap; \ arr->len = 0; \ return arr; \ } #define arr_push_declare(T) [[maybe_unused]] static void ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, push)(array_of(T) *arr, T val) #define arr_push_body(T) [[maybe_unused]] static void ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, push)(array_of(T) *arr, T val){ \ if(arr->len < arr->cap){ \ arr->data[(arr->len)++] = val; \ } \ } #define arr_pop_declare(T) [[maybe_unused]] static T ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, pop)(array_of(T) *arr) #define arr_pop_body(T) [[maybe_unused]] static T ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, pop)(array_of(T) *arr){ \ return arr->data[--(arr->len)]; \ } #define arr_free_declare(T) [[maybe_unused]] static void ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, free)(array_of(T) *arr) #define arr_free_body(T) [[maybe_unused]] static void ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, free)(array_of(T) *arr){ \ free(arr); \ } #ifdef CUSTOM_AUTOFREE #define arr_autofree_declare(T) [[maybe_unused,gnu::alias(arr__stringify(CUSTOM_AUTOFREE))]] static void ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, autofree)(array_of(T) **p) #define arr_autofree_body(T) #else #define arr_autofree_declare(T) [[maybe_unused]] static void ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, autofree)(array_of(T) **p) #define arr_autofree_body(T) [[maybe_unused]] static void ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(T, autofree)(array_of(T) **p){\ free(*p);\ } #endif typedef arr_t(ARRAY_OF) ARR_T_NOT_EXPOSED__ARR_MAKE_NAME(ARRAY_OF, t); arr_init_declare(ARRAY_OF); arr_push_declare(ARRAY_OF); arr_pop_declare(ARRAY_OF); arr_free_declare(ARRAY_OF); arr_autofree_declare(ARRAY_OF); #ifndef ARRAY_NO_IMPLEM arr_init_body(ARRAY_OF) arr_push_body(ARRAY_OF) arr_pop_body(ARRAY_OF) arr_free_body(ARRAY_OF) arr_autofree_body(ARRAY_OF) #endif #undef arr_init_declare #undef arr_init_body #undef arr_push_declare #undef arr_push_body #undef arr_pop_declare #undef arr_pop_body #undef arr_free_declare #undef arr_free_body #undef arr_autofree_declare #undef arr_autofree_body #undef arr__stringify_expand #undef arr__stringify #undef CUSTOM_AUTOFREE #undef ARRAY_OF #endif