On Sat, Dec 7, 2024 at 10:24 AM Charles R Hogg via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
`std::nextafter` and friends provide the next representable value after the first argument, in the direction of the second argument.

Often, I find myself wanting specifically the next-higher or next-lower representable value.  In these cases, it feels awkward to cook up a number that I know will be higher or lower.

Positive infinity is greater than all real numbers.
Negative infinity is less than all real numbers.
(And std::nextafter(+inf, +inf) is +inf; std::nextafter(NaN, anything) is NaN; std::nextafter(-inf, +inf) is -DBL_MAX or -LDBL_MAX, depending on the computed return type. These outcomes all seem sensible to me.)

[...] `infinity` would be a disastrous choice for integral types, where it returns `0`.  (Not that we typically intentionally use `nextafter` for integral types, but it may happen in a generic template by accident.)

`std::nextafter(42, [anything])` is already disastrous, because `std::nextafter` is not a generic function; it's an overload set. It works on floating-point types only. If you pass it an integer, it will convert that integer to `double` and give you back the next `double` after it, not the next integer. (Or the next `long double`, if the second argument is a `long double`.)
https://godbolt.org/z/9YGxv91v7
 
Sometimes I wonder: wouldn't it be more intent-based to provide something like `std::next_higher()` and `std::next_lower()`, with a single argument?  Has this ever been proposed?

If you really want to, you can do this with a macro (or inline function or whatever):
 #define NEXT_HIGHER(x) std::nextafter((x), +HUGE_VAL)
 #define NEXT_LOWER(x) std::nextafter((x), -HUGE_VAL)
I don't think that's worth adding to the paper standard, especially given the possibility of confusion between similarly named functions.

–Arthur