instantiate each of a tuple of templates (Take 2)

monarch_dodra monarchdodra at gmail.com
Fri Aug 2 06:07:55 PDT 2013


On Friday, 2 August 2013 at 12:58:08 UTC, John Colvin wrote:
>> Is this what you want?
>
> I just ran in to a problem with this. It can't work for 
> anything other than global functions.
>
> void main()
> {	
>     int fun6(int i)
>     {
>         writeln("fun6 ", i);
>         return i;
>     }
>     a!(fun6)(99);
> }
>
> std/typetuple.d(664): Error: template instance pred!(fun6) 
> cannot use local 'fun6' as parameter to non-global template 
> isVoidFun(alias fun)
>
> So it's back to that same problem again.

The "root" problem is that filter just isn't adapted here. If you 
don't mind writing "filter 2 (for example)" though...

//--------
import std.stdio, std.typetuple;

template isVoidArg(alias F, U)
{
     enum isVoidArg = is(typeof(F(U.init)) == void);
}
template isNonVoidArg(alias F, U)
{
     enum isNonVoidArg = is(typeof({auto a = F(U.init);}));
}
template isErrorArg(alias F, U)
{
     enum isErrorArg = !is(typeof(F(U.init)));
}

template Filter2(alias pred, U, TList...)
{
     static if (TList.length == 0)
     {
         alias Filter2 = TypeTuple!();
     }
     else static if (TList.length == 1)
     {
         static if (pred!(TList[0], U))
             alias Filter2 = TypeTuple!(TList[0]);
         else
             alias Filter2 = TypeTuple!();
     }
     else
     {
         alias Filter2 =
             TypeTuple!(
                 Filter2!(pred, U, TList[ 0  .. $/2]),
                 Filter2!(pred, U, TList[$/2 ..  $ ]));
     }
}

template a(funs...)
{
    auto a(R)(R r)
    {
       alias nonVoidFuns = Filter2!(isNonVoidArg, R, funs);
       alias voidFuns = Filter2!(isVoidArg, R, funs);
       alias voidErrorFuns = Filter2!(isErrorArg, R, funs);

       import std.functional : adjoin;

       writeln("Calling all non voids!");
       adjoin!nonVoidFuns(r);
       writeln("Calling all voids!");
       adjoin!voidFuns(r);
    }
}

void main()
{
     void fun1(string i)
     {
         writeln("fun1 ", i);
     }
     int fun2()
     {
         writeln("fun2");
         return int.min;
     }
     void fun3(int i)
     {
         writeln("fun3 ", i);
     }
     int fun4(int i)
     {
         writeln("fun4 ", i);
         return i;
     }

     a!(fun1, fun2, fun3, fun4)(99);
}
//--------

The template names kind of suck though. You may want to change 
some of them.


More information about the Digitalmars-d-learn mailing list