Commit 29c7ba51 authored by Marcus Holland-Moritz's avatar Marcus Holland-Moritz Committed by Facebook Github Bot 7

Fix conversion from bool to floating point value

Summary:
Due to the definition of how floating point values convert to boolean,
the check for undefined behaviour wouldn't work correctly. The result
of (1 - 0.9999999999999999) would yield 0 when converted to an integer,
but yields true (1) when converted to a boolean.

As all floating point values can thus be converted to boolean without
triggering undefined behaviour, this change overloads checkConversion()
appropriately

Reviewed By: yfeldblum

Differential Revision: D3477368

fbshipit-source-id: 5b2aeb6194629cf3a6195529aac2362c0d35799c
parent 1186ac53
......@@ -1163,10 +1163,11 @@ namespace detail {
* integer value without triggering undefined behaviour.
*/
template <typename Tgt, typename Src>
typename std::enable_if<
std::is_floating_point<Src>::value && std::is_integral<Tgt>::value,
inline typename std::enable_if<
std::is_floating_point<Src>::value && std::is_integral<Tgt>::value &&
!std::is_same<Tgt, bool>::value,
bool>::type
inline checkConversion(const Src& value) {
checkConversion(const Src& value) {
constexpr Src tgtMaxAsSrc = static_cast<Src>(std::numeric_limits<Tgt>::max());
constexpr Src tgtMinAsSrc = static_cast<Src>(std::numeric_limits<Tgt>::min());
if (value >= tgtMaxAsSrc) {
......@@ -1193,13 +1194,22 @@ inline checkConversion(const Src& value) {
// Integers can always safely be converted to floating point values
template <typename Tgt, typename Src>
typename std::enable_if<
constexpr typename std::enable_if<
std::is_integral<Src>::value && std::is_floating_point<Tgt>::value,
bool>::type
checkConversion(const Src&) {
return true;
}
// Also, floating point values can always be safely converted to bool
// Per the standard, any floating point value that is not zero will yield true
template <typename Tgt, typename Src>
constexpr typename std::enable_if<
std::is_floating_point<Src>::value && std::is_same<Tgt, bool>::value,
bool>::type
checkConversion(const Src&) {
return true;
}
}
/**
......
......@@ -823,6 +823,16 @@ TEST(Conv, IntToFloat) {
#endif
}
TEST(Conv, BoolToFloat) {
EXPECT_EQ(to<double>(true), 1.0);
EXPECT_EQ(to<double>(false), 0.0);
}
TEST(Conv, FloatToBool) {
EXPECT_EQ(to<bool>(1.0), true);
EXPECT_EQ(to<bool>(0.0), false);
}
TEST(Conv, NewUint64ToString) {
char buf[21];
......
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