Thread overview | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 05, 2014 Need help with movement from C to D | ||||
---|---|---|---|---|
| ||||
Guys, could someone help me with suitable template? I have C macro, which calculates the offset of the field in a struct: #define offsetof(type, field) ((long) &((type *)0)->field) A similar D code is, as far as I know, type.field.offsetof Is there an any way to make a corresponding D template? Thank you! |
May 05, 2014 Re: Need help with movement from C to D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrey | On Monday, 5 May 2014 at 03:57:54 UTC, Andrey wrote:
> Guys, could someone help me with suitable template?
>
> I have C macro, which calculates the offset of the field in a struct:
>
> #define offsetof(type, field) ((long) &((type *)0)->field)
>
> A similar D code is, as far as I know,
>
> type.field.offsetof
>
> Is there an any way to make a corresponding D template?
>
> Thank you!
Something like:
unittest {
enum offsetof(string type, string field) = mixin(type ~ "." ~ field ~ ".offsetof");
struct StrToBob {
string str;
int bob;
}
writeln(offsetof!("StrToBob", "bob"));
}
?
If not that then I'm not sure what you're asking for.
|
May 05, 2014 Re: Need help with movement from C to D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrey | Andrey: > A similar D code is, as far as I know, > > type.field.offsetof Yes, it's a built-in feature of D. > Is there an any way to make a corresponding D template? I don't understand. Please explain better. Bye, bearophile |
May 05, 2014 Re: Need help with movement from C to D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrey | On Monday, 5 May 2014 at 03:57:54 UTC, Andrey wrote: > > A similar D code is, as far as I know, > > type.field.offsetof > > Is there an any way to make a corresponding D template? What you've written is the specific syntax for offsetof in D. If the intent is to create a template so that you can simply find/replace offsetof(type,field) with offsetoftemplate!(type,field) then I think it is easier to create a sed script - better yet a D program - for replacing the C macro with D code. Example program: import std.array; import std.file; import std.regex; import std.string; int main(string[] args) { if (args.length < 2) return -1; auto regex = ctRegex!(`offsetof\(([^,]+),([^)]+)\)`); auto sink = appender!(char[])(); foreach (filename; args[1..$]) { auto text = readText(filename); sink.reserve(text.length); replaceAllInto!(cap => cap[1].strip~"."~cap[2].strip~".offsetof")(sink, text, regex); write(filename, sink.data); sink.clear(); } return 0; } |
May 05, 2014 Re: Need help with movement from C to D | ||||
---|---|---|---|---|
| ||||
Posted in reply to safety0ff | On Monday, 5 May 2014 at 09:04:29 UTC, safety0ff wrote:
> auto regex = ctRegex!(`offsetof\(([^,]+),([^)]+)\)`);
> auto sink = appender!(char[])();
> foreach (filename; args[1..$])
> {
> auto text = readText(filename);
> sink.reserve(text.length);
> replaceAllInto!(cap => cap[1].strip~"."~cap[2].strip~".offsetof")(sink, text, regex);
> write(filename, sink.data);
> sink.clear();
> }
> return 0;
> }
Cool!! Thank you!!!
|
May 05, 2014 Re: Need help with movement from C to D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Isaacson | On Monday, 5 May 2014 at 04:05:35 UTC, Mark Isaacson wrote:
> enum offsetof(string type, string field) = mixin(type ~ "." ~ field ~ ".offsetof");
>
That's exactly what I'm looking for!!
|
May 05, 2014 Re: Need help with movement from C to D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Isaacson | On Monday, 5 May 2014 at 04:05:35 UTC, Mark Isaacson wrote:
> Something like:
>
> unittest {
> enum offsetof(string type, string field) = mixin(type ~ "." ~ field ~ ".offsetof");
>
> struct StrToBob {
> string str;
> int bob;
> }
>
> writeln(offsetof!("StrToBob", "bob"));
> }
>
> ?
>
> If not that then I'm not sure what you're asking for.
That enum template might be better like this:
enum offsetof(T, string field) = mixin(type.stringof ~ "." ~ field ~ ".offsetof");
To ensure that a syntactically valid symbol is passed as the type.
|
May 06, 2014 Re: Need help with movement from C to D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Monday, 5 May 2014 at 17:55:37 UTC, Meta wrote: > > enum offsetof(T, string field) = mixin(type.stringof ~ "." ~ field ~ ".offsetof"); > > To ensure that a syntactically valid symbol is passed as the type. Interestingly, but this code doesn't compile: enum offsetof(typenfield) = mixin(type.stringof ~ ".offsetof"); writeln(offsetof!(StrToBob.bob)); |
May 06, 2014 Re: Need help with movement from C to D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrey | On Tuesday, 6 May 2014 at 11:09:37 UTC, Andrey wrote: > On Monday, 5 May 2014 at 17:55:37 UTC, Meta wrote: > >> >> enum offsetof(T, string field) = mixin(type.stringof ~ "." ~ field ~ ".offsetof"); >> >> To ensure that a syntactically valid symbol is passed as the type. > > Interestingly, but this code doesn't compile: > > enum offsetof(typenfield) = mixin(type.stringof ~ ".offsetof"); > > writeln(offsetof!(StrToBob.bob)); That's because `StrToBob.bob.stringof` is "bob". You can use this instead: import std.traits; enum offsetof(alias typenfield) = mixin(fullyQualifiedName!(typenfield) ~ ".offsetof"); |
May 06, 2014 Re: Need help with movement from C to D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | I'm not sure why you'd want to wrap the .offsetof expression in a template, but it can easily be done like this: enum offsetOf(alias A, string S) = mixin("A."~S~".offsetof"); Keep in mind that D's offsetof is flawed - if the object does not contain the requested member, but implicitly converts to another one that does have such field then the expression compiles, but yields a bogus value. Eg struct S { int a, b, c; S2 s2; alias s2 this; } struct S2 { int d, e; } static assert(S.e.offsetof==4); // Oops. artur |
Copyright © 1999-2021 by the D Language Foundation