Common/BitUtils: Implement BitCast(To|From)Array

This commit is contained in:
Techjar 2019-12-18 23:36:56 -05:00
parent 3cf2857aac
commit 79092cdda0
1 changed files with 48 additions and 0 deletions

View File

@ -4,6 +4,7 @@
#pragma once
#include <array>
#include <climits>
#include <cstddef>
#include <cstring>
@ -240,6 +241,53 @@ inline auto BitCastPtr(PtrType* ptr) noexcept -> BitCastPtrType<T, PtrType>
return BitCastPtrType<T, PtrType>{ptr};
}
// Similar to BitCastPtr, but specifically for aliasing structs to arrays.
template <typename ArrayType, typename T,
typename Container = std::array<ArrayType, sizeof(T) / sizeof(ArrayType)>>
inline auto BitCastToArray(const T& obj) noexcept -> Container
{
static_assert(sizeof(T) % sizeof(ArrayType) == 0,
"Size of array type must be a factor of size of source type.");
static_assert(std::is_trivially_copyable<T>(),
"BitCastToArray source type must be trivially copyable.");
static_assert(std::is_trivially_copyable<Container>(),
"BitCastToArray array type must be trivially copyable.");
Container result;
std::memcpy(result.data(), &obj, sizeof(T));
return result;
}
template <typename ArrayType, typename T,
typename Container = std::array<ArrayType, sizeof(T) / sizeof(ArrayType)>>
inline void BitCastFromArray(const Container& array, T& obj) noexcept
{
static_assert(sizeof(T) % sizeof(ArrayType) == 0,
"Size of array type must be a factor of size of destination type.");
static_assert(std::is_trivially_copyable<Container>(),
"BitCastFromArray array type must be trivially copyable.");
static_assert(std::is_trivially_copyable<T>(),
"BitCastFromArray destination type must be trivially copyable.");
std::memcpy(&obj, array.data(), sizeof(T));
}
template <typename ArrayType, typename T,
typename Container = std::array<ArrayType, sizeof(T) / sizeof(ArrayType)>>
inline auto BitCastFromArray(const Container& array) noexcept -> T
{
static_assert(sizeof(T) % sizeof(ArrayType) == 0,
"Size of array type must be a factor of size of destination type.");
static_assert(std::is_trivially_copyable<Container>(),
"BitCastFromArray array type must be trivially copyable.");
static_assert(std::is_trivially_copyable<T>(),
"BitCastFromArray destination type must be trivially copyable.");
T obj;
std::memcpy(&obj, array.data(), sizeof(T));
return obj;
}
template <typename T>
void SetBit(T& value, size_t bit_number, bool bit_value)
{