about summary refs log tree commit diff
path: root/absl/strings/internal
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/internal')
-rw-r--r--absl/strings/internal/str_format/arg.cc12
-rw-r--r--absl/strings/internal/str_format/arg.h4
-rw-r--r--absl/strings/internal/str_format/convert_test.cc37
3 files changed, 52 insertions, 1 deletions
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc
index b40be8ff3824..b567a5c5bcf0 100644
--- a/absl/strings/internal/str_format/arg.cc
+++ b/absl/strings/internal/str_format/arg.cc
@@ -32,6 +32,10 @@ void ReducePadding(size_t n, size_t *capacity) {
 template <typename T>
 struct MakeUnsigned : std::make_unsigned<T> {};
 template <>
+struct MakeUnsigned<absl::int128> {
+  using type = absl::uint128;
+};
+template <>
 struct MakeUnsigned<absl::uint128> {
   using type = absl::uint128;
 };
@@ -39,6 +43,8 @@ struct MakeUnsigned<absl::uint128> {
 template <typename T>
 struct IsSigned : std::is_signed<T> {};
 template <>
+struct IsSigned<absl::int128> : std::true_type {};
+template <>
 struct IsSigned<absl::uint128> : std::false_type {};
 
 class ConvertedIntInfo {
@@ -363,6 +369,11 @@ IntegralConvertResult FormatConvertImpl(unsigned long long v,  // NOLINT
                                         FormatSinkImpl *sink) {
   return {ConvertIntArg(v, conv, sink)};
 }
+IntegralConvertResult FormatConvertImpl(absl::int128 v,
+                                        const ConversionSpec conv,
+                                        FormatSinkImpl *sink) {
+  return {ConvertIntArg(v, conv, sink)};
+}
 IntegralConvertResult FormatConvertImpl(absl::uint128 v,
                                         const ConversionSpec conv,
                                         FormatSinkImpl *sink) {
@@ -372,6 +383,7 @@ IntegralConvertResult FormatConvertImpl(absl::uint128 v,
 ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_();
 
 
+
 }  // namespace str_format_internal
 
 }  // namespace absl
diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h
index 5cb3a14d6833..2119ca0036e5 100644
--- a/absl/strings/internal/str_format/arg.h
+++ b/absl/strings/internal/str_format/arg.h
@@ -144,6 +144,8 @@ IntegralConvertResult FormatConvertImpl(long long v,  // NOLINT
 IntegralConvertResult FormatConvertImpl(unsigned long long v,  // NOLINT
                                         ConversionSpec conv,
                                         FormatSinkImpl* sink);
+IntegralConvertResult FormatConvertImpl(int128 v, ConversionSpec conv,
+                                        FormatSinkImpl* sink);
 IntegralConvertResult FormatConvertImpl(uint128 v, ConversionSpec conv,
                                         FormatSinkImpl* sink);
 template <typename T, enable_if_t<std::is_same<T, bool>::value, int> = 0>
@@ -408,6 +410,7 @@ class FormatArgImpl {
                                              __VA_ARGS__);                     \
   ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(unsigned long long, /* NOLINT */  \
                                              __VA_ARGS__);                     \
+  ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(int128, __VA_ARGS__);             \
   ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(uint128, __VA_ARGS__);            \
   ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(float, __VA_ARGS__);              \
   ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(double, __VA_ARGS__);             \
@@ -418,6 +421,7 @@ class FormatArgImpl {
 
 ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(extern);
 
+
 }  // namespace str_format_internal
 }  // namespace absl
 
diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc
index ab8d53914119..5f198059fe5f 100644
--- a/absl/strings/internal/str_format/convert_test.cc
+++ b/absl/strings/internal/str_format/convert_test.cc
@@ -390,7 +390,6 @@ typedef ::testing::Types<
     AllIntTypes;
 INSTANTIATE_TYPED_TEST_CASE_P(TypedFormatConvertTestWithAllIntTypes,
                               TypedFormatConvertTest, AllIntTypes);
-
 TEST_F(FormatConvertTest, VectorBool) {
   // Make sure vector<bool>'s values behave as bools.
   std::vector<bool> v = {true, false};
@@ -402,6 +401,42 @@ TEST_F(FormatConvertTest, VectorBool) {
                             FormatArgImpl(cv[0]), FormatArgImpl(cv[1])})));
 }
 
+
+TEST_F(FormatConvertTest, Int128) {
+  absl::int128 positive = static_cast<absl::int128>(0x1234567890abcdef) * 1979;
+  absl::int128 negative = -positive;
+  absl::int128 max = absl::Int128Max(), min = absl::Int128Min();
+  const FormatArgImpl args[] = {FormatArgImpl(positive),
+                                FormatArgImpl(negative), FormatArgImpl(max),
+                                FormatArgImpl(min)};
+
+  struct Case {
+    const char* format;
+    const char* expected;
+  } cases[] = {
+      {"%1$d", "2595989796776606496405"},
+      {"%1$30d", "        2595989796776606496405"},
+      {"%1$-30d", "2595989796776606496405        "},
+      {"%1$u", "2595989796776606496405"},
+      {"%1$x", "8cba9876066020f695"},
+      {"%2$d", "-2595989796776606496405"},
+      {"%2$30d", "       -2595989796776606496405"},
+      {"%2$-30d", "-2595989796776606496405       "},
+      {"%2$u", "340282366920938460867384810655161715051"},
+      {"%2$x", "ffffffffffffff73456789f99fdf096b"},
+      {"%3$d", "170141183460469231731687303715884105727"},
+      {"%3$u", "170141183460469231731687303715884105727"},
+      {"%3$x", "7fffffffffffffffffffffffffffffff"},
+      {"%4$d", "-170141183460469231731687303715884105728"},
+      {"%4$x", "80000000000000000000000000000000"},
+  };
+
+  for (auto c : cases) {
+    UntypedFormatSpecImpl format(c.format);
+    EXPECT_EQ(c.expected, FormatPack(format, absl::MakeSpan(args)));
+  }
+}
+
 TEST_F(FormatConvertTest, Uint128) {
   absl::uint128 v = static_cast<absl::uint128>(0x1234567890abcdef) * 1979;
   absl::uint128 max = absl::Uint128Max();