Skip to content

Commit 0360089

Browse files
Add barebones-combined
1 parent 8e511ea commit 0360089

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

barebones-combined.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
18+
/* The `Enum` typeclass allows types to be enumerable */
19+
typedef struct
20+
{
21+
int (*const from_enum)(void* self);
22+
} EnumTC;
23+
24+
typedef struct
25+
{
26+
void* self;
27+
EnumTC const* tc;
28+
} Enum;
29+
30+
31+
/* Typeclass that asks for both `Show` and `Enum` implementation */
32+
typedef struct
33+
{
34+
void* self;
35+
ShowTC const* showtc;
36+
EnumTC const* enumtc;
37+
} ShowEnum;
38+
39+
void print_shen(ShowEnum shen)
40+
{
41+
char* const s = shen.showtc->show(shen.self);
42+
int enm = shen.enumtc->from_enum(shen.self);
43+
printf("%s : %d\n", s, enm);
44+
free(s);
45+
}
46+
47+
/* The `show` function implementation for `int` */
48+
static char* int_show(int* x)
49+
{
50+
/*
51+
Note: The `show` function of a `Show` typeclass is expected to return a malloc'ed value
52+
The users of a generic `Show` are expected to `free` the returned pointer from the function `show`.
53+
*/
54+
size_t len = snprintf(NULL, 0, "%d", *x);
55+
char* const res = malloc((len + 1) * sizeof(*res));
56+
snprintf(res, len + 1, "%d", *x);
57+
return res;
58+
}
59+
60+
/* Make function to build a generic `Show` out of a concrete type- `int` */
61+
Show int_to_show(int* x)
62+
{
63+
/* Build the vtable once and attach a pointer to it every time */
64+
static ShowTC const tc = {.show = (char* (*const)(void*))(int_show) };
65+
return (Show){.tc = &tc, .self = x};
66+
}
67+
68+
/* The `from_enum` function implementation for `int` */
69+
static int int_from_enum(int* x)
70+
{
71+
return *x;
72+
}
73+
74+
/* Make function to build a generic `Show` out of a concrete type- `int` */
75+
Enum int_to_enum(int* x)
76+
{
77+
/* Build the vtable once and attach a pointer to it every time */
78+
static EnumTC const tc = {.from_enum = (int (*const)(void*))(int_from_enum) };
79+
return (Enum){.tc = &tc, .self = x};
80+
}
81+
82+
int main(void)
83+
{
84+
int x = 42;
85+
ShowEnum shen = { .self = &x, .showtc = int_to_show(&x).tc, .enumtc = int_to_enum(&x).tc };
86+
print_shen(shen);
87+
return 0;
88+
}

0 commit comments

Comments
 (0)