Named arguments via struct initialization in functions
Michael Coulombe via Digitalmars-d
digitalmars-d at puremagic.com
Wed Mar 9 21:17:03 PST 2016
On Wednesday, 9 March 2016 at 12:55:16 UTC, Idan Arye wrote:
> Allowing something like `auto params = [:y : 50, :x : 100]`
> won't really solve anything. It works nicely in Ruby, because
> Ruby has dynamic typing and with some syntactic sugar you get
> elegant syntax for dynamic structs. But in a structured
> language like D, you run into the problem that `[:y : 50, :x :
> 100] is an associative array with a determined type for it's
> values, so you can't do things like `[:y : 50, :x : "hello"]` -
> which greatly limits the usability of this syntax.
I posted (in a previous thread about this issue) a library
solution to this:
import std.typecons, std.meta;
private struct Named(string n, T) {
enum name = n;
T value;
}
template NamedToAS(N...) {
static if (N.length == 0) {
alias NamedToAS = AliasSeq!();
}
else {
alias NamedToAS = AliasSeq!(typeof(N[0].init.value),
N[0].name, NamedToAS!(N[1 .. $]));
}
}
struct Tup {
static auto opDollar(size_t i)() {
return immutable KeyWordDollar();
}
static auto opIndex(NamedArgs...)(NamedArgs nas) {
Tuple!(NamedToAS!NamedArgs) tup;
foreach(i, ref na ; tup) {
na = nas[i].value;
}
return tup;
}
}
void overrideFrom(TupDef, TupOver)(ref TupDef defaultMap, ref
TupOver overrideMap) {
foreach(i, ref field ; overrideMap) {
__traits(getMember, defaultMap, TupOver.fieldNames[i]) =
field;
}
}
auto println(KWA)(KWA kwa) {
auto args = Tup[$.str = "abc", $.repeat = 2, $.sep = " "];
args.overrideFrom(kwa);
import std.stdio;
bool first = true;
foreach(i ; 0 .. args.repeat) {
if (first) first = false; else write(args.sep);
write(args.str);
}
writeln();
}
unittest {
println(Tup[$.str = "xyz", $.repeat = 8]);
}
More information about the Digitalmars-d
mailing list