-
Notifications
You must be signed in to change notification settings - Fork 2
/
map.h
41 lines (34 loc) · 2.96 KB
/
map.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#ifndef IT_MAP_H
#define IT_MAP_H
#include "iterable_utils.h"
#define IterMap(ElmntType, FnRetType) IterMap##ElmntType##FnRetType
#define DefineIterMap(ElmntType, FnRetType) \
typedef struct \
{ \
FnRetType (*const mapfn)(ElmntType x); \
Iterable(ElmntType) const src; \
} IterMap(ElmntType, FnRetType)
/* Name of the function that wraps an IterMap(ElmntType, FnRetType) for given ElmntType and FnRetType into an iterable
*/
#define prep_itermap_of(ElmntType, FnRetType) CONCAT(CONCAT(prep_, IterMap(ElmntType, FnRetType)), _itr)
/* Map the function `fn` of type `FnRetType (*)(ElmntType)` over `it` to make a new iterable */
#define map_over(it, fn, ElmntType, FnRetType) \
prep_itermap_of(ElmntType, FnRetType)(&(IterMap(ElmntType, FnRetType)){.mapfn = fn, .src = it})
/*
Define the iterator implementation function for an IterMap struct
Also define a function with the given `Name` - which takes in an iterable and a function to map over said iterable,
wraps said iterable and function in an `IterMap` struct and wraps that around its `Iterable` impl
*/
#define define_itermap_func(ElmntType, FnRetType) \
static Maybe(FnRetType) CONCAT(IterMap(ElmntType, FnRetType), _nxt)(IterMap(ElmntType, FnRetType) * self) \
{ \
Iterable(ElmntType) const srcit = self->src; \
Maybe(ElmntType) res = srcit.tc->next(srcit.self); \
if (is_nothing(res)) { \
return Nothing(FnRetType); \
} \
return Just(self->mapfn(from_just_(res)), FnRetType); \
} \
impl_iterator(IterMap(ElmntType, FnRetType)*, FnRetType, prep_itermap_of(ElmntType, FnRetType), \
CONCAT(IterMap(ElmntType, FnRetType), _nxt))
#endif /* !IT_MAP_H */