Created
August 22, 2017 16:08
-
-
Save io12/5be3d6c5ebb54c04b637bc76e9154fcc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
$----------------$ | |
| Example usage: | | |
$----------------$------------------------------------------------------$ | |
| #include <stdbool.h> | | |
| #include <stdio.h> | | |
| | | |
| #include "func.h" | | |
| | | |
| LIST_TYPE(int) | | |
| | | |
| bool is_even(const int *x) | | |
| { return | | |
| *x % 2 == 0; | | |
| } | | |
| | | |
| int *print_int(const int *x) | | |
| { return int_dup(( | | |
| printf("%d\n", *x), x)); | | |
| } | | |
| | | |
| int main(void) | | |
| { | | |
| let intList* list = list(int, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); | | |
| let intList* filtered_list = int_filter(list, is_even); | | |
| int_map(filtered_list, print_int); | | |
| } | | |
$-----------------------------------------------------------------------$ | |
*/ | |
#ifndef FUNC_H__ | |
#define FUNC_H__ | |
#include <stdbool.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define let const | |
#define list(type, ...) list__(type, ((type[]){ __VA_ARGS__ })) | |
#define list__(type, arr) \ | |
type##_list__(sizeof(arr[0]), sizeof(arr) / sizeof(arr[0]), arr) | |
#define LIST_TYPE(type) \ | |
typedef bool type##Predicate(const type *); \ | |
typedef type *type##UnaryFunc(const type *); \ | |
typedef type *type##BinaryFunc(const type *, const type *); \ | |
\ | |
typedef struct type##list type##List; \ | |
\ | |
struct type##list { \ | |
type *head; \ | |
type##List *tail; \ | |
}; \ | |
\ | |
type *type##_dup(const type *t); \ | |
type##List *type##_list__(const size_t size, const size_t nmemb, \ | |
const type arr[]); \ | |
type##List *type##_prepend(type *head, type##List *tail); \ | |
type##List *type##_map(const type##List *list, type##UnaryFunc *func); \ | |
type##List *type##_filter(const type##List *list, type##Predicate *func); \ | |
type *type##_reduce(const type##List *list, type##BinaryFunc *func); \ | |
\ | |
inline type *type##_dup(const type *t) \ | |
{ return \ | |
memcpy(malloc(sizeof(type)), t, sizeof(type)); \ | |
} \ | |
\ | |
inline type##List *type##_list__(const size_t size, const size_t nmemb, \ | |
const type arr[]) \ | |
{ return \ | |
nmemb == 0 \ | |
? NULL \ | |
: type##_prepend(type##_dup(arr), \ | |
type##_list__(size, nmemb - 1, arr + 1)); \ | |
} \ | |
\ | |
inline type##List *type##_prepend(type *head, type##List *tail) \ | |
{ \ | |
type##List * const super = malloc(sizeof(type##List)); \ | |
super->head = head; \ | |
super->tail = tail; \ | |
return super; \ | |
} \ | |
\ | |
inline type##List *type##_map(const type##List *list, type##UnaryFunc *func) \ | |
{ return \ | |
list == NULL \ | |
? NULL \ | |
: type##_prepend(func(list->head), type##_map(list->tail, func)); \ | |
} \ | |
\ | |
inline type##List *type##_filter(const type##List *list, type##Predicate *func) \ | |
{ return \ | |
list == NULL \ | |
? NULL \ | |
: func(list->head) \ | |
? type##_prepend(list->head, type##_filter(list->tail, func)) \ | |
: type##_filter(list->tail, func); \ | |
} \ | |
\ | |
inline type *type##_reduce(const type##List *list, type##BinaryFunc *func) \ | |
{ return \ | |
list->tail == NULL \ | |
? list->head \ | |
: func(list->head, type##_reduce(list->tail, func)); \ | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment