summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-06-22 12:37:04 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-06-27 22:16:56 +0000
commit6ca65dd97d252d1618dd9870bf119b2d482e7eaf (patch)
tree3fb0e8923c9145270605dfb5d5b7e86ba81ea031 /src
parent01d5aaa0f6bded240e9b0c8fb32a91d2afe8ae4d (diff)
Move qle_bitfield to qendian_p.h
Makes the qle_bitfield template more generic and moves it to qendian_p.h It is also hardened to be more reliable. Change-Id: I53214ec99cceee4f5e8934ae688c99e555a5fb42 Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qendian_p.h84
-rw-r--r--src/corelib/json/qjson_p.h91
2 files changed, 85 insertions, 90 deletions
diff --git a/src/corelib/global/qendian_p.h b/src/corelib/global/qendian_p.h
index b279701a31..42d91cf735 100644
--- a/src/corelib/global/qendian_p.h
+++ b/src/corelib/global/qendian_p.h
@@ -51,7 +51,7 @@
// We mean it.
//
-#include "qendian.h"
+#include <QtCore/qendian.h>
QT_BEGIN_NAMESPACE
@@ -136,6 +136,88 @@ typedef QBEInteger<quint16> quint16_be;
typedef QBEInteger<quint32> quint32_be;
typedef QBEInteger<quint64> quint64_be;
+// 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 Q_DECL_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>;
+
+
QT_END_NAMESPACE
#endif // QENDIAN_P_H
diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h
index 5d600843aa..131528376b 100644
--- a/src/corelib/json/qjson_p.h
+++ b/src/corelib/json/qjson_p.h
@@ -140,97 +140,10 @@ typedef q_littleendian<int> qle_int;
typedef q_littleendian<unsigned int> qle_uint;
template<int pos, int width>
-class qle_bitfield
-{
-public:
- uint val;
-
- enum {
- mask = ((1u << width) - 1) << pos
- };
-
- void operator =(uint t) {
- uint i = qFromLittleEndian(val);
- i &= ~mask;
- i |= t << pos;
- val = qToLittleEndian(i);
- }
- operator uint() const {
- uint t = qFromLittleEndian(val);
- t &= mask;
- t >>= pos;
- return t;
- }
- bool operator !() const {
- return !operator uint();
- }
-
- bool operator ==(uint t) { return uint(*this) == t; }
- bool operator !=(uint t) { return uint(*this) != t; }
- bool operator <(uint t) { return uint(*this) < t; }
- bool operator >(uint t) { return uint(*this) > t; }
- bool operator <=(uint t) { return uint(*this) <= t; }
- bool operator >=(uint t) { return uint(*this) >= t; }
- qle_bitfield &operator +=(uint i) {
- *this = (uint(*this) + i);
- return *this;
- }
- qle_bitfield &operator -=(uint i) {
- *this = (uint(*this) - i);
- return *this;
- }
- qle_bitfield &operator |=(uint i) {
- *this = (uint(*this) | i);
- return *this;
- }
- qle_bitfield &operator &=(uint i) {
- *this = (uint(*this) & i);
- return *this;
- }
-};
+using qle_bitfield = QLEIntegerBitfield<uint, pos, width>;
template<int pos, int width>
-class qle_signedbitfield
-{
-public:
- uint val;
-
- enum {
- mask = ((1u << width) - 1) << pos
- };
-
- void operator =(int t) {
- uint i = qFromLittleEndian(val);
- i &= ~mask;
- i |= t << pos;
- val = qToLittleEndian(i);
- }
- operator int() const {
- uint i = qFromLittleEndian(val);
- i <<= 32 - width - pos;
- int t = (int) i;
- t >>= 32 - width;
- return t;
- }
- bool operator !() const {
- return !operator int();
- }
-
- bool operator ==(int t) { return int(*this) == t; }
- bool operator !=(int t) { return int(*this) != t; }
- bool operator <(int t) { return int(*this) < t; }
- bool operator >(int t) { return int(*this) > t; }
- bool operator <=(int t) { return int(*this) <= t; }
- bool operator >=(int t) { return int(*this) >= t; }
- qle_signedbitfield &operator +=(int i) {
- *this = (int(*this) + i);
- return *this;
- }
- qle_signedbitfield &operator -=(int i) {
- *this = (int(*this) - i);
- return *this;
- }
-};
+using qle_signedbitfield = QLEIntegerBitfield<int, pos, width>;
typedef qle_uint offset;