From: Rusty Russell Date: Wed, 30 Sep 2009 03:17:22 +0000 (+0930) Subject: typesafe_cb: more support for typesafe compare functions. X-Git-Url: https://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=517114490e7153643b4c0a12c59a060568d7ae00;ds=inline typesafe_cb: more support for typesafe compare functions. --- diff --git a/ccan/typesafe_cb/typesafe_cb.h b/ccan/typesafe_cb/typesafe_cb.h index 594e894a..0eb57d95 100644 --- a/ccan/typesafe_cb/typesafe_cb.h +++ b/ccan/typesafe_cb/typesafe_cb.h @@ -63,6 +63,28 @@ __builtin_choose_expr(__builtin_types_compatible_p(typeof(1?(expr):0), oktype), rtype (*)(typeof(arg)), \ rtype (*)(void *)) +/** + * typesafe_cb_const - cast a const callback function if it matches the arg + * @rtype: the return type of the callback function + * @fn: the callback function to cast + * @arg: the (pointer) argument to hand to the callback function. + * + * If a callback function takes a single argument, this macro does appropriate + * casts to a function which takes a single const void * argument if the + * callback provided matches the @arg. + * + * It is assumed that @arg is of pointer type: usually @arg is passed + * or assigned to a void * elsewhere anyway. + * + * Example: + * void _register_callback(void (*fn)(const void *arg), const void *arg); + * #define register_callback(fn, arg) \ + * _register_callback(typesafe_cb_const(void, (fn), (arg)), (arg)) + */ +#define typesafe_cb_const(rtype, fn, arg) \ + cast_if_type((fn), \ + rtype (*)(const typeof(*arg)*), rtype (*)(const void *)) + /** * typesafe_cb_preargs - cast a callback function if it matches the arg * @rtype: the return type of the callback function @@ -117,4 +139,28 @@ __builtin_choose_expr(__builtin_types_compatible_p(typeof(1?(expr):0), oktype), rtype (*)(typeof(arg), __VA_ARGS__), \ rtype (*)(void *, __VA_ARGS__)) +/** + * typesafe_cb_cmp - cast a compare function if it matches the arg + * @rtype: the return type of the callback function + * @fn: the callback function to cast + * @arg: the (pointer) argument(s) to hand to the compare function. + * + * If a callback function takes two matching-type arguments, this macro does + * appropriate casts to a function which takes two const void * arguments if + * the callback provided takes two a const pointers to @arg. + * + * It is assumed that @arg is of pointer type: usually @arg is passed + * or assigned to a void * elsewhere anyway. + * + * Example: + * void _my_qsort(void *base, size_t nmemb, size_t size, + * int (*cmp)(const void *, const void *)); + * #define my_qsort(base, nmemb, cmpfn) \ + * _my_qsort((base), (nmemb), sizeof(*(base)), \ + * typesafe_cb_cmp(int, (cmpfn), (base)), (arg)) + */ +#define typesafe_cb_cmp(rtype, cmpfn, arg) \ + cast_if_type((cmpfn), \ + rtype (*)(const typeof(*arg)*, const typeof(*arg)*), \ + rtype (*)(const void *, const void *)) #endif /* CCAN_CAST_IF_TYPE_H */