C++ (Qt)struct A { int a; // 2 bits int b; // 15}; struct B { A a; int b; // 26 int c; // 1 int d; // 53}; struct C { int a; // 42 B b[]; int c; // 12};
C++ (Qt)template<N, S>struct Field { bool v // if N == 1 int8_t v // if N <= 8 && S=signed uint8_t v // if N <= 8 && S=unsigned ...};
C++ (Qt)// Схемы пакетовauto ShemaPacket1 = std::make_tuple( 3, 3, 10, 52 );auto ShemaPacket2 = std::make_tuple( 9, 11, 37, 60, 1, 1 ); // Возвращает упакованный bit_arrayauto bits1 = pack( ShemaPacket1, 1, 2, 8, 1024 );auto bits2 = pack( ShemaPacket1, data.val1, data.val2, data.val3, data.val4 );auto bits3 = pack( ShemaPacket2, 15, 0, 0, 1024, 1, 0 ); // Возвращает кортеж значений по указанной схеме или exceptionauto result1 = unpack( bits1, ShemaPacket1 )auto [val1, val2, val3, val4] = unpack( bits1, ShemaPacket1 )auto result3 = unpack( bits3, ShemaPacket2 )
C++ (Qt)static const unsigned int BitsInByte = 8; unsigned long readBits(unsigned char bits, unsigned char *buf, unsigned int *pBufPos){ unsigned int bufPos = *pBufPos, newBufPos = bufPos + bits; unsigned int bufIndexOfFirstByte = bufPos / BitsInByte; unsigned int ignoreBitsInFirstByte = bufPos % BitsInByte; unsigned int fullByteStart = bufPos + (BitsInByte - ignoreBitsInFirstByte); unsigned int additionalBits = newBufPos - fullByteStart; unsigned int bitsInLastByte = additionalBits - (additionalBits / BitsInByte) * BitsInByte; unsigned int bufIndexOfLastByte = (newBufPos - 1) / BitsInByte + (bitsInLastByte ? 0 : 1); // start with remainder bits of the first byte unsigned long value = buf[bufIndexOfFirstByte] >> ignoreBitsInFirstByte; // add "full" bytes in between for (unsigned int fullByteIndex = fullByteStart / BitsInByte, lshiftBits = BitsInByte - ignoreBitsInFirstByte; fullByteIndex < bufIndexOfLastByte; ++fullByteIndex, lshiftBits += BitsInByte) value |= buf[fullByteIndex] << lshiftBits; // end with a piece of the last byte if (bitsInLastByte) value |= (buf[bufIndexOfLastByte] & ((1 << bitsInLastByte) - 1)) << (bits - bitsInLastByte); *pBufPos = newBufPos; return value;} int main(){ unsigned char buf[] = {0, 0x1E, 0x40}; unsigned int pos = 0; std::cout << readBits(9, buf, &pos) << ' ' << readBits(13, buf, &pos) << '\n'; // 0 15 return 0;}
C++ (Qt)int main(){ std::array c = {std::byte{0}, std::byte{0x78}, std::byte{0x2}}; // swapped auto u = bitpacker::unpack(BP_STRING("<u9u13"), c); // < означает LSB std::cout << std::get<0>(u) << ' ' << std::get<1>(u) << '\n'; return 0;}
C++ (Qt)// C++17#include <type_traits>#include <iostream> struct I{ virtual int64_t value() const = 0; virtual void print() const = 0;}; template<int N>struct A : public I{ static constexpr auto size = N; std::conditional_t<size == 1, bool, std::conditional_t<size <= 8, char, int> > v; A(decltype(v) vv) : v(vv) {} int64_t value() const override { return v; } void print() const override { std::cout << size << ' ' << std::boolalpha << v << '\n'; }}; int main(){ A<1> a{true}; A<8> b{'!'}; A<10> c{42}; static_assert(a.size == 1); static_assert(std::is_same_v<decltype(a.v), bool>); static_assert(std::is_same_v<decltype(b.v), char>); static_assert(std::is_same_v<decltype(c.v), int>); for (auto const i : std::initializer_list<I const *>{&a, &b, &c}) { std::cout << i->value() << '\t'; i->print(); } return 0;}
C++ (Qt) /// finds the smallest fixed width unsigned integer that can fit NumBits bits template <size_type NumBits> using unsigned_type = std::conditional_t<NumBits <= 8, uint8_t, std::conditional_t<NumBits <= 16, uint16_t, std::conditional_t<NumBits <= 32, uint32_t, std::conditional_t<NumBits <= 64, uint64_t, void >>>>; /// finds the smallest fixed width signed integer that can fit NumBits bits template <size_type NumBits> using signed_type = std::conditional_t<NumBits <= 8, int8_t, std::conditional_t<NumBits <= 16, int16_t, std::conditional_t<NumBits <= 32, int32_t, std::conditional_t<NumBits <= 64, int64_t, void >>>>;
C++ (Qt)std::array c = {std::byte{0}, std::byte{0x78}, std::byte{0x2}};
C++ (Qt)struct A { int m_B; int m_C; ... qint64 m_bits;}