Add bit_cast

This commit is contained in:
Victor Zverovich 2018-05-06 08:07:28 -07:00
parent 0adccaefb6
commit a4c7d99f70
2 changed files with 21 additions and 0 deletions

View File

@ -211,6 +211,17 @@ inline uint32_t clzll(uint64_t x) {
namespace fmt { namespace fmt {
namespace internal { namespace internal {
// An equivalent of `*reinterpret_cast<Dest*>(&source)` that doesn't produce
// undefined behavior (e.g. due to type aliasing).
// Example: uint64_t d = bit_cast<uint64_t>(2.718);
template <typename Dest, typename Source>
inline Dest bit_cast(const Source& source) {
static_assert(sizeof(Dest) == sizeof(Source), "size mismatch");
Dest dest;
std::memcpy(&dest, &source, sizeof(dest));
return dest;
}
// An implementation of begin and end for pre-C++11 compilers such as gcc 4. // An implementation of begin and end for pre-C++11 compilers such as gcc 4.
template <typename C> template <typename C>
FMT_CONSTEXPR auto begin(const C &c) -> decltype(c.begin()) { FMT_CONSTEXPR auto begin(const C &c) -> decltype(c.begin()) {

View File

@ -397,6 +397,16 @@ TEST(FixedBufferTest, BufferOverflow) {
EXPECT_THROW_MSG(buffer.resize(11), std::runtime_error, "buffer overflow"); EXPECT_THROW_MSG(buffer.resize(11), std::runtime_error, "buffer overflow");
} }
TEST(UtilTest, BitCast) {
struct S {
uint32_t u[2];
};
auto s = fmt::internal::bit_cast<S>(uint64_t(42));
EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), 42);
s = fmt::internal::bit_cast<S>(uint64_t(~0ull));
EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), ~0ull);
}
TEST(UtilTest, Increment) { TEST(UtilTest, Increment) {
char s[10] = "123"; char s[10] = "123";
increment(s); increment(s);