Endian: Remove old special integer bitfields
The only way to use them was to put them in a union and then write all the members of the union to set the various bit ranges. As only one member of a union can be active at any time, the compiler is free to optimize those writes away, though. This has started happening in the wild now. As we have a replacement, we can remove the old and broken code now. Task-number: QTBUG-99545 Change-Id: I90718ec06662258d1c15220f54da9eed2186c5a5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
bc144312c1
commit
4912903e37
|
|
@ -20,81 +20,6 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// Note if using multiple of these bitfields in a union; the underlying storage type must
|
||||
// match. Since we always use an unsigned storage type, unsigned and signed versions may
|
||||
// be used together, but different bit-widths may not.
|
||||
template<class S, int pos, int width>
|
||||
class QSpecialIntegerBitfield
|
||||
{
|
||||
protected:
|
||||
typedef typename S::StorageType T;
|
||||
typedef typename std::make_unsigned<T>::type UT;
|
||||
|
||||
static constexpr UT mask()
|
||||
{
|
||||
return ((UT(1) << width) - 1) << pos;
|
||||
}
|
||||
public:
|
||||
// FIXME: val is public until qtdeclarative is fixed to not access it directly.
|
||||
UT val;
|
||||
|
||||
QSpecialIntegerBitfield &operator=(T t)
|
||||
{
|
||||
UT i = S::fromSpecial(val);
|
||||
i &= ~mask();
|
||||
i |= (UT(t) << pos) & mask();
|
||||
val = S::toSpecial(i);
|
||||
return *this;
|
||||
}
|
||||
operator T() const
|
||||
{
|
||||
if (std::is_signed<T>::value) {
|
||||
UT i = S::fromSpecial(val);
|
||||
i <<= (sizeof(T) * 8) - width - pos;
|
||||
T t = T(i);
|
||||
t >>= (sizeof(T) * 8) - width;
|
||||
return t;
|
||||
}
|
||||
return (S::fromSpecial(val) & mask()) >> pos;
|
||||
}
|
||||
|
||||
bool operator!() const { return !(val & S::toSpecial(mask())); }
|
||||
bool operator==(QSpecialIntegerBitfield<S, pos, width> i) const
|
||||
{
|
||||
return ((val ^ i.val) & S::toSpecial(mask())) == 0;
|
||||
}
|
||||
bool operator!=(QSpecialIntegerBitfield<S, pos, width> i) const
|
||||
{
|
||||
return ((val ^ i.val) & S::toSpecial(mask())) != 0;
|
||||
}
|
||||
|
||||
QSpecialIntegerBitfield &operator+=(T i) { return (*this = (T(*this) + i)); }
|
||||
QSpecialIntegerBitfield &operator-=(T i) { return (*this = (T(*this) - i)); }
|
||||
QSpecialIntegerBitfield &operator*=(T i) { return (*this = (T(*this) * i)); }
|
||||
QSpecialIntegerBitfield &operator/=(T i) { return (*this = (T(*this) / i)); }
|
||||
QSpecialIntegerBitfield &operator%=(T i) { return (*this = (T(*this) % i)); }
|
||||
QSpecialIntegerBitfield &operator|=(T i) { return (*this = (T(*this) | i)); }
|
||||
QSpecialIntegerBitfield &operator&=(T i) { return (*this = (T(*this) & i)); }
|
||||
QSpecialIntegerBitfield &operator^=(T i) { return (*this = (T(*this) ^ i)); }
|
||||
QSpecialIntegerBitfield &operator>>=(T i) { return (*this = (T(*this) >> i)); }
|
||||
QSpecialIntegerBitfield &operator<<=(T i) { return (*this = (T(*this) << i)); }
|
||||
};
|
||||
|
||||
template<typename T, int pos, int width>
|
||||
using QLEIntegerBitfield = QSpecialIntegerBitfield<QLittleEndianStorageType<T>, pos, width>;
|
||||
|
||||
template<typename T, int pos, int width>
|
||||
using QBEIntegerBitfield = QSpecialIntegerBitfield<QBigEndianStorageType<T>, pos, width>;
|
||||
|
||||
template<int pos, int width>
|
||||
using qint32_le_bitfield = QLEIntegerBitfield<int, pos, width>;
|
||||
template<int pos, int width>
|
||||
using quint32_le_bitfield = QLEIntegerBitfield<uint, pos, width>;
|
||||
template<int pos, int width>
|
||||
using qint32_be_bitfield = QBEIntegerBitfield<int, pos, width>;
|
||||
template<int pos, int width>
|
||||
using quint32_be_bitfield = QBEIntegerBitfield<uint, pos, width>;
|
||||
|
||||
enum class QSpecialIntegerBitfieldInitializer {};
|
||||
constexpr QSpecialIntegerBitfieldInitializer QSpecialIntegerBitfieldZero{};
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,6 @@ private slots:
|
|||
void endianIntegers_data();
|
||||
void endianIntegers();
|
||||
|
||||
void endianBitfields();
|
||||
|
||||
void endianBitfieldUnions_data();
|
||||
void endianBitfieldUnions();
|
||||
};
|
||||
|
|
@ -344,33 +342,6 @@ void tst_QtEndian::endianIntegers()
|
|||
#endif
|
||||
}
|
||||
|
||||
void tst_QtEndian::endianBitfields()
|
||||
{
|
||||
union {
|
||||
quint32_be_bitfield<21, 11> upper;
|
||||
quint32_be_bitfield<10, 11> lower;
|
||||
qint32_be_bitfield<0, 10> bottom;
|
||||
} u;
|
||||
|
||||
u.upper = 200;
|
||||
QCOMPARE(u.upper, 200U);
|
||||
u.lower = 1000;
|
||||
u.bottom = -8;
|
||||
QCOMPARE(u.lower, 1000U);
|
||||
QCOMPARE(u.upper, 200U);
|
||||
|
||||
u.lower += u.upper;
|
||||
QCOMPARE(u.upper, 200U);
|
||||
QCOMPARE(u.lower, 1200U);
|
||||
|
||||
u.upper = 65536 + 7;
|
||||
u.lower = 65535;
|
||||
QCOMPARE(u.lower, 65535U & ((1<<11) - 1));
|
||||
QCOMPARE(u.upper, 7U);
|
||||
|
||||
QCOMPARE(u.bottom, -8);
|
||||
}
|
||||
|
||||
template<template<typename... Accessors> typename Union, template<int, int, typename> typename Member>
|
||||
void testBitfieldUnion()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue