Norman James | 6a58a27 | 2015-10-07 14:34:16 -0500 | [diff] [blame] | 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 | * container_off - get offset to enclosing structure
|
| 41 | * @containing_type: the type this member is within
|
| 42 | * @member: the name of this member within the structure.
|
| 43 | *
|
| 44 | * Given a pointer to a member of a structure, this macro does
|
| 45 | * typechecking and figures out the offset to the enclosing type.
|
| 46 | *
|
| 47 | * Example:
|
| 48 | * struct foo {
|
| 49 | * int fielda, fieldb;
|
| 50 | * // ...
|
| 51 | * };
|
| 52 | * struct info {
|
| 53 | * int some_other_field;
|
| 54 | * struct foo my_foo;
|
| 55 | * };
|
| 56 | *
|
| 57 | * static struct info *foo_to_info(struct foo *foo)
|
| 58 | * {
|
| 59 | * size_t off = container_off(struct info, my_foo);
|
| 60 | * return (void *)((char *)foo - off);
|
| 61 | * }
|
| 62 | */
|
| 63 | #define container_off(containing_type, member) \
|
| 64 | offsetof(containing_type, member)
|
| 65 |
|
| 66 | /**
|
| 67 | * container_of_var - get pointer to enclosing structure using a variable
|
| 68 | * @member_ptr: pointer to the structure member
|
| 69 | * @container_var: a pointer of same type as this member's container
|
| 70 | * @member: the name of this member within the structure.
|
| 71 | *
|
| 72 | * Given a pointer to a member of a structure, this macro does pointer
|
| 73 | * subtraction to return the pointer to the enclosing type.
|
| 74 | *
|
| 75 | * Example:
|
| 76 | * static struct info *foo_to_i(struct foo *foo)
|
| 77 | * {
|
| 78 | * struct info *i = container_of_var(foo, i, my_foo);
|
| 79 | * return i;
|
| 80 | * }
|
| 81 | */
|
| 82 | #if HAVE_TYPEOF
|
| 83 | #define container_of_var(member_ptr, container_var, member) \
|
| 84 | container_of(member_ptr, typeof(*container_var), member)
|
| 85 | #else
|
| 86 | #define container_of_var(member_ptr, container_var, member) \
|
| 87 | ((void *)((char *)(member_ptr) - \
|
| 88 | container_off_var(container_var, member)))
|
| 89 | #endif
|
| 90 |
|
| 91 | /**
|
| 92 | * container_off_var - get offset of a field in enclosing structure
|
| 93 | * @container_var: a pointer to a container structure
|
| 94 | * @member: the name of a member within the structure.
|
| 95 | *
|
| 96 | * Given (any) pointer to a structure and a its member name, this
|
| 97 | * macro does pointer subtraction to return offset of member in a
|
| 98 | * structure memory layout.
|
| 99 | *
|
| 100 | */
|
| 101 | #if HAVE_TYPEOF
|
| 102 | #define container_off_var(var, member) \
|
| 103 | container_off(typeof(*var), member)
|
| 104 | #else
|
| 105 | #define container_off_var(var, member) \
|
| 106 | ((char *)&(var)->member - (char *)(var))
|
| 107 | #endif
|
| 108 |
|
| 109 | #endif /* CCAN_CONTAINER_OF_H */
|