On 06/29/2013 05:46 AM, snow wrote:

> On Friday, 28 June 2013 at 17:07:22 UTC, Ali Çehreli wrote:

>> Your opCmp does not provide a complete ordering of objects:
>>
>>     int opCmp(ref const Vector3D vec) {
>>         if (this.x > vec.x && this.y > vec.y && this.z > vec.z)
>>             return 1;
>>
>>         if (this.x < vec.x && this.y < vec.y && this.z < vec.z)
>>             return -1;
>>
>>         return 0;
>>     }
>>
>> According to that function, the following two values are neither less
>> than nor greater than the other:
>>
>>     // passes:
>>     assert(!(Vector3D(1, 2, 3) < Vector3D(2, 1, 3)) &&
>>            !(Vector3D(1, 2, 3) > Vector3D(2, 1, 3)));
>>
>> Ali
>
> I tried this now:
>      int opCmp(ref const Vector3D vec) {
>          if (this.x > vec.x && this.y > vec.y && this.z > vec.z)
>              return 1;
>          return -1;
>      }
> this should be a total ordering,

Unfortunately, no. opCmp must return 0 when the values are considered equal.

> because a Vector is always greater or smaller, than another,
> but I still get the same exception.

Not knowing whether it applies to your case, the following is one almost correct way of writing opCmp:

    int opCmp(ref const Vector3D vec) {
        return cast(int)(x != vec.x
                         ? x - vec.x
                         : (y != vec.y
                            ? y - vec.y
                            : z - vec.z));
    }

The reason I said "almost" is due to the usual floating point equality comparison warnings. Values that are supposed to be equal may not compare equal due to accumulated earlier floating point calculation errors.

Ali

Reply via email to