Merging two named Tuples

Edwin van Leeuwen via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Oct 29 11:59:17 PDT 2015


On Saturday, 24 October 2015 at 11:04:14 UTC, Edwin van Leeuwen 
wrote:
> I am trying to write a function to merge two named structs, but 
> am completely stuck on how to do that and was wondering if 
> anyone good provide any help. I know I can access the different 
> names with tup.fieldNames, but basically can't work out how to 
> use that to build the new return type. Below is an outline of 
> what I am trying to do (with unittest). Any pointers would be 
> greatly appreciated.

I tried the following, but get a compile error:
source/ggplotd/aes.d(633): Error: variable tup cannot be read at 
compile time
source/ggplotd/aes.d(633): Error: argument to mixin must be a 
string, not (__error)
source/ggplotd/aes.d(646): Error: template instance 
ggplotd.aes.merge!(Tuple!(string[], "x", string[], "y", string[], 
"label"), Tuple!(double[], "x", double[], "y")) error 
instantiating

import std.typecons : Tuple;
template merge(T, U)
{
     auto merge( T base, U other )
     {
         string typing = "Tuple!(";
         string variables = "(";
         foreach( i, t; other.fieldNames )
         {
             typing ~= other.Types[i].stringof ~ ",\"" ~ t ~ "\",";
             variables ~= "other." ~ t ~ ",";
         }

         foreach( i, t; base.fieldNames )
         {
             bool contains = false;
             foreach( _, t2; other.fieldNames )
             {
                 if (t==t2)
                     contains = true;
             }
             if (!contains)
             {
                 typing ~= base.Types[i].stringof ~ ",\"" ~ t ~ 
"\",";
                 variables ~= "base." ~ t ~ ",";
             }
         }
         string tup = typing[0..$-1] ~ ")" ~ variables[0..$-1] ~ 
");";
         // Do some clever CTFE
         return mixin(tup);
     }
}

///
unittest
{
     auto xs = ["a","b"];
     auto ys = ["c","d"];
     auto labels = ["e","f"];
     auto aes = Tuple!(string[], "x", string[], "y", string[], 
"label")(
             xs, ys, labels );

     auto nlAes = merge( aes, Tuple!(double[], "x",
                 double[], "y" )(
                 [0,1], [3,4] ) );

     assertEqual( nlAes.x[0], 0 );
     assertEqual( nlAes.label.front, "e" );
}

I guess fieldNames does not exist at compile time? Can I get the 
fieldNames etc at compile time?

Cheers, Edwin


More information about the Digitalmars-d-learn mailing list