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