www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 6384] New: std.traits.isComparable

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6384

           Summary: std.traits.isComparable
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc



I suggest to add isComparable to std.traits, to be used as template constraint
for (both user defined and standard library) sorting/searching functions. It
looks for a opCmp or in general for


template isComparable(T) {
    enum bool isComparable = is(typeof({ return T.init < T.init; }));
}

version (unittest) {
    static assert(isComparable!int);
    static assert(isComparable!string);
    static assert(!isComparable!creal);

    static struct Foo {}
    static assert(!isComparable!Foo);

    static struct Bar {
        bool opCmp(Bar) { return true; }
    }
    static assert(isComparable!Bar);
}


I think using this constraint will improve the error messages of functions like
std.algorithm.sort too, etc:

import std.algorithm;
static struct Foo {}
static struct Bar {
    bool opCmp(Bar) { return true; }
}
void main() {
    auto a1 = [Foo(), Foo()];
    sort(a1);
    auto a2 = [Bar(), Bar()];
    sort(a2);
}


With DMD 2.054 it gives:

...\dmd\src\phobos\std\algorithm.d(6438): Error: static assert  "Invalid
predicate passed to sort: a < b"
test.d(8):        instantiated from here: sort!("a <
b",cast(SwapStrategy)0,Foo[])

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 26 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6384




Note that `std.algorithm.sort` can accept arbitrary predicate, and you can use
something like


    Complex!double[] cmplxarr;
    ...
    sort!"a.re < b.re"(cmplxarr);


If the purpose is to improve the error message of `std.algorithm.sort`,
`isComparable` won't work.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 26 2011
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6384




There are actually at least two possible isComparable's that would be helpful
in signature constraints. One checks if "a<b" compiles, the other checks if
"a==b" compiles.

I notice that some Phobos code uses is(typeof(a) : typeof(b)) in signature
constraints, only to write if(a==b) in the function body, which is fallacious:
just because a is implicitly convertible to b does not necessarily mean == is
defined between them.

More generally, code should really test for specific operations they need to
use, instead of just assuming that is(A : B) implies A.init <op> B.init is
valid. To that end, maybe we need isValidBinaryOp instead:

template isValidBinaryOp(T1, string op, T2) {
    alias isValidBinaryOp = is(mixin("T1.init" ~ op ~ "T2.init") : bool);
}

then we could write signature constraints of the form:

auto myFunc(T,U)(T t, U u)
    if (isValidBinaryOp!(T, "<", U))
{ ... }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 22 2013