[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
#if __cplusplus >= 202002L && defined(OX_USE_STDLIB)
#include <bit>
#endif
#include "memops.hpp"
#include "types.hpp"
#include "typetraits.hpp"
@ -16,7 +20,7 @@ namespace ox {
template<typename To, typename From>
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));
return dst;
}
@ -52,3 +56,23 @@ static_assert(onMask<int>(3) == 7);
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 {
auto srcBuf = static_cast<const char*>(src);
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]);
}
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 {
auto srcBuf = static_cast<const char*>(src);
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]);
}
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 {
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);
}
return ptr;

View File

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