]> git.ozlabs.org Git - ccan/blob - ccan/container_of/container_of.h
ea8f1dd36cc191d6d3d3f690d342c0845d61d32e
[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(containing_type, member))                    \
36           + check_types_match(*(member_ptr), ((containing_type *)0)->member))
37
38 /**
39  * container_off - get offset to enclosing structure
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  * Example:
47  *      struct foo {
48  *              int fielda, fieldb;
49  *              // ...
50  *      };
51  *      struct info {
52  *              int some_other_field;
53  *              struct foo my_foo;
54  *      };
55  *
56  *      static struct info *foo_to_info(struct foo *foo)
57  *      {
58  *              size_t off = container_off(struct info, my_foo);
59  *              return (void *)((char *)foo - off);
60  *      }
61  */
62 #define container_off(containing_type, member)  \
63         offsetof(containing_type, member)
64
65 /**
66  * container_of_var - get pointer to enclosing structure using a variable
67  * @member_ptr: pointer to the structure member
68  * @container_var: a pointer of same type as this member's container
69  * @member: the name of this member within the structure.
70  *
71  * Given a pointer to a member of a structure, this macro does pointer
72  * subtraction to return the pointer to the enclosing type.
73  *
74  * Example:
75  *      static struct info *foo_to_i(struct foo *foo)
76  *      {
77  *              struct info *i = container_of_var(foo, i, my_foo);
78  *              return i;
79  *      }
80  */
81 #if HAVE_TYPEOF
82 #define container_of_var(member_ptr, container_var, member) \
83         container_of(member_ptr, typeof(*container_var), member)
84 #else
85 #define container_of_var(member_ptr, container_var, member)             \
86         ((void *)((char *)(member_ptr)                                  \
87                   - ((char *)&(container_var)->member                   \
88                      - (char *)(container_var))))
89 #endif
90
91 #endif /* CCAN_CONTAINER_OF_H */