<br><br><div class="gmail_quote">On Sat, Jul 31, 2010 at 17:24, Andrej Mitrovic <span dir="ltr"><<a href="mailto:andrej.mitrovich@gmail.com">andrej.mitrovich@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I think there really is some bug here. I tried to use your template helper function, and it seems the order in which I put two constraints in a template signature changes the way dmd compiles the code. Consider this:<div class="im">
</div></blockquote><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">T[] find(T, E)(T[] haystack, E needle)</div>
if (is(typeof(haystack[0] != needle) == bool) &&<br> areComparable!(T, E))<div class="im"><br></div></blockquote><div>...</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">T1[] find(T1, T2)(T1[] longer, T2[] shorter)<br></div> if (is(typeof(longer[0 .. 1] == shorter) : bool) && (areComparable!(T1, T2)))<div class="im"></div></blockquote><div><br></div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">This will give out the error "incompatible types for comparing of string and immutable(char)". </div>
</blockquote><div><br></div><div>That's because the first part of the constraint is tested, to allow for short-circuiting the second part. So the bad array comparison triggers the problem in object._EqArray.</div><div>
<br></div><div>You should always test for the most general constraint first, I guess. In this particular case, use areComparable!(A,B) as the first argument to && in both templates.</div><div><br></div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">But if I reverse the order of the constraints in the second template, like so:</div><div class="im"><br>
T1[] find(T1, T2)(T1[] longer, T2[] shorter)</div> if (areComparable!(T1, T2) && is(typeof(longer[0 .. 1] == shorter) : bool))<div class="im"></div></blockquote><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">Then this happily compiles. </div></blockquote><div><br></div><div>Well, yes. The second template cannot be instantiated: T1 is a string, T2 is a character. So isComparable evaluates to 'false' and the constraints short-circuits to 'false'.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">All of the asserts will call the first templated function.</div><div><div></div><div class="h5">
<br></div></div></blockquote><div><br></div><div>Because you are looking for an element in a sequence of element in all three cases. That's what the first version of find() do.</div><div>If you test:</div><div><br></div>
<div>assert(find(d, [1.5]); // [1.5] is a one-element array.</div><div>assert(find(d, [1.5, 2.4]); // finding d in d.</div><div>assert(find("one two three", "two");</div><div><br></div><div><br></div><div>
it will activate the second version for all these new asserts: you are looking for a sequence of elements in a sequence of elements, which is what the second find does.</div><div><br></div><div>Philippe</div><div><br></div>
<div><br></div><div> </div></div>