summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qendian.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global/qendian.h')
-rw-r--r--src/corelib/global/qendian.h91
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