typesafe_cb.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #ifndef CCAN_CAST_IF_TYPE_H
  2. #define CCAN_CAST_IF_TYPE_H
  3. #include "config.h"
  4. #if HAVE_TYPEOF && HAVE_BUILTIN_CHOOSE_EXPR && HAVE_BUILTIN_TYPES_COMPATIBLE_P
  5. /**
  6. * cast_if_type - only cast an expression if it is of a given type
  7. * @expr: the expression to cast
  8. * @oktype: the type we allow
  9. * @desttype: the type to cast to
  10. *
  11. * This macro is used to create functions which allow multiple types.
  12. * The result of this macro is used somewhere that a @desttype type is
  13. * expected: if @expr was of type @oktype, it will be cast to
  14. * @desttype type. As a result, if @expr is any type other than
  15. * @oktype or @desttype, a compiler warning will be issued.
  16. *
  17. * This macro can be used in static initializers.
  18. *
  19. * This is merely useful for warnings: if the compiler does not
  20. * support the primitives required for cast_if_type(), 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
  23. * the "typeof": it will not be evaluated if typeof is not supported.
  24. *
  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(expr) \
  29. * _set_some_value(cast_if_type((expr), unsigned long, void *))
  30. */
  31. #define cast_if_type(expr, oktype, desttype) \
  32. __builtin_choose_expr(__builtin_types_compatible_p(typeof(1?(expr):0), oktype), \
  33. (desttype)(expr), (expr))
  34. #else
  35. #define cast_if_type(expr, oktype, desttype) ((desttype)(expr))
  36. #endif
  37. /**
  38. * typesafe_cb - cast a callback function if it matches the arg
  39. * @rettype: the return type of the callback function
  40. * @fn: the callback function to cast
  41. * @arg: the (pointer) argument to hand to the callback function.
  42. *
  43. * If a callback function takes a single argument, this macro does
  44. * appropriate casts to a function which takes a single void * argument if the
  45. * callback provided matches the @arg (or a const or volatile version).
  46. *
  47. * It is assumed that @arg is of pointer type: usually @arg is passed
  48. * or assigned to a void * elsewhere anyway.
  49. *
  50. * Example:
  51. * void _register_callback(void (*fn)(void *arg), void *arg);
  52. * #define register_callback(fn, arg) \
  53. * _register_callback(typesafe_cb(void, (fn), (arg)), (arg))
  54. */
  55. #define typesafe_cb(rettype, fn, arg) \
  56. cast_if_type(cast_if_type(cast_if_type((fn), \
  57. rettype (*)(const typeof(arg)), \
  58. rettype (*)(void *)), \
  59. rettype (*)(volatile typeof(arg)), \
  60. rettype (*)(void *)), \
  61. rettype (*)(typeof(arg)), \
  62. rettype (*)(void *))
  63. /**
  64. * typesafe_cb_preargs - cast a callback function if it matches the arg
  65. * @rettype: the return type of the callback function
  66. * @fn: the callback function to cast
  67. * @arg: the (pointer) argument to hand to the callback function.
  68. *
  69. * This is a version of typesafe_cb() for callbacks that take other arguments
  70. * before the @arg.
  71. *
  72. * Example:
  73. * void _register_callback(void (*fn)(int, void *arg), void *arg);
  74. * #define register_callback(fn, arg) \
  75. * _register_callback(typesafe_cb_preargs(void, (fn), (arg), int),\
  76. * (arg))
  77. */
  78. #define typesafe_cb_preargs(rettype, fn, arg, ...) \
  79. cast_if_type(cast_if_type(cast_if_type((fn), \
  80. rettype (*)(__VA_ARGS__, \
  81. const typeof(arg)), \
  82. rettype (*)(__VA_ARGS__, \
  83. void *)), \
  84. rettype (*)(__VA_ARGS__, \
  85. volatile typeof(arg)), \
  86. rettype (*)(__VA_ARGS__, void *)), \
  87. rettype (*)(__VA_ARGS__, typeof(arg)), \
  88. rettype (*)(__VA_ARGS__, void *))
  89. /**
  90. * typesafe_cb_postargs - cast a callback function if it matches the arg
  91. * @rettype: the return type of the callback function
  92. * @fn: the callback function to cast
  93. * @arg: the (pointer) argument to hand to the callback function.
  94. *
  95. * This is a version of typesafe_cb() for callbacks that take other arguments
  96. * after the @arg.
  97. *
  98. * Example:
  99. * void _register_callback(void (*fn)(void *arg, int), void *arg);
  100. * #define register_callback(fn, arg) \
  101. * _register_callback(typesafe_cb_preargs(void, (fn), (arg), int),\
  102. * (arg))
  103. */
  104. #define typesafe_cb_postargs(rettype, fn, arg, ...) \
  105. cast_if_type(cast_if_type(cast_if_type((fn), \
  106. rettype (*)(const typeof(arg), \
  107. __VA_ARGS__), \
  108. rettype (*)(void *, \
  109. __VA_ARGS__)), \
  110. rettype (*)(volatile typeof(arg), \
  111. __VA_ARGS__), \
  112. rettype (*)(void *, __VA_ARGS__)), \
  113. rettype (*)(typeof(arg), __VA_ARGS__), \
  114. rettype (*)(void *, __VA_ARGS__))
  115. #endif /* CCAN_CAST_IF_TYPE_H */