How would I write a template constraint for the following struct
struct Foo (T, U) {
}
to indicate that both T and U must be comparable using <? By that I mean that two Ts can be compared with < and two Us can be compared with < - a T and a U can be incomparable.
I believe this will do what you ask, though there may 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) { }
The most concise way that I can think of doing that at the moment is
struct Foo(T, U)
if(is(typeof(T[0] < T[0])) && is(typeof(U[0] < U[0])))
{
}
but I'd probably declare it as
struct Foo(T, U)
if(is(typeof(T.init < T.init)) && is(typeof(U.init < U.init)))
{
}
because it's more straightforward. Some folks might use the use of static arrays confusing, and it's not necessary. But it is technically a bit shorter.
The : bool portion in murphyslaw's answer isn't actually necessary, because < can't result in anything but bool, because the compiler translates <, <=, >, and >= to calls to opCmp on user-defined types, so the programmer doesn't have the opportunity to make them result in anything other than bool (and of course, the comparison operators result in bool for the built-in types). But murphyslaw's answer will work just as well. It's just more verbose than required.
The main place that : bool or == bool would be required would be if you wanted to accept a predicate rather than use the comparison operators directly (since then, you're dealing with an arbitrary function), and that's typically what the generic algorithms in Phobos end up doing. e.g. the signature of one of find's overloads is
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're planning on using the comparison operators directly, then simply checking that they compile is enough.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With