BitUtils: Add C++14/C++17 compatible equivalent of std::bit_cast from C++2a

Given bit conversions between types are quite common in emulation
(particularly when it comes to floating-point among other things) it
makes sense to provide a utility function that keeps all the boilerplate
contained; especially considering it makes it harder to accidentally
misuse std::memcpy (such as accidentally transposing arguments, etc).

Another benefit of this function is that it doesn't require separating
declarations from assignments, allowing variables to be declared const.
This makes the scenario of of uninitialized variables being used less
likely to occur.
This commit is contained in:
Lioncash 2018-05-10 09:54:35 -04:00
parent fd1ea63383
commit b3292298c9
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
2 changed files with 47 additions and 0 deletions

View file

@ -127,3 +127,16 @@ TEST(BitUtils, IsValidLowMask)
EXPECT_FALSE(Common::IsValidLowMask((u64) ~(0b10000)));
EXPECT_FALSE(Common::IsValidLowMask((u64)(~((u64)(~0b0) >> 1) | 0b1111)));
}
TEST(BitUtils, BitCast)
{
EXPECT_EQ(0x00000000U, Common::BitCast<u32>(0.0f));
EXPECT_EQ(0x80000000U, Common::BitCast<u32>(-0.0f));
EXPECT_EQ(0x3F800000U, Common::BitCast<u32>(1.0f));
EXPECT_EQ(0xBF800000U, Common::BitCast<u32>(-1.0f));
EXPECT_EQ(0x0000000000000000ULL, Common::BitCast<u64>(0.0));
EXPECT_EQ(0x8000000000000000ULL, Common::BitCast<u64>(-0.0));
EXPECT_EQ(0x3FF0000000000000ULL, Common::BitCast<u64>(1.0));
EXPECT_EQ(0xBFF0000000000000ULL, Common::BitCast<u64>(-1.0));
}