#include <stdio.h>
#include <stdlib.h>
typedef struct array {
void* data;
int size;
long size_t;
} Array;
typedef void (*mono_func)(void*);
typedef void (*map_func)(void*, void*);
typedef int (*filter_func)(void*);
void print_int(void* x){
printf("%d ", *(int*)x);
}
void dbl(void* out, void* in) {
*(int*)out = *(int*)in * 2;
}
void assign_int(void* out, void* in) {
*(int*)out = *(int*)in;
}
int is_even(void* x){
return *(int*)x % 2 == 0;
}
void each(Array* arr, mono_func f) {
for(int i=0; i < arr->size; i++){
f(arr->data + (i * arr->size_t));
}
}
void map(Array* arr, Array* new_arr, map_func f) {
for(int i=0; i < arr->size; i++){
f(new_arr->data + (i * new_arr->size_t), arr->data + (i * arr->size_t));
}
}
void filter(Array* arr, Array* new_arr, filter_func f, map_func assign) {
int count = 0;
for(int i=0; i < arr->size; i++){
void* v = arr->data + (i * arr->size_t);
if(f(v)){
assign(new_arr->data + (count++ * new_arr->size_t), v);
} else {
new_arr->size--;
}
}
}
int main() {
Array arr = {&(int[]){1, 2, 3, 4, 5}[0], 5, sizeof(int)};
Array *mapped_arr = (Array*)malloc(sizeof(struct array));
mapped_arr->data = malloc(sizeof(int) * 5);
mapped_arr->size = 5;
mapped_arr->size_t = sizeof(int);
Array *filtered_arr = (Array*)malloc(sizeof(struct array));
filtered_arr->data = malloc(sizeof(int) * 5);
filtered_arr->size = 5;
filtered_arr->size_t = sizeof(int);
each(&arr, &print_int);
printf("\n");
map(&arr, mapped_arr, &dbl);
each(mapped_arr, &print_int);
printf("\n");
filter(&arr, filtered_arr, is_even, &assign_int);
each(filtered_arr, &print_int);
printf("\n");
return 0;
}