www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Passing several tuples (T...) to templates without expanding them

reply "simendsjo" <simendsjo gmail.com> writes:
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
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
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
parent reply "simendsjo" <simendsjo gmail.com> writes:
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
Mar 13 2013
parent reply "simendsjo" <simendsjo gmail.com> writes:
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..
Mar 13 2013
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
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
prev sibling parent reply "jerro" <a a.com> writes:
 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)
Mar 13 2013
parent "simendsjo" <simendsjo gmail.com> writes:
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; } }
Mar 13 2013