I've been trying to figure this one out, and thought it would be a fun one to take a look at :)
Ok, so I'm creating a type as constexpr using bitfields. Since bitfields can change from one implementation or platform to another, I want to static_assert that the bits are in the right place. With me so far? Here's the code for the type I'm creating:
// Currently hard-coded for 64bit, will change later when I get past this part...
constexpr int getPointerBitCount() { return 64; }
constexpr int getPointerByteWidth() { return getPointerBitCount() / 8; }
constexpr int getPointerDataWidth() { return 3; }
constexpr int getPointerPointerWidth() { return getPointerBitCount() - getPointerDataWidth(); }
struct PointerData
{
bool _invalid :1;
bool _delete :1;
bool _unused :1;
uint64_t _pointer :getPointerPointerWidth();
constexpr PointerData(bool invalid, bool isDelete, bool unused)
: _invalid{invalid}
, _delete{isDelete}
, _unused{unused}
, _pointer{0}
{
}
};
So now what I would like to do is this:
static_assert(reinterpret_cast<uint64_t>(PointerData(true, false, false)) == 1, "PointerData not supported on this platform");
static_assert(reinterpret_cast<uint64_t>(PointerData(false, true, false)) == 2, "PointerData not supported on this platform");
static_assert(reinterpret_cast<uint64_t>(PointerData(false, false, true)) == 4, "PointerData not supported on this platform");
Basically, I need to create the PointerData type as constexpr, and then run tests on it as if the entire thing was a uint64_t (or uint32_t on 32 bit). But, my compiler says I can't use reinterpret_cast here. Thoughts on how I can do this?
Running bitwise operators to compute the value will not achieve what I'm looking for. I need to access the variable "as is". The test here is to see if the first bit in a bitfield is equal to 1. (and the second = 2, and the 3rd = 4).
I looked into creating a union out of this, but I'm not sure if that's appropriate given the bitfields. Unsure.
I'm new to the constexpr stuff, so help would be appreciated!