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 :)

Reply via email to