diff options
| author | Techjar <tecknojar@gmail.com> | 2019-12-18 23:36:56 -0500 |
|---|---|---|
| committer | Techjar <tecknojar@gmail.com> | 2019-12-22 14:48:47 -0500 |
| commit | 79092cdda08b5b89dd874ffb7de161efcd65af16 (patch) | |
| tree | 42e87a4df5ebab6c803ade55e3a9744ff4a437ee /Source/Core/Common | |
| parent | 3cf2857aac51437dd36ce883bc3d0973c2d02718 (diff) | |
Common/BitUtils: Implement BitCast(To|From)Array
Diffstat (limited to 'Source/Core/Common')
| -rw-r--r-- | Source/Core/Common/BitUtils.h | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/Source/Core/Common/BitUtils.h b/Source/Core/Common/BitUtils.h index 8b64a92508..79c1a7799e 100644 --- a/Source/Core/Common/BitUtils.h +++ b/Source/Core/Common/BitUtils.h @@ -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) { |
