AuROXTL/Include/auROXTL/auTypeUtils.hpp
2024-06-19 13:44:31 +01:00

762 lines
18 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auTypeUtils.hpp
Date: 2022-2-10
Author: Reece
***/
#pragma once
#include "auEndianness.hpp"
#if defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86) || defined(AURORA_ARCH_ARM)
#define AURORA_PERMIT_ARBITRARY_REF
#endif
template <class T>
static auline T AuReadGenericLE(const void *ptr, int offset)
{
#if defined(AURORA_PERMIT_ARBITRARY_REF)
T temp = *reinterpret_cast<const T *>(reinterpret_cast<const AuUInt8 *>(ptr) + offset);
#else
T temp;
AuMemcpy(&temp, reinterpret_cast<const AuUInt8 *>(ptr) + offset, sizeof(temp));
#endif
if constexpr (sizeof(T) != 1)
{
#if !defined(AU_CPU_ENDIAN_LITTLE)
temp = AuFlipEndian(temp);
#endif
}
return temp;
}
template <class T>
static auline T AuReadGenericBE(const void *ptr, int offset)
{
#if defined(AURORA_PERMIT_ARBITRARY_REF)
T temp = *reinterpret_cast<const T *>(reinterpret_cast<const AuUInt8 *>(ptr) + offset);
#else
T temp;
AuMemcpy(&temp, reinterpret_cast<const AuUInt8 *>(ptr) + offset, sizeof(temp));
#endif
if constexpr (sizeof(T) != 1)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
temp = AuFlipEndian(temp);
#endif
}
return temp;
}
static auline AuUInt64 AuReadU64LE(const void *ptr, int offset)
{
return AuReadGenericLE<AuUInt64>(ptr, offset);
}
static auline AuUInt32 AuReadU32LE(const void *ptr, int offset)
{
return AuReadGenericLE<AuUInt32>(ptr, offset);
}
static auline AuUInt16 AuReadU16LE(const void *ptr, int offset)
{
return AuReadGenericLE<AuUInt16>(ptr, offset);
}
static auline AuUInt8 AuReadU8LE(const void *ptr, int offset)
{
return AuReadGenericLE<AuUInt8>(ptr, offset);
}
static auline AuInt64 AuReadS64LE(const void *ptr, int offset)
{
return AuReadGenericLE<AuInt64>(ptr, offset);
}
static auline AuInt32 AuReadS32LE(const void *ptr, int offset)
{
return AuReadGenericLE<AuInt32>(ptr, offset);
}
static auline AuInt16 AuReadS16LE(const void *ptr, int offset)
{
return AuReadGenericLE<AuInt16>(ptr, offset);
}
static auline AuInt8 AuReadS8LE(const void *ptr, int offset)
{
return AuReadGenericLE<AuInt8>(ptr, offset);
}
static auline AuUInt64 AuReadU64BE(const void *ptr, int offset)
{
return AuReadGenericBE<AuUInt64>(ptr, offset);
}
static auline AuUInt32 AuReadU32BE(const void *ptr, int offset)
{
return AuReadGenericBE<AuUInt32>(ptr, offset);
}
static auline AuUInt16 AuReadU16BE(const void *ptr, int offset)
{
return AuReadGenericBE<AuUInt16>(ptr, offset);
}
static auline AuUInt8 AuReadU8BE(const void *ptr, int offset)
{
return AuReadGenericBE<AuUInt8>(ptr, offset);
}
static auline AuInt64 AuReadS64BE(const void *ptr, int offset)
{
return AuReadGenericBE<AuInt64>(ptr, offset);
}
static auline AuInt32 AuReadS32BE(const void *ptr, int offset)
{
return AuReadGenericBE<AuInt32>(ptr, offset);
}
static auline AuInt16 AuReadS16BE(const void *ptr, int offset)
{
return AuReadGenericBE<AuInt16>(ptr, offset);
}
static auline AuInt8 AuReadS8BE(const void *ptr, int offset)
{
return AuReadGenericBE<AuInt8>(ptr, offset);
}
static auline AuUInt64 AuReadU64(const void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadU64LE(ptr, offset);
#else
return AuReadU64BE(ptr, offset);
#endif
}
static auline AuUInt32 AuReadU32(const void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadU32LE(ptr, offset);
#else
return AuReadU32BE(ptr, offset);
#endif
}
static auline AuUInt16 AuReadU16(const void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadU16LE(ptr, offset);
#else
return AuReadU16BE(ptr, offset);
#endif
}
static auline AuUInt8 AuReadU8(const void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadU8LE(ptr, offset);
#else
return AuReadU8BE(ptr, offset);
#endif
}
static auline AuInt64 AuReadS64(const void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadS64LE(ptr, offset);
#else
return AuReadS64BE(ptr, offset);
#endif
}
static auline AuInt32 AuReadS32(const void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadS32LE(ptr, offset);
#else
return AuReadS32BE(ptr, offset);
#endif
}
static auline AuInt16 AuReadS16(const void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadS16LE(ptr, offset);
#else
return AuReadS16BE(ptr, offset);
#endif
}
static auline AuInt8 AuReadS8(const void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadS8LE(ptr, offset);
#else
return AuReadS8BE(ptr, offset);
#endif
}
template <class T>
static auline void AuWriteGenericLE(void *ptr, int offset, T value)
{
#if !defined(AU_CPU_ENDIAN_LITTLE)
value = AuFlipEndian(value);
#endif
#if defined(AURORA_PERMIT_ARBITRARY_REF)
*reinterpret_cast<T *>(reinterpret_cast<AuUInt8 *>(ptr) + offset) = value;
#else
AuMemcpy(reinterpret_cast<AuUInt8 *>(ptr) + offset, &value, sizeof(value));
#endif
}
template <class T>
static auline void AuWriteGenericBE(void *ptr, int offset, T value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
value = AuFlipEndian(value);
#endif
#if defined(AURORA_PERMIT_ARBITRARY_REF)
*reinterpret_cast<T *>(reinterpret_cast<AuUInt8 *>(ptr) + offset) = value;
#else
AuMemcpy(reinterpret_cast<AuUInt8 *>(ptr) + offset, &value, sizeof(value));
#endif
}
static auline void AuWriteU64LE(void *ptr, int offset, AuUInt64 value)
{
AuWriteGenericLE<AuUInt64>(ptr, offset, value);
}
static auline void AuWriteU32LE(void *ptr, int offset, AuUInt32 value)
{
AuWriteGenericLE<AuUInt32>(ptr, offset, value);
}
static auline void AuWriteU16LE(void *ptr, int offset, AuUInt16 value)
{
AuWriteGenericLE<AuUInt16>(ptr, offset, value);
}
static auline void AuWriteU8LE(void *ptr, int offset, AuUInt8 value)
{
AuWriteGenericLE<AuUInt8>(ptr, offset, value);
}
static auline void AuWriteS64LE(void *ptr, int offset, AuInt64 value)
{
AuWriteGenericLE<AuInt64>(ptr, offset, value);
}
static auline void AuWriteS32LE(void *ptr, int offset, AuInt32 value)
{
AuWriteGenericLE<AuInt32>(ptr, offset, value);
}
static auline void AuWriteS16LE(void *ptr, int offset, AuInt16 value)
{
AuWriteGenericLE<AuInt16>(ptr, offset, value);
}
static auline void AuWriteS8LE(void *ptr, int offset, AuInt8 value)
{
AuWriteGenericLE<AuInt8>(ptr, offset, value);
}
static auline void AuWriteU64BE(void *ptr, int offset, AuUInt64 value)
{
AuWriteGenericBE<AuUInt64>(ptr, offset, value);
}
static auline void AuWriteU32BE(void *ptr, int offset, AuUInt32 value)
{
AuWriteGenericBE<AuUInt32>(ptr, offset, value);
}
static auline void AuWriteU16BE(void *ptr, int offset, AuUInt16 value)
{
AuWriteGenericBE<AuUInt16>(ptr, offset, value);
}
static auline void AuWriteU8BE(void *ptr, int offset, AuUInt8 value)
{
AuWriteGenericBE<AuUInt8>(ptr, offset, value);
}
static auline void AuWriteS64BE(void *ptr, int offset, AuInt64 value)
{
AuWriteGenericBE<AuInt64>(ptr, offset, value);
}
static auline void AuWriteS32BE(void *ptr, int offset, AuInt32 value)
{
AuWriteGenericBE<AuInt32>(ptr, offset, value);
}
static auline void AuWriteS16BE(void *ptr, int offset, AuInt16 value)
{
AuWriteGenericBE<AuInt16>(ptr, offset, value);
}
static auline void AuWriteS8BE(void *ptr, int offset, AuInt8 value)
{
AuWriteGenericBE<AuInt8>(ptr, offset, value);
}
static auline void AuWriteU64(void *ptr, int offset, AuUInt64 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteU64LE(ptr, offset, value);
#else
AuWriteU64BE(ptr, offset, value);
#endif
}
static auline void AuWriteU32(void *ptr, int offset, AuUInt32 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteU32LE(ptr, offset, value);
#else
AuWriteU32BE(ptr, offset, value);
#endif
}
static auline void AuWriteU16(void *ptr, int offset, AuUInt16 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteU16LE(ptr, offset, value);
#else
AuWriteU16BE(ptr, offset, value);
#endif
}
static auline void AuWriteU8(void *ptr, int offset, AuUInt8 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteU8LE(ptr, offset, value);
#else
AuWriteU8BE(ptr, offset, value);
#endif
}
static auline void AuWriteS64(void *ptr, int offset, AuInt64 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteS64LE(ptr, offset, value);
#else
AuWriteS64BE(ptr, offset, value);
#endif
}
static auline void AuWriteS32(void *ptr, int offset, AuInt32 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteS32LE(ptr, offset, value);
#else
AuWriteS32BE(ptr, offset, value);
#endif
}
static auline void AuWriteS16(void *ptr, int offset, AuInt16 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteS16LE(ptr, offset, value);
#else
AuWriteS16BE(ptr, offset, value);
#endif
}
static auline void AuWriteS8(void *ptr, int offset, AuInt8 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteS8LE(ptr, offset, value);
#else
AuWriteS8BE(ptr, offset, value);
#endif
}
template <class T>
static auline T AuReadGenericLE(const volatile void *ptr, int offset)
{
#if defined(AURORA_PERMIT_ARBITRARY_REF) && ((defined(AURORA_COMPILER_CLANG) && !defined(CLANG_NOT_X86_AND_NOT_VOLATILEMS)) || defined(AURORA_COMPILER_MSVC))
T temp = *reinterpret_cast<const volatile T *>(reinterpret_cast<const volatile AuUInt8 *>(ptr) + offset);
#else
AURORA_COMPILER_VOLATILE_BARRIER();
T temp;
AuMemcpy(&temp, ((const AuUInt8 *)ptr) + offset, sizeof(temp));
#endif
if constexpr (sizeof(T) != 1)
{
#if !defined(AU_CPU_ENDIAN_LITTLE)
temp = AuFlipEndian(temp);
#endif
}
return temp;
}
template <class T>
static auline T AuReadGenericBE(const volatile void *ptr, int offset)
{
#if defined(AURORA_PERMIT_ARBITRARY_REF) && ((defined(AURORA_COMPILER_CLANG) && !defined(CLANG_NOT_X86_AND_NOT_VOLATILEMS)) || defined(AURORA_COMPILER_MSVC))
T temp = *reinterpret_cast<const volatile T *>(reinterpret_cast<const volatile AuUInt8 *>(ptr) + offset);
#else
AURORA_COMPILER_VOLATILE_BARRIER();
T temp;
AuMemcpy(&temp, ((const AuUInt8 *)ptr) + offset, sizeof(temp));
#endif
if constexpr (sizeof(T) != 1)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
temp = AuFlipEndian(temp);
#endif
}
return temp;
}
static auline AuUInt64 AuReadU64LE(const volatile void *ptr, int offset)
{
return AuReadGenericLE<AuUInt64>(ptr, offset);
}
static auline AuUInt32 AuReadU32LE(const volatile void *ptr, int offset)
{
return AuReadGenericLE<AuUInt32>(ptr, offset);
}
static auline AuUInt16 AuReadU16LE(const volatile void *ptr, int offset)
{
return AuReadGenericLE<AuUInt16>(ptr, offset);
}
static auline AuUInt8 AuReadU8LE(const volatile void *ptr, int offset)
{
return AuReadGenericLE<AuUInt8>(ptr, offset);
}
static auline AuInt64 AuReadS64LE(const volatile void *ptr, int offset)
{
return AuReadGenericLE<AuInt64>(ptr, offset);
}
static auline AuInt32 AuReadS32LE(const volatile void *ptr, int offset)
{
return AuReadGenericLE<AuInt32>(ptr, offset);
}
static auline AuInt16 AuReadS16LE(const volatile void *ptr, int offset)
{
return AuReadGenericLE<AuInt16>(ptr, offset);
}
static auline AuInt8 AuReadS8LE(const volatile void *ptr, int offset)
{
return AuReadGenericLE<AuInt8>(ptr, offset);
}
static auline AuUInt64 AuReadU64BE(const volatile void *ptr, int offset)
{
return AuReadGenericBE<AuUInt64>(ptr, offset);
}
static auline AuUInt32 AuReadU32BE(const volatile void *ptr, int offset)
{
return AuReadGenericBE<AuUInt32>(ptr, offset);
}
static auline AuUInt16 AuReadU16BE(const volatile void *ptr, int offset)
{
return AuReadGenericBE<AuUInt16>(ptr, offset);
}
static auline AuUInt8 AuReadU8BE(const volatile void *ptr, int offset)
{
return AuReadGenericBE<AuUInt8>(ptr, offset);
}
static auline AuInt64 AuReadS64BE(const volatile void *ptr, int offset)
{
return AuReadGenericBE<AuInt64>(ptr, offset);
}
static auline AuInt32 AuReadS32BE(const volatile void *ptr, int offset)
{
return AuReadGenericBE<AuInt32>(ptr, offset);
}
static auline AuInt16 AuReadS16BE(const volatile void *ptr, int offset)
{
return AuReadGenericBE<AuInt16>(ptr, offset);
}
static auline AuInt8 AuReadS8BE(const volatile void *ptr, int offset)
{
return AuReadGenericBE<AuInt8>(ptr, offset);
}
static auline AuUInt64 AuReadU64(const volatile void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadU64LE(ptr, offset);
#else
return AuReadU64BE(ptr, offset);
#endif
}
static auline AuUInt32 AuReadU32(const volatile void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadU32LE(ptr, offset);
#else
return AuReadU32BE(ptr, offset);
#endif
}
static auline AuUInt16 AuReadU16(const volatile void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadU16LE(ptr, offset);
#else
return AuReadU16BE(ptr, offset);
#endif
}
static auline AuUInt8 AuReadU8(const volatile void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadU8LE(ptr, offset);
#else
return AuReadU8BE(ptr, offset);
#endif
}
static auline AuInt64 AuReadS64(const volatile void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadS64LE(ptr, offset);
#else
return AuReadS64BE(ptr, offset);
#endif
}
static auline AuInt32 AuReadS32(const volatile void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadS32LE(ptr, offset);
#else
return AuReadS32BE(ptr, offset);
#endif
}
static auline AuInt16 AuReadS16(const volatile void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadS16LE(ptr, offset);
#else
return AuReadS16BE(ptr, offset);
#endif
}
static auline AuInt8 AuReadS8(const volatile void *ptr, int offset)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
return AuReadS8LE(ptr, offset);
#else
return AuReadS8BE(ptr, offset);
#endif
}
template <class T>
static auline void AuWriteGenericLE(volatile void *ptr, int offset, T value)
{
#if !defined(AU_CPU_ENDIAN_LITTLE)
value = AuFlipEndian(value);
#endif
#if defined(AURORA_PERMIT_ARBITRARY_REF)
*reinterpret_cast<volatile T *>(reinterpret_cast<volatile AuUInt8 *>(ptr) + offset) = value;
#else
AuMemcpy(reinterpret_cast<AuUInt8 *>(ptr) + offset, &value, sizeof(value));
#endif
}
template <class T>
static auline void AuWriteGenericBE(volatile void *ptr, int offset, T value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
value = AuFlipEndian(value);
#endif
#if defined(AURORA_PERMIT_ARBITRARY_REF)
*reinterpret_cast<volatile T *>(reinterpret_cast<volatile AuUInt8 *>(ptr) + offset) = value;
#else
AuMemcpy(reinterpret_cast<AuUInt8 *>(ptr) + offset, &value, sizeof(value));
#endif
}
static auline void AuWriteU64LE(volatile void *ptr, int offset, AuUInt64 value)
{
AuWriteGenericLE<AuUInt64>(ptr, offset, value);
}
static auline void AuWriteU32LE(volatile void *ptr, int offset, AuUInt32 value)
{
AuWriteGenericLE<AuUInt32>(ptr, offset, value);
}
static auline void AuWriteU16LE(volatile void *ptr, int offset, AuUInt16 value)
{
AuWriteGenericLE<AuUInt16>(ptr, offset, value);
}
static auline void AuWriteU8LE(volatile void *ptr, int offset, AuUInt8 value)
{
AuWriteGenericLE<AuUInt8>(ptr, offset, value);
}
static auline void AuWriteS64LE(volatile void *ptr, int offset, AuInt64 value)
{
AuWriteGenericLE<AuInt64>(ptr, offset, value);
}
static auline void AuWriteS32LE(volatile void *ptr, int offset, AuInt32 value)
{
AuWriteGenericLE<AuInt32>(ptr, offset, value);
}
static auline void AuWriteS16LE(volatile void *ptr, int offset, AuInt16 value)
{
AuWriteGenericLE<AuInt16>(ptr, offset, value);
}
static auline void AuWriteS8LE(volatile void *ptr, int offset, AuInt8 value)
{
AuWriteGenericLE<AuInt8>(ptr, offset, value);
}
static auline void AuWriteU64BE(volatile void *ptr, int offset, AuUInt64 value)
{
AuWriteGenericBE<AuUInt64>(ptr, offset, value);
}
static auline void AuWriteU32BE(volatile void *ptr, int offset, AuUInt32 value)
{
AuWriteGenericBE<AuUInt32>(ptr, offset, value);
}
static auline void AuWriteU16BE(volatile void *ptr, int offset, AuUInt16 value)
{
AuWriteGenericBE<AuUInt16>(ptr, offset, value);
}
static auline void AuWriteU8BE(volatile void *ptr, int offset, AuUInt8 value)
{
AuWriteGenericBE<AuUInt8>(ptr, offset, value);
}
static auline void AuWriteS64BE(volatile void *ptr, int offset, AuInt64 value)
{
AuWriteGenericBE<AuInt64>(ptr, offset, value);
}
static auline void AuWriteS32BE(volatile void *ptr, int offset, AuInt32 value)
{
AuWriteGenericBE<AuInt32>(ptr, offset, value);
}
static auline void AuWriteS16BE(volatile void *ptr, int offset, AuInt16 value)
{
AuWriteGenericBE<AuInt16>(ptr, offset, value);
}
static auline void AuWriteS8BE(volatile void *ptr, int offset, AuInt8 value)
{
AuWriteGenericBE<AuInt8>(ptr, offset, value);
}
static auline void AuWriteU64(volatile void *ptr, int offset, AuUInt64 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteU64LE(ptr, offset, value);
#else
AuWriteU64BE(ptr, offset, value);
#endif
}
static auline void AuWriteU32(volatile void *ptr, int offset, AuUInt32 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteU32LE(ptr, offset, value);
#else
AuWriteU32BE(ptr, offset, value);
#endif
}
static auline void AuWriteU16(volatile void *ptr, int offset, AuUInt16 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteU16LE(ptr, offset, value);
#else
AuWriteU16BE(ptr, offset, value);
#endif
}
static auline void AuWriteU8(volatile void *ptr, int offset, AuUInt8 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteU8LE(ptr, offset, value);
#else
AuWriteU8BE(ptr, offset, value);
#endif
}
static auline void AuWriteS64(volatile void *ptr, int offset, AuInt64 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteS64LE(ptr, offset, value);
#else
AuWriteS64BE(ptr, offset, value);
#endif
}
static auline void AuWriteS32(volatile void *ptr, int offset, AuInt32 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteS32LE(ptr, offset, value);
#else
AuWriteS32BE(ptr, offset, value);
#endif
}
static auline void AuWriteS16(volatile void *ptr, int offset, AuInt16 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteS16LE(ptr, offset, value);
#else
AuWriteS16BE(ptr, offset, value);
#endif
}
static auline void AuWriteS8(volatile void *ptr, int offset, AuInt8 value)
{
#if defined(AU_CPU_ENDIAN_LITTLE)
AuWriteS8LE(ptr, offset, value);
#else
AuWriteS8BE(ptr, offset, value);
#endif
}