C++ Logo

std-proposals

Advanced search

[std-proposals] std::bitset split and concat

From: Nikolaj Fogh <nikolajfogh_at_[hidden]>
Date: Sat, 16 Nov 2024 22:55:42 +0100
Hi

When working with binary data, one often needs to split a larger
std::bitset into several smaller std::bitsets. One example is if you
have a memory-mapped register read into a std::bitset.

The reverse is also needed to concatenate sub-bitsets into a larger bitset.

Currently, splitting and concatenating these requires using mask and
shift operations on the bitset, which can be complicated to read and
thus, error-prone.

I propose adding two utility functions (split and concat) for std::bitset:

template<size_t... slices, size_t num_bits_in_source>
constexpr auto split(std::bitset<num_bits_in_source> source)

template<size_t num_bits, size_t... num_bits_rest>
constexpr auto concat(std::bitset<num_bits> bits,
std::bitset<num_bits_rest>... rest)

split would return a tuple of bitsets.

The use of these functions could be as follows:

  std::bitset<8> uxlcr{"10010111"};
  auto [divisor_latch_access, break_ctrl, parity, parity_enable,
stopbit, word_length] = split<1,1,2,1,1,2>(uxlcr);
  word_length = 0b10;
  uxlcr = concat(divisor_latch_access, break_ctrl, parity,
parity_enable, stopbit, word_length);

Another use-case is extracting sextets to generate base-64 encoded data:

--- to base64 ---
const auto datablock = std::bitset<24>{...};
const auto sextets = std::split<6,6,6,6>(data);
const auto ascii = sextets2chars(sextets);

--- from base64 ---
const auto chars = std::array<char, 4>{...};
const auto sextets = chars2sextets(chars);
const auto binary = std::concat(sextets);

sextets will in these examples be a tuple of 4 std::bitset<6>

Example implementation:
https://godbolt.org/z/P8PaqvnMa

Looking forward to your thoughts on this.

Best regards
  Nikolaj Fogh

Received on 2024-11-16 21:55:58