s3-libgpo/gpo_filesync.c: return on read error
[Samba/gebeck_regimport.git] / lib / ccan / typesafe_cb / typesafe_cb.h
blob40cfa3979891c3ac04cac3a8204e8d59693d8e70
1 #ifndef CCAN_TYPESAFE_CB_H
2 #define CCAN_TYPESAFE_CB_H
3 #include "config.h"
5 #if HAVE_TYPEOF && HAVE_BUILTIN_CHOOSE_EXPR && HAVE_BUILTIN_TYPES_COMPATIBLE_P
6 /**
7 * typesafe_cb_cast - only cast an expression if it matches a given type
8 * @desttype: the type to cast to
9 * @oktype: the type we allow
10 * @expr: the expression to cast
12 * This macro is used to create functions which allow multiple types.
13 * The result of this macro is used somewhere that a @desttype type is
14 * expected: if @expr is exactly of type @oktype, then it will be
15 * cast to @desttype type, otherwise left alone.
17 * This macro can be used in static initializers.
19 * This is merely useful for warnings: if the compiler does not
20 * support the primitives required for typesafe_cb_cast(), it becomes an
21 * unconditional cast, and the @oktype argument is not used. In
22 * particular, this means that @oktype can be a type which uses the
23 * "typeof": it will not be evaluated if typeof is not supported.
25 * Example:
26 * // We can take either an unsigned long or a void *.
27 * void _set_some_value(void *val);
28 * #define set_some_value(e) \
29 * _set_some_value(typesafe_cb_cast(void *, (e), unsigned long))
31 #define typesafe_cb_cast(desttype, oktype, expr) \
32 __builtin_choose_expr( \
33 __builtin_types_compatible_p(__typeof__(0?(expr):(expr)), \
34 oktype), \
35 (desttype)(expr), (expr))
36 #else
37 #define typesafe_cb_cast(desttype, oktype, expr) ((desttype)(expr))
38 #endif
40 /**
41 * typesafe_cb_cast3 - only cast an expression if it matches given types
42 * @desttype: the type to cast to
43 * @ok1: the first type we allow
44 * @ok2: the second type we allow
45 * @ok3: the third type we allow
46 * @expr: the expression to cast
48 * This is a convenient wrapper for multiple typesafe_cb_cast() calls.
49 * You can chain them inside each other (ie. use typesafe_cb_cast()
50 * for expr) if you need more than 3 arguments.
52 * Example:
53 * // We can take either a long, unsigned long, void * or a const void *.
54 * void _set_some_value(void *val);
55 * #define set_some_value(expr) \
56 * _set_some_value(typesafe_cb_cast3(void *,, \
57 * long, unsigned long, const void *,\
58 * (expr)))
60 #define typesafe_cb_cast3(desttype, ok1, ok2, ok3, expr) \
61 typesafe_cb_cast(desttype, ok1, \
62 typesafe_cb_cast(desttype, ok2, \
63 typesafe_cb_cast(desttype, ok3, \
64 (expr))))
66 /**
67 * typesafe_cb - cast a callback function if it matches the arg
68 * @rtype: the return type of the callback function
69 * @atype: the (pointer) type which the callback function expects.
70 * @fn: the callback function to cast
71 * @arg: the (pointer) argument to hand to the callback function.
73 * If a callback function takes a single argument, this macro does
74 * appropriate casts to a function which takes a single atype argument if the
75 * callback provided matches the @arg.
77 * It is assumed that @arg is of pointer type: usually @arg is passed
78 * or assigned to a void * elsewhere anyway.
80 * Example:
81 * void _register_callback(void (*fn)(void *arg), void *arg);
82 * #define register_callback(fn, arg) \
83 * _register_callback(typesafe_cb(void, (fn), void*, (arg)), (arg))
85 #define typesafe_cb(rtype, atype, fn, arg) \
86 typesafe_cb_cast(rtype (*)(atype), \
87 rtype (*)(__typeof__(arg)), \
88 (fn))
90 /**
91 * typesafe_cb_preargs - cast a callback function if it matches the arg
92 * @rtype: the return type of the callback function
93 * @atype: the (pointer) type which the callback function expects.
94 * @fn: the callback function to cast
95 * @arg: the (pointer) argument to hand to the callback function.
97 * This is a version of typesafe_cb() for callbacks that take other arguments
98 * before the @arg.
100 * Example:
101 * void _register_callback(void (*fn)(int, void *arg), void *arg);
102 * #define register_callback(fn, arg) \
103 * _register_callback(typesafe_cb_preargs(void, (fn), void *, \
104 * (arg), int), \
105 * (arg))
107 #define typesafe_cb_preargs(rtype, atype, fn, arg, ...) \
108 typesafe_cb_cast(rtype (*)(__VA_ARGS__, atype), \
109 rtype (*)(__VA_ARGS__, __typeof__(arg)), \
110 (fn))
113 * typesafe_cb_postargs - cast a callback function if it matches the arg
114 * @rtype: the return type of the callback function
115 * @atype: the (pointer) type which the callback function expects.
116 * @fn: the callback function to cast
117 * @arg: the (pointer) argument to hand to the callback function.
119 * This is a version of typesafe_cb() for callbacks that take other arguments
120 * after the @arg.
122 * Example:
123 * void _register_callback(void (*fn)(void *arg, int), void *arg);
124 * #define register_callback(fn, arg) \
125 * _register_callback(typesafe_cb_postargs(void, (fn), void *, \
126 * (arg), int), \
127 * (arg))
129 #define typesafe_cb_postargs(rtype, atype, fn, arg, ...) \
130 typesafe_cb_cast(rtype (*)(atype, __VA_ARGS__), \
131 rtype (*)(__typeof__(arg), __VA_ARGS__), \
132 (fn))
133 #endif /* CCAN_CAST_IF_TYPE_H */