As of C++17 there are the following types representing an 8-bit unit of storage:
- char, unsigned char
- int8_t, uint8_t
- std::byte
As I understand it the intent is that char's should now be used when the byte is actually representing a character, for example, in a string. int8_t should be used when the byte is representing a numeric value that happens to be an integer only needing 8-bits of storage. And std::byte should be used for everything else, essentially as a unit of binary data -- if you read a binary file from the file system, say.
But what about bit fields? bit flags ... whatever you want to call them. Like say you are writing a random maze generator and you want to represent the maze as an std::vector of bytes where each byte contains flags as bits specifying which walls of a cell are present. If you wanted to convert back and forth between a struct of bools and byte representation of such a cell you would have to use something like the following syntax as far as I call tell:
const std::byte kTop{0b0001};
const std::byte kRight{0b0010};
const std::byte kBottom{0b0100};
const std::byte kLeft{0b1000};
Maze::Cell::Cell(std::byte b) :
top( static_cast<bool>(b & kTop) ),
right( static_cast<bool>(b & kRight) ),
bottom( static_cast<bool>( b & kBottom) ),
left( static_cast<bool>(b & kLeft) )
{
}
std::byte Maze::Cell::toByte() const
{
return (top ? kTop : std::byte{0}) |
(right ? kRight : std::byte{0}) |
(bottom ? kBottom : std::byte{0}) |
(left ? kLeft : std::byte{0});
}
This syntax seems to a little verbose to me, having to explicitly cast to bool, having no short literal for std::byte{0}, etc.
Is there some simpler syntax for this sort of thing or is std::byte the wrong choice of type?
std::int_least8_t
orstd::int_fast8_t
.std::int8_t
doesn’t exist if the hardware doesn’t have an 8-bit type. – Pete Becker