Commit be90fbfb authored by Marc Horowitz's avatar Marc Horowitz Committed by facebook-github-bot-9

make to<bool> skip range check

Summary: to<bool>(42) should return true, not throw an exception.

Reviewed By: @yfeldblum

Differential Revision: D2459766
parent facd5a7e
...@@ -86,6 +86,21 @@ to(Src && value) { ...@@ -86,6 +86,21 @@ to(Src && value) {
* Integral to integral * Integral to integral
******************************************************************************/ ******************************************************************************/
/**
* Unchecked conversion from integral to boolean. This is different from the
* other integral conversions because we use the C convention of treating any
* non-zero value as true, instead of range checking.
*/
template <class Tgt, class Src>
typename std::enable_if<
std::is_integral<Src>::value
&& !std::is_same<Tgt, Src>::value
&& std::is_same<Tgt, bool>::value,
Tgt>::type
to(const Src & value) {
return value != 0;
}
/** /**
* Checked conversion from integral to integral. The checks are only * Checked conversion from integral to integral. The checks are only
* performed when meaningful, e.g. conversion from int to long goes * performed when meaningful, e.g. conversion from int to long goes
...@@ -94,8 +109,9 @@ to(Src && value) { ...@@ -94,8 +109,9 @@ to(Src && value) {
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_integral<Src>::value std::is_integral<Src>::value
&& std::is_integral<Tgt>::value && !std::is_same<Tgt, Src>::value
&& !std::is_same<Tgt, Src>::value, && !std::is_same<Tgt, bool>::value
&& std::is_integral<Tgt>::value,
Tgt>::type Tgt>::type
to(const Src & value) { to(const Src & value) {
/* static */ if (std::numeric_limits<Tgt>::max() /* static */ if (std::numeric_limits<Tgt>::max()
......
...@@ -90,6 +90,9 @@ TEST(Conv, digits10) { ...@@ -90,6 +90,9 @@ TEST(Conv, digits10) {
// Test to<T>(T) // Test to<T>(T)
TEST(Conv, Type2Type) { TEST(Conv, Type2Type) {
bool boolV = true;
EXPECT_EQ(to<bool>(boolV), true);
int intV = 42; int intV = 42;
EXPECT_EQ(to<int>(intV), 42); EXPECT_EQ(to<int>(intV), 42);
...@@ -109,6 +112,7 @@ TEST(Conv, Type2Type) { ...@@ -109,6 +112,7 @@ TEST(Conv, Type2Type) {
EXPECT_EQ(to<folly::StringPiece>(spV), "StringPiece"); EXPECT_EQ(to<folly::StringPiece>(spV), "StringPiece");
// Rvalues // Rvalues
EXPECT_EQ(to<bool>(true), true);
EXPECT_EQ(to<int>(42), 42); EXPECT_EQ(to<int>(42), 42);
EXPECT_EQ(to<float>(4.2f), 4.2f); EXPECT_EQ(to<float>(4.2f), 4.2f);
EXPECT_EQ(to<double>(.42), .42); EXPECT_EQ(to<double>(.42), .42);
...@@ -725,6 +729,17 @@ TEST(Conv, EnumClassToString) { ...@@ -725,6 +729,17 @@ TEST(Conv, EnumClassToString) {
EXPECT_EQ("foo.65", to<string>("foo.", A::z)); EXPECT_EQ("foo.65", to<string>("foo.", A::z));
} }
TEST(Conv, IntegralToBool) {
EXPECT_FALSE(to<bool>(0));
EXPECT_FALSE(to<bool>(0ul));
EXPECT_TRUE(to<bool>(1));
EXPECT_TRUE(to<bool>(1ul));
EXPECT_TRUE(to<bool>(-42));
EXPECT_TRUE(to<bool>(42ul));
}
template<typename Src> template<typename Src>
void testStr2Bool() { void testStr2Bool() {
EXPECT_FALSE(to<bool>(Src("0"))); EXPECT_FALSE(to<bool>(Src("0")));
......
...@@ -150,6 +150,10 @@ TEST(Json, ParseTrailingComma) { ...@@ -150,6 +150,10 @@ TEST(Json, ParseTrailingComma) {
EXPECT_THROW(parseJson("{\"a\":1,}", off), std::runtime_error); EXPECT_THROW(parseJson("{\"a\":1,}", off), std::runtime_error);
} }
TEST(Json, BoolConversion) {
EXPECT_TRUE(parseJson("42").asBool());
}
TEST(Json, JavascriptSafe) { TEST(Json, JavascriptSafe) {
auto badDouble = (1ll << 63ll) + 1; auto badDouble = (1ll << 63ll) + 1;
dynamic badDyn = badDouble; dynamic badDyn = badDouble;
......
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