Files
Endianness/include/Endianness.hpp

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