Ecco una versione aggiornata che si compila con le recenti versioni del compilatore D:
/**
Return a Tuple expression of $(D Func) being
applied to every tuple argument.
*/
template Map(alias Func, args...)
{
static auto ref ArgCall(alias Func, alias arg)() { return Func(arg); }
static if (args.length > 1)
alias Map = TypeTuple!(ArgCall!(Func, args[0]), Map!(Func, args[1 .. $]));
else
alias Map = ArgCall!(Func, args[0]);
}
///
unittest
{
import std.conv;
int square(int arg)
{
return arg * arg;
}
int refSquare(ref int arg)
{
arg *= arg;
return arg;
}
ref int refRetSquare(ref int arg)
{
arg *= arg;
return arg;
}
void test(int a, int b)
{
assert(a == 4, a.text);
assert(b == 16, b.text);
}
void testRef(ref int a, ref int b)
{
assert(a++ == 16, a.text);
assert(b++ == 256, b.text);
}
int a = 2;
int b = 4;
test(Map!(square, a, b));
test(Map!(refSquare, a, b));
assert(a == 4);
assert(b == 16);
testRef(Map!(refRetSquare, a, b));
assert(a == 17);
assert(b == 257);
}
fonte
2012-10-17 03:55:33
in realtà che non necessariamente funziona se la trasformata di funzione restituisce un tipo diverso. Ma se hai fatto import std.traits; ParameterTypeTuple! Chiama a; piuttosto che T a ;, penso che lo farebbe. –
C'è un altro problema: non funziona quando T contiene tipi immutabili. Penso che l'unico modo per farlo bene è usare i mixin di stringhe. Sto lavorando a una richiesta di pull per Phobos ora. –
La mia implementazione funziona con tipi con campi immutabili: http://stackoverflow.com/a/12926873/279684 –