TDPL: Overloading template functions

Philippe Sigaud philippe.sigaud at gmail.com
Sun Aug 1 14:32:35 PDT 2010


On Sat, Jul 31, 2010 at 00:58, Andrej Mitrovic
<andrej.mitrovich at gmail.com>wrote:

>
> 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:
>
>
> (snip)


> unittest {
>     double[] d1 = [6.0, 1.5, 2.4, 3];
>     float[] d2 = [1.5, 2.4];
>     assert(find(d1, d2) == d1[1 .. $]); // unit test failure on line 40.
> }
>

The assert fails, because find(d1, d2) does not returns [1.5, 2.4, 3] in my
case.
That's because floating points types are notoriously difficult to test for
equality:

double d = 2.4;
float f = 2.4;
writeln(d == f); // false! 2.4 do not have the same representation as a
float or as a double.

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.

To test floating point values, use std.math.approxEqual.

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:

import std.functional: binaryFun; // template transforming strings like "a
==b" into functions.

T1[] find(alias comparator = "a == b", T1, T2)(T1[] longer, T2[] shorter)
    if (is(typeof(
                       binaryFun!comparator(longer[0 .. 1], shorter)) :
bool))

{
    while (longer.length >= shorter.length) {
        if (binaryFun!comparator(longer[0 .. shorter.length], shorter))
            break;
        longer = longer[1 .. $];
    }
    return longer;
}


usage:

void main()
{
    double[] d = [1.0, 1.5, 2.4, 3.14];
    float[] f = [1.5, 2.4];
    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
    writeln(find!approxEqual(d, f)); // [1.5, 2.4, 3.14]
}

btw, the behavior is not correct: find(d,f) should return an empty array,
not [3.14]...


I was actually thinking about ways of simplifying the constraint definitions
> with some helper functions. That's a pretty cool trick, thanks!
>

It's used throughout Phobos, particularly in the template-heavy modules,
like std.algorithm or std.range.

Philippe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20100801/8b01cde4/attachment.html>


More information about the Digitalmars-d mailing list