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