84 lines
2.2 KiB
C++
84 lines
2.2 KiB
C++
|
|
#pragma once
|
|
#include <algorithm>
|
|
#include <cstdint>
|
|
#include <bit>
|
|
#include <concepts>
|
|
#include <ranges>
|
|
|
|
namespace IntegerLiterals
|
|
{
|
|
using u8 = uint8_t; using ub = u8;
|
|
using u16 = uint16_t; using us = u16;
|
|
using u32 = uint32_t; //using ul = u32;
|
|
using u64 = uint64_t; using ud = u64;
|
|
|
|
using s8 = int8_t; using sb = s8;
|
|
using s16 = int16_t; using ss = s16;
|
|
using s32 = int32_t; using sl = s32;
|
|
using s64 = int64_t; using sd = s64;
|
|
|
|
}
|
|
|
|
/// https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
|
|
|
|
|
|
/// Platform-independent functions for swapping the byte order of common data types.
|
|
namespace Endianness
|
|
{
|
|
using namespace IntegerLiterals;
|
|
|
|
/// Returns true if the host machine is big-endian.
|
|
constexpr bool IsBigEndian() noexcept { return (std::endian::native == std::endian::big); }
|
|
|
|
/// Returns true if the host machine is little-endian.
|
|
constexpr bool IsLittleEndian() noexcept { return (std::endian::native == std::endian::little); }
|
|
|
|
template <typename T>
|
|
T ReverseByteOrder(T val)
|
|
{
|
|
T retVal;
|
|
char* pVal = (char*)&val;
|
|
char* pRetVal = (char*)&retVal;
|
|
int size = sizeof(T);
|
|
for (int i = 0; i < size; i++)
|
|
{
|
|
pRetVal[size - 1 - i] = pVal[i];
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
#pragma region Template Specializations
|
|
/// This function simply returns the input value, as no byte order can be swapped on a single-byte-length value.
|
|
template <> u8 ReverseByteOrder<u8>(u8 val);
|
|
/// This function simply returns the input value, as no byte order can be swapped on a single-byte-length value.
|
|
template <> s8 ReverseByteOrder<s8>(s8 val);;
|
|
template <> u16 ReverseByteOrder<u16>(u16 val);
|
|
template <> u32 ReverseByteOrder<u32>(u32 val);
|
|
|
|
template <> u64 ReverseByteOrder<u64>(u64 val);
|
|
template <> s16 ReverseByteOrder<s16>(s16 val);
|
|
|
|
template <> s32 ReverseByteOrder<s32>(s32 val);
|
|
|
|
template <> s64 ReverseByteOrder<s64>(s64 val);
|
|
|
|
#pragma endregion
|
|
|
|
template <typename T>
|
|
T ReverseByteOrderIfLittleEndian(T val)
|
|
{
|
|
if (IsLittleEndian())
|
|
return ReverseByteOrder(val);
|
|
else return val;
|
|
|
|
}
|
|
|
|
template <typename T> T HostToNetworkOrder(T host) { return ReverseByteOrderIfLittleEndian(host);}
|
|
|
|
template <typename T> T NetworkToHostOrder(T network) { return ReverseByteOrderIfLittleEndian(network);}
|
|
|
|
|
|
|
|
}
|