instantiate each of a tuple of templates (Take 2)

John Colvin john.loughran.colvin at gmail.com
Fri Aug 2 05:58:06 PDT 2013


On Friday, 2 August 2013 at 11:26:41 UTC, monarch_dodra wrote:
> 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?

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.


More information about the Digitalmars-d-learn mailing list