endian: add constant versions.
[ccan] / ccan / check_type / check_type.h
1 /* CC0 (Public domain) - see LICENSE file for details */
2 #ifndef CCAN_CHECK_TYPE_H
3 #define CCAN_CHECK_TYPE_H
4 #include "config.h"
5
6 /**
7  * check_type - issue a warning or build failure if type is not correct.
8  * @expr: the expression whose type we should check (not evaluated).
9  * @type: the exact type we expect the expression to be.
10  *
11  * This macro is usually used within other macros to try to ensure that a macro
12  * argument is of the expected type.  No type promotion of the expression is
13  * done: an unsigned int is not the same as an int!
14  *
15  * check_type() always evaluates to 0.
16  *
17  * If your compiler does not support typeof, then the best we can do is fail
18  * to compile if the sizes of the types are unequal (a less complete check).
19  *
20  * Example:
21  *      // They should always pass a 64-bit value to _set_some_value!
22  *      #define set_some_value(expr)                    \
23  *              _set_some_value((check_type((expr), uint64_t), (expr)))
24  */
25
26 /**
27  * check_types_match - issue a warning or build failure if types are not same.
28  * @expr1: the first expression (not evaluated).
29  * @expr2: the second expression (not evaluated).
30  *
31  * This macro is usually used within other macros to try to ensure that
32  * arguments are of identical types.  No type promotion of the expressions is
33  * done: an unsigned int is not the same as an int!
34  *
35  * check_types_match() always evaluates to 0.
36  *
37  * If your compiler does not support typeof, then the best we can do is fail
38  * to compile if the sizes of the types are unequal (a less complete check).
39  *
40  * Example:
41  *      // Do subtraction to get to enclosing type, but make sure that
42  *      // pointer is of correct type for that member.
43  *      #define container_of(mbr_ptr, encl_type, mbr)                   \
44  *              (check_types_match((mbr_ptr), &((encl_type *)0)->mbr),  \
45  *               ((encl_type *)                                         \
46  *                ((char *)(mbr_ptr) - offsetof(enclosing_type, mbr))))
47  */
48 #if HAVE_TYPEOF
49 #define check_type(expr, type)                  \
50         ((typeof(expr) *)0 != (type *)0)
51
52 #define check_types_match(expr1, expr2)         \
53         ((typeof(expr1) *)0 != (typeof(expr2) *)0)
54 #else
55 #include <ccan/build_assert/build_assert.h>
56 /* Without typeof, we can only test the sizes. */
57 #define check_type(expr, type)                                  \
58         BUILD_ASSERT_OR_ZERO(sizeof(expr) == sizeof(type))
59
60 #define check_types_match(expr1, expr2)                         \
61         BUILD_ASSERT_OR_ZERO(sizeof(expr1) == sizeof(expr2))
62 #endif /* HAVE_TYPEOF */
63
64 #endif /* CCAN_CHECK_TYPE_H */