rval->ref const(T), implicit conversions

tsbockman via Digitalmars-d digitalmars-d at puremagic.com
Mon Jan 18 10:57:24 PST 2016


On Monday, 18 January 2016 at 18:08:31 UTC, tsbockman wrote:
> Again, I can probably automate generation of the wrapper easily 
> enough.

Genericized:

template acceptRVals(alias func) {
private:
     import std.traits : arity;
     alias impl = acceptRVals!(arity!func);

public:
     alias acceptRVals = impl!func;
}
template acceptRVals(size_t arity) {
     private enum mixStr = function() {
         import std.conv : to;

         string ctParams = "";
         string rtParams = "";
         string callArgs = "";

         foreach(size_t a; 0 .. arity) {
             string aStr = a.to!string;
             ctParams ~= "T" ~ aStr;
             rtParams ~= "auto ref T" ~ aStr ~ " a" ~ aStr;
             callArgs ~= "a" ~ aStr;

             if(a < (arity - 1)) {
                 ctParams ~= ", ";
                 rtParams ~= ", ";
                 callArgs ~= ", ";
             }
         }

         return "pragma(inline, true) auto acceptRVals(" ~ 
ctParams ~ ")(" ~ rtParams ~ ") { return func(" ~ callArgs ~ "); 
}";
     }();

     template acceptRVals(alias func) {
         mixin(mixStr);
     }
}

struct CustomString {
     this(string data) {
         this.data = data;
     }

     string data;
     alias data this;
}

import std.stdio;

alias func = acceptRVals!(function(ref CustomString s1, ref 
CustomString s2) {
     writeln(s1);
     writeln(s2);
     s2 = "universe!";
});

void main() {
     CustomString b = CustomString("world!");
     func(CustomString("Hello"), b);

     writeln("Hello");
     writeln(b);
}

(I'm sure there are various corner cases not handled properly by 
this; obviously it would be nice if this was just handled 
automatically by the compiler like it should be.)


More information about the Digitalmars-d mailing list