104 lines
3.8 KiB
C++
104 lines
3.8 KiB
C++
#ifndef DIGGLER_PLATFORM_ENDIAN_HPP
|
|
#define DIGGLER_PLATFORM_ENDIAN_HPP
|
|
|
|
#include <cstdint>
|
|
|
|
namespace Diggler {
|
|
|
|
constexpr uint16_t byteSwap16(uint16_t x) {
|
|
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
|
|
return __builtin_bswap16(x);
|
|
#else
|
|
return static_cast<uint16_t>((x >> 8) | (x << 8));
|
|
#endif
|
|
}
|
|
|
|
constexpr uint32_t byteSwap32(uint32_t x) {
|
|
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
|
|
return __builtin_bswap32(x);
|
|
#elif defined(__ICC) || defined(__INTEL_COMPILER)
|
|
return _bswap(x);
|
|
#else
|
|
return (x>>24) | ((x<<8) & 0x00FF0000) | ((x>>8) & 0x0000FF00) | (x<<24);
|
|
#endif
|
|
}
|
|
|
|
constexpr uint64_t byteSwap64(uint64_t x) {
|
|
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
|
|
return __builtin_bswap64(x);
|
|
#elif defined(__ICC) || defined(__INTEL_COMPILER)
|
|
return _bswap64(x);
|
|
#else
|
|
return (x>>56) | ((x<<40) & 0x00FF000000000000UL) | ((x<<24) & 0x0000FF0000000000UL) |
|
|
((x<<8) & 0x000000FF00000000UL) | ((x>>8) & 0x00000000FF000000UL) |
|
|
((x>>24) & 0x0000000000FF0000UL) | ((x>>40) & 0x000000000000FF00UL) | (x<<56);
|
|
#endif
|
|
}
|
|
|
|
enum class Endianness : uint8_t {
|
|
Little,
|
|
Big
|
|
};
|
|
|
|
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || \
|
|
defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \
|
|
defined(__BIG_ENDIAN__) || \
|
|
defined(__sparc) || defined(__sparc__) || \
|
|
defined(_POWER) || defined(__powerpc__) || \
|
|
defined(__ppc__) || defined(__hpux) || \
|
|
defined(__s390__) || \
|
|
defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
|
|
defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__)
|
|
|
|
constexpr Endianness SystemEndianness = Endianness::Big;
|
|
|
|
constexpr uint16_t toBe16(uint16_t x) { return x; }
|
|
constexpr uint16_t toLe16(uint16_t x) { return byteSwap16(x); }
|
|
constexpr uint16_t fromBe16(uint16_t x) { return x; }
|
|
constexpr uint16_t fromLe16(uint16_t x) { return byteSwap16(x); }
|
|
|
|
constexpr uint32_t toBe32(uint32_t x) { return x; }
|
|
constexpr uint32_t toLe32(uint32_t x) { return byteSwap32(x); }
|
|
constexpr uint32_t fromBe32(uint32_t x) { return x; }
|
|
constexpr uint32_t fromLe32(uint32_t x) { return byteSwap32(x); }
|
|
|
|
constexpr uint64_t toBe64(uint64_t x) { return x; }
|
|
constexpr uint64_t toLe64(uint64_t x) { return byteSwap64(x); }
|
|
constexpr uint64_t fromBe64(uint64_t x) { return x; }
|
|
constexpr uint64_t fromLe64(uint64_t x) { return byteSwap64(x); }
|
|
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || \
|
|
defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \
|
|
defined(__LITTLE_ENDIAN__) || \
|
|
defined(__i386__) || defined(__alpha__) || \
|
|
defined(__ia64) || defined(__ia64__) || \
|
|
defined(_M_IX86) || defined(_M_IA64) || \
|
|
defined(_M_ALPHA) || defined(__amd64) || \
|
|
defined(__amd64__) || defined(_M_AMD64) || \
|
|
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
|
|
defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \
|
|
defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__)
|
|
|
|
constexpr Endianness SystemEndianness = Endianness::Little;
|
|
|
|
constexpr uint16_t toBe16(uint16_t x) { return byteSwap16(x); }
|
|
constexpr uint16_t toLe16(uint16_t x) { return x; }
|
|
constexpr uint16_t fromBe16(uint16_t x) { return byteSwap16(x); }
|
|
constexpr uint16_t fromLe16(uint16_t x) { return x; }
|
|
|
|
constexpr uint32_t toBe32(uint32_t x) { return byteSwap32(x); }
|
|
constexpr uint32_t toLe32(uint32_t x) { return x; }
|
|
constexpr uint32_t fromBe32(uint32_t x) { return byteSwap32(x); }
|
|
constexpr uint32_t fromLe32(uint32_t x) { return x; }
|
|
|
|
constexpr uint64_t toBe64(uint64_t x) { return byteSwap64(x); }
|
|
constexpr uint64_t toLe64(uint64_t x) { return x; }
|
|
constexpr uint64_t fromBe64(uint64_t x) { return byteSwap64(x); }
|
|
constexpr uint64_t fromLe64(uint64_t x) { return x; }
|
|
#else
|
|
#error "Unable to determine endianness"
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif /* DIGGLER_PLATFORM_ENDIAN_HPP */
|