From: Marcus Holland-Moritz Date: Mon, 27 Jun 2016 23:39:27 +0000 (-0700) Subject: Allow unchecked conversion from floating point to bool X-Git-Tag: 2016.07.26~112 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=12c01784f91e2581c22c4fe4e435c16a527df0a7;p=folly.git Allow unchecked conversion from floating point to bool Summary: In order to be consistent with integral-to-bool conversion, this change allows conversion from floating point values to bool following the same rule that is to be consistent with C(++) conventions. Also, any arithmetic value can be converted to bool without potential for undefined behaviour, so no extra checks are required. Differential Revision: D3483760 fbshipit-source-id: 024b58d348ef679079aba4d9d5277acb46aba2a1 --- diff --git a/folly/Conv.h b/folly/Conv.h index 8c03e28f..871853d3 100644 --- a/folly/Conv.h +++ b/folly/Conv.h @@ -83,24 +83,27 @@ to(Src && value) { } /******************************************************************************* - * Integral to integral + * Arithmetic to boolean ******************************************************************************/ /** - * Unchecked conversion from integral to boolean. This is different from the - * other integral conversions because we use the C convention of treating any + * Unchecked conversion from arithmetic to boolean. This is different from the + * other arithmetic conversions because we use the C convention of treating any * non-zero value as true, instead of range checking. */ template typename std::enable_if< - std::is_integral::value - && !std::is_same::value - && std::is_same::value, - Tgt>::type -to(const Src & value) { - return value != 0; + std::is_arithmetic::value && !std::is_same::value && + std::is_same::value, + Tgt>::type +to(const Src& value) { + return value != Src(); } +/******************************************************************************* + * Integral to integral + ******************************************************************************/ + /** * Checked conversion from integral to integral. The checks are only * performed when meaningful, e.g. conversion from int to long goes @@ -1220,11 +1223,11 @@ checkConversion(const Src&) { */ template typename std::enable_if< - (std::is_integral::value && std::is_floating_point::value) - || - (std::is_floating_point::value && std::is_integral::value), - Tgt>::type -to(const Src & value) { + (std::is_integral::value && std::is_floating_point::value) || + (std::is_floating_point::value && std::is_integral::value && + !std::is_same::value), + Tgt>::type +to(const Src& value) { if (detail::checkConversion(value)) { Tgt result = Tgt(value); if (detail::checkConversion(result)) { diff --git a/folly/test/ConvTest.cpp b/folly/test/ConvTest.cpp index 77594c8b..4bbca6da 100644 --- a/folly/test/ConvTest.cpp +++ b/folly/test/ConvTest.cpp @@ -840,6 +840,13 @@ TEST(Conv, BoolToFloat) { TEST(Conv, FloatToBool) { EXPECT_EQ(to(1.0), true); EXPECT_EQ(to(0.0), false); + EXPECT_EQ(to(2.7), true); + EXPECT_EQ(to(std::numeric_limits::max()), true); + EXPECT_EQ(to(std::numeric_limits::min()), true); + EXPECT_EQ(to(std::numeric_limits::lowest()), true); + EXPECT_EQ(to(std::numeric_limits::quiet_NaN()), true); + EXPECT_EQ(to(std::numeric_limits::infinity()), true); + EXPECT_EQ(to(-std::numeric_limits::infinity()), true); } TEST(Conv, NewUint64ToString) {