string interpolation fun

Steven Schveighoffer schveiguy at gmail.com
Thu Dec 13 15:53:01 UTC 2018


Another idea I had for solving a different problem with string 
interpolation: better named-field struct initialization.

The below compiles and runs as expected with 
https://github.com/dlang/dmd/pull/7988

//
// build T with parameters using string interpolation
//
T make(T, Args...)() if (Args.length > 0 && Args.length % 2 == 0)
{
     T result;
     import std.string;
     static foreach(i; 0 .. Args.length / 2)
     {{
         // remove all punctuation and spaces
          static assert(is(typeof(Args[i * 2]) == string));
         enum symbol = Args[i * 2].strip(" :=,");
         static if(symbol.length > 0)
         {
             __traits(getMember, result, symbol) = Args[i * 2 + 1];
         }
         else
         {
             __traits(getMember, result, __traits(identifier, Args[i * 2 
+ 1])) = Args[i * 2 + 1];
         }
     }}
     return result;
}

struct S
{
     int x;
     int y;
}
void main()
{
     import std.stdio;
     int x = 1;
     int y = 2;
     auto s = make!(S, i"x: $(y), y: $(x)"); // name the fields to assign
     auto s2 = make!(S, i":$(x), :$(y)"); // use symbol name as field name
     auto s3 = make!(S, i"x: $(6), y: $(7)"); // use literals to assign
     writeln(i"$(s), $(s2), $(s3)"); // runtime parameters
}


One thing we are missing here, is a sure-fire way to know which parts of 
the CT-sequence are literal, and which ones are parameters. For 
instance, at first I tried this for s2:

make!(S, i"$(x), $(y)");

but it failed because there is no prefix string for x. I couldn't think 
of a good static if condition that checked to see if the parameter was 
string literal or not, without also capturing string expressions inside 
the $().

Any ideas?

-Steve


More information about the Digitalmars-d mailing list