www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Another attempt at passing keyword-arguments to functions

reply Tomer Filiba <tomerfiliba gmail.com> writes:
What do you guys think?

struct KW(alias F) {
     private import std.string, std.range, std.traits, 
std.typecons, std.algorithm;
     mixin({
         string s;
         foreach(i, name; ParameterIdentifierTuple!F) {
             static assert ((ParameterStorageClassTuple!F[i] & 
ParameterStorageClass.out_) == 0, "Cannot pass 'out' parameters");
             static assert ((ParameterStorageClassTuple!F[i] & 
ParameterStorageClass.ref_) == 0, "Cannot pass 'ref' parameters");
             s ~= fullyQualifiedName!(ParameterTypeTuple!F[i]) ~ " 
" ~ name ~ ";\n";
         }
         return s;
     }());
     private static KW _instance;

      disable this();
      disable this(this);

     static auto opIndex(T...)(ref T _) {
         static assert (T.length == 
ParameterIdentifierTuple!F.length);
         mixin("return F(" ~ 
ParameterIdentifierTuple!F.tuple.array.map!(p => "_instance." ~ 
p).join(",") ~ ");");
     }

     static KW* opDollar(int dim)() {
         return &_instance;
     }
}

auto f(int x, string y) {
     return x*2 + y.length;
}

void main() {
     auto res = KW!f[$.y = "foo", $.x = 5];

     import std.stdio;
     writeln(res);     // 13
}


-tomer
Nov 09 2015
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 9 November 2015 at 12:11:31 UTC, Tomer Filiba wrote:
 What do you guys think?
Clever, nice code. You could also do something similar with a delegate.. like rig it so KW!f((args) { args.foo = "bar"; args.bar = 12; }); calls it in a similar way. There, you'd just pass the args pointer to the function rather than through the opDollar. But either way, nice usage of things.
Nov 09 2015