Hi,
I'm interested in how much appetite there would be for the following set of functions in <bit>:
template<class T>
T sign_fill(T x) noexcept;
// Fills the integer with the most significant bit of x.
template<class T>
T bit_mask(T x) noexcept;
// Returns (T{1} << x) - T{1};
template<class T>
bool get_bit(T x, int i);
// Gets ith bit in x.
template<class T>
T set_bit(T x, int i);
template<class T>
T set_bit(T x, int i, bool b);
// Sets ith bit in x to 1 and b, respectively.
template<class T>
T reset_bit(T x, int i);
// Sets ith bit in x to 0.
template<class T>
T flip_bit(T x, int i);
// Sets ith bit in x to its complement.
These kinds of things are building blocks used in bit manipulation all the time.
It's also not trivial to get optimal codegen for all compilers on all architectures. I've actually overhauled the top answer on the StackOverflow post at https://stackoverflow.com/q/47981/5740428, and I can say from experience that not every way to write set_bit(T, int, bool) is equally good.
Sign-filling is a pretty common technique, and writing it out by hand is somewhat tedious because it requires going through std::numeric_limits to do it generically.
Even if we leave these arguments aside, the problem with writing say, (x | (1 << i)) instead of set_bit(x, i) is the lack of expressiveness. It's somewhat like writing inline assembly and then puzzling together that cmp and je collectively perform a jump if two registers are unequal. It's easy if you did it 1000 times before, but not obvious to novice readers at all.
The question is mainly where to draw the line. There are tons of different bit manipulation techniques, like isolating the lowest set bit, etc. However, none of these are anywhere near as common as simple setting/getting specific bits. I cherry-picked creating bit masks and sign-filling because they stand out from the crowd, in my experience. Maybe I could collect some data on this.
Jan