<xstd/ints/bit/bit_select.hpp>¶
xstd::bit_select¶
template<unsigned_integer T>
constexpr auto bit_select(T x, int k) -> int;
The position of the one of rank k in an unsigned integer. An xstd extension beside
P3104's permutations: no paper proposes it, and it has no <bit>
counterpart to forward to.
Parameters¶
| Parameter | Meaning |
|---|---|
x |
the value whose ones are searched |
k |
the rank of the one to find, counting from zero |
Constraints: T models unsigned_integer. bool, the character types, a signed type and a signed bit-precise type
are turned away.
Preconditions: 0 <= k and k < popcount(x).
Return value¶
Returns: The n in [0, N) for which x[n] is one and x[0] + … + x[n-1] is k: the position of x's one of
rank k, counting from zero at the least significant end.
Exceptions¶
- Throws: Nothing, for a
Twhose operators throw nothing. - It is not
noexcept, for any type.
Remarks¶
- A call that violates the precondition is not a core constant expression, whether or not
NDEBUGis defined. - The result is an
int, whatever the width ofT. - A type no wider than a block calls the block kernel once. A wider type skips whole blocks by their population,
subtracting it from
k, until the one of rankklies in the current block, and adds that block's offset to what the block kernel finds there. - Outside a constant expression, where
XSTD_INTS_HAS_FAST_BMI2is defined, as forbit_compress, the block kernel deposits2^kthroughxby onePDEPand returns the deposit'scountr_zero. Everywhere else, and in every constant expression, it is Vigna's broadword select, which finds the byte holding the one by one multiply and one compare and the bit within it from a table, with no loop or branch on the value. - A 64-bit call contains a
pdepunder-mbmi2, and under-march=x86-64-v3is apdepfollowed at once bytzcnt, with no branch or call; it has nopextorpdepunder-march=x86-64,-mgfni,bdver4,znver1orznver2.
Notes¶
- It is the inverse of rank: exactly
kones ofxlie below the one it finds, and expanding2^kthroughxdeposits on it. At rank zero it iscountr_zero(x), and at rankpopcount(x) - 1it isbit_width(x) - 1. - Every rank of a full value is its own position, and the ones on either side of bit 64 are found in order.
- A call is a constant expression for every type it takes.
See also¶
| Entity | Relation |
|---|---|
bit_expand |
deposits 2^k on the position it finds |
countr_zero, popcount |
its answer at rank zero, and the bound on k |
bit_width |
one past its answer at the top rank |
| Notation | what N, x[n] and a block mean here |