Perfect forwarding
Jean-Louis Leroy
jl at leroy.nyc
Sun Jul 26 18:14:03 UTC 2020
On Sunday, 26 July 2020 at 01:29:21 UTC, Andrei Alexandrescu
wrote:
> This topic came about during beerconf (it was fun!): Write an
> idiomatic template `forward` that takes an alias `fun` and
> defines (generates) one overload for each overload of `fun`.
> Example:
>
> template forward(alias fun)
> {
> ...
> }
>
> Now for this function:
>
> void myfun(int, ref double, out string);
> int myfun(in string, inout double);
>
> the instantiation would be (stylized):
>
> template forward!myfun
> {
> void myfun(int a, ref double b, out string c)
> {
> return myfun(a, b, c);
> }
> int myfun(in string a, inout double b)
> {
> return myfun(a, b);
> }
> }
>
> So the challenge is implementing forward() to do this.
Using bolts' experimental refraction module:
module challenge;
import std.format;
import bolts.experimental.refraction;
template forward(alias fun)
{
enum name = __traits(identifier, fun);
static foreach (ovl; __traits(getOverloads, __traits(parent,
fun), name)) {
mixin(
{
enum original = refract!(ovl, "ovl");
return original.withBody(q{{
return %s(%s);
}}.format(original.name,
original.argumentMixture))
.mixture;
}());
}
}
void myfun(int, ref double, out string);
int myfun(in string, inout double);
pragma(msg, typeof(__traits(getOverloads, forward!myfun,
"myfun")[0]));
pragma(msg, typeof(__traits(getOverloads, forward!myfun,
"myfun")[1]));
Output:
@system void(int _0, ref double _1, out string _2)
@system int(const(string) _0, inout(double) _1)
Okay the "in" is missing in front of the first argument of the
second overload, but it doesn't seem to be there in the first
place:
pragma(msg, typeof(__traits(getOverloads, challenge,
"myfun")[1]));
Output:
int(const(string), inout(double))
Also the body of the forwarders should probably use
`std.functional.forward`.
More information about the Digitalmars-d
mailing list