summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2021-10-11 19:18:01 -0400
committerAndy Soffer <asoffer@google.com>2021-10-13 11:09:28 -0400
commit291afb8d9c43572763dbdbab26f200faf413dc20 (patch)
treebbef3ef26a7ec79187a4933c8034309c77fae028
parent83d061af56eab0f030e44557c1db9fcd3d3c21b7 (diff)
downloadgoogletest-git-B4DE7B5F4F45390ABCFB887AFADA9303.tar.gz
Export Test - Do Not MergeB4DE7B5F4F45390ABCFB887AFADA9303
Add printer for __{u,}int128_t. PiperOrigin-RevId: 402417369
-rw-r--r--googletest/include/gtest/gtest-printers.h6
-rw-r--r--googletest/src/gtest-printers.cc45
-rw-r--r--googletest/test/googletest-printers-test.cc18
3 files changed, 69 insertions, 0 deletions
diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h
index 98d04944..a28843d1 100644
--- a/googletest/include/gtest/gtest-printers.h
+++ b/googletest/include/gtest/gtest-printers.h
@@ -477,6 +477,12 @@ inline void PrintTo(char8_t c, ::std::ostream* os) {
}
#endif
+// gcc/clang __{u,}int128_t
+#if defined(__SIZEOF_INT128__)
+GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);
+GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);
+#endif // __SIZEOF_INT128__
+
// Overloads for C strings.
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
inline void PrintTo(char* s, ::std::ostream* os) {
diff --git a/googletest/src/gtest-printers.cc b/googletest/src/gtest-printers.cc
index 41e29ccd..0c80ab7c 100644
--- a/googletest/src/gtest-printers.cc
+++ b/googletest/src/gtest-printers.cc
@@ -304,6 +304,51 @@ void PrintTo(char32_t c, ::std::ostream* os) {
<< static_cast<uint32_t>(c);
}
+// gcc/clang __{u,}int128_t
+#if defined(__SIZEOF_INT128__)
+void PrintTo(__uint128_t v, ::std::ostream* os) {
+ if (v == 0) {
+ *os << "0";
+ return;
+ }
+
+ // Buffer large enough for ceil(log10(2^128))==39 and the null terminator
+ char buf[40];
+ char* p = buf + sizeof(buf);
+
+ // Some configurations have a __uint128_t, but no support for built in
+ // division. Do manual long division instead.
+
+ uint64_t high = static_cast<uint64_t>(v >> 64);
+ uint64_t low = static_cast<uint64_t>(v);
+
+ *--p = 0;
+ while (high != 0 || low != 0) {
+ uint64_t high_mod = high % 10;
+ high = high / 10;
+ // This is the long division algorithm specialized for a divisor of 10 and
+ // only two elements.
+ // Notable values:
+ // 2^64 / 10 == 1844674407370955161
+ // 2^64 % 10 == 6
+ const uint64_t carry = 6 * high_mod + low % 10;
+ low = low / 10 + high_mod * 1844674407370955161 + carry / 10;
+
+ char digit = static_cast<char>(carry % 10);
+ *--p = '0' + digit;
+ }
+ *os << p;
+}
+void PrintTo(__int128_t v, ::std::ostream* os) {
+ __uint128_t uv = static_cast<__uint128_t>(v);
+ if (v < 0) {
+ *os << "-";
+ uv = -uv;
+ }
+ PrintTo(uv, os);
+}
+#endif // __SIZEOF_INT128__
+
// Prints the given array of characters to the ostream. CharType must be either
// char, char8_t, char16_t, char32_t, or wchar_t.
// The array starts at begin, the length is len, it may include '\0' characters
diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc
index 9c9a223a..eb78eabc 100644
--- a/googletest/test/googletest-printers-test.cc
+++ b/googletest/test/googletest-printers-test.cc
@@ -449,6 +449,24 @@ TEST(PrintBuiltInTypeTest, Size_t) {
#endif // !GTEST_OS_WINDOWS
}
+// gcc/clang __{u,}int128_t values.
+#if defined(__SIZEOF_INT128__)
+TEST(PrintBuiltInTypeTest, Int128) {
+ // Small ones
+ EXPECT_EQ("0", Print(__int128_t{0}));
+ EXPECT_EQ("0", Print(__uint128_t{0}));
+ EXPECT_EQ("12345", Print(__int128_t{12345}));
+ EXPECT_EQ("12345", Print(__uint128_t{12345}));
+ EXPECT_EQ("-12345", Print(__int128_t{-12345}));
+
+ // Large ones
+ EXPECT_EQ("340282366920938463463374607431768211455", Print(~__uint128_t{}));
+ __int128_t max_128 = static_cast<__int128_t>(~__uint128_t{} / 2);
+ EXPECT_EQ("-170141183460469231731687303715884105728", Print(~max_128));
+ EXPECT_EQ("170141183460469231731687303715884105727", Print(max_128));
+}
+#endif // __SIZEOF_INT128__
+
// Floating-points.
TEST(PrintBuiltInTypeTest, FloatingPoints) {
EXPECT_EQ("1.5", Print(1.5f)); // float