80 lines
1.8 KiB
C++
80 lines
1.8 KiB
C++
// File: crn_packed_uint
|
|
// See Copyright Notice and license at the end of inc/crnlib.h
|
|
#pragma once
|
|
|
|
namespace crnlib {
|
|
template <unsigned int N>
|
|
struct packed_uint {
|
|
inline packed_uint() {}
|
|
|
|
inline packed_uint(unsigned int val) { *this = val; }
|
|
|
|
inline packed_uint(const packed_uint& other) { *this = other; }
|
|
|
|
inline packed_uint& operator=(const packed_uint& rhs) {
|
|
if (this != &rhs)
|
|
memcpy(m_buf, rhs.m_buf, sizeof(m_buf));
|
|
return *this;
|
|
}
|
|
|
|
inline packed_uint& operator=(unsigned int val) {
|
|
#ifdef CRNLIB_BUILD_DEBUG
|
|
if (N == 1) {
|
|
CRNLIB_ASSERT(val <= 0xFFU);
|
|
} else if (N == 2) {
|
|
CRNLIB_ASSERT(val <= 0xFFFFU);
|
|
} else if (N == 3) {
|
|
CRNLIB_ASSERT(val <= 0xFFFFFFU);
|
|
}
|
|
#endif
|
|
|
|
val <<= (8U * (4U - N));
|
|
|
|
for (unsigned int i = 0; i < N; i++) {
|
|
m_buf[i] = static_cast<unsigned char>(val >> 24U);
|
|
val <<= 8U;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
inline operator unsigned int() const {
|
|
switch (N) {
|
|
case 1:
|
|
return m_buf[0];
|
|
case 2:
|
|
return (m_buf[0] << 8U) | m_buf[1];
|
|
case 3:
|
|
return (m_buf[0] << 16U) | (m_buf[1] << 8U) | (m_buf[2]);
|
|
default:
|
|
return (m_buf[0] << 24U) | (m_buf[1] << 16U) | (m_buf[2] << 8U) | (m_buf[3]);
|
|
}
|
|
}
|
|
|
|
unsigned char m_buf[N];
|
|
};
|
|
template <typename T>
|
|
class packed_value {
|
|
public:
|
|
packed_value() {}
|
|
packed_value(T val) { *this = val; }
|
|
|
|
inline operator T() const {
|
|
T result = 0;
|
|
for (int i = sizeof(T) - 1; i >= 0; i--)
|
|
result = static_cast<T>((result << 8) | m_bytes[i]);
|
|
return result;
|
|
}
|
|
packed_value& operator=(T val) {
|
|
for (int i = 0; i < sizeof(T); i++) {
|
|
m_bytes[i] = static_cast<uint8>(val);
|
|
val >>= 8;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
uint8 m_bytes[sizeof(T)];
|
|
};
|
|
} // namespace crnlib
|