On Monday, 8 February 2016 at 13:37:19 UTC, Andrei Alexandrescu wrote:
On 2/7/16 7:11 PM, John Colvin wrote:
alias dump = dumpTo!stdout;
alias errDump = dumpTo!stderr;

I'm hoping for something with a simpler syntax, a la dump!(stdout, "x") where stdout is optional. -- Andrei

How about this, which allows you to specify variables as alias parameters (i.e. without strings) as well. It could be a lot neater if a static assert is used in the body instead of using template constraints, but obviously that has its downsides.

import std.stdio : File;
import std.traits : isSomeString;
import std.meta : allSatisfy;

private template isAlias(a ...)
if (a.length == 1)
{
    enum isAlias = __traits(compiles, { alias b = a[0]; })
        && is(typeof(a[0]));
}

private template isStringValue(a ...)
if (a.length == 1)
{
    enum isStringValue = isSomeString!(typeof(a[0]));
}

private template isStringOrAlias(a ...)
if (a.length == 1)
{
    /* can't use templateOr in the dump template constraints
* because `Error: template instance F!(a) cannot use local 'a'
     * as parameter to non-global template templateOr(T...)` */
     * enum isStringOrAlias = isAlias!a || isStringValue!a;
}

mixin template dump(alias file, Args ...)
if (is(typeof(file) == File) && Args.length > 0
    && allSatisfy!(isStringOrAlias, Args))
{
    auto _unused_dump = {
        import std.traits : Select;
        // can put expressions directly in Select with
// https://github.com/D-Programming-Language/phobos/pull/3978
        enum sep = ", ";
        enum term = "\n";
        foreach (i, arg; Args)
        {
            static if (isSomeString!(typeof(arg)))
                file.write(arg, " = ", mixin(arg),
                    Select!(i < Args.length - 1, sep, term));
            else
file.write(__traits(identifier, Args[i]), " = ", arg,
                    Select!(i < Args.length - 1, sep, term));
        }
        return false;
    }();
}

mixin template dump(Args ...)
if (Args.length > 0
    && allSatisfy!(isStringOrAlias, Args))
{
    import std.stdio : stdout;
    mixin .dump!(stdout, Args);
}

unittest
{
    import std.stdio;
    int a = 3, b = 4;
    mixin dump!q{ a + b };
    mixin dump!(stderr, "a - b");

    mixin dump!a;
    mixin dump!(stderr, a, b);
}

Reply via email to