Commit 87f505a5 authored by Rusty Russell's avatar Rusty Russell

container_of: add container_off_var macro

Based on patch by Andrey Smirnov <andrew.smirnov@gmail.com>:
    
    There is are certain use-cases when it is necessary to know the offset
    of the member in a structure's memory layout. One such use-case can be
    seen in `ccan/list/list.h' in macros `list_for_each' and
    `list_for_each_safe'. This commit implements said functionality with
    `container_of_var_off' macro.

Renamed container_of_var_off -> container_off_var now we have container_off.
parent 56023cca
......@@ -82,10 +82,27 @@
#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) \
- ((char *)&(container_var)->member \
- (char *)(container_var))))
#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) \
((char *)&(var)->member - (char *)(var))
#endif
#endif /* CCAN_CONTAINER_OF_H */
......@@ -12,7 +12,7 @@ int main(int argc, char *argv[])
int *intp = &foo.a;
char *charp = &foo.b;
plan_tests(6);
plan_tests(8);
ok1(container_of(intp, struct foo, a) == &foo);
ok1(container_of(charp, struct foo, b) == &foo);
ok1(container_of_var(intp, &foo, a) == &foo);
......@@ -20,5 +20,7 @@ int main(int argc, char *argv[])
ok1(container_off(struct foo, a) == 0);
ok1(container_off(struct foo, b) == offsetof(struct foo, b));
ok1(container_off_var(&foo, a) == 0);
ok1(container_off_var(&foo, b) == offsetof(struct foo, b));
return exit_status();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment