instantiate each of a tuple of templates (Take 2)

monarch_dodra monarchdodra at gmail.com
Fri Aug 2 04:26:39 PDT 2013


On Friday, 2 August 2013 at 10:54:06 UTC, John Colvin wrote:
> On Thursday, 1 August 2013 at 15:08:53 UTC, John Colvin wrote:
>> On Thursday, 1 August 2013 at 14:57:07 UTC, monarch_dodra 
>> wrote:
>>> On Thursday, 1 August 2013 at 12:50:42 UTC, John Colvin wrote:
>>>> template a(T ...)
>>>> {
>>>>  void a(R r)
>>>>  {
>>>>      //want to get a tuple of
>>>>      //the members of T, each
>>>>      //instantiated with R.
>>>>
>>>>      //do some RT stuff
>>>>  }
>>>> }
>>>>
>>>> Is this possible?
>>>>
>>>> Whatever I try, I keep running in to "cannot use local as 
>>>> parameter to non-global template" errors, which I understand 
>>>> is to do with context pointers
>>>> However, this is all compile-time work based entirely on 
>>>> types, there should be no need for any context pointers.
>>>
>>> Still not sure what you want, but you may want to look into 
>>> adjoin and  staticMap.
>>
>> Sorry, now I've thought about it some more it appears I was 
>> asking the wrong question completely!
>>
>> Here's the situation (you might recognise the pattern from 
>> std.algorithm.map):
>>
>> template a(funs...)
>> {
>>    auto a(R)(R r)
>>    {
>>        alias /*something*/ nonVoidFuns;
>>        alias /*something*/ voidFuns;
>>
>>        //do stuff with nonVoidFuns and voidFuns applied to r
>>    }
>> }
>>
>> so i need to find the return type of each fun, when called 
>> with something of type R (bearing in mind that fun!R may not 
>> be the same type as fun(r) as fun might be T fun(T)(T[] a), 
>> then filter funs to seperate the void functions from the 
>> non-void ones. Or something else to that effect.
>>
>> I've tried several things with std.typetuple.Filter but 
>> nothing seems to work.
>
> Any ideas anyone? It seems like something that should be easily 
> done somehow.

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

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

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

       import std.functional : adjoin;

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

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;
}

void main()
{
     a!(fun1, fun2, fun3, fun4)(99);
}
//----
Calling all non voids!
fun4 5
Calling all voids!
fun3 5
//----

Is this what you want?


More information about the Digitalmars-d-learn mailing list