Сейчас вот наваял шаблончик: может, пригодится?
Предназначен для облегчения работы с битовыми полями.
(может, я изобрел велосипед, а может нет)
/////////////////
// template class
template <
class BITFIELDS, // a structure, using bit fields
class INTTYPE = unsigned // a numeric type
>
union FlagsUnion
{
// data members
INTTYPE value;
BITFIELDS bits;
// constructors
FlagsUnion() {}
FlagsUnion(INTTYPE v) : value(v) {}
FlagsUnion(const BITFIELDS& b) : bits(b) {}
// assignment
int operator = (INTTYPE v) { return value = v; }
const BITFIELDS& operator = (const BITFIELDS& b)
{
value = 0;
return bits = b;
}
// convert to number
operator INTTYPE () const { return value; }
operator INTTYPE& () { return value; }
// convert to structure
operator const BITFIELDS& () const { return bits; }
operator BITFIELDS& () const { return bits; }
// access to members of the structure
const BITFIELDS* operator -> () const { return &bits; }
BITFIELDS* operator -> () { return &bits; }
};
А это — пример (абстрактный)
/////////////////
// example of use
struct BF
{
unsigned a : 1;
unsigned b : 1;
};
BF bf = { 1, 0 };
// construction
FlagsUnion<BF> fu1, fu2(0x2), fu3(bf);
// assignment
fu1 = 0x1;
fu1 = bf;
// access
unsigned i = fu1;
bf = fu1;
// access to members
fu1.value = 0x1;
fu1.bits.a = 1;
fu1->b = 1;
А вот конкретный: расшифровка HRESULT
struct HRESULT_BITS // low-endian 32 bit
{
// 0-15 code (what it is)
unsigned code : 16;
// 16-26 facility (what subsystem has reported: Windows, RPC, IDispatch, user-defined, etc.)
unsigned fac : 11
// 27-30 reserved
bool r : 1;
bool N : 1;
bool C : 1;
bool R : 1;
// 31 severity (error or success)
bool sev : 1;
};
typedef FlagsUnion<HRESULT_BITS, HRESULT> HResultBits;
HResultBits hr;
hr->sev = SEVERITY_ERROR;
hr->facility = FACILITY_ITF; // user-defined
hr->code = 0x123; // some error code
// same as
hr = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x123);
И еще один пример: расшифровка float (MSDN: KB
Q36068 — INFO: IEEE Floating-Point Representation and MS Languages)
struct IEEE_REAL_4_BITS
{
int sign : 1;
int exponent : 8; // с вычтенной 1 (2^0 --> exponent = 0)
unsigned mantissa : 23; // затейливо нормализовано: 1000...0b <-> 1+1/2; 0110...0b <-> 1+6/8
};
struct IEEE_REAL_8_BITS
{
int sign : 1;
int exponent : 11;
unsigned mantissa : 52;
};
typedef FlagsUnion<IEEE_REAL_4_BITS, float> FloatBits;
typedef FlagsUnion<IEEE_REAL_8_BITS, double> DoubleBits;
К>И еще один пример: расшифровка float (MSDN: KB Q36068 — INFO: IEEE Floating-Point Representation and MS Languages)
К>К>struct IEEE_REAL_4_BITS
К>{
К> int sign : 1;
К> signed int exponent : 8; // с вычтенной 1 (2^0 --> exponent = -1)
К> unsigned mantissa : 23; // затейливо нормализовано: <...> здесь я напутал.
// мантисса (изображенная big endian)
// число (двоичное)
// дробь
// ...0001b -- 1.1b = 1 + 1/2
// ...0010b -- 1.01b = 1 + 1/4
// ...0011b -- 1.11b = 1 + 3/4
// ...0100b -- 1.001b = 1 + 1/8
// т.е. k-й разряд мантиссы соответствует степени 2^(-k)
К>};
К>struct IEEE_REAL_8_BITS
К>{
К> int sign : 1;
К> signed int exponent : 11;
К> unsigned mantissa : 52;
К>};
К>