Re: Need help with movement from C to D
Artur Skawina: But I have no idea why anybody would want to wrap this trivial expression like that. And, I have no idea if the, hmm, /unconventional/ D offsetof semantics are in the bugzilla. It's not really a bug, but a design mistake... https://issues.dlang.org/show_bug.cgi?id=12714 Bye, bearophile
Re: Need help with movement from C to D
On Tuesday, 6 May 2014 at 15:13:41 UTC, Artur Skawina via Digitalmars-d-learn wrote: On 05/06/14 16:45, via Digitalmars-d-learn wrote: On Tuesday, 6 May 2014 at 14:25:01 UTC, Artur Skawina via Digitalmars-d-learn wrote: 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); Great, that's even shorter. Somehow I was fixated on converting the symbol to a string first, but of course the name is directly available in the mixin: enum offsetof(alias typenfield) = mixin(typenfield.offsetof); I didn't realize that worked, but it does. So... enum offsetOf(alias A) = A.offsetof; But I have no idea why anybody would want to wrap this trivial expression like that. And, I have no idea if the, hmm, /unconventional/ D offsetof semantics are in the bugzilla. It's not really a bug, but a design mistake... artur just out of curiousity, why an alias is used there?
Re: Need help with movement from C to D
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));
Re: Need help with movement from C to D
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);
Re: Need help with movement from C to D
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
Re: Need help with movement from C to D
Artur Skawina: 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. Is this in Bugzilla? Bye, bearophile
Re: Need help with movement from C to D
On Tuesday, 6 May 2014 at 14:25:01 UTC, Artur Skawina via Digitalmars-d-learn wrote: 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); Great, that's even shorter. Somehow I was fixated on converting the symbol to a string first, but of course the name is directly available in the mixin: enum offsetof(alias typenfield) = mixin(typenfield.offsetof);
Re: Need help with movement from C to D
On 05/06/14 16:45, via Digitalmars-d-learn wrote: On Tuesday, 6 May 2014 at 14:25:01 UTC, Artur Skawina via Digitalmars-d-learn wrote: 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); Great, that's even shorter. Somehow I was fixated on converting the symbol to a string first, but of course the name is directly available in the mixin: enum offsetof(alias typenfield) = mixin(typenfield.offsetof); I didn't realize that worked, but it does. So... enum offsetOf(alias A) = A.offsetof; But I have no idea why anybody would want to wrap this trivial expression like that. And, I have no idea if the, hmm, /unconventional/ D offsetof semantics are in the bugzilla. It's not really a bug, but a design mistake... artur
Re: Need help with movement from C to D
Artur Skawina: And, I have no idea if the, hmm, /unconventional/ D offsetof semantics are in the bugzilla. It's not really a bug, but a design mistake... Design mistakes are valid bugzilla entries. At worst the bad behavior could be documented. But often it's possible to fix the design too, with a small breaking change. Bye, bearophile
Re: Need help with movement from C to D
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
Re: Need help with movement from C to D
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; }
Re: Need help with movement from C to D
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!!!
Re: Need help with movement from C to D
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!!
Re: Need help with movement from C to D
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.
Re: Need help with movement from C to D
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.