From afe16fa0f3be08438f7df12233455122b4cf48ba Mon Sep 17 00:00:00 2001 From: MerryMage Date: Wed, 7 Feb 2018 12:22:35 +0000 Subject: [PATCH] cast_util: Add BitCast and BitCastPointee --- src/CMakeLists.txt | 1 + src/common/cast_util.h | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/common/cast_util.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d22195aa..1986898a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,7 @@ add_library(dynarmic common/aes.h common/assert.h common/bit_util.h + common/cast_util.h common/common_types.h common/crc32.cpp common/crc32.h diff --git a/src/common/cast_util.h b/src/common/cast_util.h new file mode 100644 index 00000000..5a756b5c --- /dev/null +++ b/src/common/cast_util.h @@ -0,0 +1,38 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2018 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#pragma once + +#include +#include + +namespace Dynarmic::Common { + +/// Reinterpret objects of one type as another by bit-casting between object representations. +template +inline Dest BitCast(const Source& source) { + static_assert(sizeof(Dest) == sizeof(Source), "size of destination and source objects must be equal"); + static_assert(std::is_trivially_copyable_v, "destination type must be trivially copyable."); + static_assert(std::is_trivially_copyable_v, "source type must be trivially copyable"); + + typename std::aligned_storage_t dest; + std::memcpy(&dest, &source, sizeof(dest)); + return reinterpret_cast(dest); +} + +/// Reinterpret objects of any arbitrary type as another type by bit-casting between object representations. +/// Note that here we do not verify if source has enough bytes to read from. +template +inline Dest BitCastPointee(const SourcePtr source) { + static_assert(sizeof(SourcePtr) == sizeof(void*), "source pointer must have size of a pointer"); + static_assert(std::is_trivially_copyable_v, "destination type must be trivially copyable."); + + typename std::aligned_storage_t dest; + std::memcpy(&dest, BitCast(source), sizeof(dest)); + return reinterpret_cast(dest); +} + +} // namespace Dynarmic::Common