<div class="gmail_quote">On Sat, Jul 31, 2010 at 00:58, 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;">
<br>could you please try this out with your new object.di if you have any time?). I hope Andrei won't mind for pasting this here:<br><div class="gmail_quote"><div><div class="im"><br><br></div></div></div></blockquote>
<div>(snip)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="gmail_quote"><div><div class="im"></div><div class="im">unittest {<br></div><div class="im">
double[] d1 = [6.0, 1.5, 2.4, 3];<br> float[] d2 = [1.5, 2.4];<br>
assert(find(d1, d2) == d1[1 .. $]); // unit test failure on line 40.<br>}<br></div></div></div></blockquote><div><br></div><div>The assert fails, because find(d1, d2) does not returns [1.5, 2.4, 3] in my case.</div><div>
That's because floating points types are notoriously difficult to test for equality:</div><div><br></div><div>double d = 2.4;</div><div>float f = 2.4;</div><div>writeln(d == f); // false! 2.4 do not have the same representation as a float or as a double.</div>
<div><br></div><div>So I guess there must have been some pb with the testing Andrei has done on the examples, because this particular example do not work.</div><div><br></div><div>To test floating point values, use std.math.approxEqual.</div>
<div><br></div><div>For a function like find() you can imagine either using approxEqual as the comparator when you detect T/E, T1/T2 to be floating point values, or defer to the user to give you a valid comparator, as an alias:</div>
<div><br></div><div>import std.functional: binaryFun; // template transforming strings like "a ==b" into functions.</div><div><br></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 12.5px; border-collapse: collapse; "><div class="im" style="color: rgb(80, 0, 80); ">
T1[] find(alias comparator = "a == b", T1, T2)(T1[] longer, T2[] shorter)<br></div> if (is(typeof(</span></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 12.5px; border-collapse: collapse; "> binaryFun!comparator(longer[0 .. 1], shorter)) : bool))<div class="im" style="color: rgb(80, 0, 80); ">
<br>{<br> while (longer.length >= shorter.length) {<br> if (binaryFun!comparator(longer[0 .. shorter.length], shorter))<br> break;<br> longer = longer[1 .. $];<br> }<br> return longer;<br>
}<br></div></span></div><div><br></div><div><br></div><div>usage:</div><div><div><br></div><div>void main()</div><div>{</div><div> double[] d = [1.0, 1.5, 2.4, 3.14];</div><div> float[] f = [1.5, 2.4];</div><div> writeln(find(d, f)); // use a == b as a comparator, so returns 3.14, did not see 1.5 float and 1.5 double as equal</div>
<div> writeln(find!approxEqual(d, f)); // [1.5, 2.4, 3.14]</div><div>}</div></div><div><br></div><div>btw, the behavior is not correct: find(d,f) should return an empty array, not [3.14]...</div><div><br></div><div><br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="gmail_quote"><div><div class="im">I was actually thinking about ways of simplifying the constraint definitions with some helper functions. That's a pretty cool trick, thanks!</div>
</div></div>
</blockquote></div><br><div>It's used throughout Phobos, particularly in the template-heavy modules, like std.algorithm or std.range.</div><div><br></div><div>Philippe</div>