| Home | Libraries | People | FAQ | More

## bit

### Authors

- Peter Dimov

### Header <boost/core/bit.hpp>

The header `<boost/core/bit.hpp>` implements, in a portable way, the C++20 `<bit>` header.

#### Synopsis

    namespace boost
    {
    namespace core
    {

    // bit_cast

    template<class To, class From>
    To bit_cast(From const& from) noexcept;

    // byteswap

    template<class T>
    constexpr T byteswap(T x) noexcept;

    // Integral powers of 2

    template<class T>
    constexpr bool has_single_bit(T x) noexcept;

    template<class T>
    constexpr T bit_ceil(T x) noexcept;

    template<class T>
    constexpr T bit_floor(T x) noexcept;

    template<class T>
    constexpr int bit_width(T x) noexcept;

    // Rotating

    template<class T>
    constexpr T rotl(T x, int s) noexcept;

    template<class T>
    constexpr T rotr(T x, int s) noexcept;

    // 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;

    // Endian

    enum class endian
    {
        little = see below,
        big = see below,
        native = see below
    };

    using endian_type = endian; // portable alias for C++03 code

    } // namespace core
    } // namespace boost

Note: even though the functions are shown as `constexpr` in the synopsis, since they are implemented via compiler-specific intrinsics, portable code cannot generally rely on their being usable in a constant expression context.

#### bit_cast

`template<class To, class From> To bit_cast(From const& from) noexcept;`

- Requires: `To` and `From` must be trivially copyable and `sizeof(To)` must be the same as `sizeof(From)`.
- Returns: A value of type `To` with the storage bytes copied from `from`.

#### byteswap

`template<class T> constexpr T byteswap(T x) noexcept;`

- Requires: `T` must be an integer type (i.e. one of `char`, `signed char`, `unsigned char`, `short`, `unsigned short`, `int`, `unsigned int`, `long`, `unsigned long`, `long long`, `unsigned long long`) without padding bits.
- Returns: `x` with the storage bytes reversed.

#### Integral powers of 2

`template<class T> constexpr bool has_single_bit(T x) noexcept;`

- Requires: `T` must be an unsigned integer type (i.e. one of `unsigned char`, `unsigned short`, `unsigned int`, `unsigned long`, `unsigned long long`).
- Returns: `true` if `x` is an integral power of two, `false` otherwise. (`has_single_bit(0u)` is false.)

`template<class T> constexpr T bit_ceil(T x) noexcept;`

- Requires: `T` must be an unsigned integer type.
- Returns: The smallest integral power of 2 greater than or equal to `x`. If this value is not representable in `T`, behavior is undefined.

`template<class T> constexpr T bit_floor(T x) noexcept;`

- Requires: `T` must be an unsigned integer type.
- 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;`

- Requires: `T` must be an unsigned integer type.
- Returns: If `x == 0`, 0; otherwise one plus the base-2 logarithm of `x`, with any fractional part discarded.

#### Rotating

In the following descriptions, `N` denotes `numeric_limits<T>::digits` and `r` denotes `s % N`.

`template<class T> constexpr T rotl(T x, int s) noexcept;`

- Requires: `T` must be an unsigned integer type.
- Returns: If `s` is negative, `rotr(x, -s)`; if `r` is 0, `x`; if `r` is positive, `(x << r) | (x >> (N - r))`.

`template<class T> constexpr T rotr(T x, int s) noexcept;`

- Requires: `T` must be an unsigned integer type.
- Returns: If `s` is negative, `rotl(x, -s)`; if `r` is 0, `x`; if `r` is positive, `(x >> r) | (x << (N - r))`.

#### Counting

`template<class T> constexpr int countl_zero(T x) noexcept;`

- Requires: `T` must be an unsigned integer type.
- Returns: The number of consecutive 0 bits in the value of `x`, starting from the most significant ("left") bit.

`template<class T> constexpr int countl_one(T x) noexcept;`

- Requires: `T` must be an unsigned integer type.
- Returns: The number of consecutive 1 bits in the value of `x`, starting from the most significant bit.

`template<class T> constexpr int countr_zero(T x) noexcept;`

- Requires: `T` must be an unsigned integer type.
- Returns: The number of consecutive 0 bits in the value of `x`, starting from the least significant ("right") bit.

`template<class T> constexpr int countr_one(T x) noexcept;`

- Requires: `T` must be an unsigned integer type.
- Returns: The number of consecutive 1 bits in the value of `x`, starting from the least significant bit.

`template<class T> constexpr int popcount(T x) noexcept;`

- Requires: `T` must be an unsigned integer type.
- Returns: The number of 1 bits in the value of `x`.

#### Endian

Under C++11, `endian` is defined as `enum class endian` as shown in the synopsis. Under C++03, its definition is

    namespace endian
    {
    enum type
    {
        little = see below,
        big = see below,
        native = see below
    };
    }

    typedef endian::type endian_type;

The values of `endian::big` and `endian::little` are distinct. `endian::native` is equal to `endian::big` on big endian platforms, equal to `endian::little` on little endian platforms, and a distinct value on platforms that are neither.

Note that you should not rely on `little` and `big` having any specific values, because the C++20 standard leaves these unspecified.