Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
March 13, 2013 Passing several tuples (T...) to templates without expanding them | ||||
---|---|---|---|---|
| ||||
Say you have a tuple type: struct Tuple(T...) { alias T Tuple; } and a template template t(alias A, alias B) { // something something } Given alias Tuple!(int, 1) A; alias Tuple!(int, 1) B; Is it possible to send this to template t as follows t!(A, B) without it expanding to t!(int, 1, int, 1) ? This is what I'm trying to achieve, but encapsulated in a template: alias Tuple!(int, "aoeu", short) A; alias Tuple!(int, "aoeu", short) B; foreach(i, T; A) { pragma(msg, i, " ", T); pragma(msg, isEqual!(T, B[i])); } |
March 13, 2013 Re: Passing several tuples (T...) to templates without expanding them | ||||
---|---|---|---|---|
| ||||
Posted in reply to simendsjo | On Wednesday, 13 March 2013 at 10:34:14 UTC, simendsjo wrote:
> Say you have a tuple type:
> struct Tuple(T...) {
> alias T Tuple;
> }
>
> and a template
> template t(alias A, alias B) {
> // something something
> }
>
> Given
> alias Tuple!(int, 1) A;
> alias Tuple!(int, 1) B;
>
> Is it possible to send this to template t as follows
> t!(A, B)
> without it expanding to
> t!(int, 1, int, 1)
> ?
>
> This is what I'm trying to achieve, but encapsulated in a template:
> alias Tuple!(int, "aoeu", short) A;
> alias Tuple!(int, "aoeu", short) B;
> foreach(i, T; A) {
> pragma(msg, i, " ", T);
> pragma(msg, isEqual!(T, B[i]));
> }
I have trouble understanding the question. Perhaps you are confusing Tuple and TypeTuple?
TypeTuples are not actual types, and always expanded.
Tuple is an actual type, and doent expand unless requested via expand.
As for your code, it is a bit confusing, because most of it doesn't compile...
In any case, this code:
//----
alias Tuple!(int, int) A;
alias Tuple!(uint, uint) B;
void foo(Args...)()
{
foreach(i, Type; Args)
writefln("Type %d: %s.", i, Type.stringof);
}
foo!(A, B)();
//----
produces
//----
Type 0: Tuple!(int, int).
Type 1: Tuple!(uint, uint).
//----
Is this what you want?
Also, if you want to extract a type out of a tuple, you need to use "Type":
//----
alias Tuple!(int, "aoeu", short) A;
alias Tuple!(int, "aoeu", short) B;
foreach(i, T; A.Types)
{
pragma(msg, "A ", i, " ", T.stringof);
pragma(msg, "B ", i, " ", B.Types[i].stringof);
pragma(msg, is(T == B.Types[i]));
}
//----
This works
//----
A 0u int
B 0u int
true
A 1u short
B 1u short
true
//----
Writing A[0] will just tell you that "need 'this' to access member". Because pragma errors aren't blocking errors, things get confusing.
|
March 13, 2013 Re: Passing several tuples (T...) to templates without expanding them | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Wednesday, 13 March 2013 at 11:13:55 UTC, monarch_dodra wrote:
> On Wednesday, 13 March 2013 at 10:34:14 UTC, simendsjo wrote:
>> Say you have a tuple type:
>> struct Tuple(T...) {
>> alias T Tuple;
>> }
>>
>> and a template
>> template t(alias A, alias B) {
>> // something something
>> }
>>
>> Given
>> alias Tuple!(int, 1) A;
>> alias Tuple!(int, 1) B;
>>
>> Is it possible to send this to template t as follows
>> t!(A, B)
>> without it expanding to
>> t!(int, 1, int, 1)
>> ?
>>
>> This is what I'm trying to achieve, but encapsulated in a template:
>> alias Tuple!(int, "aoeu", short) A;
>> alias Tuple!(int, "aoeu", short) B;
>> foreach(i, T; A) {
>> pragma(msg, i, " ", T);
>> pragma(msg, isEqual!(T, B[i]));
>> }
>
> I have trouble understanding the question. Perhaps you are confusing Tuple and TypeTuple?
I'm not using phobos Tuple as it didn't work well with both types and values.
I want a Tuple!(int, 1, "aoeu") to have exactly these values; int, 1, "aoeu".
alias Tuple!(int, 1) T; // Attempted to instantiate Tuple with an invalid argument: 1
|
March 13, 2013 Re: Passing several tuples (T...) to templates without expanding them | ||||
---|---|---|---|---|
| ||||
Posted in reply to simendsjo | On Wednesday, 13 March 2013 at 11:21:53 UTC, simendsjo wrote:
> On Wednesday, 13 March 2013 at 11:13:55 UTC, monarch_dodra wrote:
>> On Wednesday, 13 March 2013 at 10:34:14 UTC, simendsjo wrote:
>>> Say you have a tuple type:
>>> struct Tuple(T...) {
>>> alias T Tuple;
>>> }
>>>
>>> and a template
>>> template t(alias A, alias B) {
>>> // something something
>>> }
>>>
>>> Given
>>> alias Tuple!(int, 1) A;
>>> alias Tuple!(int, 1) B;
>>>
>>> Is it possible to send this to template t as follows
>>> t!(A, B)
>>> without it expanding to
>>> t!(int, 1, int, 1)
>>> ?
>>>
>>> This is what I'm trying to achieve, but encapsulated in a template:
>>> alias Tuple!(int, "aoeu", short) A;
>>> alias Tuple!(int, "aoeu", short) B;
>>> foreach(i, T; A) {
>>> pragma(msg, i, " ", T);
>>> pragma(msg, isEqual!(T, B[i]));
>>> }
>>
>> I have trouble understanding the question. Perhaps you are confusing Tuple and TypeTuple?
>
> I'm not using phobos Tuple as it didn't work well with both types and values.
> I want a Tuple!(int, 1, "aoeu") to have exactly these values; int, 1, "aoeu".
>
> alias Tuple!(int, 1) T; // Attempted to instantiate Tuple with an invalid argument: 1
Ahem.. Seems TypeTuple is exactly like my Tuple, so I'll change my code to use TypeTuple. The question still stands though..
If it's not possible, as you say, I'll try to figure out a workaround..
|
March 13, 2013 Re: Passing several tuples (T...) to templates without expanding them | ||||
---|---|---|---|---|
| ||||
Posted in reply to simendsjo | On Wednesday, 13 March 2013 at 11:26:24 UTC, simendsjo wrote:
>
> Ahem.. Seems TypeTuple is exactly like my Tuple, so I'll change my code to use TypeTuple. The question still stands though..
> If it's not possible, as you say, I'll try to figure out a workaround..
Yeah, Tuple is a Tuple in the C++ definition: An aggregate.
I'm don't have a solution for you. TypeTuple really isn't a "type", so you can't really *not* expand them, nor pass them "as is" to a template, or anything else like that.
It sounds like you are trying to work around the problem of "template function with two var-arg arguments"?
If you know each var-args relative size, then you can alias a slice:
template foo(Args...)
{
alias A = Args[0 .. $/2];
alias B = Args[$/2 .. $];
void foo()
{
foreach(i, T; A) {
pragma(msg, i, " ", T);
pragma(msg, isEqual!(T, B[i]));
}
}
}
void main()
{
alias TypeTuple!(int, 1, short) A;
alias TypeTuple!(int, 1, short) B;
foo!(A, B)();
}
Not perfect, but works all right.
|
March 13, 2013 Re: Passing several tuples (T...) to templates without expanding them | ||||
---|---|---|---|---|
| ||||
Posted in reply to simendsjo | >>>> and a template
>>>> template t(alias A, alias B) {
>>>> // something something
>>>> }
>>>>
>>>> Given
>>>> alias Tuple!(int, 1) A;
>>>> alias Tuple!(int, 1) B;
>>>>
>>>> Is it possible to send this to template t as follows
>>>> t!(A, B)
>>>> without it expanding to
>>>> t!(int, 1, int, 1)
>>>> ?
Not as far as I know. You can work that around it by wrapping it in a non eponymous template. I use a template like this for this purpose:
template group(a...){ alias a members; }
then you do
alias A = group!(int, 1);
alias B = group!(int, 1);
t!(A, B)
And you use A.members and B.members inside t. You could also declare A and B as you did above, and use t like this:
t!(group!A, group!B)
|
March 13, 2013 Re: Passing several tuples (T...) to templates without expanding them | ||||
---|---|---|---|---|
| ||||
Posted in reply to jerro | On Wednesday, 13 March 2013 at 15:49:06 UTC, jerro wrote:
>>>>> and a template
>>>>> template t(alias A, alias B) {
>>>>> // something something
>>>>> }
>>>>>
>>>>> Given
>>>>> alias Tuple!(int, 1) A;
>>>>> alias Tuple!(int, 1) B;
>>>>>
>>>>> Is it possible to send this to template t as follows
>>>>> t!(A, B)
>>>>> without it expanding to
>>>>> t!(int, 1, int, 1)
>>>>> ?
>
> Not as far as I know. You can work that around it by wrapping it in a non eponymous template. I use a template like this for this purpose:
>
> template group(a...){ alias a members; }
>
> then you do
>
> alias A = group!(int, 1);
> alias B = group!(int, 1);
>
> t!(A, B)
>
> And you use A.members and B.members inside t. You could also declare A and B as you did above, and use t like this:
>
> t!(group!A, group!B)
Thanks, that's a good idea, and I'll probably rewrite my code to use this.
For my needs I just hardcoded it, stuffing everything in the same template.
template hasEqualAttributes(Recursive recursive, alias A, alias B)
{
alias AttributeTuple!(recursive, A) AAttr;
alias AttributeTuple!(recursive, B) BAttr;
static if(AAttr.length != BAttr.length)
{
enum hasEqualAttributes = false;
}
else
{
template _hasEqualAttributes(int i)
{
static if(i >= AAttr.length)
enum _hasEqualAttributes = true;
else
enum _hasEqualAttributes = isEqual!(AAttr[i], BAttr[i]) && _hasEqualAttributes!(i+1);
}
enum hasEqualAttributes = _hasEqualAttributes!0;
}
}
|
Copyright © 1999-2021 by the D Language Foundation