6#include "TTauri/Foundation/os_detect.hpp"
7#include "TTauri/Foundation/memory.hpp"
9#if TT_COMPILER == TT_CC_MSVC
21#if TT_PROCESSOR == TT_CPU_X64 || TT_PROCESSOR == TT_CPU_ARM
22constexpr Endian endian = Endian::Little;
24#error "Endian not configured for this processor."
28[[nodiscard]] tt_force_inline std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>,T>
29byte_swap(T x)
noexcept
31#if TT_COMPILER == TT_CC_CLANG || TT_COMPILER == TT_CC_GCC
32 if constexpr (
sizeof(T) ==
sizeof(uint64_t)) {
33 return static_cast<T
>(__builtin_bswap64(
static_cast<uint64_t
>(x)));
34 }
else if constexpr (
sizeof(T) ==
sizeof(uint32_t)) {
35 return static_cast<T
>(__builtin_bswap32(
static_cast<uint32_t
>(x)));
36 }
else if constexpr (
sizeof(T) ==
sizeof(uint16_t)) {
37 return static_cast<T
>(__builtin_bswap16(
static_cast<uint16_t
>(x)));
41#elif TT_COMPILER == TT_CC_MSVC
42 if constexpr (
sizeof(T) ==
sizeof(uint64_t)) {
43 return static_cast<T
>(_byteswap_uint64(
static_cast<uint64_t
>(x)));
44 }
else if constexpr (
sizeof(T) ==
sizeof(
unsigned long)) {
45 return static_cast<T
>(_byteswap_ulong(
static_cast<unsigned long>(x)));
46 }
else if constexpr (
sizeof(T) ==
sizeof(
unsigned short)) {
47 return static_cast<T
>(_byteswap_ushort(
static_cast<unsigned short>(x)));
52#error "Byteswap not implemented for this compiler."
57[[nodiscard]] tt_force_inline std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>,T>
58byte_swap(T x)
noexcept
60 return static_cast<T
>(byte_swap(
static_cast<std::make_unsigned_t<T>
>(x)));
64[[nodiscard]] tt_force_inline std::enable_if_t<std::is_floating_point_v<T>,T>
65byte_swap(T x)
noexcept
67 if constexpr (std::is_same_v<T, float>) {
68 auto utmp = bit_cast<uint32_t>(x);
69 utmp = byte_swap(utmp);
70 return bit_cast<float>(x);
71 }
else if constexpr (std::is_same_v<T, double>) {
72 auto utmp = bit_cast<uint64_t>(x);
73 utmp = byte_swap(utmp);
74 return bit_cast<double>(x);
81[[nodiscard]] tt_force_inline std::enable_if_t<std::is_integral_v<T>,T>
84 if constexpr (endian == Endian::Little) {
92[[nodiscard]] tt_force_inline std::enable_if_t<std::is_integral_v<T>,T>
95 if constexpr (endian == Endian::Big) {
103[[nodiscard]] tt_force_inline std::enable_if_t<std::is_integral_v<T>,T>
106 if constexpr (endian == Endian::Little) {
114[[nodiscard]] tt_force_inline std::enable_if_t<std::is_integral_v<T>,T>
117 if constexpr (endian == Endian::Big) {
124template<
typename T,Endian E,
size_t A=alignof(T)>
126 alignas(A) std::byte _value[
sizeof(T)];
128 [[nodiscard]] tt_force_inline T value()
const noexcept {
130 std::memcpy(&aligned_value, &_value[0],
sizeof(T));
132 if constexpr (E == endian || E == Endian::Native) {
133 return aligned_value;
135 return byte_swap(aligned_value);
141 if constexpr (E == endian || E == Endian::Native) {
144 aligned_value = byte_swap(x);
146 std::memcpy(&_value[0], &aligned_value,
sizeof(T));
Definition endian.hpp:125