[ox/std] Add support for proper std::bit_cast with C++20 enabled

This commit is contained in:
Gary Talent 2021-07-24 20:39:40 -05:00
parent bd0b8e4ee9
commit 9418f54ebc
3 changed files with 29 additions and 4 deletions

View File

@ -8,6 +8,10 @@
#pragma once #pragma once
#if __cplusplus >= 202002L && defined(OX_USE_STDLIB)
#include <bit>
#endif
#include "memops.hpp" #include "memops.hpp"
#include "types.hpp" #include "types.hpp"
#include "typetraits.hpp" #include "typetraits.hpp"
@ -16,7 +20,7 @@ namespace ox {
template<typename To, typename From> template<typename To, typename From>
constexpr typename enable_if<sizeof(To) == sizeof(From), To>::type cbit_cast(From src) noexcept { constexpr typename enable_if<sizeof(To) == sizeof(From), To>::type cbit_cast(From src) noexcept {
To dst; To dst = {};
ox_memcpy(&dst, &src, sizeof(src)); ox_memcpy(&dst, &src, sizeof(src));
return dst; return dst;
} }
@ -52,3 +56,23 @@ static_assert(onMask<int>(3) == 7);
static_assert(onMask<int>(4) == 15); static_assert(onMask<int>(4) == 15);
} }
namespace std {
#if __cplusplus >= 202002L && !defined(OX_USE_STDLIB)
template<typename To, typename From>
constexpr typename ox::enable_if<sizeof(To) == sizeof(From), To>::type bit_cast(From src) noexcept {
return __builtin_bitcast(src);
}
#elif __cplusplus < 202002L
template<typename To, typename From>
typename ox::enable_if<sizeof(To) == sizeof(From), To>::type bit_cast(From src) noexcept {
To dst = {};
memcpy(&dst, &src, sizeof(src));
return dst;
}
#endif
}

View File

@ -29,7 +29,7 @@ int ox_memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept;
constexpr void *ox_memcpy(void *dest, const void *src, std::size_t size) noexcept { constexpr void *ox_memcpy(void *dest, const void *src, std::size_t size) noexcept {
auto srcBuf = static_cast<const char*>(src); auto srcBuf = static_cast<const char*>(src);
auto dstBuf = static_cast<char*>(dest); auto dstBuf = static_cast<char*>(dest);
for (std::size_t i = 0; i < size; i++) { for (std::size_t i = 0; i < size; ++i) {
dstBuf[i] = static_cast<char>(srcBuf[i]); dstBuf[i] = static_cast<char>(srcBuf[i]);
} }
return dest; return dest;
@ -38,7 +38,7 @@ constexpr void *ox_memcpy(void *dest, const void *src, std::size_t size) noexcep
constexpr void *ox_memmove(void *dest, const void *src, std::size_t size) noexcept { constexpr void *ox_memmove(void *dest, const void *src, std::size_t size) noexcept {
auto srcBuf = static_cast<const char*>(src); auto srcBuf = static_cast<const char*>(src);
auto dstBuf = static_cast<char*>(dest); auto dstBuf = static_cast<char*>(dest);
for (std::size_t i = 0; i < size; i++) { for (std::size_t i = 0; i < size; ++i) {
dstBuf[i] = static_cast<char>(srcBuf[i]); dstBuf[i] = static_cast<char>(srcBuf[i]);
} }
return dest; return dest;
@ -46,7 +46,7 @@ constexpr void *ox_memmove(void *dest, const void *src, std::size_t size) noexce
constexpr void *ox_memset(void *ptr, int val, std::size_t size) noexcept { constexpr void *ox_memset(void *ptr, int val, std::size_t size) noexcept {
auto buf = static_cast<uint8_t*>(ptr); auto buf = static_cast<uint8_t*>(ptr);
for (std::size_t i = 0; i < size; i++) { for (std::size_t i = 0; i < size; ++i) {
buf[i] = static_cast<uint8_t>(val); buf[i] = static_cast<uint8_t>(val);
} }
return ptr; return ptr;

View File

@ -64,6 +64,7 @@ namespace ox {
template<typename T, std::size_t sz = sizeof(T)> template<typename T, std::size_t sz = sizeof(T)>
struct alignas(alignof(T)) AllocAlias { struct alignas(alignof(T)) AllocAlias {
char buff[sz]; char buff[sz];
constexpr AllocAlias() noexcept = default;
}; };