diff options
author | Chris Robinson <[email protected]> | 2023-05-04 09:16:59 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-05-04 09:27:19 -0700 |
commit | 6e0a0a2692a4303d6410c24bf83e09ca47ac6759 (patch) | |
tree | 906db65a3900d89b07a67d8b938ecc5977dcb9bb /common | |
parent | 3d2e586636f765eb2fccebb757305295d7b2c954 (diff) |
Make and use a bit_cast function
Instead of reinterpret_casting between incompatible types
Diffstat (limited to 'common')
-rw-r--r-- | common/albit.h | 11 | ||||
-rw-r--r-- | common/dynload.cpp | 3 |
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) |