summaryrefslogtreecommitdiff
path: root/Source/Core/Common
diff options
context:
space:
mode:
authorTechjar <tecknojar@gmail.com>2019-12-18 23:36:56 -0500
committerTechjar <tecknojar@gmail.com>2019-12-22 14:48:47 -0500
commit79092cdda08b5b89dd874ffb7de161efcd65af16 (patch)
tree42e87a4df5ebab6c803ade55e3a9744ff4a437ee /Source/Core/Common
parent3cf2857aac51437dd36ce883bc3d0973c2d02718 (diff)
Common/BitUtils: Implement BitCast(To|From)Array
Diffstat (limited to 'Source/Core/Common')
-rw-r--r--Source/Core/Common/BitUtils.h48
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)
{