File tree Expand file tree Collapse file tree 1 file changed +78
-0
lines changed Expand file tree Collapse file tree 1 file changed +78
-0
lines changed Original file line number Diff line number Diff line change
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+
5
+ /* The `Show` typeclass allows types to be turned into their string representation */
6
+ typedef struct
7
+ {
8
+ char * (* const show )(void * self );
9
+ } ShowTC ;
10
+
11
+ typedef struct
12
+ {
13
+ void * self ;
14
+ ShowTC const * tc ;
15
+ } Show ;
16
+
17
+ #define impl_show (T , Name , show_f ) \
18
+ Show Name(T* x) \
19
+ { \
20
+ char* (*const show_)(T* self) = (show_f); \
21
+ (void)show_; \
22
+ static ShowTC const tc = {.show = (char* (*const)(void*))(show_f) }; \
23
+ return (Show){.tc = &tc, .self = x}; \
24
+ }
25
+
26
+ /* Polymorphic printing function */
27
+ void print (Show showable )
28
+ {
29
+ char * const s = showable .tc -> show (showable .self );
30
+ puts (s );
31
+ free (s );
32
+ }
33
+
34
+
35
+ /* A very holy enum */
36
+ typedef enum
37
+ {
38
+ holy ,
39
+ hand ,
40
+ grenade
41
+ } Antioch ;
42
+
43
+ static inline char * strdup_ (char const * x )
44
+ {
45
+ char * const s = malloc ((strlen (x ) + 1 ) * sizeof (* s ));
46
+ strcpy (s , x );
47
+ return s ;
48
+ }
49
+
50
+ /* The `show` function implementation for `Antioch*` */
51
+ static char * antioch_show (Antioch * x )
52
+ {
53
+ /*
54
+ Note: The `show` function of a `Show` typeclass is expected to return a malloc'ed value
55
+ The users of a generic `Show` are expected to `free` the returned pointer from the function `show`.
56
+ */
57
+ switch (* x )
58
+ {
59
+ case holy :
60
+ return strdup_ ("holy" );
61
+ case hand :
62
+ return strdup_ ("hand" );
63
+ case grenade :
64
+ return strdup_ ("grenade" );
65
+ default :
66
+ return strdup_ ("breakfast cereal" );
67
+ }
68
+ }
69
+
70
+ /* Make function to build a generic `Show` out of a concrete type- `Antioch` */
71
+ impl_show (Antioch , prep_antioch_show , antioch_show )
72
+
73
+ int main (void )
74
+ {
75
+ Show const antsh = prep_antioch_show (& (Antioch ){ hand });
76
+ print (antsh );
77
+ return 0 ;
78
+ }
You can’t perform that action at this time.
0 commit comments