Commit cc7dde63 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Use bit_cast in Endian

Summary:
[Folly] Use `bit_cast` in `Endian`.

Requires moving `bit_cast` to the top of the header.

Reviewed By: aary

Differential Revision: D14080604

fbshipit-source-id: cae28003895f1326138459c3a951d38e27e27506
parent e90b9cb4
...@@ -62,6 +62,28 @@ ...@@ -62,6 +62,28 @@
namespace folly { namespace folly {
#if __cpp_lib_bit_cast
using std::bit_cast;
#else
// mimic: std::bit_cast, C++20
template <
typename To,
typename From,
std::enable_if_t<
sizeof(From) == sizeof(To) && std::is_trivial<To>::value &&
is_trivially_copyable<From>::value,
int> = 0>
To bit_cast(const From& src) noexcept {
To to;
std::memcpy(&to, &src, sizeof(From));
return to;
}
#endif
namespace detail { namespace detail {
template <typename Dst, typename Src> template <typename Dst, typename Src>
constexpr std::make_signed_t<Dst> bits_to_signed(Src const s) { constexpr std::make_signed_t<Dst> bits_to_signed(Src const s) {
...@@ -203,15 +225,11 @@ struct EndianInt { ...@@ -203,15 +225,11 @@ struct EndianInt {
std::is_floating_point<T>::value, std::is_floating_point<T>::value,
"template type parameter must be non-bool integral or floating point"); "template type parameter must be non-bool integral or floating point");
static T swap(T x) { static T swap(T x) {
// we implement this with memcpy because that is defined behavior in C++ // we implement this with bit_cast because that is defined behavior in C++
// we rely on compilers to optimize away the memcpy calls // we rely on compilers to optimize away the bit_cast calls
constexpr auto s = sizeof(T); constexpr auto s = sizeof(T);
using B = typename uint_types_by_size<s>::type; using B = typename uint_types_by_size<s>::type;
B b; return bit_cast<T>(byteswap_gen(bit_cast<B>(x)));
std::memcpy(&b, &x, s);
b = byteswap_gen(b);
std::memcpy(&x, &b, s);
return x;
} }
static T big(T x) { static T big(T x) {
return kIsLittleEndian ? EndianInt::swap(x) : x; return kIsLittleEndian ? EndianInt::swap(x) : x;
...@@ -375,26 +393,4 @@ T bitReverse(T n) { ...@@ -375,26 +393,4 @@ T bitReverse(T n) {
return static_cast<T>(Endian::swap(m)); return static_cast<T>(Endian::swap(m));
} }
#if __cpp_lib_bit_cast
using std::bit_cast;
#else
// mimic: std::bit_cast, C++20
template <
typename To,
typename From,
std::enable_if_t<
sizeof(From) == sizeof(To) && std::is_trivial<To>::value &&
is_trivially_copyable<From>::value,
int> = 0>
To bit_cast(const From& src) noexcept {
To to;
std::memcpy(&to, &src, sizeof(From));
return to;
}
#endif
} // namespace folly } // namespace folly
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment