diff options
Diffstat (limited to 'src/corelib/global/qendian.h')
-rw-r--r-- | src/corelib/global/qendian.h | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index a14fce23f8..0e67a1ab8e 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -41,12 +41,18 @@ #ifndef QENDIAN_H #define QENDIAN_H +#include <QtCore/qfloat16.h> #include <QtCore/qglobal.h> // include stdlib.h and hope that it defines __GLIBC__ for glibc-based systems #include <stdlib.h> #include <string.h> +#ifdef min // MSVC +#undef min +#undef max +#endif + QT_BEGIN_NAMESPACE /* @@ -146,6 +152,31 @@ template <> inline Q_DECL_CONSTEXPR qint8 qbswap<qint8>(qint8 source) return source; } +// floating specializations +template<typename Float> +Float qbswapFloatHelper(Float source) +{ + // memcpy call in qFromUnaligned is recognized by optimizer as a correct way of type prunning + auto temp = qFromUnaligned<typename QIntegerForSizeof<Float>::Unsigned>(&source); + temp = qbswap(temp); + return qFromUnaligned<Float>(&temp); +} + +template <> inline qfloat16 qbswap<qfloat16>(qfloat16 source) +{ + return qbswapFloatHelper(source); +} + +template <> inline float qbswap<float>(float source) +{ + return qbswapFloatHelper(source); +} + +template <> inline double qbswap<double>(double source) +{ + return qbswapFloatHelper(source); +} + /* * qbswap(const T src, const void *dest); * Changes the byte order of \a src from big endian to little endian or vice versa @@ -157,6 +188,14 @@ template <typename T> inline void qbswap(const T src, void *dest) qToUnaligned<T>(qbswap<T>(src), dest); } +template <int Size> void *qbswap(const void *source, qsizetype count, void *dest) noexcept; +template<> inline void *qbswap<1>(const void *source, qsizetype count, void *dest) noexcept +{ + return source != dest ? memcpy(dest, source, size_t(count)) : dest; +} +template<> Q_CORE_EXPORT void *qbswap<2>(const void *source, qsizetype count, void *dest) noexcept; +template<> Q_CORE_EXPORT void *qbswap<4>(const void *source, qsizetype count, void *dest) noexcept; +template<> Q_CORE_EXPORT void *qbswap<8>(const void *source, qsizetype count, void *dest) noexcept; #if Q_BYTE_ORDER == Q_BIG_ENDIAN @@ -172,6 +211,15 @@ template <typename T> inline void qToBigEndian(T src, void *dest) { qToUnaligned<T>(src, dest); } template <typename T> inline void qToLittleEndian(T src, void *dest) { qbswap<T>(src, dest); } + +template <typename T> inline void qToBigEndian(const void *source, qsizetype count, void *dest) +{ if (source != dest) memcpy(dest, source, count * sizeof(T)); } +template <typename T> inline void qToLittleEndian(const void *source, qsizetype count, void *dest) +{ qbswap<sizeof(T)>(source, count, dest); } +template <typename T> inline void qFromBigEndian(const void *source, qsizetype count, void *dest) +{ if (source != dest) memcpy(dest, source, count * sizeof(T)); } +template <typename T> inline void qFromLittleEndian(const void *source, qsizetype count, void *dest) +{ qbswap<sizeof(T)>(source, count, dest); } #else // Q_LITTLE_ENDIAN template <typename T> inline Q_DECL_CONSTEXPR T qToBigEndian(T source) @@ -187,6 +235,14 @@ template <typename T> inline void qToBigEndian(T src, void *dest) template <typename T> inline void qToLittleEndian(T src, void *dest) { qToUnaligned<T>(src, dest); } +template <typename T> inline void qToBigEndian(const void *source, qsizetype count, void *dest) +{ qbswap<sizeof(T)>(source, count, dest); } +template <typename T> inline void qToLittleEndian(const void *source, qsizetype count, void *dest) +{ if (source != dest) memcpy(dest, source, count * sizeof(T)); } +template <typename T> inline void qFromBigEndian(const void *source, qsizetype count, void *dest) +{ qbswap<sizeof(T)>(source, count, dest); } +template <typename T> inline void qFromLittleEndian(const void *source, qsizetype count, void *dest) +{ if (source != dest) memcpy(dest, source, count * sizeof(T)); } #endif // Q_BYTE_ORDER == Q_BIG_ENDIAN @@ -254,6 +310,27 @@ public: { return (*this = S::fromSpecial(val) & i); } QSpecialInteger &operator ^=(T i) { return (*this = S::fromSpecial(val) ^ i); } + QSpecialInteger &operator ++() + { return (*this = S::fromSpecial(val) + 1); } + QSpecialInteger &operator --() + { return (*this = S::fromSpecial(val) - 1); } + QSpecialInteger operator ++(int) + { + QSpecialInteger<S> pre = *this; + *this += 1; + return pre; + } + QSpecialInteger operator --(int) + { + QSpecialInteger<S> pre = *this; + *this -= 1; + return pre; + } + + static constexpr QSpecialInteger max() + { return QSpecialInteger(std::numeric_limits<T>::max()); } + static constexpr QSpecialInteger min() + { return QSpecialInteger(std::numeric_limits<T>::min()); } }; template<typename T> @@ -291,6 +368,13 @@ public: QLEInteger &operator |=(T i); QLEInteger &operator &=(T i); QLEInteger &operator ^=(T i); + QLEInteger &operator ++(); + QLEInteger &operator --(); + QLEInteger &operator ++(int); + QLEInteger &operator --(int); + + static constexpr QLEInteger max(); + static constexpr QLEInteger min(); }; template<typename T> @@ -311,6 +395,13 @@ public: QBEInteger &operator |=(T i); QBEInteger &operator &=(T i); QBEInteger &operator ^=(T i); + QBEInteger &operator ++(); + QBEInteger &operator --(); + QBEInteger &operator ++(int); + QBEInteger &operator --(int); + + static constexpr QBEInteger max(); + static constexpr QBEInteger min(); }; #else |