As discussed in DConf2015: Python-like keyword arguments
Michael Coulombe via Digitalmars-d
digitalmars-d at puremagic.com
Fri May 29 05:59:31 PDT 2015
I know some people don't like abusing opDollar, but here's my
implementation:
import std.traits, std.algorithm, std.conv;
private struct Named(string n, T) {
enum name = n;
T value;
}
private auto makeNameIndex(NamedList...)(string[] names) {
auto indices = new size_t[](names.length);
foreach(i, n ; NamedList) {
auto x = names.countUntil(n.name);
assert(x >= 0, "Keyword Parameter \"" ~ n.name ~ "\" does
not exist in " ~ text(names));
indices[x] = i;
}
return indices;
}
private immutable struct KeyWordDollar {
@property
auto opDispatch(string param, T)(T t) {
return Named!(param,T)(t);
}
}
private struct KeyWordManager(alias f) {
private enum paramNames = [ParameterIdentifierTuple!f];
auto opDollar(size_t pos = 0)() const {
return immutable KeyWordDollar();
}
auto opIndex(NamedArgs...)(NamedArgs namedArgs) {
enum ordering = makeNameIndex!NamedArgs(paramNames);
ParameterTypeTuple!f args;
foreach(i, ref a; args) {
a = namedArgs[ ordering[i] ].value;
}
return f(args);
}
}
auto kw(alias f)() {
return KeyWordManager!f();
}
int foo(int x, int y) {
return x+y;
}
unittest {
assert(8 == kw!foo[$.y = 5, $.x = 3]);
}
More information about the Digitalmars-d
mailing list