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