Andrei:<br>>> this(U)(U another) if (is(U == Tuple!(V), V...)) { ... }<br><br><div class="gmail_quote">Sean:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Is that 'is' syntax correct? </blockquote><div><br>No, halas you can't put a V... inside an is expression. Only is(U == Tuple!V, V) is authorized.<br>To detect a Tuple, I use the following workaround: std.typecons.Tuple has a .Types member, so test for it (and btw .Types will give you the V tuple):<br>
<br>this(U)(U another) if (is(U.Types)) // U is a Tuple<br><br>{<br>alias U.Types V;<br>...<br>}<br><br>also, testing for U.stringof beginning with "Tuple!("... But I don't like this.<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
I've got to say that tuples are proving to be both incredibly powerful and incredibly frustrating to work with. </blockquote><div><br>Agreed.<br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
I'm still trying to sort out a working test to tell these two functions apart:<br>
<br>
void fnA(Tuple!int) {}<br>
void fnB(int) {}<br></blockquote><div><br>Like this?<br><br><br><br>template isTuple(T)<br>{<br> static if (is(T.Types))<br> enum bool isTuple = true;<br> else<br> enum bool isTuple = false;<br>}<br><br>
template InternalTypes(T) if (isTuple!T) // Gosh, I need it later, DMD doesn't like some complex types expressions<br>{<br> alias T.Types InternalTypes;<br>}<br><br>template isTupleFunction(alias fun)<br>{<br> static if (ParameterTypeTuple!fun.length == 1 && isTuple!(ParameterTypeTuple!fun[0]))<br>
enum bool isTupleFunction = true;<br> else<br> enum bool isTupleFunction = false;<br>}<br><br><br>But you also need to test for fun to be a standard function.<br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<br>
Alternately, a way to pass a Tuple!int to either one automatically would be even better. Or instead, make Variant.convertsTo distinguish between the two. Right now it doesn't.<br></blockquote><div><br>One thing nice to know (sorry if that's common knowledge) is that you can send a Tuple to a standard function by using its .field/.expand member.<br>
<br>int foo(int i, double d, string s) { return i*s.length;}<br><br>auto t = tuple(2, 3.14, "abc");<br><br>foo(t.expand); // 2*3<br><br><br>To automate the process, you can use a function adaptor:<br><br>/**<br>
Transforms a tuple-taking function into a standard function.<br>*/<br>template untuplify(alias fun)<br>{<br> static if (isTupleFunction!fun)<br> ReturnType!fun untuplify(InternalTypes!(ParameterTypeTuple!fun[0]) args)<br>
{<br> return fun(tuple(args));<br> }<br> else // consider fun to be a function, that should be tested<br> alias fun untuplify;<br>}<br><br>/**<br>Transforms a standard function into a tuple-accepting one.<br>
*/<br>template tuplify(alias fun)<br>{<br> static if (isTupleFunction!fun)<br> alias fun tuplify;<br> else<br> ReturnType!fun tuplify(Tuple!(ParameterTypeTuple!fun) args)<br> {<br> return fun(args.expand);<br>
}<br>}<br><br><br>It's too bad I have to use a secondary template like InternalTypes, but <br><br> InternalTypes!(ParameterTypeTuple!fun[0]) <br><br>is accepted, whereas <br><br> ParameterTypeTuple!fun[0].Types<br>
<br> is not.<br><br><br><br> Philippe<br><br></div></div>