Thread overview
in a template argument, specify which object member to access?
Feb 08, 2016
cy
Feb 08, 2016
Mengu
Feb 08, 2016
cy
Feb 08, 2016
cym13
Feb 09, 2016
Mengu
Feb 08, 2016
cy
February 08, 2016
object.member lets me access the member of the object, but what if I want to access those members in a generic way, but in a different arrangement depending on context? Like if I wanted to first follow a tree down, and second priority would be going left to right, but then I wanted to first go right, and second priority would be going down to up.

struct A {
	string up;
	string down;
	string left;
	string right;
}

template goPlaces(D1,D2,D3) {
	string go(A a) {
		return "go " ~ a.D1 ~ " then go " ~ a.D2 ~ " then go " ~ a.D3;
	}
}

import std.stdio;

void main() {
	A a = {"north","south","east","west"};
	writeln(goPlaces!(up,down,left)(a));
}

Do I just have to use a mixin? Or implement those members as indexes in an array, if I want to use them differently?

enum Way { UP, DOWN, LEFT, RIGHT };
struct A {
	string[Way.max+1] ways;
}
...
February 08, 2016
On Monday, 8 February 2016 at 21:09:47 UTC, cy wrote:
> object.member lets me access the member of the object, but what if I want to access those members in a generic way, but in a different arrangement depending on context? Like if I wanted to first follow a tree down, and second priority would be going left to right, but then I wanted to first go right, and second priority would be going down to up.
>
> [...]

i believe you can use __traits(getMember) there.
February 08, 2016
This is what I have so far. Using mixin(rawstring~templatearg) for every time I access the member is kind of cludgy though.

struct A {
	string up;
	string down;
	string left;
	string right;
}

template goPlaces(string D1, string D2, string D3) {
	string goPlaces(ref A a) {
		mixin("a."~D2) = "deetoo";
		return "go " ~
			mixin("a."~D1) ~ " then go " ~
			mixin("a."~D2) ~ " then go " ~
			mixin("a."~D3);		
	}
}

void main() {
	import std.stdio;
	A a = {"north","south","east","west"};
	writeln(goPlaces!("up","left","down")(a));
	writeln(a.left);
}

>top postinglol
On Monday, 8 February 2016 at 21:09:47 UTC, cy wrote:
> object.member lets me access the member of the object, but what if I want to access those members in a generic way, but in a different arrangement depending on context? Like if I wanted to first follow a tree down, and second priority would be going left to right, but then I wanted to first go right, and second priority would be going down to up.
>
> struct A {
> 	string up;
> 	string down;
> 	string left;
> 	string right;
> }
>
> template goPlaces(D1,D2,D3) {
> 	string go(A a) {
> 		return "go " ~ a.D1 ~ " then go " ~ a.D2 ~ " then go " ~ a.D3;
> 	}
> }
>
> import std.stdio;
>
> void main() {
> 	A a = {"north","south","east","west"};
> 	writeln(goPlaces!(up,down,left)(a));
> }
>
> Do I just have to use a mixin? Or implement those members as indexes in an array, if I want to use them differently?
>
> enum Way { UP, DOWN, LEFT, RIGHT };
> struct A {
> 	string[Way.max+1] ways;
> }
> ...

February 08, 2016
On Monday, 8 February 2016 at 22:38:45 UTC, Mengu wrote:
> i believe you can use __traits(getMember) there.

Great! Should have refreshed before sending that reply...

I wonder if mixin("a."~member) is better or worse than __traits(getMember,a,member)...
February 08, 2016
On Monday, 8 February 2016 at 22:46:06 UTC, cy wrote:
> On Monday, 8 February 2016 at 22:38:45 UTC, Mengu wrote:
>> i believe you can use __traits(getMember) there.
>
> Great! Should have refreshed before sending that reply...
>
> I wonder if mixin("a."~member) is better or worse than __traits(getMember,a,member)...

I think I prefer the mixin version because it doesn't rely on compiler internals and is easier to read IMHO but this is very questionable.
February 09, 2016
On Monday, 8 February 2016 at 22:46:06 UTC, cy wrote:
> On Monday, 8 February 2016 at 22:38:45 UTC, Mengu wrote:
>> i believe you can use __traits(getMember) there.
>
> Great! Should have refreshed before sending that reply...
>
> I wonder if mixin("a."~member) is better or worse than __traits(getMember,a,member)...

i think it's a matter of taste and here's how i would do it:

import std.stdio;
import std.array;

struct A {
  string up;
  string down;
  string left;
  string right;
}

string goPlaces(args...)(A a) {
  string[] result;
  foreach (arg; args) {
    result ~= __traits(getMember, a, arg);
  }
  return "go " ~ result.join(" then go ");
}

void main() {
  A a = {"north", "south", "east", "west"};
  writeln(goPlaces!("up", "down", "left")(a));
  writeln(goPlaces!("down", "right", "left", "up")(a));
}

// outputs
// go north then go south then go east
// go south then go west then go east then go north