On Tuesday, 23 May 2017 at 18:14:34 UTC, ag0aep6g wrote:
Something like this:
----
import core.vararg;
import std.meta: AliasSeq, staticMap;
import std.traits: isCopyable;
struct A
{
void delegate(...) dg;
auto fun(T, U ...)(T t, auto ref U u)
{
template UncopyableToPointer(T)
{
static if (!isCopyable!T) alias UncopyableToPointer
= T*;
else alias UncopyableToPointer = T;
}
alias U2 = staticMap!(UncopyableToPointer, U);
U2 u2;
foreach (i, E; U)
{
static if (!isCopyable!E) u2[i] = &u[i];
else u2[i] = u[i];
}
return dg(t, u2);
}
}
struct SomeStructThatIsNotCopyable
{
@disable this(this);
}
void main()
{
void dlg(...)
{
import std.stdio;
foreach (i, t; _arguments)
{
foreach (T; AliasSeq!(int, string,
SomeStructThatIsNotCopyable*))
{
if (t == typeid(T))
{
static if (is(T : U*, U) && !isCopyable!U)
{
write("uncopyable type");
}
else write(_argptr.va_arg!T);
}
}
/* otherwise: don't know how to handle the type */
write(" ");
}
writeln();
}
auto a = A(&dlg);
SomeStructThatIsNotCopyable s;
a.fun(5, "a", /* by ref: */ s, /* or by pointer: */ &s);
}
----
That's not exactly pretty, of course. Both A.fun and the
delegate are quite complicated. But it might be workable, if
run-time variadics are acceptable.
I wouldn't be surprised if the problem can be solved more
elegantly. But I don't see how at the moment.
That's cool :)
but anyway, even if I have such params, there are not much of
them, so it just a minor semantic issue to explicitely name them
and their types instead of showing, that they are passed but not
used inside dlg.
And thanks a lot to all for great ideas :)