#ifndef PQ_ENDIAN_H
#define PQ_ENDIAN_H

#include <QtEndian>

#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0))
#define EndianPointType void
#else
#define EndianPointType uchar
#endif

union  FloatUint
{
    float _float;
    uint _uint;
};

template <>
inline float qFromBigEndian(float src)
{
    FloatUint s;
    s._float = src;
    s._uint = qFromBigEndian(s._uint);
    return s._float;
}

template <>
inline float qFromBigEndian<float>(const EndianPointType *src)
{
    FloatUint s;
    s._uint = qFromBigEndian<uint>(src);
    return s._float;
}

template <>
inline float qFromLittleEndian(float src)
{
    FloatUint s;
    s._float = src;
    s._uint = qFromLittleEndian(s._uint);
    return s._float;
}

template <>
inline float qFromLittleEndian<float>(const EndianPointType *src)
{
    FloatUint s;
    s._uint = qFromLittleEndian<uint>(src);
    return s._float;
}

template <>
inline float qToBigEndian(float src)
{
    FloatUint s;
    s._float = src;
    s._uint = qToBigEndian(s._uint);
    return s._float;
}

template <>
inline void qToBigEndian(float src, EndianPointType *dest)
{
    FloatUint s;
    s._float = src;
    qToBigEndian<uint>(s._uint,dest);
}

template <>
inline float qToLittleEndian(float src)
{
    FloatUint s;
    s._float = src;
    s._uint = qToLittleEndian(s._uint);
    return s._float;
}

template <>
inline void qToLittleEndian(float src, EndianPointType *dest)
{
    FloatUint s;
    s._float = src;
    qToLittleEndian<uint>(s._uint,dest);
}


union DoubleUint64
{
    double _double;
    quint64 _uint64;
};

template <>
inline double qFromBigEndian(double src)
{
    DoubleUint64 s;
    s._double = src;
    s._uint64 = qFromBigEndian(s._uint64);
    return s._double;
}

template <>
inline double qFromBigEndian<double>(const EndianPointType *src)
{
    DoubleUint64 s;
    s._uint64 = qFromBigEndian<quint64>(src);
    return s._double;
}

template <>
inline double qFromLittleEndian(double src)
{
    DoubleUint64 s;
    s._double = src;
    s._uint64 = qFromLittleEndian(s._uint64);
    return s._double;
}

template <>
inline double qFromLittleEndian<double>(const EndianPointType *src)
{
    DoubleUint64 s;
    s._uint64 = qFromLittleEndian<quint64>(src);
    return s._double;
}

template <>
inline double qToBigEndian(double src)
{
    DoubleUint64 s;
    s._double = src;
    s._uint64 = qToBigEndian(s._uint64);
    return s._double;
}

template <>
inline void qToBigEndian(double src, EndianPointType *dest)
{
    DoubleUint64 s;
    s._double = src;
    qToBigEndian(s._uint64,dest);
}

template <>
inline double qToLittleEndian(double src)
{
    DoubleUint64 s;
    s._double = src;
    s._uint64 = qToLittleEndian(s._uint64);
    return s._double;
}

template <>
inline void qToLittleEndian(double src, EndianPointType *dest)
{
    DoubleUint64 s;
    s._double = src;
    qToLittleEndian(s._uint64,dest);
}


#endif // ENDIAN_H
