container_of: add container_off() helper.
[ccan] / ccan / container_of / container_of.h
1 #ifndef CCAN_CONTAINER_OF_H
2 #define CCAN_CONTAINER_OF_H
3 #include <stddef.h>
4
5 #include "config.h"
6 #include <ccan/check_type/check_type.h>
7
8 /**
9  * container_of - get pointer to enclosing structure
10  * @member_ptr: pointer to the structure member
11  * @containing_type: the type this member is within
12  * @member: the name of this member within the structure.
13  *
14  * Given a pointer to a member of a structure, this macro does pointer
15  * subtraction to return the pointer to the enclosing type.
16  *
17  * Example:
18  *      struct foo {
19  *              int fielda, fieldb;
20  *              // ...
21  *      };
22  *      struct info {
23  *              int some_other_field;
24  *              struct foo my_foo;
25  *      };
26  *
27  *      static struct info *foo_to_info(struct foo *foo)
28  *      {
29  *              return container_of(foo, struct info, my_foo);
30  *      }
31  */
32 #define container_of(member_ptr, containing_type, member)               \
33          ((containing_type *)                                           \
34           ((char *)(member_ptr)                                         \
35            - container_off((member_ptr), containing_type, member)))
36
37 /**
38  * container_off - get offset to enclosing structure
39  * @member_ptr: pointer to the structure member
40  * @containing_type: the type this member is within
41  * @member: the name of this member within the structure.
42  *
43  * Given a pointer to a member of a structure, this macro does
44  * typechecking and figures out the offset to the enclosing type.
45  *
46  * Note that @member_ptr is not evaluated.
47  *
48  * Example:
49  *      struct foo {
50  *              int fielda, fieldb;
51  *              // ...
52  *      };
53  *      struct info {
54  *              int some_other_field;
55  *              struct foo my_foo;
56  *      };
57  *
58  *      static struct info *foo_to_info(struct foo *foo)
59  *      {
60  *              size_t off = container_off(foo, struct info, my_foo);
61  *              return (void *)((char *)foo - off);
62  *      }
63  */
64 #define container_off(member_ptr, containing_type, member)              \
65         (offsetof(containing_type, member)                              \
66          + check_types_match(*(member_ptr), ((containing_type *)0)->member))
67
68 /**
69  * container_of_var - get pointer to enclosing structure using a variable
70  * @member_ptr: pointer to the structure member
71  * @var: a pointer to a structure of same type as this member is within
72  * @member: the name of this member within the structure.
73  *
74  * Given a pointer to a member of a structure, this macro does pointer
75  * subtraction to return the pointer to the enclosing type.
76  *
77  * Example:
78  *      static struct info *foo_to_i(struct foo *foo)
79  *      {
80  *              struct info *i = container_of_var(foo, i, my_foo);
81  *              return i;
82  *      }
83  */
84 #if HAVE_TYPEOF
85 #define container_of_var(member_ptr, var, member) \
86         container_of(member_ptr, typeof(*var), member)
87 #else
88 #define container_of_var(member_ptr, var, member)               \
89         ((void *)((char *)(member_ptr)                          \
90                   - ((char *)&(var)->member - (char *)(var))))
91 #endif
92
93 #endif /* CCAN_CONTAINER_OF_H */