]> git.ozlabs.org Git - ccan/blob - ccan/container_of/container_of.h
tools/ccanlint: add args to main.
[ccan] / ccan / container_of / container_of.h
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 static inline char *container_of_or_null_(void *member_ptr, size_t offset)
66 {
67         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 */