Branch data Line data Source code
1 : : /* CC0 (Public domain) - see LICENSE file for details */
2 : : #ifndef CCAN_CONTAINER_OF_H
3 : : #define CCAN_CONTAINER_OF_H
4 : : #include <stddef.h>
5 : :
6 : : #include "config.h"
7 : : #include <ccan/check_type/check_type.h>
8 : :
9 : : /**
10 : : * container_of - get pointer to enclosing structure
11 : : * @member_ptr: pointer to the structure member
12 : : * @containing_type: the type this member is within
13 : : * @member: the name of this member within the structure.
14 : : *
15 : : * Given a pointer to a member of a structure, this macro does pointer
16 : : * subtraction to return the pointer to the enclosing type.
17 : : *
18 : : * Example:
19 : : * struct foo {
20 : : * int fielda, fieldb;
21 : : * // ...
22 : : * };
23 : : * struct info {
24 : : * int some_other_field;
25 : : * struct foo my_foo;
26 : : * };
27 : : *
28 : : * static struct info *foo_to_info(struct foo *foo)
29 : : * {
30 : : * return container_of(foo, struct info, my_foo);
31 : : * }
32 : : */
33 : : #define container_of(member_ptr, containing_type, member) \
34 : : ((containing_type *) \
35 : : ((char *)(member_ptr) \
36 : : - container_off(containing_type, member)) \
37 : : + check_types_match(*(member_ptr), ((containing_type *)0)->member))
38 : :
39 : :
40 : : /**
41 : : * container_of_or_null - get pointer to enclosing structure, or NULL
42 : : * @member_ptr: pointer to the structure member
43 : : * @containing_type: the type this member is within
44 : : * @member: the name of this member within the structure.
45 : : *
46 : : * Given a pointer to a member of a structure, this macro does pointer
47 : : * subtraction to return the pointer to the enclosing type, unless it
48 : : * is given NULL, in which case it also returns NULL.
49 : : *
50 : : * Example:
51 : : * struct foo {
52 : : * int fielda, fieldb;
53 : : * // ...
54 : : * };
55 : : * struct info {
56 : : * int some_other_field;
57 : : * struct foo my_foo;
58 : : * };
59 : : *
60 : : * static struct info *foo_to_info_allowing_null(struct foo *foo)
61 : : * {
62 : : * return container_of_or_null(foo, struct info, my_foo);
63 : : * }
64 : : */
65 : 8 : static inline char *container_of_or_null_(void *member_ptr, size_t offset)
66 : : {
67 : 8 : return member_ptr ? (char *)member_ptr - offset : NULL;
68 : : }
69 : : #define container_of_or_null(member_ptr, containing_type, member) \
70 : : ((containing_type *) \
71 : : container_of_or_null_(member_ptr, \
72 : : container_off(containing_type, member)) \
73 : : + check_types_match(*(member_ptr), ((containing_type *)0)->member))
74 : :
75 : : /**
76 : : * container_off - get offset to enclosing structure
77 : : * @containing_type: the type this member is within
78 : : * @member: the name of this member within the structure.
79 : : *
80 : : * Given a pointer to a member of a structure, this macro does
81 : : * typechecking and figures out the offset to the enclosing type.
82 : : *
83 : : * Example:
84 : : * struct foo {
85 : : * int fielda, fieldb;
86 : : * // ...
87 : : * };
88 : : * struct info {
89 : : * int some_other_field;
90 : : * struct foo my_foo;
91 : : * };
92 : : *
93 : : * static struct info *foo_to_info(struct foo *foo)
94 : : * {
95 : : * size_t off = container_off(struct info, my_foo);
96 : : * return (void *)((char *)foo - off);
97 : : * }
98 : : */
99 : : #define container_off(containing_type, member) \
100 : : offsetof(containing_type, member)
101 : :
102 : : /**
103 : : * container_of_var - get pointer to enclosing structure using a variable
104 : : * @member_ptr: pointer to the structure member
105 : : * @container_var: a pointer of same type as this member's container
106 : : * @member: the name of this member within the structure.
107 : : *
108 : : * Given a pointer to a member of a structure, this macro does pointer
109 : : * subtraction to return the pointer to the enclosing type.
110 : : *
111 : : * Example:
112 : : * static struct info *foo_to_i(struct foo *foo)
113 : : * {
114 : : * struct info *i = container_of_var(foo, i, my_foo);
115 : : * return i;
116 : : * }
117 : : */
118 : : #if HAVE_TYPEOF
119 : : #define container_of_var(member_ptr, container_var, member) \
120 : : container_of(member_ptr, typeof(*container_var), member)
121 : : #else
122 : : #define container_of_var(member_ptr, container_var, member) \
123 : : ((void *)((char *)(member_ptr) - \
124 : : container_off_var(container_var, member)))
125 : : #endif
126 : :
127 : : /**
128 : : * container_off_var - get offset of a field in enclosing structure
129 : : * @container_var: a pointer to a container structure
130 : : * @member: the name of a member within the structure.
131 : : *
132 : : * Given (any) pointer to a structure and a its member name, this
133 : : * macro does pointer subtraction to return offset of member in a
134 : : * structure memory layout.
135 : : *
136 : : */
137 : : #if HAVE_TYPEOF
138 : : #define container_off_var(var, member) \
139 : : container_off(typeof(*var), member)
140 : : #else
141 : : #define container_off_var(var, member) \
142 : : ((const char *)&(var)->member - (const char *)(var))
143 : : #endif
144 : :
145 : : #endif /* CCAN_CONTAINER_OF_H */
|