a few more `<bit>` functions such as `std::bit_reverse` or `std::bit_compress`.
It was already in LWG prior to Kona, but SG6 Numerics needed to double-check that
the numbers make sense and whatnot.
It looks like they do.
##### [P3772R0](https://isocpp.org/files/papers/P3772R0.html) `std::simd` overloads for bit permutations
This just adds the corresponding `std::simd` overloads to do everything in P3014 in parallel.
Almost every other function in `<bit>` already has a SIMD overload,
so this is just a consistency fix.
##### [P3724R1](https://isocpp.org/files/papers/P3724R1.html) Integer division
This adds a bunch of functions for performing integer division with rounding modes
other than truncation/towards zero, which the builtin `/` operator does.
SG6 Numerics overall liked the idea,
but the proposal went a bit overboard with the amount of rounding modes added.
I'm yoinking `std::div_to_odd` and `std::div_to_even` out of the next revision.
Neither me nor anyone in the room was able to think of a use case for these.
##### [P3793R0](https://isocpp.org/files/papers/P3793R0.html) Better shifting
This adds two functions `std::shl` and `std::shr`,
which allow you to perform overlong shifts without undefined behavior.
The builtin `<<` operator has UB for "overlong" and negative shifts,
i.e. `int32_t(1) << 32` and `1 << -1` are UB.
Both of these problems are addressed by the "safer" new functions.
However, there was a lot of discussion around how to handle negative shifts.
The paper currently turns this into an implementation-defined result + erroneous behavior,
but about half the room wanted the "mathematically correct" behavior of shifting in the opposite direction in negative inputs.
The next revision should do that.
In hindsight, I realized that "safety by default" is probably a good feature,
and what's currently proposed is a half-measure.
While there is a cost to checking for negative inputs,
you can get the fast behavior like `std::shl(x, std::to_unsigned(s))`,
where `std::to_unsigned` comes from P3643R2.
You can also just `static_cast`, obviously.
In any case, shifting in the opposite direction seems like the best approach to me now;
it just needs a bit of confidence, some benchmarks, etc. to convince LEWG of that.
##### [P3735R0](https://isocpp.org/files/papers/P3735R0.html) `partial_sort_n`, `nth_element_n`
This paper made it past SG9 Ranges,
and the idea was overall well-received.
With the new algorithms, you would be able to write
int elems[] {3, 1, 2};
std::ranges::partial_sort_n(elems, 10); // now {1, 2, 3}
Notably, even if the provided size exceeds the size of the range,
you don't get UB.
By comparison, attempting to "get lowest 10 elements with `std::partial_sort`" is dangerous:
std::ranges::partial_sort(elems, elems + 10); // UB in pointer arithmetic
I've seen this bug happen often enough for me to make a proposal.
The only issue is that SG9 didn't like the name (`_n` suffixes usually mean something else in `<algorithm>`,
so it's getting renamed to `partial_sort_at_most`.
https://redd.it/1oyltrq
@r_cpp
Post #24262
19