120 lines
2.5 KiB
C++
120 lines
2.5 KiB
C++
/***
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: auEndianness.hpp
|
|
Date: 2022-2-6
|
|
Author: Reece
|
|
***/
|
|
#pragma once
|
|
|
|
template <class T>
|
|
struct AuEndianUtils
|
|
{
|
|
static T Swap(T in);
|
|
};
|
|
|
|
template <class T>
|
|
inline T AuEndianUtils<T>::Swap(T in)
|
|
{
|
|
if constexpr (sizeof(T) == 8)
|
|
return (T(in) & 0xFF) << T(56) |
|
|
(T(in >> T(8)) & T(0xFF)) << T(48) |
|
|
(T(in >> T(16)) & T(0xFF)) << T(40) |
|
|
(T(in >> T(24)) & T(0xFF)) << T(32) |
|
|
(T(in >> T(32)) & T(0xFF)) << T(24) |
|
|
(T(in >> T(40)) & T(0xFF)) << T(16) |
|
|
(T(in >> T(48)) & T(0xFF)) << T(8) |
|
|
(T(in >> T(56)) & T(0xFF));
|
|
|
|
if constexpr (sizeof(T) == 4)
|
|
return T(in & 0xFF) << 24 |
|
|
(T(in >> 8) & 0xFF) << 16 |
|
|
(T(in >> 16) & 0xFF) << 8 |
|
|
(T(in >> 24) & 0xFF);
|
|
|
|
if constexpr (sizeof(T) == 2)
|
|
return (in & 0xFF) << 8 |
|
|
((in >> 8) & 0xFF);
|
|
|
|
return in;
|
|
}
|
|
|
|
#if defined(AURORA_COMPILER_MSVC)
|
|
|
|
template <>
|
|
inline AuUInt64 AuEndianUtils<AuUInt64>::Swap(AuUInt64 in)
|
|
{
|
|
return _byteswap_uint64(in);
|
|
}
|
|
|
|
template <>
|
|
inline AuUInt32 AuEndianUtils<AuUInt32>::Swap(AuUInt32 in)
|
|
{
|
|
return _byteswap_ulong(in);
|
|
}
|
|
|
|
template <>
|
|
inline unsigned long AuEndianUtils<unsigned long>::Swap(unsigned long in)
|
|
{
|
|
return _byteswap_ulong(in);
|
|
}
|
|
|
|
template <>
|
|
inline AuUInt16 AuEndianUtils<AuUInt16>::Swap(AuUInt16 in)
|
|
{
|
|
return _byteswap_ushort(in);
|
|
}
|
|
|
|
#elif defined(AURORA_COMPILER_CLANG)
|
|
|
|
template <>
|
|
inline AuUInt64 AuEndianUtils<AuUInt64>::Swap(AuUInt64 in)
|
|
{
|
|
return __builtin_bswap64(in);
|
|
}
|
|
|
|
template <>
|
|
inline AuUInt32 AuEndianUtils<AuUInt32>::Swap(AuUInt32 in)
|
|
{
|
|
return __builtin_bswap32(in);
|
|
}
|
|
|
|
template <>
|
|
inline AuUInt16 AuEndianUtils<AuUInt16>::Swap(AuUInt16 in)
|
|
{
|
|
return __builtin_bswap16(in);
|
|
}
|
|
|
|
#endif
|
|
|
|
template <class Type_t>
|
|
inline auline Type_t AuFlipEndian(Type_t in)
|
|
{
|
|
return AuEndianUtils<Type_t>::Swap(in);
|
|
}
|
|
|
|
template <class Type_t>
|
|
inline auline Type_t AuEndianFlip(Type_t in)
|
|
{
|
|
return AuEndianUtils<Type_t>::Swap(in);
|
|
}
|
|
|
|
template <class Type_t>
|
|
inline auline Type_t AuEndianNormalizeLittle(Type_t in)
|
|
{
|
|
#if defined(AU_CPU_ENDIAN_LITTLE)
|
|
return (in);
|
|
#else
|
|
return AuFlipEndian(in);
|
|
#endif
|
|
}
|
|
|
|
template <class Type_t>
|
|
inline auline Type_t AuEndianNormalizeBig(Type_t in)
|
|
{
|
|
#if defined(AU_CPU_ENDIAN_LITTLE)
|
|
return AuFlipEndian(in);
|
|
#else
|
|
return (in);
|
|
#endif
|
|
} |