aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-05-04 09:16:59 -0700
committerChris Robinson <[email protected]>2023-05-04 09:27:19 -0700
commit6e0a0a2692a4303d6410c24bf83e09ca47ac6759 (patch)
tree906db65a3900d89b07a67d8b938ecc5977dcb9bb /common
parent3d2e586636f765eb2fccebb757305295d7b2c954 (diff)
Make and use a bit_cast function
Instead of reinterpret_casting between incompatible types
Diffstat (limited to 'common')
-rw-r--r--common/albit.h11
-rw-r--r--common/dynload.cpp3
2 files changed, 13 insertions, 1 deletions
diff --git a/common/albit.h b/common/albit.h
index ad596208..a563a4e7 100644
--- a/common/albit.h
+++ b/common/albit.h
@@ -2,6 +2,7 @@
#define AL_BIT_H
#include <cstdint>
+#include <cstring>
#include <limits>
#include <type_traits>
#if !defined(__GNUC__) && (defined(_WIN32) || defined(_WIN64))
@@ -10,6 +11,16 @@
namespace al {
+template<typename To, typename From>
+std::enable_if_t<sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From>
+ && std::is_trivially_copyable_v<To>,
+To> bit_cast(const From &src) noexcept
+{
+ union { char c; To dst; } u;
+ std::memcpy(&u.dst, &src, sizeof(To));
+ return u.dst;
+}
+
#ifdef __BYTE_ORDER__
enum class endian {
little = __ORDER_LITTLE_ENDIAN__,
diff --git a/common/dynload.cpp b/common/dynload.cpp
index f1c2a7eb..86c36e00 100644
--- a/common/dynload.cpp
+++ b/common/dynload.cpp
@@ -3,6 +3,7 @@
#include "dynload.h"
+#include "albit.h"
#include "strutils.h"
#ifdef _WIN32
@@ -17,7 +18,7 @@ void *LoadLib(const char *name)
void CloseLib(void *handle)
{ FreeLibrary(static_cast<HMODULE>(handle)); }
void *GetSymbol(void *handle, const char *name)
-{ return reinterpret_cast<void*>(GetProcAddress(static_cast<HMODULE>(handle), name)); }
+{ return al::bit_cast<void*>(GetProcAddress(static_cast<HMODULE>(handle), name)); }
#elif defined(HAVE_DLFCN_H)