Thread overview
std.algorithm.cmp doesn't seem to support numeric types?
Oct 16, 2019
DNoob
Oct 16, 2019
Paul Backus
Oct 16, 2019
Adam D. Ruppe
Oct 16, 2019
Dennis
Oct 16, 2019
Ali Çehreli
Oct 16, 2019
Adam D. Ruppe
October 16, 2019
I'm just learning D, so it's very possible that I'm missing a more appropriate function that exists elsewhere, but basically I found today that while I could easily write a cmp function that worked for everything, the one in std.algorithm doesn't seem to:

import std.stdio, std.algorithm;

pure nothrow @nogc @system byte my_cmp(T1, T2)(T1 a, T2 b)
{
    if (a < b)
    {
        return -1;
    }
    else if (a == b)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

void main()
{
  //template error on the next line if uncommented
  //writeln(cmp(1, 2));

  writeln(my_cmp(1, 2));
}

Any advice would be much appreciated!
October 16, 2019
On Wednesday, 16 October 2019 at 19:25:18 UTC, DNoob wrote:
> I'm just learning D, so it's very possible that I'm missing a more appropriate function that exists elsewhere, but basically I found today that while I could easily write a cmp function that worked for everything, the one in std.algorithm doesn't seem to:

std.algorithm.cmp compares two ranges, not two values. From the documentation:

> Performs a lexicographical comparison on two input ranges. Iterating r1 and
> r2 in lockstep, cmp compares each element e1 of r1 with the corresponding
> element e2 in r2. If one of the ranges has been finished, cmp returns a
> negative value if r1 has fewer elements than r2, a positive value if r1 has
> more elements than r2, and 0 if the ranges have the same number of elements.

Source: https://dlang.org/phobos/std_algorithm_comparison.html#.cmp
October 16, 2019
On Wednesday, 16 October 2019 at 19:25:18 UTC, DNoob wrote:
> I'm just learning D, so it's very possible that I'm missing a more appropriate function that exists elsewhere, but basically I found today that while I could easily write a cmp function that worked for everything, the one in std.algorithm doesn't seem to:

Yeah, it is primarily for strings, to be used as a sorting predicate.

For numbers, simple less than (for bool comparisons) or subtraction operators (for the integer ones) will do it.

Notice that the docs say "a negative value" rather than -1 specifically. That's because the implementation for integers an be as simple as

return a - b; // if b > a, you get a negative value

and thus doesn't really need a specific function.
October 16, 2019
On Wednesday, 16 October 2019 at 20:07:10 UTC, Adam D. Ruppe wrote:
> Notice that the docs say "a negative value" rather than -1 specifically. That's because the implementation for integers an be as simple as
>
> return a - b; // if b > a, you get a negative value

Except that e.g. -2 - int.max underflows to int.max suggesting that int.max < -2.
October 16, 2019
On 10/16/2019 02:34 PM, Dennis wrote:

> Except that e.g. -2 - int.max underflows to int.max suggesting that
> int.max < -2.

Timon had corrected me on that point a while back, so I had added the following warning at


http://ddili.org/ders/d.en/operator_overloading.html#ix_operator_overloading.opCmp

"Warning: Using subtraction for the implementation of opCmp is a bug if valid values of a member can cause overflow."

However, note how I say "overflow" instead of "underflow". The reason is, underflow is a different concept that applies only to floating point values[1]. Apparently, "integer underflow" has become common usage as well[2].

Ali

[1] https://en.wikipedia.org/wiki/Arithmetic_underflow

[2] https://en.wikipedia.org/wiki/Integer_overflow

October 16, 2019
On Wednesday, 16 October 2019 at 21:34:35 UTC, Dennis wrote:
> Except that e.g. -2 - int.max underflows to int.max suggesting that int.max < -2.

Eh yeah, it would be something you should check in opCmp.

But this is how it is actually implemented on the processor itself, just the cpu happens to also check the overflow for you automatically...