summaryrefslogtreecommitdiff
path: root/jni/ruby/ccan/container_of/container_of.h
blob: ae3e1fc81f905aa5117a76bd477db5c9befd8115 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* CC0 (Public domain) - see ccan/licenses/CC0 file for details */
#ifndef CCAN_CONTAINER_OF_H
#define CCAN_CONTAINER_OF_H
#include "ccan/check_type/check_type.h"

/**
 * container_of - get pointer to enclosing structure
 * @member_ptr: pointer to the structure member
 * @containing_type: the type this member is within
 * @member: the name of this member within the structure.
 *
 * Given a pointer to a member of a structure, this macro does pointer
 * subtraction to return the pointer to the enclosing type.
 *
 * Example:
 *      struct foo {
 *              int fielda, fieldb;
 *              // ...
 *      };
 *      struct info {
 *              int some_other_field;
 *              struct foo my_foo;
 *      };
 *
 *      static struct info *foo_to_info(struct foo *foo)
 *      {
 *              return container_of(foo, struct info, my_foo);
 *      }
 */
#define container_of(member_ptr, containing_type, member)               \
         ((containing_type *)                                           \
          ((char *)(member_ptr)                                         \
           - container_off(containing_type, member))                    \
          + check_types_match(*(member_ptr), ((containing_type *)0)->member))


/**
 * container_of_or_null - get pointer to enclosing structure, or NULL
 * @member_ptr: pointer to the structure member
 * @containing_type: the type this member is within
 * @member: the name of this member within the structure.
 *
 * Given a pointer to a member of a structure, this macro does pointer
 * subtraction to return the pointer to the enclosing type, unless it
 * is given NULL, in which case it also returns NULL.
 *
 * Example:
 *      struct foo {
 *              int fielda, fieldb;
 *              // ...
 *      };
 *      struct info {
 *              int some_other_field;
 *              struct foo my_foo;
 *      };
 *
 *      static struct info *foo_to_info_allowing_null(struct foo *foo)
 *      {
 *              return container_of_or_null(foo, struct info, my_foo);
 *      }
 */
static inline char *container_of_or_null_(void *member_ptr, size_t offset)
{
        return member_ptr ? (char *)member_ptr - offset : NULL;
}
#define container_of_or_null(member_ptr, containing_type, member)       \
        ((containing_type *)                                            \
         container_of_or_null_(member_ptr,                              \
                               container_off(containing_type, member))  \
         + check_types_match(*(member_ptr), ((containing_type *)0)->member))

/**
 * container_off - get offset to enclosing structure
 * @containing_type: the type this member is within
 * @member: the name of this member within the structure.
 *
 * Given a pointer to a member of a structure, this macro does
 * typechecking and figures out the offset to the enclosing type.
 *
 * Example:
 *      struct foo {
 *              int fielda, fieldb;
 *              // ...
 *      };
 *      struct info {
 *              int some_other_field;
 *              struct foo my_foo;
 *      };
 *
 *      static struct info *foo_to_info(struct foo *foo)
 *      {
 *              size_t off = container_off(struct info, my_foo);
 *              return (void *)((char *)foo - off);
 *      }
 */
#define container_off(containing_type, member)  \
        offsetof(containing_type, member)

/**
 * container_of_var - get pointer to enclosing structure using a variable
 * @member_ptr: pointer to the structure member
 * @container_var: a pointer of same type as this member's container
 * @member: the name of this member within the structure.
 *
 * Given a pointer to a member of a structure, this macro does pointer
 * subtraction to return the pointer to the enclosing type.
 *
 * Example:
 *      static struct info *foo_to_i(struct foo *foo)
 *      {
 *              struct info *i = container_of_var(foo, i, my_foo);
 *              return i;
 *      }
 */
#if HAVE_TYPEOF
#define container_of_var(member_ptr, container_var, member) \
        container_of(member_ptr, typeof(*container_var), member)
#else
#define container_of_var(member_ptr, container_var, member)     \
        ((void *)((char *)(member_ptr)  -                       \
                  container_off_var(container_var, member)))
#endif

/**
 * container_off_var - get offset of a field in enclosing structure
 * @container_var: a pointer to a container structure
 * @member: the name of a member within the structure.
 *
 * Given (any) pointer to a structure and a its member name, this
 * macro does pointer subtraction to return offset of member in a
 * structure memory layout.
 *
 */
#if HAVE_TYPEOF
#define container_off_var(var, member)          \
        container_off(typeof(*var), member)
#else
#define container_off_var(var, member)                  \
        ((const char *)&(var)->member - (const char *)(var))
#endif

#endif /* CCAN_CONTAINER_OF_H */