On Tuesday, 26 February 2019 at 22:56:37 UTC, Victor Porton wrote:
On Tuesday, 26 February 2019 at 22:51:15 UTC, Q. Schroll wrote:
Grouping arguments could be done, but from my experience, it does not buy you anything; rather it makes it worse. Better just deal with heterogeneous stuff just like std.typecons.Tuple does.

After fixing the error you pointed me, it does not work too:

mixin ProviderParams!("S", ((int, "x"), (float, "y")));

Also: Can I nevertheless group arguments?

No, not the way you do. The module std.meta defines AliasSeq as follows:

    alias AliasSeq(X...) = X;

It is literally equivalent to

    template AliasSeq(X...)
    {
        alias AliasSeq = X; // "eponymous template member"
    }

In

    mixin ProviderParams!("S", ((int, "x"), (float, "y")));

the parenthesized stuff like (int, "x") is invalid in terms of formal grammar. You could use AliasSeq!(int, "x") if you really want to display grouping in your source code. Note however that this does not do anything. The sequence is being flattened by the compiler, i.e.

mixin ProviderParams!("S", AliasSeq!(AliasSeq!(int, "x"), AliasSeq!(float, "y")));

is exactly the same as

    mixin ProviderParams!("S", int, "x", float, "y");

which I wrote in my answer.

When you don't use a eponymous template member, you can access them manually:

    template Pack(X...)
    {
        alias Contents = X; // not "eponymous template member"
    }

Using this, you can create what I call packs. For some template T, while T!(AliasSeq!(int, bool), AliasSeq!(float, string, long)) is the same as writing T!(int, bool), the T!(Pack!(int, bool), Pack!(float, string, long)) is different from T!(int, bool, float, string, long). In the AliasSeq template, the eponymous template member feature of D immediately expands the sequence.

If the template T is defined like this:

    template T(Args...)
    { .. }

In the AliasSeq case, Args[0] is int, Args[1] is bool, Args[2] is float, ... In the Pack case, Args[0] is Pack!(int, bool), Args[1] is Pack!(float, string, long), and Args[0].Contents[0] is int, Args[0].Contents[1] is bool, Args[1].Contents[0] is float ...

I've used Packs once to get the Cartesian product of an AliasSeq of Packs. It is a mess. I'd only use Packs when absolutely necessary; in your case, it does not seem so.

In your case, you seem to need some initial thing "S" and then pairs of things.

    template you_name_it(Arg, args...)
    if (args.length % 2 == 0) // ensures pairs
    {
        static foreach (i; args.length / 2)
        {
            // access the type by args[2*i]
            // access the name (or whatever) by args[2*i+1]
        }
    }

You could get the sequence of types and the sequence of names using

    alias Types = Stride!(2, args);
    alias Names = Stride!(2, args[1 .. $]);

Reply via email to