6 * typesafe_cb - macros for safe callbacks.
8 * The basis of the typesafe_cb header is typesafe_cb_cast(): a
9 * conditional cast macro. If an expression exactly matches a given
10 * type, it is cast to the target type, otherwise it is left alone.
12 * This allows us to create functions which take a small number of
13 * specific types, rather than being forced to use a void *. In
14 * particular, it is useful for creating typesafe callbacks as the
15 * helpers typesafe_cb(), typesafe_cb_preargs() and
16 * typesafe_cb_postargs() demonstrate.
18 * The standard way of passing arguments to callback functions in C is
19 * to use a void pointer, which the callback then casts back to the
20 * expected type. This unfortunately subverts the type checking the
21 * compiler would perform if it were a direct call. Here's an example:
23 * static void my_callback(void *_obj)
25 * struct obj *obj = _obj;
29 * register_callback(my_callback, &my_obj);
31 * If we wanted to use the natural type for my_callback (ie. "void
32 * my_callback(struct obj *obj)"), we could make register_callback()
33 * take a void * as its first argument, but this would subvert all
34 * type checking. We really want register_callback() to accept only
35 * the exactly correct function type to match the argument, or a
36 * function which takes a void *.
38 * This is where typesafe_cb() comes in: it uses typesafe_cb_cast() to
39 * cast the callback function if it matches the argument type:
41 * void _register_callback(void (*cb)(void *arg), void *arg);
42 * #define register_callback(cb, arg) \
43 * _register_callback(typesafe_cb(void, void *, (cb), (arg)), \
46 * On compilers which don't support the extensions required
47 * typesafe_cb_cast() and friend become an unconditional cast, so your
48 * code will compile but you won't get type checking.
51 * #include <ccan/typesafe_cb/typesafe_cb.h>
55 * // Generic callback infrastructure.
57 * struct callback *next;
59 * int (*callback)(int value, void *arg);
62 * static struct callback *callbacks;
64 * static void _register_callback(int value, int (*cb)(int, void *),
67 * struct callback *new = malloc(sizeof(*new));
68 * new->next = callbacks;
74 * #define register_callback(value, cb, arg) \
75 * _register_callback(value, \
76 * typesafe_cb_preargs(int, void *, \
80 * static struct callback *find_callback(int value)
84 * for (i = callbacks; i; i = i->next)
85 * if (i->value == value)
90 * // Define several silly callbacks. Note they don't use void *!
91 * #define DEF_CALLBACK(name, op) \
92 * static int name(int val, int *arg) \
94 * printf("%s", #op); \
95 * return val op *arg; \
97 * DEF_CALLBACK(multiply, *);
98 * DEF_CALLBACK(add, +);
99 * DEF_CALLBACK(divide, /);
100 * DEF_CALLBACK(sub, -);
101 * DEF_CALLBACK(or, |);
102 * DEF_CALLBACK(and, &);
103 * DEF_CALLBACK(xor, ^);
104 * DEF_CALLBACK(assign, =);
106 * // Silly game to find the longest chain of values.
107 * int main(int argc, char *argv[])
109 * int i, run = 1, num = argc > 1 ? atoi(argv[1]) : 0;
111 * for (i = 1; i < 1024;) {
112 * // Since run is an int, compiler checks "add" does too.
113 * register_callback(i++, add, &run);
114 * register_callback(i++, divide, &run);
115 * register_callback(i++, sub, &run);
116 * register_callback(i++, multiply, &run);
117 * register_callback(i++, or, &run);
118 * register_callback(i++, and, &run);
119 * register_callback(i++, xor, &run);
120 * register_callback(i++, assign, &run);
123 * printf("%i ", num);
125 * struct callback *cb = find_callback(num % i);
127 * printf("-> STOP\n");
130 * num = cb->callback(num, cb->arg);
131 * printf("->%i ", num);
134 * printf("-> Winner!\n");
138 * License: CC0 (Public domain)
139 * Author: Rusty Russell <rusty@rustcorp.com.au>
141 int main(int argc, char *argv[])
146 if (strcmp(argv[1], "depends") == 0) {