Make folly's T_CHECK_TIMEOUT/T_CHECK_TIME_LT use SKIP() on failure
[folly.git] / folly / test / ConvTest.cpp
index 04fac62a678f52d8103aba7fa61d9b57ef92fcfa..3cf6d5b8a06e735894bfb5175b6b458dbf8eab01 100644 (file)
 using namespace std;
 using namespace folly;
 
-static int8_t s8;
-static uint8_t u8;
-static int16_t s16;
-static uint16_t u16;
-static int32_t s32;
-static uint32_t u32;
-static int64_t s64;
-static uint64_t u64;
+
+
+TEST(Conv, digits10Minimal) {
+  // Not much of a test (and it's included in the test below anyway).
+  // I just want to inspect the generated assembly for this function.
+  folly::doNotOptimizeAway(digits10(random() * random()));
+}
+
+TEST(Conv, digits10) {
+  char buffer[100];
+  uint64_t power;
+
+  // first, some basic sniff tests
+  EXPECT_EQ( 1, digits10(0));
+  EXPECT_EQ( 1, digits10(1));
+  EXPECT_EQ( 1, digits10(9));
+  EXPECT_EQ( 2, digits10(10));
+  EXPECT_EQ( 2, digits10(99));
+  EXPECT_EQ( 3, digits10(100));
+  EXPECT_EQ( 3, digits10(999));
+  EXPECT_EQ( 4, digits10(1000));
+  EXPECT_EQ( 4, digits10(9999));
+  EXPECT_EQ(20, digits10(18446744073709551615ULL));
+
+  // try the first X nonnegatives.
+  // Covers some more cases of 2^p, 10^p
+  for (uint64_t i = 0; i < 100000; i++) {
+    snprintf(buffer, sizeof(buffer), "%lu", i);
+    EXPECT_EQ(strlen(buffer), digits10(i));
+  }
+
+  // try powers of 2
+  power = 1;
+  for (int p = 0; p < 64; p++) {
+    snprintf(buffer, sizeof(buffer), "%lu", power);
+    EXPECT_EQ(strlen(buffer), digits10(power));
+    snprintf(buffer, sizeof(buffer), "%lu", power - 1);
+    EXPECT_EQ(strlen(buffer), digits10(power - 1));
+    snprintf(buffer, sizeof(buffer), "%lu", power + 1);
+    EXPECT_EQ(strlen(buffer), digits10(power + 1));
+    power *= 2;
+  }
+
+  // try powers of 10
+  power = 1;
+  for (int p = 0; p < 20; p++) {
+    snprintf(buffer, sizeof(buffer), "%lu", power);
+    EXPECT_EQ(strlen(buffer), digits10(power));
+    snprintf(buffer, sizeof(buffer), "%lu", power - 1);
+    EXPECT_EQ(strlen(buffer), digits10(power - 1));
+    snprintf(buffer, sizeof(buffer), "%lu", power + 1);
+    EXPECT_EQ(strlen(buffer), digits10(power + 1));
+    power *= 10;
+  }
+}
 
 // Test to<T>(T)
 TEST(Conv, Type2Type) {
+  bool boolV = true;
+  EXPECT_EQ(to<bool>(boolV), true);
+
   int intV = 42;
   EXPECT_EQ(to<int>(intV), 42);
 
@@ -55,6 +105,7 @@ TEST(Conv, Type2Type) {
   EXPECT_EQ(to<folly::StringPiece>(spV), "StringPiece");
 
   // Rvalues
+  EXPECT_EQ(to<bool>(true), true);
   EXPECT_EQ(to<int>(42), 42);
   EXPECT_EQ(to<float>(4.2f), 4.2f);
   EXPECT_EQ(to<double>(.42), .42);
@@ -66,7 +117,7 @@ TEST(Conv, Type2Type) {
 
 TEST(Conv, Integral2Integral) {
   // Same size, different signs
-  s64 = numeric_limits<uint8_t>::max();
+  int64_t s64 = numeric_limits<uint8_t>::max();
   EXPECT_EQ(to<uint8_t>(s64), s64);
 
   s64 = numeric_limits<int8_t>::max();
@@ -586,6 +637,7 @@ TEST(Conv, DoubleToInt) {
   EXPECT_EQ(i, 42);
   try {
     auto i = to<int>(42.1);
+    LOG(ERROR) << "to<int> returned " << i << " instead of throwing";
     EXPECT_TRUE(false);
   } catch (std::range_error& e) {
     //LOG(INFO) << e.what();
@@ -600,7 +652,9 @@ TEST(Conv, EnumToInt) {
   EXPECT_EQ(j, 42);
   try {
     auto i = to<char>(y);
-    LOG(ERROR) << static_cast<unsigned int>(i);
+    LOG(ERROR) << "to<char> returned "
+               << static_cast<unsigned int>(i)
+               << " instead of throwing";
     EXPECT_TRUE(false);
   } catch (std::range_error& e) {
     //LOG(INFO) << e.what();
@@ -623,6 +677,9 @@ TEST(Conv, IntToEnum) {
   EXPECT_EQ(j, 100);
   try {
     auto i = to<A>(5000000000L);
+    LOG(ERROR) << "to<A> returned "
+               << static_cast<unsigned int>(i)
+               << " instead of throwing";
     EXPECT_TRUE(false);
   } catch (std::range_error& e) {
     //LOG(INFO) << e.what();
@@ -639,15 +696,12 @@ TEST(Conv, UnsignedEnum) {
   EXPECT_EQ(e, x);
   try {
     auto i = to<int32_t>(x);
-    LOG(ERROR) << to<uint32_t>(x);
+    LOG(ERROR) << "to<int32_t> returned " << i << " instead of throwing";
     EXPECT_TRUE(false);
   } catch (std::range_error& e) {
   }
 }
 
-#if defined(__clang__) || __GNUC_PREREQ(4, 7)
-// to<enum class> and to(enum class) only supported in gcc 4.7 onwards
-
 TEST(Conv, UnsignedEnumClass) {
   enum class E : uint32_t { x = 3000000000U };
   auto u = to<uint32_t>(E::x);
@@ -659,7 +713,7 @@ TEST(Conv, UnsignedEnumClass) {
   EXPECT_EQ(e, E::x);
   try {
     auto i = to<int32_t>(E::x);
-    LOG(ERROR) << to<uint32_t>(E::x);
+    LOG(ERROR) << "to<int32_t> returned " << i << " instead of throwing";
     EXPECT_TRUE(false);
   } catch (std::range_error& e) {
   }
@@ -674,7 +728,16 @@ TEST(Conv, EnumClassToString) {
   EXPECT_EQ("foo.65", to<string>("foo.", A::z));
 }
 
-#endif // gcc 4.7 onwards
+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>
 void testStr2Bool() {
@@ -958,6 +1021,22 @@ void u64ToAsciiFollyBM(unsigned int n, uint64_t value) {
   }
 }
 
+// Benchmark unsigned to string conversion
+
+void u64ToStringClibMeasure(unsigned int n, uint64_t value) {
+  // FOLLY_RANGE_CHECK_TO_STRING expands to std::to_string, except on Android
+  // where std::to_string is not supported
+  FOR_EACH_RANGE (i, 0, n) {
+    FOLLY_RANGE_CHECK_TO_STRING(value + n);
+  }
+}
+
+void u64ToStringFollyMeasure(unsigned int n, uint64_t value) {
+  FOR_EACH_RANGE (i, 0, n) {
+    to<std::string>(value + n);
+  }
+}
+
 // Benchmark uitoa with string append
 
 void u2aAppendClassicBM(unsigned int n, uint64_t value) {
@@ -1067,6 +1146,34 @@ DEFINE_BENCHMARK_GROUP(12345678901234567890U);
 
 #undef DEFINE_BENCHMARK_GROUP
 
+#define DEFINE_BENCHMARK_GROUP(n)                        \
+  BENCHMARK_PARAM(u64ToStringClibMeasure, n);            \
+  BENCHMARK_RELATIVE_PARAM(u64ToStringFollyMeasure, n);  \
+  BENCHMARK_DRAW_LINE();
+
+DEFINE_BENCHMARK_GROUP(1);
+DEFINE_BENCHMARK_GROUP(12);
+DEFINE_BENCHMARK_GROUP(123);
+DEFINE_BENCHMARK_GROUP(1234);
+DEFINE_BENCHMARK_GROUP(12345);
+DEFINE_BENCHMARK_GROUP(123456);
+DEFINE_BENCHMARK_GROUP(1234567);
+DEFINE_BENCHMARK_GROUP(12345678);
+DEFINE_BENCHMARK_GROUP(123456789);
+DEFINE_BENCHMARK_GROUP(1234567890);
+DEFINE_BENCHMARK_GROUP(12345678901);
+DEFINE_BENCHMARK_GROUP(123456789012);
+DEFINE_BENCHMARK_GROUP(1234567890123);
+DEFINE_BENCHMARK_GROUP(12345678901234);
+DEFINE_BENCHMARK_GROUP(123456789012345);
+DEFINE_BENCHMARK_GROUP(1234567890123456);
+DEFINE_BENCHMARK_GROUP(12345678901234567);
+DEFINE_BENCHMARK_GROUP(123456789012345678);
+DEFINE_BENCHMARK_GROUP(1234567890123456789);
+DEFINE_BENCHMARK_GROUP(12345678901234567890U);
+
+#undef DEFINE_BENCHMARK_GROUP
+
 #define DEFINE_BENCHMARK_GROUP(n)                       \
   BENCHMARK_PARAM(clibAtoiMeasure, n);                  \
   BENCHMARK_RELATIVE_PARAM(lexicalCastMeasure, n);      \