I'm currently trying to simulate some firmware in C++11. In the firmware we have a fixed data length of 32 bits, we split this 32 bits into smaller packets e.g we have a packet which as a size of 9 bits, another of 6 which gets packed into the 32 bit word.
In C++ I want to ensure the data I type in is of those lengths. I don't care if I overflow, just that only the 9 bits are operated on or passed onto another function.
Ideally I'd like some simple typedef like:
only_18_bits some_value;
struct sel_vals{
int_fast32_t m_val : 18;
int_fast8_t c_val : 5;
}
But this is a little annoying as I'd have to do this whenever I want to use it:
sel_vals somevals;
somevals.m_val = 5;
Seems a little verbose to me plus I have to declare the struct first.
Also for obvious reasons, I can't just do something like:
typedef sel_vals.m_val sel_vals_m_t;
typedef std::vector<sel_vals_m_t>;
I could use std::bitset<9>
but whenever I want to do some maths I have to convert it to unsigned, it just gets a little messy. I want to avoid mess.
Any ideas?
I would suggest a wrapper facade, something along these lines:
#include <cstdint>
template<int nbits> class bits {
uint64_t value;
static const uint64_t mask = (~(uint64_t)0) >> (64-nbits);
public:
bits(uint64_t initValue=0) : value(initValue & mask) {}
bits &operator=(uint64_t newValue)
{
value=newValue & mask;
}
operator uint64_t() const { return value; }
};
//
bits<19> only_19_bits_of_precision;
With a little bit of work, you can define math operator overloads that directly operate on these templates.
With a little bit of more work, you could work this template to pick a smaller internal value, uint32_t
, uint16_t
, or uint8_t
, if the nbits
template parameter is small enough.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With