digitalmars.D.learn - Passing several tuples (T...) to templates without expanding them
- simendsjo (24/24) Mar 13 2013 Say you have a tuple type:
- monarch_dodra (49/73) Mar 13 2013 I have trouble understanding the question. Perhaps you are
- simendsjo (7/38) Mar 13 2013 I'm not using phobos Tuple as it didn't work well with both types
- simendsjo (5/45) Mar 13 2013 Ahem.. Seems TypeTuple is exactly like my Tuple, so I'll change
- monarch_dodra (28/32) Mar 13 2013 Yeah, Tuple is a Tuple in the C++ definition: An aggregate.
- jerro (11/25) Mar 13 2013 Not as far as I know. You can work that around it by wrapping it
- simendsjo (27/52) Mar 13 2013 Thanks, that's a good idea, and I'll probably rewrite my code to
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])); }
Mar 13 2013
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.
Mar 13 2013
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: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: 1Say 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?
Mar 13 2013
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: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..On Wednesday, 13 March 2013 at 10:34:14 UTC, simendsjo wrote: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: 1Say 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?
Mar 13 2013
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.
Mar 13 2013
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)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) ?
Mar 13 2013
On Wednesday, 13 March 2013 at 15:49:06 UTC, jerro wrote: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; } }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)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) ?
Mar 13 2013