Export Test - Do Not Merge

Add printer for __{u,}int128_t.

PiperOrigin-RevId: 402417369
This commit is contained in:
Abseil Team 2021-10-11 19:18:01 -04:00 committed by Andy Soffer
parent 83d061af56
commit 291afb8d9c
3 changed files with 69 additions and 0 deletions

View File

@ -477,6 +477,12 @@ inline void PrintTo(char8_t c, ::std::ostream* os) {
} }
#endif #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. // Overloads for C strings.
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
inline void PrintTo(char* s, ::std::ostream* os) { inline void PrintTo(char* s, ::std::ostream* os) {

View File

@ -304,6 +304,51 @@ void PrintTo(char32_t c, ::std::ostream* os) {
<< static_cast<uint32_t>(c); << 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 // Prints the given array of characters to the ostream. CharType must be either
// char, char8_t, char16_t, char32_t, or wchar_t. // char, char8_t, char16_t, char32_t, or wchar_t.
// The array starts at begin, the length is len, it may include '\0' characters // The array starts at begin, the length is len, it may include '\0' characters

View File

@ -449,6 +449,24 @@ TEST(PrintBuiltInTypeTest, Size_t) {
#endif // !GTEST_OS_WINDOWS #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. // Floating-points.
TEST(PrintBuiltInTypeTest, FloatingPoints) { TEST(PrintBuiltInTypeTest, FloatingPoints) {
EXPECT_EQ("1.5", Print(1.5f)); // float EXPECT_EQ("1.5", Print(1.5f)); // float