how to assign tuple named Tuple easily

Inquie via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Mar 13 07:09:58 PDT 2017


On Monday, 13 March 2017 at 00:51:27 UTC, Adam D. Ruppe wrote:
> On Monday, 13 March 2017 at 00:02:12 UTC, Inquie wrote:
>> I just figured it didn't work in general, but seems to be an 
>> issue with appending.
>
> Oh, it is because of the implicit construction thing, see my 
> answer here to learn more: 
> http://stackoverflow.com/a/42285015/1457000
>
> You can construct the named tuple from a tuple() but you can't 
> convert one to another since the names change the type.
>
> I don't think the language has a solution with this since you 
> can't implicit construct nor overload operators on built in 
> arrays (if it is a custom array, you can do an opOpAssign).
>
> What you could do is
>
> alias ShortName = Tuple!(int, "A");
>
> ShortName[] a;
> a ~= ShortName(3);
>
> ... of course, at that point, you can also just use a regular 
> struct too...


Yeah, so, surely though we can extract the names from the 
variable and then supply those like I mentioned?

Tuple!(int, "A")[] x;
x ~= tuple!(ExtractTupleNames!x)(3);

which would be equivalent to

x ~= tuple!("A")(3)

which, of course, works.

ExtractTupleNames is a template that surely can get the names 
from x? Knowing it's type and that every other element of the 
type is a "name" it should be able to get the names then provide 
them to tuple? From there, we could redefine tuple to do this 
automatically as

x ~= tuple!x(3)

? Seems like it would probably be rather trivial with a bit of 
template code?


Ok, I did this real quick, maybe you can see how to improve it 
and reduce verbosity:

import std.typecons, std.typetuple, std.meta, std.string, 
std.array, std.range;

template ExtractTupleNames(T)
{	

	string fix()
	{
		enum q = (T.stringof[7..$-3]);	
		return "alias ExtractTupleNames = AliasSeq!("~q~");";
	}

	mixin(fix());
	
}

void main(string[] argv)
{


	Tuple!(int, "A", double, "B")[] x;

	x ~= tuple!("A", "B")(3, 5.0);
	x ~= tuple!(int, "A", double, "B")(3, 5.0);
	x ~= tuple!(ExtractTupleNames!(typeof(x)))(3, 5.0);
}

The goal would be to not have to specify the long string each 
time.

e.g., the third line would be either

x ~= tuple!(x)(3, 5.0);

or

x ~= tuple!typeof(x)(3, 5.0);

It would be nice if we could pass a "run time" variable since we 
are only going to use it's type in the first place(avoids having 
to specify the typeof at the call point).

I realize that we will probably have to redefine tuple but I'm ok 
with that as it only makes it more robust.








More information about the Digitalmars-d-learn mailing list