|
pstore2
|
A portable bit-field type. More...
#include <cstddef>#include <cstdint>#include <limits>#include <type_traits>#include "pstore/support/assert.hpp"

Go to the source code of this file.
Variables | |
| template<typename ValueType , unsigned Index, unsigned Bits> | |
| pstore::details::mask_ | |
A portable bit-field type.
C and C++ bit-fields are a nice easy way to declare structure members with an explicit number of bits. However, their portability is severely limited if the exact layout of the structure is important: the language standards allow the compiler complete freedom in deciding where are how the bits are allocated in the underlying memory. We need some of the pstore data structures to be consistent regardless of the compiler being used, and there are static assertions which enforce these guarantees. Unfortunately, if we can't guarantee the bit-field layout then we can't used traditional bit-fields in these structures.
The template class provded here is a simple means to define a structure member which uses specified bits from a value of a specified base type.
Using it is simple. Define a union consisting of a member of the base type and one member for each of the bit-fields. For example:
union {
std::uint8_t v;
bit_field<std::uint8_t, 0, 2> f1; // f1 is bits [0-2)
bit_field<std::uint8_t, 2, 6> f2; // f2 is bits [2-7)
};
This is approximately equivalent to the standard C:
struct {
std::uint8_t f1 : 2;
std::uint8_t f2 : 6;
};
The difference is that in the first example the union will occupy 8 bits with f1 being bits [0-2) and f1 beng bits [2-7). The standards make few guarantees about the second example.
It's worth noting that the 'v' member of the first example should be initialized to 0 before fields f1 or f2 are read or written. This is to ensure the masks performed by the bit-field instances don't try to read or write uninitialized memory.
1.8.13