字节序判断和转换
#if _WIN32
#include <cstdlib>
# define BYTE_SWAP_2(x) _byteswap_ushort(x)
# define BYTE_SWAP_4(x) _byteswap_ulong(x)
# define BYTE_SWAP_8(x) _byteswap_uint64(x)
#elif __linux__
#include <endian.h>
#include <byteswap.h>
#if !defined(BYTE_ORDER) && !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
#define BYTE_ORDER __BYTE_ORDER__
#define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
#define BIG_ENDIAN __ORDER_BIG_ENDIAN__
#endif
# define BYTE_SWAP_2(x) bswap_16(x)
# define BYTE_SWAP_4(x) bswap_32(x)
# define BYTE_SWAP_8(x) bswap_64(x)
#elif __APPLE__
#include <machine/endian.h>
# define BYTE_SWAP_2(x) __builtin_bswap16(x)
# define BYTE_SWAP_4(x) __builtin_bswap32(x)
# define BYTE_SWAP_8(x) __builtin_bswap64(x)
#endif
template<typename T>
constexpr void hton(T &obj)
{
#if _WIN32 || (defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN))
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Conversion not supported!");
switch (sizeof(T))
{
case 2:
obj = static_cast<T>( BYTE_SWAP_2(reinterpret_cast<uint16_t &>(obj)) );
break;
case 4:
obj = static_cast<T>( BYTE_SWAP_4(reinterpret_cast<uint32_t &>(obj)) );
break;
case 8:
obj = static_cast<T>( BYTE_SWAP_8(reinterpret_cast<uint64_t &>(obj)) );
break;
default:
break;
}
#endif
}
template<typename T>
constexpr void ntoh(T &obj)
{
hton(obj);
}