Skip to content

Commit

Permalink
Support for int128 to string type conversion.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 542269673
Change-Id: Ib6f7e9a57f83d73dd6fb9c45fc9f85ff0fdd75fe
  • Loading branch information
Tsige Solomon authored and Copybara-Service committed Jun 21, 2023
1 parent 166d71d commit 34eb767
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 0 deletions.
1 change: 1 addition & 0 deletions absl/numeric/BUILD.bazel
Expand Up @@ -97,6 +97,7 @@ cc_test(
"//absl/base",
"//absl/hash:hash_testing",
"//absl/meta:type_traits",
"//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
Expand Down
1 change: 1 addition & 0 deletions absl/numeric/CMakeLists.txt
Expand Up @@ -72,6 +72,7 @@ absl_cc_test(
absl::base
absl::hash_testing
absl::type_traits
absl::strings
GTest::gmock_main
)

Expand Down
12 changes: 12 additions & 0 deletions absl/numeric/int128.cc
Expand Up @@ -202,6 +202,10 @@ std::string Uint128ToFormattedString(uint128 v, std::ios_base::fmtflags flags) {

} // namespace

std::string uint128::ToString() const {
return Uint128ToFormattedString(*this, std::ios_base::dec);
}

std::ostream& operator<<(std::ostream& os, uint128 v) {
std::ios_base::fmtflags flags = os.flags();
std::string rep = Uint128ToFormattedString(v, flags);
Expand Down Expand Up @@ -285,6 +289,14 @@ int128 operator%(int128 lhs, int128 rhs) {
}
#endif // ABSL_HAVE_INTRINSIC_INT128

std::string int128::ToString() const {
std::string rep;
if (Int128High64(*this) < 0) rep = "-";
rep.append(Uint128ToFormattedString(UnsignedAbsoluteValue(*this),
std::ios_base::dec));
return rep;
}

std::ostream& operator<<(std::ostream& os, int128 v) {
std::ios_base::fmtflags flags = os.flags();
std::string rep;
Expand Down
17 changes: 17 additions & 0 deletions absl/numeric/int128.h
Expand Up @@ -32,6 +32,7 @@
#include <cstring>
#include <iosfwd>
#include <limits>
#include <string>
#include <utility>

#include "absl/base/config.h"
Expand Down Expand Up @@ -217,9 +218,17 @@ class
return H::combine(std::move(h), Uint128High64(v), Uint128Low64(v));
}

// Support for absl::StrCat() etc.
template <typename Sink>
friend void AbslStringify(Sink& sink, uint128 v) {
sink.Append(v.ToString());
}

private:
constexpr uint128(uint64_t high, uint64_t low);

std::string ToString() const;

// TODO(strel) Update implementation to use __int128 once all users of
// uint128 are fixed to not depend on alignof(uint128) == 8. Also add
// alignas(16) to class definition to keep alignment consistent across
Expand Down Expand Up @@ -454,9 +463,17 @@ class int128 {
return H::combine(std::move(h), Int128High64(v), Int128Low64(v));
}

// Support for absl::StrCat() etc.
template <typename Sink>
friend void AbslStringify(Sink& sink, int128 v) {
sink.Append(v.ToString());
}

private:
constexpr int128(int64_t high, uint64_t low);

std::string ToString() const;

#if defined(ABSL_HAVE_INTRINSIC_INT128)
__int128 v_;
#else // ABSL_HAVE_INTRINSIC_INT128
Expand Down
7 changes: 7 additions & 0 deletions absl/numeric/int128_stream_test.cc
Expand Up @@ -18,6 +18,7 @@
#include <string>

#include "gtest/gtest.h"
#include "absl/strings/str_cat.h"

namespace {

Expand Down Expand Up @@ -87,6 +88,9 @@ constexpr std::ios::fmtflags kBase = std::ios::showbase;
constexpr std::ios::fmtflags kPos = std::ios::showpos;

void CheckUint128Case(const Uint128TestCase& test_case) {
if (test_case.flags == kDec && test_case.width == 0) {
EXPECT_EQ(absl::StrCat(test_case.value), test_case.expected);
}
std::ostringstream os;
os.flags(test_case.flags);
os.width(test_case.width);
Expand Down Expand Up @@ -155,6 +159,9 @@ struct Int128TestCase {
};

void CheckInt128Case(const Int128TestCase& test_case) {
if (test_case.flags == kDec && test_case.width == 0) {
EXPECT_EQ(absl::StrCat(test_case.value), test_case.expected);
}
std::ostringstream os;
os.flags(test_case.flags);
os.width(test_case.width);
Expand Down

0 comments on commit 34eb767

Please sign in to comment.