Warning, file /include/QtCore/qendian.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005 #ifndef QENDIAN_H
0006 #define QENDIAN_H
0007
0008 #if 0
0009 #pragma qt_class(QtEndian)
0010 #endif
0011
0012 #include <QtCore/qfloat16.h>
0013 #include <QtCore/qglobal.h>
0014
0015 #include <limits>
0016
0017
0018 #include <stdlib.h>
0019 #include <string.h>
0020
0021 #ifdef min
0022 #undef min
0023 #undef max
0024 #endif
0025
0026 QT_BEGIN_NAMESPACE
0027
0028
0029
0030
0031
0032
0033
0034 template <typename T> Q_ALWAYS_INLINE void qToUnaligned(const T src, void *dest)
0035 {
0036
0037
0038 const size_t size = sizeof(T);
0039 #if __has_builtin(__builtin_memcpy)
0040 __builtin_memcpy
0041 #else
0042 memcpy
0043 #endif
0044 (dest, &src, size);
0045 }
0046
0047 template <typename T> Q_ALWAYS_INLINE T qFromUnaligned(const void *src)
0048 {
0049 T dest;
0050 const size_t size = sizeof(T);
0051 #if __has_builtin(__builtin_memcpy)
0052 __builtin_memcpy
0053 #else
0054 memcpy
0055 #endif
0056 (&dest, src, size);
0057 return dest;
0058 }
0059
0060
0061
0062 inline constexpr quint64 qbswap_helper(quint64 source)
0063 {
0064 return 0
0065 | ((source & Q_UINT64_C(0x00000000000000ff)) << 56)
0066 | ((source & Q_UINT64_C(0x000000000000ff00)) << 40)
0067 | ((source & Q_UINT64_C(0x0000000000ff0000)) << 24)
0068 | ((source & Q_UINT64_C(0x00000000ff000000)) << 8)
0069 | ((source & Q_UINT64_C(0x000000ff00000000)) >> 8)
0070 | ((source & Q_UINT64_C(0x0000ff0000000000)) >> 24)
0071 | ((source & Q_UINT64_C(0x00ff000000000000)) >> 40)
0072 | ((source & Q_UINT64_C(0xff00000000000000)) >> 56);
0073 }
0074
0075 inline constexpr quint32 qbswap_helper(quint32 source)
0076 {
0077 return 0
0078 | ((source & 0x000000ff) << 24)
0079 | ((source & 0x0000ff00) << 8)
0080 | ((source & 0x00ff0000) >> 8)
0081 | ((source & 0xff000000) >> 24);
0082 }
0083
0084 inline constexpr quint16 qbswap_helper(quint16 source)
0085 {
0086 return quint16( 0
0087 | ((source & 0x00ff) << 8)
0088 | ((source & 0xff00) >> 8) );
0089 }
0090
0091 inline constexpr quint8 qbswap_helper(quint8 source)
0092 {
0093 return source;
0094 }
0095
0096
0097
0098
0099
0100
0101
0102 template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
0103 inline constexpr T qbswap(T source)
0104 {
0105 return T(qbswap_helper(typename QIntegerForSizeof<T>::Unsigned(source)));
0106 }
0107
0108 #ifdef QT_SUPPORTS_INT128
0109
0110 inline constexpr quint128 qbswap(quint128 source)
0111 {
0112 quint128 result = {};
0113 result = qbswap_helper(quint64(source));
0114 result <<= 64;
0115 result |= qbswap_helper(quint64(source >> 64));
0116 return result;
0117 }
0118
0119 inline constexpr qint128 qbswap(qint128 source)
0120 {
0121 return qint128(qbswap(quint128(source)));
0122 }
0123 #endif
0124
0125
0126 template<typename Float>
0127 Float qbswapFloatHelper(Float source)
0128 {
0129
0130 auto temp = qFromUnaligned<typename QIntegerForSizeof<Float>::Unsigned>(&source);
0131 temp = qbswap(temp);
0132 return qFromUnaligned<Float>(&temp);
0133 }
0134
0135 inline qfloat16 qbswap(qfloat16 source)
0136 {
0137 return qbswapFloatHelper(source);
0138 }
0139
0140 inline float qbswap(float source)
0141 {
0142 return qbswapFloatHelper(source);
0143 }
0144
0145 inline double qbswap(double source)
0146 {
0147 return qbswapFloatHelper(source);
0148 }
0149
0150
0151
0152
0153
0154
0155
0156 template <typename T> inline void qbswap(const T src, void *dest)
0157 {
0158 qToUnaligned<T>(qbswap(src), dest);
0159 }
0160
0161 template <int Size> void *qbswap(const void *source, qsizetype count, void *dest) noexcept;
0162 template<> inline void *qbswap<1>(const void *source, qsizetype count, void *dest) noexcept
0163 {
0164 return source != dest ? memcpy(dest, source, size_t(count)) : dest;
0165 }
0166 template<> Q_CORE_EXPORT void *qbswap<2>(const void *source, qsizetype count, void *dest) noexcept;
0167 template<> Q_CORE_EXPORT void *qbswap<4>(const void *source, qsizetype count, void *dest) noexcept;
0168 template<> Q_CORE_EXPORT void *qbswap<8>(const void *source, qsizetype count, void *dest) noexcept;
0169
0170 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
0171
0172 template <typename T> inline constexpr T qToBigEndian(T source)
0173 { return source; }
0174 template <typename T> inline constexpr T qFromBigEndian(T source)
0175 { return source; }
0176 template <typename T> inline constexpr T qToLittleEndian(T source)
0177 { return qbswap(source); }
0178 template <typename T> inline constexpr T qFromLittleEndian(T source)
0179 { return qbswap(source); }
0180 template <typename T> inline void qToBigEndian(T src, void *dest)
0181 { qToUnaligned<T>(src, dest); }
0182 template <typename T> inline void qToLittleEndian(T src, void *dest)
0183 { qbswap<T>(src, dest); }
0184
0185 template <typename T> inline void qToBigEndian(const void *source, qsizetype count, void *dest)
0186 { if (source != dest) memcpy(dest, source, count * sizeof(T)); }
0187 template <typename T> inline void qToLittleEndian(const void *source, qsizetype count, void *dest)
0188 { qbswap<sizeof(T)>(source, count, dest); }
0189 template <typename T> inline void qFromBigEndian(const void *source, qsizetype count, void *dest)
0190 { if (source != dest) memcpy(dest, source, count * sizeof(T)); }
0191 template <typename T> inline void qFromLittleEndian(const void *source, qsizetype count, void *dest)
0192 { qbswap<sizeof(T)>(source, count, dest); }
0193 #else
0194
0195 template <typename T> inline constexpr T qToBigEndian(T source)
0196 { return qbswap(source); }
0197 template <typename T> inline constexpr T qFromBigEndian(T source)
0198 { return qbswap(source); }
0199 template <typename T> inline constexpr T qToLittleEndian(T source)
0200 { return source; }
0201 template <typename T> inline constexpr T qFromLittleEndian(T source)
0202 { return source; }
0203 template <typename T> inline void qToBigEndian(T src, void *dest)
0204 { qbswap<T>(src, dest); }
0205 template <typename T> inline void qToLittleEndian(T src, void *dest)
0206 { qToUnaligned<T>(src, dest); }
0207
0208 template <typename T> inline void qToBigEndian(const void *source, qsizetype count, void *dest)
0209 { qbswap<sizeof(T)>(source, count, dest); }
0210 template <typename T> inline void qToLittleEndian(const void *source, qsizetype count, void *dest)
0211 { if (source != dest) memcpy(dest, source, count * sizeof(T)); }
0212 template <typename T> inline void qFromBigEndian(const void *source, qsizetype count, void *dest)
0213 { qbswap<sizeof(T)>(source, count, dest); }
0214 template <typename T> inline void qFromLittleEndian(const void *source, qsizetype count, void *dest)
0215 { if (source != dest) memcpy(dest, source, count * sizeof(T)); }
0216 #endif
0217
0218
0219
0220
0221
0222
0223
0224 template <typename T> inline T qFromLittleEndian(const void *src)
0225 {
0226 return qFromLittleEndian(qFromUnaligned<T>(src));
0227 }
0228
0229 template <> inline quint8 qFromLittleEndian<quint8>(const void *src)
0230 { return static_cast<const quint8 *>(src)[0]; }
0231 template <> inline qint8 qFromLittleEndian<qint8>(const void *src)
0232 { return static_cast<const qint8 *>(src)[0]; }
0233
0234
0235
0236
0237
0238 template <class T> inline T qFromBigEndian(const void *src)
0239 {
0240 return qFromBigEndian(qFromUnaligned<T>(src));
0241 }
0242
0243 template <> inline quint8 qFromBigEndian<quint8>(const void *src)
0244 { return static_cast<const quint8 *>(src)[0]; }
0245 template <> inline qint8 qFromBigEndian<qint8>(const void *src)
0246 { return static_cast<const qint8 *>(src)[0]; }
0247
0248 template<class S>
0249 class QSpecialInteger
0250 {
0251 typedef typename S::StorageType T;
0252 T val;
0253 public:
0254 QSpecialInteger() = default;
0255 explicit constexpr QSpecialInteger(T i) : val(S::toSpecial(i)) {}
0256
0257 QSpecialInteger &operator =(T i) { val = S::toSpecial(i); return *this; }
0258 operator T() const { return S::fromSpecial(val); }
0259
0260 bool operator ==(QSpecialInteger<S> i) const { return val == i.val; }
0261 bool operator !=(QSpecialInteger<S> i) const { return val != i.val; }
0262
0263 QSpecialInteger &operator +=(T i)
0264 { return (*this = S::fromSpecial(val) + i); }
0265 QSpecialInteger &operator -=(T i)
0266 { return (*this = S::fromSpecial(val) - i); }
0267 QSpecialInteger &operator *=(T i)
0268 { return (*this = S::fromSpecial(val) * i); }
0269 QSpecialInteger &operator >>=(T i)
0270 { return (*this = S::fromSpecial(val) >> i); }
0271 QSpecialInteger &operator <<=(T i)
0272 { return (*this = S::fromSpecial(val) << i); }
0273 QSpecialInteger &operator /=(T i)
0274 { return (*this = S::fromSpecial(val) / i); }
0275 QSpecialInteger &operator %=(T i)
0276 { return (*this = S::fromSpecial(val) % i); }
0277 QSpecialInteger &operator |=(T i)
0278 { return (*this = S::fromSpecial(val) | i); }
0279 QSpecialInteger &operator &=(T i)
0280 { return (*this = S::fromSpecial(val) & i); }
0281 QSpecialInteger &operator ^=(T i)
0282 { return (*this = S::fromSpecial(val) ^ i); }
0283 QSpecialInteger &operator ++()
0284 { return (*this = S::fromSpecial(val) + 1); }
0285 QSpecialInteger &operator --()
0286 { return (*this = S::fromSpecial(val) - 1); }
0287 QSpecialInteger operator ++(int)
0288 {
0289 QSpecialInteger<S> pre = *this;
0290 *this += 1;
0291 return pre;
0292 }
0293 QSpecialInteger operator --(int)
0294 {
0295 QSpecialInteger<S> pre = *this;
0296 *this -= 1;
0297 return pre;
0298 }
0299
0300 static constexpr QSpecialInteger max()
0301 { return QSpecialInteger((std::numeric_limits<T>::max)()); }
0302 static constexpr QSpecialInteger min()
0303 { return QSpecialInteger((std::numeric_limits<T>::min)()); }
0304 };
0305
0306 template<typename T>
0307 class QLittleEndianStorageType {
0308 public:
0309 typedef T StorageType;
0310 static constexpr T toSpecial(T source) { return qToLittleEndian(source); }
0311 static constexpr T fromSpecial(T source) { return qFromLittleEndian(source); }
0312 };
0313
0314 template<typename T>
0315 class QBigEndianStorageType {
0316 public:
0317 typedef T StorageType;
0318 static constexpr T toSpecial(T source) { return qToBigEndian(source); }
0319 static constexpr T fromSpecial(T source) { return qFromBigEndian(source); }
0320 };
0321
0322 #ifdef Q_QDOC
0323 template<typename T>
0324 class QLEInteger {
0325 public:
0326 explicit constexpr QLEInteger(T i);
0327 QLEInteger &operator =(T i);
0328 operator T() const;
0329 bool operator ==(QLEInteger i) const;
0330 bool operator !=(QLEInteger i) const;
0331 QLEInteger &operator +=(T i);
0332 QLEInteger &operator -=(T i);
0333 QLEInteger &operator *=(T i);
0334 QLEInteger &operator >>=(T i);
0335 QLEInteger &operator <<=(T i);
0336 QLEInteger &operator /=(T i);
0337 QLEInteger &operator %=(T i);
0338 QLEInteger &operator |=(T i);
0339 QLEInteger &operator &=(T i);
0340 QLEInteger &operator ^=(T i);
0341 QLEInteger &operator ++();
0342 QLEInteger &operator --();
0343 QLEInteger operator ++(int);
0344 QLEInteger operator --(int);
0345
0346 static constexpr QLEInteger max();
0347 static constexpr QLEInteger min();
0348 };
0349
0350 template<typename T>
0351 class QBEInteger {
0352 public:
0353 explicit constexpr QBEInteger(T i);
0354 QBEInteger &operator =(T i);
0355 operator T() const;
0356 bool operator ==(QBEInteger i) const;
0357 bool operator !=(QBEInteger i) const;
0358 QBEInteger &operator +=(T i);
0359 QBEInteger &operator -=(T i);
0360 QBEInteger &operator *=(T i);
0361 QBEInteger &operator >>=(T i);
0362 QBEInteger &operator <<=(T i);
0363 QBEInteger &operator /=(T i);
0364 QBEInteger &operator %=(T i);
0365 QBEInteger &operator |=(T i);
0366 QBEInteger &operator &=(T i);
0367 QBEInteger &operator ^=(T i);
0368 QBEInteger &operator ++();
0369 QBEInteger &operator --();
0370 QBEInteger operator ++(int);
0371 QBEInteger operator --(int);
0372
0373 static constexpr QBEInteger max();
0374 static constexpr QBEInteger min();
0375 };
0376 #else
0377
0378 template<typename T>
0379 using QLEInteger = QSpecialInteger<QLittleEndianStorageType<T>>;
0380
0381 template<typename T>
0382 using QBEInteger = QSpecialInteger<QBigEndianStorageType<T>>;
0383 #endif
0384 template <typename T>
0385 class QTypeInfo<QLEInteger<T> >
0386 : public QTypeInfoMerger<QLEInteger<T>, T> {};
0387
0388 template <typename T>
0389 class QTypeInfo<QBEInteger<T> >
0390 : public QTypeInfoMerger<QBEInteger<T>, T> {};
0391
0392 typedef QLEInteger<qint16> qint16_le;
0393 typedef QLEInteger<qint32> qint32_le;
0394 typedef QLEInteger<qint64> qint64_le;
0395 typedef QLEInteger<quint16> quint16_le;
0396 typedef QLEInteger<quint32> quint32_le;
0397 typedef QLEInteger<quint64> quint64_le;
0398
0399 typedef QBEInteger<qint16> qint16_be;
0400 typedef QBEInteger<qint32> qint32_be;
0401 typedef QBEInteger<qint64> qint64_be;
0402 typedef QBEInteger<quint16> quint16_be;
0403 typedef QBEInteger<quint32> quint32_be;
0404 typedef QBEInteger<quint64> quint64_be;
0405
0406 QT_END_NAMESPACE
0407
0408 #endif