Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 01, 2013 instantiate each of a tuple of templates (Take 2) | ||||
---|---|---|---|---|
| ||||
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. |
August 01, 2013 Re: instantiate each of a tuple of templates (Take 2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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.
A static foreach should do the trick. (code not actually tested)
void a(R r) //void? Not Tuple!T ?
{
Tuple!T ret
foreach(i, Type; T)
{
ret[i] = r;
}
return ret;
}
Is this what you want? This assumes that every member or T is a type, and not a name.
|
August 01, 2013 Re: instantiate each of a tuple of templates (Take 2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Thursday, 1 August 2013 at 12:50:42 UTC, John Colvin wrote: > ... Does this help http://dpaste.dzfl.pl/fe533f7a ? |
August 01, 2013 Re: instantiate each of a tuple of templates (Take 2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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.
|
August 01, 2013 Re: instantiate each of a tuple of templates (Take 2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On 08/01/13 14:50, 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.
>
Always post real and complete (even if not working) code, as figuring out what the problem is can be harder than giving the solution...
template RealTuple(A...) { alias RealTuple = A; }
template a(T ...)
{
auto a(R)(R r)
{
//want to get a tuple of
//the members of T, each
//instantiated with R.
mixin({
string m;
foreach (I, _; T)
m ~= "alias UGH"~I.stringof~" = T["~I.stringof~"];\n";
m ~= "alias TupleofTsBangR = RealTuple!(";
foreach (I, _; T)
m ~= (I?", ":"") ~ "UGH"~I.stringof~"!R";
return m ~ ");";
}());
// do some RT stuff
TupleofTsBangR x;
foreach (I, _; typeof(x))
x[I] = r;
// etc
import std.typecons;
return tuple(x);
}
}
(If this is what you were actually looking for then I hope somebody
else has another solution; this approach is just too ugly...)
artur
|
August 01, 2013 Re: instantiate each of a tuple of templates (Take 2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | 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.
|
August 01, 2013 Re: instantiate each of a tuple of templates (Take 2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Skawina | On Thursday, 1 August 2013 at 15:06:50 UTC, Artur Skawina wrote:
> On 08/01/13 14:50, 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.
>>
>
> Always post real and complete (even if not working) code, as figuring out
> what the problem is can be harder than giving the solution...
>
>
> template RealTuple(A...) { alias RealTuple = A; }
> template a(T ...)
> {
> auto a(R)(R r)
> {
> //want to get a tuple of
> //the members of T, each
> //instantiated with R.
>
> mixin({
> string m;
> foreach (I, _; T)
> m ~= "alias UGH"~I.stringof~" = T["~I.stringof~"];\n";
> m ~= "alias TupleofTsBangR = RealTuple!(";
> foreach (I, _; T)
> m ~= (I?", ":"") ~ "UGH"~I.stringof~"!R";
> return m ~ ");";
> }());
>
> // do some RT stuff
>
> TupleofTsBangR x;
> foreach (I, _; typeof(x))
> x[I] = r;
>
> // etc
>
> import std.typecons;
> return tuple(x);
> }
> }
>
> (If this is what you were actually looking for then I hope somebody
> else has another solution; this approach is just too ugly...)
>
> artur
sorry yeah I didnt think the question through before asking. I'm normally the one nagging for better example code when people ask questions!
I did consider wading through everything with string mixins etc. but it seemed like a lot of effort for what (on the surface) is a simple problem.
Anyhow, please see my response to monarch_dodra as I've revised my question somewhat
|
August 02, 2013 Re: instantiate each of a tuple of templates (Take 2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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.
|
August 02, 2013 Re: instantiate each of a tuple of templates (Take 2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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?
|
August 02, 2013 Re: instantiate each of a tuple of templates (Take 2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | 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?
Thankyou, yes that's exactly right.
Are all types guaranteed to have a working .init value? I can't think of any way not to, but I just want to be sure.
|
Copyright © 1999-2021 by the D Language Foundation