D: Template constraint to show if a given type is comparable
I believe this will do what you ask, although there might be a more concise solution:
struct Foo (T, U) if (is(typeof(T.init < T.init) : bool)
&& is(typeof(U.init < U.init) : bool)
{ }
You can clean it up a bit with a template:
enum bool isSelfComparable(T) = is(typeof(T.init < T.init) : bool);
struct Foo (T, U) if (isSelfComparable!T && isSelfComparable!U) { }
source to share
The most concise way I can do now is
struct Foo(T, U)
if(is(typeof(T[0] < T[0])) && is(typeof(U[0] < U[0])))
{
}
but I would guess that he
struct Foo(T, U)
if(is(typeof(T.init < T.init)) && is(typeof(U.init < U.init)))
{
}
because it's more straight forward. Some people might use the use of static arrays, obfuscating, and this is not required. But this is technically a bit shorter.
: bool
part murphyslaw answer is not really necessary, because <
can not lead to anything, except bool
, because the compiler translates <
, <=
, >
and >=
to call opCmp
for user-defined types, so the programmer is not possible to make them the result of anything else, except bool
(and of course comparison operators result in bool
for built-in types). But murlos' answer will work just as well. It's just more verbose than required.
The main place that is required : bool
or == bool
would be if you wanted to accept a predicate and not directly use comparison operators (since then you deal with an arbitrary function), and that is usually what generic algorithms in Phobos generate. for example the signature of one of the find
overloads
InputRange find(alias pred = "a == b", InputRange, Element)
(InputRange haystack, Element needle)
if (isInputRange!InputRange &&
is (typeof(binaryFun!pred(haystack.front, needle)) : bool))
{...}
But if you plan on using comparison operators directly, just checking that they compile is sufficient.
source to share