container_of.h (4619B)
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 "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 */