tcon: add testcase for const members in tcon_container_of()
[ccan] / ccan / tcon / test / run-container.c
1 #include <stdlib.h>
2
3 #include <ccan/tcon/tcon.h>
4 #include <ccan/build_assert/build_assert.h>
5 #include <ccan/tap/tap.h>
6
7 struct inner {
8         int inner_val;
9 };
10
11 struct outer {
12         int outer_val;
13         struct inner inner;
14 };
15
16 struct outer0 {
17         struct inner inner;
18         int outer0_val;
19 };
20
21 struct info_base {
22         char *infop;
23 };
24
25 struct info_tcon {
26         struct info_base base;
27         TCON(TCON_CONTAINER(fi, struct outer, inner);
28              TCON_CONTAINER(fi2, struct outer0, inner));
29 };
30
31 int main(int argc, char *argv[])
32 {
33         struct info_tcon info;
34         TCON_WRAP(struct info_base,
35                   TCON_CONTAINER(fi, struct outer, inner);
36                   TCON_CONTAINER(fi2, struct outer0, inner)) infow;
37         struct outer ovar;
38         struct outer0 ovar2;
39
40         plan_tests(12);
41
42         ok1(tcon_container_of(&info, fi, &ovar.inner) == &ovar);
43         ok1(tcon_member_of(&info, fi, &ovar) == &ovar.inner);
44         ok1(tcon_container_of(&infow, fi, &ovar.inner) == &ovar);
45         ok1(tcon_member_of(&infow, fi, &ovar) == &ovar.inner);
46
47         ok1(tcon_container_of(&info, fi2, &ovar2.inner) == &ovar2);
48         ok1(tcon_member_of(&info, fi2, &ovar2) == &ovar2.inner);
49         ok1(tcon_container_of(&infow, fi2, &ovar2.inner) == &ovar2);
50         ok1(tcon_member_of(&infow, fi2, &ovar2) == &ovar2.inner);
51
52         /* Check handling of NULLs */
53         ok1(tcon_container_of(&info, fi, NULL) == NULL);
54         ok1(tcon_member_of(&info, fi, NULL) == NULL);
55         ok1(tcon_container_of(&infow, fi, NULL) == NULL);
56         ok1(tcon_member_of(&infow, fi, NULL) == NULL);
57
58         return 0;
59 }