July 23, 2018 static foreach and function generation | ||||
---|---|---|---|---|
| ||||
Consider: module genfun; import std.stdio, std.format, std.traits; void foo(int a) { writeln("foo(%s)".format(a)); } void foo(int a, int b) { writeln("foo(%s, %s)".format(a, b)); } static foreach (fun; __traits(allMembers, genfun)) { static if (fun == "foo") { static if (is(typeof(__traits(getOverloads, genfun, fun)))) { static foreach (ovl; __traits(getOverloads, genfun, fun)) { void foobar(Parameters!ovl args) { // HERE write("calling "); foo(args); // HERE } } } } } void main() { foobar(1); // calling foo(1) foobar(1, 2); // calling foo(1, 2) } Now I would like to change `foo` and `foobar` to calculated symbols where marked. I would also like to use as little string mixin as possible. I tried: static foreach (fun; __traits(allMembers, genfun)) { static if (fun == "foo") { static if (is(typeof(__traits(getOverloads, genfun, fun)))) { static foreach (ovl; __traits(getOverloads, genfun, fun)) { void mixin(fun + "bar")(Parameters!ovl args) { // 1 write("calling "); mixin(fun)(args); // 2 } } } } } This gets me halfway there: #2 works but #1 does not. This works: static foreach (fun; __traits(allMembers, genfun)) { static if (fun == "foo") { static if (is(typeof(__traits(getOverloads, genfun, fun)))) { static foreach (ovl; __traits(getOverloads, genfun, fun)) { void internal(Parameters!ovl args) { mixin(fun)(args); } mixin("alias %sbar = internal;".format(fun)); } } } } Does anyone see a potential problems with this? Or a better solution? I would like to avoid the alias. |
July 23, 2018 Re: static foreach and function generation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jean-Louis Leroy | On 23.07.2018 19:05, Jean-Louis Leroy wrote: > > > This works: > > static foreach (fun; __traits(allMembers, genfun)) { > static if (fun == "foo") { > static if (is(typeof(__traits(getOverloads, genfun, fun)))) { > static foreach (ovl; __traits(getOverloads, genfun, fun)) { > void internal(Parameters!ovl args) { > mixin(fun)(args); > } > mixin("alias %sbar = internal;".format(fun)); > } > } > } > } > > > Does anyone see a potential problems with this? It generates additional symbols. > Or a better solution? I would like to avoid the alias. You can mix in the entire declaration. mixin(`void `~fun~`bar(Parameters!ovl args) { mixin(fun)(args); }`); It would of course be useful if the locations where string mixins can occur were less restricted, such that things like void mixin(fun~`bar`)(Parameters!ovl args){ ... } would work too, but this will require a DIP. |
Copyright © 1999-2021 by the D Language Foundation