d - Compile-time foreach outside function body -
is there way have foreach outside function body ex. generating code.
my scenario have associative array @ compile-time need use generate specific fields. unfortunately can't use foreach outside of function body generate members.
right using work-around have few mixins give 1 aa first mixin , mixin converts aa array , passes second mixin, second mixin recursive ng until there no more member, while calling first member in array, calls third mixin can use generate code.
it's not smooth , dynamic want , wondering if has better solution.
here solution
// first mixin takes associative array , string mixin handle items mixin template staticforeachaa(tkey,tvalue, tkey[tvalue] enumerator, string itemmixin) { enum array = arrayaa!(tkey,tvalue)(enumerator); // converts aa array of key-value pair structs alias arraytype = keyvaluepair!(tkey,tvalue); mixin staticforeacharray!(arraytype, array, itemmixin); // calls second mixin array } // second mixin "fake loops" array mixin template staticforeacharray(t, t[] array, string itemmixin) { static if (array.length) { import std.string : format; mixin(format("mixin %s!(t, array[0]);", itemmixin)); // mixins itemmixin handle current item mixin staticforeacharray!(t, array[1 .. $], itemmixin); // slices array remove item handled } } // third mixin can used whatever has done item mixin template staticforeachitem(t, t item) { import std.conv : to; pragma(msg, to!string(item)); }
and "fake foreach" associative
enum aa = [0 : 1, 1 : 2, 2 : 3]; mixin staticforeachaa!(int, int, aa, "staticforeachitem");
this print key-value pairs aa
@ compile-time.
leveraging power of compile-time functione excution (ctfe) make helper function generates code using data associative array (aa) provide.
import std.string : format; string generatecodeforeachaa(tkey, tvalue)(tvalue[tkey] data, string foreachbody) { string result; foreach(k, v ; data) { result ~= format(foreachbody, k, v); } return result; }
this function turns given aa data string formatting given foreachbody
each aa element. returned string can mixin
'ed:
enum data = [ 0 : 1, 1 : 2, 2 : 3 ]; enum code = generatecodeforeachaa(data, q{ pragma(msg, "%1$s => %2$s"); }); pragma(msg, "code: " ~ code); mixin(code);
output:
code: pragma(msg, "0 => 1"); pragma(msg, "1 => 2"); pragma(msg, "2 => 3"); 0 => 1 1 => 2 2 => 3
using generate members within struct:
struct foo { enum members = [ "foo": 123, "bar": 42 ]; mixin(generatecodeforeachaa(members, q{ typeof(%2$s) %1$s = %2$s; })); } void main() { import std.stdio : writeln; foo f; writeln("foo: ", f.foo); writeln("bar: ", f.bar); }
output:
foo: 123 bar: 42
Comments
Post a Comment