字节序判断和转换

#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

// see boost/endian/detail/intrinsic.hpp
// windows 认为都是小端
// linux 通过 endian.h 获取
// apple 通过 machine/endian.h

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);
}