templating opEquals/opCmp (e.g. for DSL/expression templates)
Dominikus Dittes Scherkl
dominikus at scherkl.de
Wed Feb 13 20:49:49 UTC 2019
On Wednesday, 13 February 2019 at 18:42:43 UTC, H. S. Teoh wrote:
> On Wed, Feb 13, 2019 at 01:50:21AM +0000, Nicholas Wilson via
> Digitalmars-d wrote:
>> On Wednesday, 13 February 2019 at 00:56:48 UTC, H. S. Teoh
>> wrote:
>> > Frankly, I think it's a very good thing that in D comparison
>> > operators are confined to opEquals/opCmp.
>>
>> So do I. Many more objects have partial ordering than
>> arithmetic, having opCmp under opBinary would be annoying.
>
> Actually, contrary to what Andrei has claimed in the past,
> opCmp (as currently implemented) does NOT allow for a
> consistent definition of a partial ordering. I know because
> I've tried to do it with an integer set type. The problem is
> that when opCmp returns 0, it's ambiguous whether it means
> "incomparable" or "equal". This makes it impossible to make <=
> equivalent to the is-subset predicate. For example, here's a
> prospective implementation:
>
> struct IntSet {
> Impl impl;
> int opCmp(in IntSet b) {
> bool isSubset = impl.isSubsetOf(b.impl);
> bool isSuperset = b.impl.isSubsetOf(impl);
>
> if (isSubset && isSuperset)
> return 0;
> else if (isSubset)
> return -1;
> else if (isSuperset)
> return 1;
> else
> return 0; // incomparable
> }
opCmp is allowed to return float, making it possible to
distinguish all 4 possible values
float opCmp(in IntSet b) {
bool isSubset = impl.isSubsetOf(b.impl);
bool isSuperset = b.impl.isSubsetOf(impl);
if (isSubset && isSuperset)
return 0;
else if (isSubset)
return -1;
else if (isSuperset)
return 1;
else
return float.init; // incomparable - NaN
}
This works fine, I've used it in several types in my libraries.
More information about the Digitalmars-d
mailing list