Jump to page: 1 2
Thread overview
Need help with movement from C to D
May 05, 2014
Andrey
May 05, 2014
Mark Isaacson
May 05, 2014
Andrey
May 05, 2014
Meta
May 06, 2014
Andrey
May 06, 2014
Marc Schütz
May 06, 2014
Artur Skawina
May 06, 2014
bearophile
May 06, 2014
Marc Schütz
May 06, 2014
Artur Skawina
May 06, 2014
bearophile
May 08, 2014
bearophile
May 08, 2014
Mengu
May 05, 2014
bearophile
May 05, 2014
safety0ff
May 05, 2014
Andrey
May 05, 2014
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
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
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
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
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
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
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
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
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
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
« First   ‹ Prev
1 2