Last active
June 10, 2016 17:52
-
-
Save alphaKAI/7bf01010b3ef6f9190960735bc400746 to your computer and use it in GitHub Desktop.
D language's template version of C's container_of and offsetof macro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#define offsetof(type, member) ((size_t)&((type*)0)->member) | |
#define container_of(ptr, type, member) ({ \ | |
const typeof( ((type *)0)->member ) *__mptr = (ptr); \ | |
(type *)( (char *)__mptr - offsetof(type,member) );}) | |
typedef struct { | |
int val1; | |
int val2; | |
} Container; | |
int main() { | |
Container c1; | |
static int val1 = 1, | |
val2 = 2; | |
c1.val1 = val1; | |
c1.val2 = val2; | |
printf("%d\n", container_of(&val2, Container, val2)->val1); | |
printf("%d\n", container_of(&val1, Container, val1)->val2); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.stdio; | |
//#define offsetof(type, member) ((size_t)&((type*)0)->member) | |
template offsetof(type, string member) { | |
size_t offsetof() { | |
return mixin("(cast(size_t)&(cast(" ~ type.stringof ~ "*)0)." ~ member ~ ")"); | |
} | |
} | |
/* | |
#define container_of(ptr, type, member) ({ \ | |
const typeof( ((type *)0)->member ) *__mptr = (ptr); \ | |
(type *)( (char *)__mptr - offsetof(type,member) );}) | |
*/ | |
template container_of_impl(P:P*, type, string member) { | |
type* container_of_impl(P* ptr) { | |
mixin("const typeof( ((cast(" ~ type.stringof ~ "*)0)." ~ member ~ ") )* __mptr = (ptr);"); | |
return cast(type*)( cast(ubyte*)__mptr - offsetof!(type, member)); | |
} | |
} | |
template container_of(type, string member) { | |
string container_of() { | |
return "(cast(" ~ type.stringof ~ "*)container_of_impl!(typeof(&" ~ member ~ "), " ~ type.stringof ~ ", " ~ member.stringof ~ ")(&" ~ member ~ "))"; | |
} | |
} | |
struct Container { | |
int val1, | |
val2; | |
} | |
void main() { | |
Container c1; | |
static int val1 = 1, | |
val2 =2; | |
c1.val1 = val1; | |
c1.val2 = val2; | |
writeln((mixin(container_of!(Container, "val2"))).val1); | |
writeln((mixin(container_of!(Container, "val1"))).val2); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment