Spec-Zone.ru › C++

std::bit_repeat

Defined in header <bit>
template< class T >
constexpr T bit_repeat( T x, int l );
(since C++29)

Repeats the bit pattern in x of length l as many times as fits into the result (with the last repetition potentially truncated).

If l is less than or equal to 0, the behavior is undefined. Call to this function is permitted in constant evaluation only if the undefined behavior does not occur.

This overload participates in overload resolution only if T is an unsigned integer type (that is, unsignedchar, unsignedshort, unsignedint, unsignedlong, unsignedlonglong, or an extended unsigned integer type).

Parameters

x - value of unsigned integer type

Return value

The repeated bit pattern.

Exceptions

Throws nothing.

Notes

Feature-test macro Value Std Feature
__cpp_lib_bitops 202607L (C++29) Bit permutations

Possible implementation

template<typename T, typename ... U>
concept neither = (!std::same_as<T, U> && ...);

// This is a valid, but highly inefficient version of bit_repeat.
template<std::unsigned_integral T>
    requires neither<T, bool, char, char8_t, char16_t, char32_t, wchar_t>
constexpr T bit_repeat_naive(T x, int l) noexcept
{
    T result = 0;
    for (int i = 0; i != std::numeric_limits<T>::digits; ++i)
        result |= ((x >> (i % length)) & 1) << i;
    return result;
}

// Constant-time implementation (preferred).
template<std::unsigned_integral T>
    requires neither<T, bool, char, char8_t, char16_t, char32_t, wchar_t>
constexpr T bit_repeat(T x, int l) noexcept
{
    static constexpr auto lookup = []
    {
        std::array<T, std::numeric_limits<T>::digits> result{};
        for (std::size_t i = 1; i != result.size(); ++i)
            result[i] = bit_repeat_naive(one, l);
        return result;
    }();
    if (l >= std::numeric_limits<T>::digits)
        return x;
    T mask = (T{1} << l) - T{1};
    return lookup[l] * (mask & x);
}

Example

#include <bit>
#include <cstdint>

static_assert(
    std::bit_repeat(
        std::uint8_t{1}, 1) ==
        std::uint8_t{0b1111'1111} and
    std::bit_repeat(
        std::uint8_t{0b1110}, 2) ==
        std::uint8_t{0b1010'1010} and
    std::bit_repeat(
        std::uint8_t{0b101}, 3) ==
        std::uint8_t{0b1'101'101} and
    std::bit_repeat(
        std::uint16_t{0b1100}, 4) ==
        std::uint16_t{0b1100'1100'1100'1100}
);

int main() {}

See also

bit_reverse
(C++29)
reverses the bits in an integer
(function template)
bit_compress
(C++29)
compresses bits of an operand using a mask (PEXT)
(function template)
bit_expand
(C++29)
expands bits from an operand using a mask (PDEP)
(function template)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/numeric/bit_repeat

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API