From: Ian Jackson Date: Fri, 27 Jan 2012 17:01:24 +0000 (+0000) Subject: libxl: New convenience macro CONTAINER_OF X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=7632e94da4d73e72a75cbc2e09326b367cf96a22;p=xen.git libxl: New convenience macro CONTAINER_OF Provide a convenient and type-safe wrapper which does the correct dance to subtract offsetof. This is very similar to the "container_of" macro in the Linux kernel, but it has an additional feature that instead of the type argument you may also pass an expression of that type; this makes initialising a variable with CONTAINER_OF easier. Signed-off-by: Ian Jackson Acked-by: Ian Campbell Committed-by: Ian Jackson --- diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 044eeb4e43..095dbcebf7 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1235,6 +1235,35 @@ _hidden void libxl__ao__destroy(libxl_ctx*, libxl__ao *ao); * Convenience macros. */ +/* + * CONTAINER_OF work like this. Given: + * typedef struct { + * ... + * member_type member_name; + * ... + * } outer_type; + * outer_type outer, *outer_var; + * member_type *inner_ptr = &outer->member_name; + * + * Then, effectively: + * outer_type *CONTAINER_OF(member_type *inner_ptr, + * *outer_var, // or type name for outer_type + * member_name); + * + * So that: + * CONTAINER_OF(inner_ptr, *outer_var, member_name) == &outer + * CONTAINER_OF(inner_ptr, outer_type, member_name) == &outer + */ +#define CONTAINER_OF(inner_ptr, outer, member_name) \ + ({ \ + typeof(outer) *container_of_; \ + container_of_ = (void*)((char*)(inner_ptr) - \ + offsetof(typeof(outer), member_name)); \ + (void)(&container_of_->member_name == \ + (typeof(inner_ptr))0) /* type check */; \ + container_of_; \ + }) + /* * All of these assume (or define)