22 General utilities library [utilities]

22.11 Bit manipulation [bit]


22.11.1 General [bit.general]

22.11.2 Header <bit> synopsis [bit.syn]

22.11.3 Function template bit_cast [bit.cast]

22.11.4 byteswap [bit.byteswap]

22.11.5 Integral powers of 2 [bit.pow.two]

22.11.6 Shifting [bit.shift]

22.11.7 Rotating [bit.rotate]

22.11.8 Counting [bit.count]

22.11.9 Permutation [bit.permute]

22.11.10 Endian [bit.endian]


22.11.1 General [bit.general]

The header <bit> provides components to access, manipulate and process both individual bits and bit sequences.

22.11.2 Header <bit> synopsis [bit.syn]

// all freestanding namespace std { // [bit.cast], bit_cast template<class To, class From> constexpr To bit_cast(const From& from) noexcept; // [bit.byteswap], byteswap template<class T> constexpr T byteswap(T value) noexcept; // [bit.pow.two], integral powers of 2 template<class T> constexpr bool has_single_bit(T x) noexcept; template<class T> constexpr T bit_ceil(T x); template<class T> constexpr T bit_floor(T x) noexcept; template<class T> constexpr int bit_width(T x) noexcept; // [bit.shift], shifting template<class T, class S> constexpr T shl(T x, S s) noexcept; template<class T, class S> constexpr T shr(T x, S s) noexcept; // [bit.rotate], rotating template<class T> constexpr T rotl(T x, int s) noexcept; template<class T> constexpr T rotr(T x, int s) noexcept; // [bit.count], counting template<class T> constexpr int countl_zero(T x) noexcept; template<class T> constexpr int countl_one(T x) noexcept; template<class T> constexpr int countr_zero(T x) noexcept; template<class T> constexpr int countr_one(T x) noexcept; template<class T> constexpr int popcount(T x) noexcept; // [bit.permute], permutation template<class T> constexpr T bit_reverse(T x) noexcept; template<class T> constexpr T bit_repeat(T x, int l); template<class T> constexpr T bit_compress(T x, T m) noexcept; template<class T> constexpr T bit_expand(T x, T m) noexcept; // [bit.endian], endian enum class endian { little = see below, big = see below, native = see below }; }

22.11.3 Function template bit_cast [bit.cast]

template<class To, class From> constexpr To bit_cast(const From& from) noexcept;
Constraints:
  • sizeof(To) == sizeof(From) is true;
  • is_trivially_copyable_v<To> is true; and
  • is_trivially_copyable_v<From> is true.
Constant When: Neither To nor From has constexpr-unknown representation ([expr.const.core]).
Returns: An object of type To.
Implicitly creates objects nested within the result ([intro.object]).
Each bit of the value representation of the result is equal to the corresponding bit in the object representation of from.
Padding bits of the result are unspecified.
Every trivially copyable object among the result and each object created within it acquires the value representation produced; if any such object does not receive a value, the behavior is undefined.
A bit in the value representation of the result is indeterminate if it does not correspond to a bit in the value representation of from or corresponds to a bit for which the smallest enclosing object is not within its lifetime or has an indeterminate value ([basic.indet]).
A bit in the value representation of the result is erroneous if it corresponds to a bit for which the smallest enclosing object has an erroneous value.
For each bit b in the value representation of the result that is indeterminate or erroneous, let u be the smallest object containing that bit enclosing b:
  • If u is of unsigned ordinary character type or std​::​byte type, u has an indeterminate value if any of the bits in its value representation are indeterminate, or otherwise has an erroneous value.
  • Otherwise, if b is indeterminate, the behavior is undefined.
  • Otherwise, the behavior is erroneous, and the result is as specified above.
The result does not otherwise contain any indeterminate or erroneous values.

22.11.4 byteswap [bit.byteswap]

template<class T> constexpr T byteswap(T value) noexcept;
Constraints: T models integral.
Mandates: T does not have padding bits ([basic.types.general]).
Let the sequence R comprise the bytes of the object representation of value in reverse order.
Returns: An object v of type T such that each byte in the object representation of v is equal to the byte in the corresponding position in R.

22.11.5 Integral powers of 2 [bit.pow.two]

template<class T> constexpr bool has_single_bit(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: true if x is an integral power of two; false otherwise.
template<class T> constexpr T bit_ceil(T x);
Let N be the smallest power of 2 greater than or equal to x.
Constraints: T is an unsigned integer type ([basic.fundamental]).
Preconditions: N is representable as a value of type T.
Returns: N.
Throws: Nothing.
Remarks: A function call expression that violates the precondition in the Preconditions: element is not a core constant expression ([expr.const.core]).
template<class T> constexpr T bit_floor(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: If x == 0, 0; otherwise the maximal value y such that has_single_bit(y) is true and y <= x.
template<class T> constexpr int bit_width(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: If x == 0, 0; otherwise one plus the base-2 logarithm of x, with any fractional part discarded.

22.11.6 Shifting [bit.shift]

Within this subclause, the result r of an arithmetic operation is first represented in a hypothetical integer type with sufficient range, then converted to T as if by static_cast<T>(r).
template<class T, class S> constexpr T shl(T x, S s) noexcept;
Constraints: Each of T and S is a signed or unsigned integer type ([basic.fundamental]).
Returns: rounded towards negative infinity.
template<class T, class S> constexpr T shr(T x, S s) noexcept;
Constraints: Each of T and S is a signed or unsigned integer type ([basic.fundamental]).
Returns: rounded towards negative infinity.

22.11.7 Rotating [bit.rotate]

In the following descriptions, let N denote numeric_limits<T>​::​digits.
template<class T> constexpr T rotl(T x, int s) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Let r be s % N.
Returns: If r is 0, x; if r is positive, (x << r) | (x >> (N - r)); if r is negative, rotr(x, -r).
template<class T> constexpr T rotr(T x, int s) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Let r be s % N.
Returns: If r is 0, x; if r is positive, (x >> r) | (x << (N - r)); if r is negative, rotl(x, -r).

22.11.8 Counting [bit.count]

In the following descriptions, let N denote numeric_limits<T>​::​digits.
template<class T> constexpr int countl_zero(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: The number of consecutive 0 bits in the value of x, starting from the most significant bit.
[Note 1: 
Returns N if x == 0.
— end note]
template<class T> constexpr int countl_one(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: The number of consecutive 1 bits in the value of x, starting from the most significant bit.
[Note 2: 
Returns N if x == numeric_limits<T>​::​max().
— end note]
template<class T> constexpr int countr_zero(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: The number of consecutive 0 bits in the value of x, starting from the least significant bit.
[Note 3: 
Returns N if x == 0.
— end note]
template<class T> constexpr int countr_one(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: The number of consecutive 1 bits in the value of x, starting from the least significant bit.
[Note 4: 
Returns N if x == numeric_limits<T>​::​max().
— end note]
template<class T> constexpr int popcount(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: The number of 1 bits in the value of x.

22.11.9 Permutation [bit.permute]

In the following descriptions, let N denote the value of numeric_limits<T>​::​digits, and let denote the value of the least significant bit in the base-2 representation of an integer α, so that α equals .
template<class T> constexpr T bit_reverse(T x) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: reverse(x), where reverse is given by Formula 22.1, and x is x.
[Note 1: 
bit_reverse(bit_reverse(x)) equals x.
— end note]
template<class T> constexpr T bit_repeat(T x, int l);
Constraints: T is an unsigned integer type ([basic.fundamental]).
Preconditions: l is greater than zero.
Returns: , where repeat is given by Formula 22.2, x is x, and l is l.
Throws: Nothing.
Remarks: A function call expression that violates the precondition in the Preconditions: element is not a core constant expression ([expr.const.core]).
[Example 1: 
bit_repeat(uint32_t{0xc}, 4) equals 0xcccccccc.
— end example]
template<class T> constexpr T bit_compress(T x, T m) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: , where compress is given by Formula 22.3, x is x, and m is m.
[Example 2: 
bit_compress(0bABCD, 0b0101) equals 0b00BD for any bits A, B, C, and D.
— end example]
template<class T> constexpr T bit_expand(T x, T m) noexcept;
Constraints: T is an unsigned integer type ([basic.fundamental]).
Returns: , where expand is given by Formula 22.4, x is x, and m is m.
[Example 3: 
bit_expand(0bABCD, 0b0101) equals 0b0C0D for any bits A, B, C, and D.
— end example]

22.11.10 Endian [bit.endian]

Two common methods of byte ordering in multibyte scalar types are big-endian and little-endian in the execution environment.
Big-endian is a format for storage of binary data in which the most significant byte is placed first, with the rest in descending order.
Little-endian is a format for storage of binary data in which the least significant byte is placed first, with the rest in ascending order.
This subclause describes the endianness of the scalar types of the execution environment.
enum class endian { little = see below, big = see below, native = see below };
If all scalar types have size 1 byte, then all of endian​::​little, endian​::​big, and endian​::​native have the same value.
Otherwise, endian​::​little is not equal to endian​::​big.
If all scalar types are big-endian, endian​::​native is equal to endian​::​big.
If all scalar types are little-endian, endian​::​native is equal to endian​::​little.
Otherwise, endian​::​native is not equal to either endian​::​big or endian​::​little.