• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <assert.h>
16 #include <locale.h>
17 #include <stdarg.h>
18 #include <stdio.h>
19 
20 #include <algorithm>
21 #include <climits>
22 #include <cmath>
23 #include <cstdlib>
24 #include <cstring>
25 #include <cwctype>
26 #include <limits>
27 #include <set>
28 #include <sstream>
29 #include <string>
30 #include <thread>  // NOLINT
31 #include <type_traits>
32 #include <vector>
33 
34 #include "gmock/gmock.h"
35 #include "gtest/gtest.h"
36 #include "absl/base/attributes.h"
37 #include "absl/base/internal/raw_logging.h"
38 #include "absl/log/log.h"
39 #include "absl/numeric/int128.h"
40 #include "absl/strings/ascii.h"
41 #include "absl/strings/internal/str_format/arg.h"
42 #include "absl/strings/internal/str_format/bind.h"
43 #include "absl/strings/match.h"
44 #include "absl/strings/str_format.h"
45 #include "absl/strings/string_view.h"
46 #include "absl/types/optional.h"
47 #include "absl/types/span.h"
48 
49 #if defined(ABSL_HAVE_STD_STRING_VIEW)
50 #include <string_view>
51 #endif
52 
53 namespace absl {
54 ABSL_NAMESPACE_BEGIN
55 namespace str_format_internal {
56 namespace {
57 
58 struct NativePrintfTraits {
59   bool hex_float_has_glibc_rounding;
60   bool hex_float_prefers_denormal_repr;
61   bool hex_float_uses_minimal_precision_when_not_specified;
62   bool hex_float_optimizes_leading_digit_bit_count;
63 };
64 
65 template <typename T, size_t N>
ArraySize(T (&)[N])66 size_t ArraySize(T (&)[N]) {
67   return N;
68 }
69 
70 template <typename T>
71 struct AlwaysFalse : std::false_type {};
72 
73 template <typename T>
LengthModFor()74 std::string LengthModFor() {
75   static_assert(AlwaysFalse<T>::value, "Unsupported type");
76   return "";
77 }
78 template <>
LengthModFor()79 std::string LengthModFor<char>() {
80   return "hh";
81 }
82 template <>
LengthModFor()83 std::string LengthModFor<signed char>() {
84   return "hh";
85 }
86 template <>
LengthModFor()87 std::string LengthModFor<unsigned char>() {
88   return "hh";
89 }
90 template <>
LengthModFor()91 std::string LengthModFor<short>() {  // NOLINT
92   return "h";
93 }
94 template <>
LengthModFor()95 std::string LengthModFor<unsigned short>() {  // NOLINT
96   return "h";
97 }
98 template <>
LengthModFor()99 std::string LengthModFor<int>() {
100   return "";
101 }
102 template <>
LengthModFor()103 std::string LengthModFor<unsigned>() {
104   return "";
105 }
106 template <>
LengthModFor()107 std::string LengthModFor<long>() {  // NOLINT
108   return "l";
109 }
110 template <>
LengthModFor()111 std::string LengthModFor<unsigned long>() {  // NOLINT
112   return "l";
113 }
114 template <>
LengthModFor()115 std::string LengthModFor<long long>() {  // NOLINT
116   return "ll";
117 }
118 template <>
LengthModFor()119 std::string LengthModFor<unsigned long long>() {  // NOLINT
120   return "ll";
121 }
122 
123 // An integral type of the same rank and signedness as `wchar_t`, that isn't
124 // `wchar_t`.
125 using IntegralTypeForWCharT =
126     std::conditional_t<std::is_signed<wchar_t>::value,
127                        // Some STLs are broken and return `wchar_t` from
128                        // `std::make_[un]signed_t<wchar_t>` when the signedness
129                        // matches. Work around by round-tripping through the
130                        // opposite signedness.
131                        std::make_signed_t<std::make_unsigned_t<wchar_t>>,
132                        std::make_unsigned_t<std::make_signed_t<wchar_t>>>;
133 
134 // Given an integral type `T`, returns a type of the same rank and signedness
135 // that is guaranteed to not be `wchar_t`.
136 template <typename T>
137 using MatchingIntegralType = std::conditional_t<std::is_same<T, wchar_t>::value,
138                                                 IntegralTypeForWCharT, T>;
139 
EscCharImpl(int v)140 std::string EscCharImpl(int v) {
141   char buf[64];
142   int n = absl::ascii_isprint(static_cast<unsigned char>(v))
143               ? snprintf(buf, sizeof(buf), "'%c'", v)
144               : snprintf(buf, sizeof(buf), "'\\x%.*x'", CHAR_BIT / 4,
145                          static_cast<unsigned>(
146                              static_cast<std::make_unsigned_t<char>>(v)));
147   assert(n > 0 && static_cast<size_t>(n) < sizeof(buf));
148   return std::string(buf, static_cast<size_t>(n));
149 }
150 
Esc(char v)151 std::string Esc(char v) { return EscCharImpl(v); }
Esc(signed char v)152 std::string Esc(signed char v) { return EscCharImpl(v); }
Esc(unsigned char v)153 std::string Esc(unsigned char v) { return EscCharImpl(v); }
154 
Esc(wchar_t v)155 std::string Esc(wchar_t v) {
156   char buf[64];
157   int n = std::iswprint(static_cast<wint_t>(v))
158               ? snprintf(buf, sizeof(buf), "L'%lc'", static_cast<wint_t>(v))
159               : snprintf(buf, sizeof(buf), "L'\\x%.*llx'",
160                          static_cast<int>(sizeof(wchar_t) * CHAR_BIT / 4),
161                          static_cast<unsigned long long>(
162                              static_cast<std::make_unsigned_t<wchar_t>>(v)));
163   assert(n > 0 && static_cast<size_t>(n) < sizeof(buf));
164   return std::string(buf, static_cast<size_t>(n));
165 }
166 
167 template <typename T>
Esc(const T & v)168 std::string Esc(const T &v) {
169   std::ostringstream oss;
170   oss << v;
171   return oss.str();
172 }
173 
StrAppendV(std::string * dst,const char * format,va_list ap)174 void StrAppendV(std::string *dst, const char *format, va_list ap) {
175   // First try with a small fixed size buffer
176   static const int kSpaceLength = 1024;
177   char space[kSpaceLength];
178 
179   // It's possible for methods that use a va_list to invalidate
180   // the data in it upon use.  The fix is to make a copy
181   // of the structure before using it and use that copy instead.
182   va_list backup_ap;
183   va_copy(backup_ap, ap);
184   int result = vsnprintf(space, kSpaceLength, format, backup_ap);
185   va_end(backup_ap);
186   if (result < kSpaceLength) {
187     if (result >= 0) {
188       // Normal case -- everything fit.
189       dst->append(space, static_cast<size_t>(result));
190       return;
191     }
192     if (result < 0) {
193       // Just an error.
194       return;
195     }
196   }
197 
198   // Increase the buffer size to the size requested by vsnprintf,
199   // plus one for the closing \0.
200   size_t length = static_cast<size_t>(result) + 1;
201   char *buf = new char[length];
202 
203   // Restore the va_list before we use it again
204   va_copy(backup_ap, ap);
205   result = vsnprintf(buf, length, format, backup_ap);
206   va_end(backup_ap);
207 
208   if (result >= 0 && static_cast<size_t>(result) < length) {
209     // It fit
210     dst->append(buf, static_cast<size_t>(result));
211   }
212   delete[] buf;
213 }
214 
215 void StrAppend(std::string *, const char *, ...) ABSL_PRINTF_ATTRIBUTE(2, 3);
StrAppend(std::string * out,const char * format,...)216 void StrAppend(std::string *out, const char *format, ...) {
217   va_list ap;
218   va_start(ap, format);
219   StrAppendV(out, format, ap);
220   va_end(ap);
221 }
222 
223 std::string StrPrint(const char *, ...) ABSL_PRINTF_ATTRIBUTE(1, 2);
StrPrint(const char * format,...)224 std::string StrPrint(const char *format, ...) {
225   va_list ap;
226   va_start(ap, format);
227   std::string result;
228   StrAppendV(&result, format, ap);
229   va_end(ap);
230   return result;
231 }
232 
VerifyNativeImplementationImpl()233 NativePrintfTraits VerifyNativeImplementationImpl() {
234   NativePrintfTraits result;
235 
236   // >>> hex_float_has_glibc_rounding. To have glibc's rounding behavior we need
237   // to meet three requirements:
238   //
239   //   - The threshold for rounding up is 8 (for e.g. MSVC uses 9).
240   //   - If the digits lower than than the 8 are non-zero then we round up.
241   //   - If the digits lower than the 8 are all zero then we round toward even.
242   //
243   // The numbers below represent all the cases covering {below,at,above} the
244   // threshold (8) with both {zero,non-zero} lower bits and both {even,odd}
245   // preceding digits.
246   const double d0079 = 65657.0;  // 0x1.0079p+16
247   const double d0179 = 65913.0;  // 0x1.0179p+16
248   const double d0080 = 65664.0;  // 0x1.0080p+16
249   const double d0180 = 65920.0;  // 0x1.0180p+16
250   const double d0081 = 65665.0;  // 0x1.0081p+16
251   const double d0181 = 65921.0;  // 0x1.0181p+16
252   result.hex_float_has_glibc_rounding =
253       StartsWith(StrPrint("%.2a", d0079), "0x1.00") &&
254       StartsWith(StrPrint("%.2a", d0179), "0x1.01") &&
255       StartsWith(StrPrint("%.2a", d0080), "0x1.00") &&
256       StartsWith(StrPrint("%.2a", d0180), "0x1.02") &&
257       StartsWith(StrPrint("%.2a", d0081), "0x1.01") &&
258       StartsWith(StrPrint("%.2a", d0181), "0x1.02");
259 
260   // >>> hex_float_prefers_denormal_repr. Formatting `denormal` on glibc yields
261   // "0x0.0000000000001p-1022", whereas on std libs that don't use denormal
262   // representation it would either be 0x1p-1074 or 0x1.0000000000000-1074.
263   const double denormal = std::numeric_limits<double>::denorm_min();
264   result.hex_float_prefers_denormal_repr =
265       StartsWith(StrPrint("%a", denormal), "0x0.0000000000001");
266 
267   // >>> hex_float_uses_minimal_precision_when_not_specified. Some (non-glibc)
268   // libs will format the following as "0x1.0079000000000p+16".
269   result.hex_float_uses_minimal_precision_when_not_specified =
270       (StrPrint("%a", d0079) == "0x1.0079p+16");
271 
272   // >>> hex_float_optimizes_leading_digit_bit_count. The number 1.5, when
273   // formatted by glibc should yield "0x1.8p+0" for `double` and "0xcp-3" for
274   // `long double`, i.e., number of bits in the leading digit is adapted to the
275   // number of bits in the mantissa.
276   const double d_15 = 1.5;
277   const long double ld_15 = 1.5;
278   result.hex_float_optimizes_leading_digit_bit_count =
279       StartsWith(StrPrint("%a", d_15), "0x1.8") &&
280       StartsWith(StrPrint("%La", ld_15), "0xc");
281 
282   return result;
283 }
284 
VerifyNativeImplementation()285 const NativePrintfTraits &VerifyNativeImplementation() {
286   static NativePrintfTraits native_traits = VerifyNativeImplementationImpl();
287   return native_traits;
288 }
289 
290 class FormatConvertTest : public ::testing::Test { };
291 
292 template <typename T>
TestStringConvert(const T & str)293 void TestStringConvert(const T& str) {
294   const FormatArgImpl args[] = {FormatArgImpl(str)};
295   struct Expectation {
296     const char *out;
297     const char *fmt;
298   };
299   const Expectation kExpect[] = {
300     {"hello",  "%1$s"      },
301     {"",       "%1$.s"     },
302     {"",       "%1$.0s"    },
303     {"h",      "%1$.1s"    },
304     {"he",     "%1$.2s"    },
305     {"hello",  "%1$.10s"   },
306     {" hello", "%1$6s"     },
307     {"   he",  "%1$5.2s"   },
308     {"he   ",  "%1$-5.2s"  },
309     {"hello ", "%1$-6.10s" },
310   };
311   for (const Expectation &e : kExpect) {
312     UntypedFormatSpecImpl format(e.fmt);
313     EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args)));
314   }
315 }
316 
TEST_F(FormatConvertTest,BasicString)317 TEST_F(FormatConvertTest, BasicString) {
318   TestStringConvert("hello");  // As char array.
319   TestStringConvert(L"hello");
320   TestStringConvert(static_cast<const char*>("hello"));
321   TestStringConvert(static_cast<const wchar_t*>(L"hello"));
322   TestStringConvert(std::string("hello"));
323   TestStringConvert(std::wstring(L"hello"));
324   TestStringConvert(string_view("hello"));
325 #if defined(ABSL_HAVE_STD_STRING_VIEW)
326   TestStringConvert(std::string_view("hello"));
327   TestStringConvert(std::wstring_view(L"hello"));
328 #endif  // ABSL_HAVE_STD_STRING_VIEW
329 }
330 
TEST_F(FormatConvertTest,NullString)331 TEST_F(FormatConvertTest, NullString) {
332   const char* p = nullptr;
333   UntypedFormatSpecImpl format("%s");
334   EXPECT_EQ("", FormatPack(format, {FormatArgImpl(p)}));
335 
336   const wchar_t* wp = nullptr;
337   UntypedFormatSpecImpl wformat("%ls");
338   EXPECT_EQ("", FormatPack(wformat, {FormatArgImpl(wp)}));
339 }
340 
TEST_F(FormatConvertTest,StringPrecision)341 TEST_F(FormatConvertTest, StringPrecision) {
342   // We cap at the precision.
343   char c = 'a';
344   const char* p = &c;
345   UntypedFormatSpecImpl format("%.1s");
346   EXPECT_EQ("a", FormatPack(format, {FormatArgImpl(p)}));
347 
348   wchar_t wc = L'a';
349   const wchar_t* wp = &wc;
350   UntypedFormatSpecImpl wformat("%.1ls");
351   EXPECT_EQ("a", FormatPack(wformat, {FormatArgImpl(wp)}));
352 
353   // We cap at the NUL-terminator.
354   p = "ABC";
355   UntypedFormatSpecImpl format2("%.10s");
356   EXPECT_EQ("ABC", FormatPack(format2, {FormatArgImpl(p)}));
357 
358   wp = L"ABC";
359   UntypedFormatSpecImpl wformat2("%.10ls");
360   EXPECT_EQ("ABC", FormatPack(wformat2, {FormatArgImpl(wp)}));
361 }
362 
363 // Pointer formatting is implementation defined. This checks that the argument
364 // can be matched to `ptr`.
365 MATCHER_P(MatchesPointerString, ptr, "") {
366   if (ptr == nullptr && arg == "(nil)") {
367     return true;
368   }
369   void* parsed = nullptr;
370   if (sscanf(arg.c_str(), "%p", &parsed) != 1) {
371     LOG(FATAL) << "Could not parse " << arg;
372   }
373   return ptr == parsed;
374 }
375 
TEST_F(FormatConvertTest,Pointer)376 TEST_F(FormatConvertTest, Pointer) {
377   static int x = 0;
378   const int *xp = &x;
379   char c = 'h';
380   char *mcp = &c;
381   const char *cp = "hi";
382   const char *cnil = nullptr;
383   wchar_t wc = L'h';
384   wchar_t *mwcp = &wc;
385   const wchar_t *wcp = L"hi";
386   const wchar_t *wcnil = nullptr;
387   const int *inil = nullptr;
388   using VoidF = void (*)();
389   VoidF fp = [] {}, fnil = nullptr;
390   volatile char vc;
391   volatile char *vcp = &vc;
392   volatile char *vcnil = nullptr;
393   volatile wchar_t vwc;
394   volatile wchar_t *vwcp = &vwc;
395   volatile wchar_t *vwcnil = nullptr;
396   const FormatArgImpl args_array[] = {
397       FormatArgImpl(xp),    FormatArgImpl(cp),     FormatArgImpl(wcp),
398       FormatArgImpl(inil),  FormatArgImpl(cnil),   FormatArgImpl(wcnil),
399       FormatArgImpl(mcp),   FormatArgImpl(mwcp),   FormatArgImpl(fp),
400       FormatArgImpl(fnil),  FormatArgImpl(vcp),    FormatArgImpl(vwcp),
401       FormatArgImpl(vcnil), FormatArgImpl(vwcnil),
402   };
403   auto args = absl::MakeConstSpan(args_array);
404 
405   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%p"), args),
406               MatchesPointerString(&x));
407   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%20p"), args),
408               MatchesPointerString(&x));
409   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%.1p"), args),
410               MatchesPointerString(&x));
411   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%.20p"), args),
412               MatchesPointerString(&x));
413   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%30.20p"), args),
414               MatchesPointerString(&x));
415 
416   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%-p"), args),
417               MatchesPointerString(&x));
418   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%-20p"), args),
419               MatchesPointerString(&x));
420   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%-.1p"), args),
421               MatchesPointerString(&x));
422   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%.20p"), args),
423               MatchesPointerString(&x));
424   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%-30.20p"), args),
425               MatchesPointerString(&x));
426 
427   // const int*
428   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%1$p"), args),
429               MatchesPointerString(xp));
430   // const char*
431   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%2$p"), args),
432               MatchesPointerString(cp));
433   // const wchar_t*
434   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%3$p"), args),
435               MatchesPointerString(wcp));
436   // null const int*
437   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%4$p"), args),
438               MatchesPointerString(nullptr));
439   // null const char*
440   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%5$p"), args),
441               MatchesPointerString(nullptr));
442   // null const wchar_t*
443   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%6$p"), args),
444               MatchesPointerString(nullptr));
445   // nonconst char*
446   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%7$p"), args),
447               MatchesPointerString(mcp));
448   // nonconst wchar_t*
449   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%8$p"), args),
450               MatchesPointerString(mwcp));
451   // function pointer
452   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%9$p"), args),
453               MatchesPointerString(reinterpret_cast<const void *>(fp)));
454   // null function pointer
455   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%10$p"), args),
456               MatchesPointerString(nullptr));
457   // volatile char*
458   EXPECT_THAT(
459       FormatPack(UntypedFormatSpecImpl("%11$p"), args),
460       MatchesPointerString(reinterpret_cast<volatile const void *>(vcp)));
461   // volatile wchar_t*
462   EXPECT_THAT(
463       FormatPack(UntypedFormatSpecImpl("%12$p"), args),
464       MatchesPointerString(reinterpret_cast<volatile const void *>(vwcp)));
465   // null volatile char*
466   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%13$p"), args),
467               MatchesPointerString(nullptr));
468   // null volatile wchar_t*
469   EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%14$p"), args),
470               MatchesPointerString(nullptr));
471 }
472 
473 struct Cardinal {
474   enum Pos { k1 = 1, k2 = 2, k3 = 3 };
475   enum Neg { kM1 = -1, kM2 = -2, kM3 = -3 };
476 };
477 
TEST_F(FormatConvertTest,Enum)478 TEST_F(FormatConvertTest, Enum) {
479   const Cardinal::Pos k3 = Cardinal::k3;
480   const Cardinal::Neg km3 = Cardinal::kM3;
481   const FormatArgImpl args[] = {FormatArgImpl(k3), FormatArgImpl(km3)};
482   UntypedFormatSpecImpl format("%1$d");
483   UntypedFormatSpecImpl format2("%2$d");
484   EXPECT_EQ("3", FormatPack(format, absl::MakeSpan(args)));
485   EXPECT_EQ("-3", FormatPack(format2, absl::MakeSpan(args)));
486 }
487 
488 template <typename T>
489 class TypedFormatConvertTest : public FormatConvertTest { };
490 
491 TYPED_TEST_SUITE_P(TypedFormatConvertTest);
492 
AllFlagCombinations()493 std::vector<std::string> AllFlagCombinations() {
494   const char kFlags[] = {'-', '#', '0', '+', ' '};
495   std::vector<std::string> result;
496   for (size_t fsi = 0; fsi < (1ull << ArraySize(kFlags)); ++fsi) {
497     std::string flag_set;
498     for (size_t fi = 0; fi < ArraySize(kFlags); ++fi)
499       if (fsi & (1ull << fi))
500         flag_set += kFlags[fi];
501     result.push_back(flag_set);
502   }
503   return result;
504 }
505 
TYPED_TEST_P(TypedFormatConvertTest,AllIntsWithFlags)506 TYPED_TEST_P(TypedFormatConvertTest, AllIntsWithFlags) {
507   typedef TypeParam T;
508   typedef typename std::make_unsigned<T>::type UnsignedT;
509   using remove_volatile_t = typename std::remove_volatile<T>::type;
510   const T kMin = std::numeric_limits<remove_volatile_t>::min();
511   const T kMax = std::numeric_limits<remove_volatile_t>::max();
512   const T kVals[] = {
513       remove_volatile_t(1),
514       remove_volatile_t(2),
515       remove_volatile_t(3),
516       remove_volatile_t(123),
517       remove_volatile_t(-1),
518       remove_volatile_t(-2),
519       remove_volatile_t(-3),
520       remove_volatile_t(-123),
521       remove_volatile_t(0),
522       kMax - remove_volatile_t(1),
523       kMax,
524       kMin + remove_volatile_t(1),
525       kMin,
526   };
527   const char kConvChars[] = {'d', 'i', 'u', 'o', 'x', 'X'};
528   const std::string kWid[] = {"", "4", "10"};
529   const std::string kPrec[] = {"", ".", ".0", ".4", ".10"};
530 
531   const std::vector<std::string> flag_sets = AllFlagCombinations();
532 
533   for (size_t vi = 0; vi < ArraySize(kVals); ++vi) {
534     const T val = kVals[vi];
535     SCOPED_TRACE(Esc(val));
536     const FormatArgImpl args[] = {FormatArgImpl(val)};
537     for (size_t ci = 0; ci < ArraySize(kConvChars); ++ci) {
538       const char conv_char = kConvChars[ci];
539       for (size_t fsi = 0; fsi < flag_sets.size(); ++fsi) {
540         const std::string &flag_set = flag_sets[fsi];
541         for (size_t wi = 0; wi < ArraySize(kWid); ++wi) {
542           const std::string &wid = kWid[wi];
543           for (size_t pi = 0; pi < ArraySize(kPrec); ++pi) {
544             const std::string &prec = kPrec[pi];
545 
546             const bool is_signed_conv = (conv_char == 'd' || conv_char == 'i');
547             const bool is_unsigned_to_signed =
548                 !std::is_signed<T>::value && is_signed_conv;
549             // Don't consider sign-related flags '+' and ' ' when doing
550             // unsigned to signed conversions.
551             if (is_unsigned_to_signed &&
552                 flag_set.find_first_of("+ ") != std::string::npos) {
553               continue;
554             }
555 
556             std::string new_fmt("%");
557             new_fmt += flag_set;
558             new_fmt += wid;
559             new_fmt += prec;
560             // old and new always agree up to here.
561             std::string old_fmt = new_fmt;
562             new_fmt += conv_char;
563             std::string old_result;
564             if (is_unsigned_to_signed) {
565               // don't expect agreement on unsigned formatted as signed,
566               // as printf can't do that conversion properly. For those
567               // cases, we do expect agreement with printf with a "%u"
568               // and the unsigned equivalent of 'val'.
569               UnsignedT uval =
570                   static_cast<std::remove_volatile_t<UnsignedT>>(val);
571               old_fmt += LengthModFor<
572                   MatchingIntegralType<std::remove_cv_t<decltype(uval)>>>();
573               old_fmt += "u";
574               old_result = StrPrint(old_fmt.c_str(), uval);
575             } else {
576               old_fmt += LengthModFor<
577                   MatchingIntegralType<std::remove_cv_t<decltype(val)>>>();
578               old_fmt += conv_char;
579               old_result = StrPrint(old_fmt.c_str(), val);
580             }
581 
582             SCOPED_TRACE(std::string() + " old_fmt: \"" + old_fmt +
583                          "\"'"
584                          " new_fmt: \"" +
585                          new_fmt + "\"");
586             UntypedFormatSpecImpl format(new_fmt);
587             EXPECT_EQ(old_result, FormatPack(format, absl::MakeSpan(args)));
588           }
589         }
590       }
591     }
592   }
593 }
594 
595 template <typename T>
StrPrintChar(T c)596 absl::optional<std::string> StrPrintChar(T c) {
597   return StrPrint("%c", static_cast<int>(c));
598 }
599 template <>
StrPrintChar(wchar_t c)600 absl::optional<std::string> StrPrintChar(wchar_t c) {
601   // musl libc has a bug where ("%lc", 0) writes no characters, and Android
602   // doesn't support forcing UTF-8 via setlocale(). Hardcode the expected
603   // answers for ASCII inputs to maximize test coverage on these platforms.
604   if (static_cast<std::make_unsigned_t<wchar_t>>(c) < 0x80) {
605     return std::string(1, static_cast<char>(c));
606   }
607 
608   // Force a UTF-8 locale to match the expected `StrFormat()` behavior.
609   // It's important to copy the string returned by `old_locale` here, because
610   // its contents are not guaranteed to be valid after the next `setlocale()`
611   // call.
612   std::string old_locale = setlocale(LC_CTYPE, nullptr);
613   if (!setlocale(LC_CTYPE, "en_US.UTF-8")) {
614     return absl::nullopt;
615   }
616   const std::string output = StrPrint("%lc", static_cast<wint_t>(c));
617   setlocale(LC_CTYPE, old_locale.c_str());
618   return output;
619 }
620 
621 template <typename T>
GetMaxForConversion()622 typename std::remove_volatile<T>::type GetMaxForConversion() {
623   return static_cast<typename std::remove_volatile<T>::type>(
624       std::numeric_limits<int>::max());
625 }
626 
627 template <>
GetMaxForConversion()628 wchar_t GetMaxForConversion<wchar_t>() {
629   // Don't return values that aren't legal Unicode. For wchar_t conversions in a
630   // UTF-8 locale, conversion behavior for such values is unspecified, and we
631   // don't care about matching it.
632   return (sizeof(wchar_t) * CHAR_BIT <= 16) ? wchar_t{0xffff}
633                                             : static_cast<wchar_t>(0x10ffff);
634 }
635 
TYPED_TEST_P(TypedFormatConvertTest,Char)636 TYPED_TEST_P(TypedFormatConvertTest, Char) {
637   // Pass a bunch of values of type TypeParam to both FormatPack and libc's
638   // vsnprintf("%c", ...) (wrapped in StrPrint) to make sure we get the same
639   // value.
640   typedef TypeParam T;
641   using remove_volatile_t = typename std::remove_volatile<T>::type;
642   std::vector<remove_volatile_t> vals = {
643       remove_volatile_t(1),  remove_volatile_t(2),  remove_volatile_t(10),   //
644       remove_volatile_t(-1), remove_volatile_t(-2), remove_volatile_t(-10),  //
645       remove_volatile_t(0),
646   };
647 
648   // We'd like to test values near std::numeric_limits::min() and
649   // std::numeric_limits::max(), too, but vsnprintf("%c", ...) can't handle
650   // anything larger than an int. Add in the most extreme values we can without
651   // exceeding that range.
652   // Special case: Formatting a wchar_t should behave like vsnprintf("%lc").
653   // Technically vsnprintf can accept a wint_t in this case, but since we must
654   // pass a wchar_t to FormatPack, the largest type we can use here is wchar_t.
655   using ArgType =
656       std::conditional_t<std::is_same<T, wchar_t>::value, wchar_t, int>;
657   static const T kMin =
658       static_cast<remove_volatile_t>(std::numeric_limits<ArgType>::min());
659   static const T kMax = GetMaxForConversion<T>();
660   vals.insert(vals.end(), {static_cast<remove_volatile_t>(kMin + 1), kMin,
661                            static_cast<remove_volatile_t>(kMax - 1), kMax});
662 
663   static const auto kMaxWCharT =
664       static_cast<remove_volatile_t>(GetMaxForConversion<wchar_t>());
665   for (const T c : vals) {
666     SCOPED_TRACE(Esc(c));
667     const FormatArgImpl args[] = {FormatArgImpl(c)};
668     UntypedFormatSpecImpl format("%c");
669     absl::optional<std::string> result = StrPrintChar(c);
670     if (result.has_value()) {
671       EXPECT_EQ(result.value(), FormatPack(format, absl::MakeSpan(args)));
672     }
673 
674     // Also test that if the format specifier is "%lc", the argument is treated
675     // as if it's a `wchar_t`.
676     const T wc =
677         std::max(remove_volatile_t{0},
678                  std::min(static_cast<remove_volatile_t>(c), kMaxWCharT));
679     SCOPED_TRACE(Esc(wc));
680     const FormatArgImpl wide_args[] = {FormatArgImpl(wc)};
681     UntypedFormatSpecImpl wide_format("%lc");
682     result = StrPrintChar(static_cast<wchar_t>(wc));
683     if (result.has_value()) {
684       EXPECT_EQ(result.value(),
685                 FormatPack(wide_format, absl::MakeSpan(wide_args)));
686     }
687   }
688 }
689 
690 REGISTER_TYPED_TEST_SUITE_P(TypedFormatConvertTest, AllIntsWithFlags, Char);
691 
692 typedef ::testing::Types<int, unsigned, volatile int, short,   // NOLINT
693                          unsigned short, long, unsigned long,  // NOLINT
694                          long long, unsigned long long,        // NOLINT
695                          signed char, unsigned char, char, wchar_t>
696     AllIntTypes;
697 INSTANTIATE_TYPED_TEST_SUITE_P(TypedFormatConvertTestWithAllIntTypes,
698                                TypedFormatConvertTest, AllIntTypes);
TEST_F(FormatConvertTest,VectorBool)699 TEST_F(FormatConvertTest, VectorBool) {
700   // Make sure vector<bool>'s values behave as bools.
701   std::vector<bool> v = {true, false};
702   const std::vector<bool> cv = {true, false};
703   EXPECT_EQ("1,0,1,0",
704             FormatPack(UntypedFormatSpecImpl("%d,%d,%d,%d"),
705                        absl::Span<const FormatArgImpl>(
706                            {FormatArgImpl(v[0]), FormatArgImpl(v[1]),
707                             FormatArgImpl(cv[0]), FormatArgImpl(cv[1])})));
708 }
709 
TEST_F(FormatConvertTest,UnicodeWideString)710 TEST_F(FormatConvertTest, UnicodeWideString) {
711   // StrFormat() should be able to convert wide strings containing Unicode
712   // characters (to UTF-8).
713   const FormatArgImpl args[] = {FormatArgImpl(L"\u47e3 \U00011112")};
714   // `u8""` forces UTF-8 encoding; MSVC will default to e.g. CP1252 (and warn)
715   // without it. However, the resulting character type differs between pre-C++20
716   // (`char`) and C++20 (`char8_t`). So deduce the right character type for all
717   // C++ versions, init it with UTF-8, then `memcpy()` to get the result as a
718   // `char*`.
719   using ConstChar8T = std::remove_reference_t<decltype(*u8"a")>;
720   ConstChar8T kOutputUtf8[] = u8"\u47e3 \U00011112";
721   char output[sizeof kOutputUtf8];
722   std::memcpy(output, kOutputUtf8, sizeof kOutputUtf8);
723   EXPECT_EQ(output,
724             FormatPack(UntypedFormatSpecImpl("%ls"), absl::MakeSpan(args)));
725 }
726 
TEST_F(FormatConvertTest,Int128)727 TEST_F(FormatConvertTest, Int128) {
728   absl::int128 positive = static_cast<absl::int128>(0x1234567890abcdef) * 1979;
729   absl::int128 negative = -positive;
730   absl::int128 max = absl::Int128Max(), min = absl::Int128Min();
731   const FormatArgImpl args[] = {FormatArgImpl(positive),
732                                 FormatArgImpl(negative), FormatArgImpl(max),
733                                 FormatArgImpl(min)};
734 
735   struct Case {
736     const char* format;
737     const char* expected;
738   } cases[] = {
739       {"%1$d", "2595989796776606496405"},
740       {"%1$30d", "        2595989796776606496405"},
741       {"%1$-30d", "2595989796776606496405        "},
742       {"%1$u", "2595989796776606496405"},
743       {"%1$x", "8cba9876066020f695"},
744       {"%2$d", "-2595989796776606496405"},
745       {"%2$30d", "       -2595989796776606496405"},
746       {"%2$-30d", "-2595989796776606496405       "},
747       {"%2$u", "340282366920938460867384810655161715051"},
748       {"%2$x", "ffffffffffffff73456789f99fdf096b"},
749       {"%3$d", "170141183460469231731687303715884105727"},
750       {"%3$u", "170141183460469231731687303715884105727"},
751       {"%3$x", "7fffffffffffffffffffffffffffffff"},
752       {"%4$d", "-170141183460469231731687303715884105728"},
753       {"%4$x", "80000000000000000000000000000000"},
754   };
755 
756   for (auto c : cases) {
757     UntypedFormatSpecImpl format(c.format);
758     EXPECT_EQ(c.expected, FormatPack(format, absl::MakeSpan(args)));
759   }
760 }
761 
TEST_F(FormatConvertTest,Uint128)762 TEST_F(FormatConvertTest, Uint128) {
763   absl::uint128 v = static_cast<absl::uint128>(0x1234567890abcdef) * 1979;
764   absl::uint128 max = absl::Uint128Max();
765   const FormatArgImpl args[] = {FormatArgImpl(v), FormatArgImpl(max)};
766 
767   struct Case {
768     const char* format;
769     const char* expected;
770   } cases[] = {
771       {"%1$d", "2595989796776606496405"},
772       {"%1$30d", "        2595989796776606496405"},
773       {"%1$-30d", "2595989796776606496405        "},
774       {"%1$u", "2595989796776606496405"},
775       {"%1$x", "8cba9876066020f695"},
776       {"%2$d", "340282366920938463463374607431768211455"},
777       {"%2$u", "340282366920938463463374607431768211455"},
778       {"%2$x", "ffffffffffffffffffffffffffffffff"},
779   };
780 
781   for (auto c : cases) {
782     UntypedFormatSpecImpl format(c.format);
783     EXPECT_EQ(c.expected, FormatPack(format, absl::MakeSpan(args)));
784   }
785 }
786 
787 template <typename Floating>
TestWithMultipleFormatsHelper(const std::vector<Floating> & floats,const std::set<Floating> & skip_verify)788 void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats,
789                                    const std::set<Floating> &skip_verify) {
790   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
791   // Reserve the space to ensure we don't allocate memory in the output itself.
792   std::string str_format_result;
793   str_format_result.reserve(1 << 20);
794   std::string string_printf_result;
795   string_printf_result.reserve(1 << 20);
796 
797   const char *const kFormats[] = {
798       "%",  "%.3", "%8.5", "%500",   "%.5000", "%.60", "%.30",   "%03",
799       "%+", "% ",  "%-10", "%#15.3", "%#.0",   "%.0",  "%1$*2$", "%1$.*2$"};
800 
801   for (const char *fmt : kFormats) {
802     for (char f : {'f', 'F',  //
803                    'g', 'G',  //
804                    'a', 'A',  //
805                    'e', 'E'}) {
806       std::string fmt_str = std::string(fmt) + f;
807 
808       if (fmt == absl::string_view("%.5000") && f != 'f' && f != 'F' &&
809           f != 'a' && f != 'A') {
810         // This particular test takes way too long with snprintf.
811         // Disable for the case we are not implementing natively.
812         continue;
813       }
814 
815       if ((f == 'a' || f == 'A') &&
816           !native_traits.hex_float_has_glibc_rounding) {
817         continue;
818       }
819 
820       for (Floating d : floats) {
821         if (!native_traits.hex_float_prefers_denormal_repr &&
822             (f == 'a' || f == 'A') && std::fpclassify(d) == FP_SUBNORMAL) {
823           continue;
824         }
825         int i = -10;
826         FormatArgImpl args[2] = {FormatArgImpl(d), FormatArgImpl(i)};
827         UntypedFormatSpecImpl format(fmt_str);
828 
829         string_printf_result.clear();
830         StrAppend(&string_printf_result, fmt_str.c_str(), d, i);
831         str_format_result.clear();
832 
833         {
834           AppendPack(&str_format_result, format, absl::MakeSpan(args));
835         }
836 
837 #ifdef _MSC_VER
838         // MSVC has a different rounding policy than us so we can't test our
839         // implementation against the native one there.
840         continue;
841 #elif defined(__APPLE__)
842         // Apple formats NaN differently (+nan) vs. (nan)
843         if (std::isnan(d)) continue;
844 #endif
845         if (string_printf_result != str_format_result &&
846             skip_verify.find(d) == skip_verify.end()) {
847           // We use ASSERT_EQ here because failures are usually correlated and a
848           // bug would print way too many failed expectations causing the test
849           // to time out.
850           ASSERT_EQ(string_printf_result, str_format_result)
851               << fmt_str << " " << StrPrint("%.18g", d) << " "
852               << StrPrint("%a", d) << " " << StrPrint("%.50f", d);
853         }
854       }
855     }
856   }
857 }
858 
TEST_F(FormatConvertTest,Float)859 TEST_F(FormatConvertTest, Float) {
860   std::vector<float> floats = {0.0f,
861                                -0.0f,
862                                .9999999f,
863                                9999999.f,
864                                std::numeric_limits<float>::max(),
865                                -std::numeric_limits<float>::max(),
866                                std::numeric_limits<float>::min(),
867                                -std::numeric_limits<float>::min(),
868                                std::numeric_limits<float>::lowest(),
869                                -std::numeric_limits<float>::lowest(),
870                                std::numeric_limits<float>::epsilon(),
871                                std::numeric_limits<float>::epsilon() + 1.0f,
872                                std::numeric_limits<float>::infinity(),
873                                -std::numeric_limits<float>::infinity(),
874                                std::nanf("")};
875 
876   // Some regression tests.
877   floats.push_back(0.999999989f);
878 
879   if (std::numeric_limits<float>::has_denorm != std::denorm_absent) {
880     floats.push_back(std::numeric_limits<float>::denorm_min());
881     floats.push_back(-std::numeric_limits<float>::denorm_min());
882   }
883 
884   for (float base :
885        {1.f, 12.f, 123.f, 1234.f, 12345.f, 123456.f, 1234567.f, 12345678.f,
886         123456789.f, 1234567890.f, 12345678901.f, 12345678.f, 12345678.f}) {
887     for (int exp = -123; exp <= 123; ++exp) {
888       for (int sign : {1, -1}) {
889         floats.push_back(sign * std::ldexp(base, exp));
890       }
891     }
892   }
893 
894   for (int exp = -300; exp <= 300; ++exp) {
895     const float all_ones_mantissa = 0xffffff;
896     floats.push_back(std::ldexp(all_ones_mantissa, exp));
897   }
898 
899   // Remove duplicates to speed up the logic below.
900   std::sort(floats.begin(), floats.end(), [](const float a, const float b) {
901     if (std::isnan(a)) return false;
902     if (std::isnan(b)) return true;
903     return a < b;
904   });
905   floats.erase(std::unique(floats.begin(), floats.end()), floats.end());
906 
907   TestWithMultipleFormatsHelper(floats, {});
908 }
909 
TEST_F(FormatConvertTest,Double)910 TEST_F(FormatConvertTest, Double) {
911   // For values that we know won't match the standard library implementation we
912   // skip verification, but still run the algorithm to catch asserts/sanitizer
913   // bugs.
914   std::set<double> skip_verify;
915   std::vector<double> doubles = {0.0,
916                                  -0.0,
917                                  .99999999999999,
918                                  99999999999999.,
919                                  std::numeric_limits<double>::max(),
920                                  -std::numeric_limits<double>::max(),
921                                  std::numeric_limits<double>::min(),
922                                  -std::numeric_limits<double>::min(),
923                                  std::numeric_limits<double>::lowest(),
924                                  -std::numeric_limits<double>::lowest(),
925                                  std::numeric_limits<double>::epsilon(),
926                                  std::numeric_limits<double>::epsilon() + 1,
927                                  std::numeric_limits<double>::infinity(),
928                                  -std::numeric_limits<double>::infinity(),
929                                  std::nan("")};
930 
931   // Some regression tests.
932   doubles.push_back(0.99999999999999989);
933 
934   if (std::numeric_limits<double>::has_denorm != std::denorm_absent) {
935     doubles.push_back(std::numeric_limits<double>::denorm_min());
936     doubles.push_back(-std::numeric_limits<double>::denorm_min());
937   }
938 
939   for (double base :
940        {1., 12., 123., 1234., 12345., 123456., 1234567., 12345678., 123456789.,
941         1234567890., 12345678901., 123456789012., 1234567890123.}) {
942     for (int exp = -123; exp <= 123; ++exp) {
943       for (int sign : {1, -1}) {
944         doubles.push_back(sign * std::ldexp(base, exp));
945       }
946     }
947   }
948 
949   // Workaround libc bug.
950   // https://sourceware.org/bugzilla/show_bug.cgi?id=22142
951   const bool gcc_bug_22142 =
952       StrPrint("%f", std::numeric_limits<double>::max()) !=
953       "1797693134862315708145274237317043567980705675258449965989174768031"
954       "5726078002853876058955863276687817154045895351438246423432132688946"
955       "4182768467546703537516986049910576551282076245490090389328944075868"
956       "5084551339423045832369032229481658085593321233482747978262041447231"
957       "68738177180919299881250404026184124858368.000000";
958 
959   for (int exp = -300; exp <= 300; ++exp) {
960     const double all_ones_mantissa = 0x1fffffffffffff;
961     doubles.push_back(std::ldexp(all_ones_mantissa, exp));
962     if (gcc_bug_22142) {
963       skip_verify.insert(doubles.back());
964     }
965   }
966 
967   if (gcc_bug_22142) {
968     using L = std::numeric_limits<double>;
969     skip_verify.insert(L::max());
970     skip_verify.insert(L::min());  // NOLINT
971     skip_verify.insert(L::denorm_min());
972     skip_verify.insert(-L::max());
973     skip_verify.insert(-L::min());  // NOLINT
974     skip_verify.insert(-L::denorm_min());
975   }
976 
977   // Remove duplicates to speed up the logic below.
978   std::sort(doubles.begin(), doubles.end(), [](const double a, const double b) {
979     if (std::isnan(a)) return false;
980     if (std::isnan(b)) return true;
981     return a < b;
982   });
983   doubles.erase(std::unique(doubles.begin(), doubles.end()), doubles.end());
984 
985   TestWithMultipleFormatsHelper(doubles, skip_verify);
986 }
987 
TEST_F(FormatConvertTest,DoubleRound)988 TEST_F(FormatConvertTest, DoubleRound) {
989   std::string s;
990   const auto format = [&](const char *fmt, double d) -> std::string & {
991     s.clear();
992     FormatArgImpl args[1] = {FormatArgImpl(d)};
993     AppendPack(&s, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
994 #if !defined(_MSC_VER)
995     // MSVC has a different rounding policy than us so we can't test our
996     // implementation against the native one there.
997     EXPECT_EQ(StrPrint(fmt, d), s);
998 #endif  // _MSC_VER
999 
1000     return s;
1001   };
1002   // All of these values have to be exactly represented.
1003   // Otherwise we might not be testing what we think we are testing.
1004 
1005   // These values can fit in a 64bit "fast" representation.
1006   const double exact_value = 0.00000000000005684341886080801486968994140625;
1007   assert(exact_value == std::pow(2, -44));
1008   // Round up at a 5xx.
1009   EXPECT_EQ(format("%.13f", exact_value), "0.0000000000001");
1010   // Round up at a >5
1011   EXPECT_EQ(format("%.14f", exact_value), "0.00000000000006");
1012   // Round down at a <5
1013   EXPECT_EQ(format("%.16f", exact_value), "0.0000000000000568");
1014   // Nine handling
1015   EXPECT_EQ(format("%.35f", exact_value),
1016             "0.00000000000005684341886080801486969");
1017   EXPECT_EQ(format("%.36f", exact_value),
1018             "0.000000000000056843418860808014869690");
1019   // Round down the last nine.
1020   EXPECT_EQ(format("%.37f", exact_value),
1021             "0.0000000000000568434188608080148696899");
1022   EXPECT_EQ(format("%.10f", 0.000003814697265625), "0.0000038147");
1023   // Round up the last nine
1024   EXPECT_EQ(format("%.11f", 0.000003814697265625), "0.00000381470");
1025   EXPECT_EQ(format("%.12f", 0.000003814697265625), "0.000003814697");
1026 
1027   // Round to even (down)
1028   EXPECT_EQ(format("%.43f", exact_value),
1029             "0.0000000000000568434188608080148696899414062");
1030   // Exact
1031   EXPECT_EQ(format("%.44f", exact_value),
1032             "0.00000000000005684341886080801486968994140625");
1033   // Round to even (up), let make the last digits 75 instead of 25
1034   EXPECT_EQ(format("%.43f", exact_value + std::pow(2, -43)),
1035             "0.0000000000001705302565824240446090698242188");
1036   // Exact, just to check.
1037   EXPECT_EQ(format("%.44f", exact_value + std::pow(2, -43)),
1038             "0.00000000000017053025658242404460906982421875");
1039 
1040   // This value has to be small enough that it won't fit in the uint128
1041   // representation for printing.
1042   const double small_exact_value =
1043       0.000000000000000000000000000000000000752316384526264005099991383822237233803945956334136013765601092018187046051025390625;  // NOLINT
1044   assert(small_exact_value == std::pow(2, -120));
1045   // Round up at a 5xx.
1046   EXPECT_EQ(format("%.37f", small_exact_value),
1047             "0.0000000000000000000000000000000000008");
1048   // Round down at a <5
1049   EXPECT_EQ(format("%.38f", small_exact_value),
1050             "0.00000000000000000000000000000000000075");
1051   // Round up at a >5
1052   EXPECT_EQ(format("%.41f", small_exact_value),
1053             "0.00000000000000000000000000000000000075232");
1054   // Nine handling
1055   EXPECT_EQ(format("%.55f", small_exact_value),
1056             "0.0000000000000000000000000000000000007523163845262640051");
1057   EXPECT_EQ(format("%.56f", small_exact_value),
1058             "0.00000000000000000000000000000000000075231638452626400510");
1059   EXPECT_EQ(format("%.57f", small_exact_value),
1060             "0.000000000000000000000000000000000000752316384526264005100");
1061   EXPECT_EQ(format("%.58f", small_exact_value),
1062             "0.0000000000000000000000000000000000007523163845262640051000");
1063   // Round down the last nine
1064   EXPECT_EQ(format("%.59f", small_exact_value),
1065             "0.00000000000000000000000000000000000075231638452626400509999");
1066   // Round up the last nine
1067   EXPECT_EQ(format("%.79f", small_exact_value),
1068             "0.000000000000000000000000000000000000"
1069             "7523163845262640050999913838222372338039460");
1070 
1071   // Round to even (down)
1072   EXPECT_EQ(format("%.119f", small_exact_value),
1073             "0.000000000000000000000000000000000000"
1074             "75231638452626400509999138382223723380"
1075             "394595633413601376560109201818704605102539062");
1076   // Exact
1077   EXPECT_EQ(format("%.120f", small_exact_value),
1078             "0.000000000000000000000000000000000000"
1079             "75231638452626400509999138382223723380"
1080             "3945956334136013765601092018187046051025390625");
1081   // Round to even (up), let make the last digits 75 instead of 25
1082   EXPECT_EQ(format("%.119f", small_exact_value + std::pow(2, -119)),
1083             "0.000000000000000000000000000000000002"
1084             "25694915357879201529997415146671170141"
1085             "183786900240804129680327605456113815307617188");
1086   // Exact, just to check.
1087   EXPECT_EQ(format("%.120f", small_exact_value + std::pow(2, -119)),
1088             "0.000000000000000000000000000000000002"
1089             "25694915357879201529997415146671170141"
1090             "1837869002408041296803276054561138153076171875");
1091 }
1092 
TEST_F(FormatConvertTest,DoubleRoundA)1093 TEST_F(FormatConvertTest, DoubleRoundA) {
1094   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
1095   std::string s;
1096   const auto format = [&](const char *fmt, double d) -> std::string & {
1097     s.clear();
1098     FormatArgImpl args[1] = {FormatArgImpl(d)};
1099     AppendPack(&s, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
1100     if (native_traits.hex_float_has_glibc_rounding) {
1101       EXPECT_EQ(StrPrint(fmt, d), s);
1102     }
1103     return s;
1104   };
1105 
1106   // 0x1.00018000p+100
1107   const double on_boundary_odd = 1267679614447900152596896153600.0;
1108   EXPECT_EQ(format("%.0a", on_boundary_odd), "0x1p+100");
1109   EXPECT_EQ(format("%.1a", on_boundary_odd), "0x1.0p+100");
1110   EXPECT_EQ(format("%.2a", on_boundary_odd), "0x1.00p+100");
1111   EXPECT_EQ(format("%.3a", on_boundary_odd), "0x1.000p+100");
1112   EXPECT_EQ(format("%.4a", on_boundary_odd), "0x1.0002p+100");  // round
1113   EXPECT_EQ(format("%.5a", on_boundary_odd), "0x1.00018p+100");
1114   EXPECT_EQ(format("%.6a", on_boundary_odd), "0x1.000180p+100");
1115 
1116   // 0x1.00028000p-2
1117   const double on_boundary_even = 0.250009536743164062500;
1118   EXPECT_EQ(format("%.0a", on_boundary_even), "0x1p-2");
1119   EXPECT_EQ(format("%.1a", on_boundary_even), "0x1.0p-2");
1120   EXPECT_EQ(format("%.2a", on_boundary_even), "0x1.00p-2");
1121   EXPECT_EQ(format("%.3a", on_boundary_even), "0x1.000p-2");
1122   EXPECT_EQ(format("%.4a", on_boundary_even), "0x1.0002p-2");  // no round
1123   EXPECT_EQ(format("%.5a", on_boundary_even), "0x1.00028p-2");
1124   EXPECT_EQ(format("%.6a", on_boundary_even), "0x1.000280p-2");
1125 
1126   // 0x1.00018001p+1
1127   const double slightly_over = 2.00004577683284878730773925781250;
1128   EXPECT_EQ(format("%.0a", slightly_over), "0x1p+1");
1129   EXPECT_EQ(format("%.1a", slightly_over), "0x1.0p+1");
1130   EXPECT_EQ(format("%.2a", slightly_over), "0x1.00p+1");
1131   EXPECT_EQ(format("%.3a", slightly_over), "0x1.000p+1");
1132   EXPECT_EQ(format("%.4a", slightly_over), "0x1.0002p+1");
1133   EXPECT_EQ(format("%.5a", slightly_over), "0x1.00018p+1");
1134   EXPECT_EQ(format("%.6a", slightly_over), "0x1.000180p+1");
1135 
1136   // 0x1.00017fffp+0
1137   const double slightly_under = 1.000022887950763106346130371093750;
1138   EXPECT_EQ(format("%.0a", slightly_under), "0x1p+0");
1139   EXPECT_EQ(format("%.1a", slightly_under), "0x1.0p+0");
1140   EXPECT_EQ(format("%.2a", slightly_under), "0x1.00p+0");
1141   EXPECT_EQ(format("%.3a", slightly_under), "0x1.000p+0");
1142   EXPECT_EQ(format("%.4a", slightly_under), "0x1.0001p+0");
1143   EXPECT_EQ(format("%.5a", slightly_under), "0x1.00018p+0");
1144   EXPECT_EQ(format("%.6a", slightly_under), "0x1.000180p+0");
1145   EXPECT_EQ(format("%.7a", slightly_under), "0x1.0001800p+0");
1146 
1147   // 0x1.1b3829ac28058p+3
1148   const double hex_value = 8.85060580848964661981881363317370414733886718750;
1149   EXPECT_EQ(format("%.0a", hex_value), "0x1p+3");
1150   EXPECT_EQ(format("%.1a", hex_value), "0x1.2p+3");
1151   EXPECT_EQ(format("%.2a", hex_value), "0x1.1bp+3");
1152   EXPECT_EQ(format("%.3a", hex_value), "0x1.1b4p+3");
1153   EXPECT_EQ(format("%.4a", hex_value), "0x1.1b38p+3");
1154   EXPECT_EQ(format("%.5a", hex_value), "0x1.1b383p+3");
1155   EXPECT_EQ(format("%.6a", hex_value), "0x1.1b382ap+3");
1156   EXPECT_EQ(format("%.7a", hex_value), "0x1.1b3829bp+3");
1157   EXPECT_EQ(format("%.8a", hex_value), "0x1.1b3829acp+3");
1158   EXPECT_EQ(format("%.9a", hex_value), "0x1.1b3829ac3p+3");
1159   EXPECT_EQ(format("%.10a", hex_value), "0x1.1b3829ac28p+3");
1160   EXPECT_EQ(format("%.11a", hex_value), "0x1.1b3829ac280p+3");
1161   EXPECT_EQ(format("%.12a", hex_value), "0x1.1b3829ac2806p+3");
1162   EXPECT_EQ(format("%.13a", hex_value), "0x1.1b3829ac28058p+3");
1163   EXPECT_EQ(format("%.14a", hex_value), "0x1.1b3829ac280580p+3");
1164   EXPECT_EQ(format("%.15a", hex_value), "0x1.1b3829ac2805800p+3");
1165   EXPECT_EQ(format("%.16a", hex_value), "0x1.1b3829ac28058000p+3");
1166   EXPECT_EQ(format("%.17a", hex_value), "0x1.1b3829ac280580000p+3");
1167   EXPECT_EQ(format("%.18a", hex_value), "0x1.1b3829ac2805800000p+3");
1168   EXPECT_EQ(format("%.19a", hex_value), "0x1.1b3829ac28058000000p+3");
1169   EXPECT_EQ(format("%.20a", hex_value), "0x1.1b3829ac280580000000p+3");
1170   EXPECT_EQ(format("%.21a", hex_value), "0x1.1b3829ac2805800000000p+3");
1171 
1172   // 0x1.0818283848586p+3
1173   const double hex_value2 = 8.2529488658208371987257123691961169242858886718750;
1174   EXPECT_EQ(format("%.0a", hex_value2), "0x1p+3");
1175   EXPECT_EQ(format("%.1a", hex_value2), "0x1.1p+3");
1176   EXPECT_EQ(format("%.2a", hex_value2), "0x1.08p+3");
1177   EXPECT_EQ(format("%.3a", hex_value2), "0x1.082p+3");
1178   EXPECT_EQ(format("%.4a", hex_value2), "0x1.0818p+3");
1179   EXPECT_EQ(format("%.5a", hex_value2), "0x1.08183p+3");
1180   EXPECT_EQ(format("%.6a", hex_value2), "0x1.081828p+3");
1181   EXPECT_EQ(format("%.7a", hex_value2), "0x1.0818284p+3");
1182   EXPECT_EQ(format("%.8a", hex_value2), "0x1.08182838p+3");
1183   EXPECT_EQ(format("%.9a", hex_value2), "0x1.081828385p+3");
1184   EXPECT_EQ(format("%.10a", hex_value2), "0x1.0818283848p+3");
1185   EXPECT_EQ(format("%.11a", hex_value2), "0x1.08182838486p+3");
1186   EXPECT_EQ(format("%.12a", hex_value2), "0x1.081828384858p+3");
1187   EXPECT_EQ(format("%.13a", hex_value2), "0x1.0818283848586p+3");
1188   EXPECT_EQ(format("%.14a", hex_value2), "0x1.08182838485860p+3");
1189   EXPECT_EQ(format("%.15a", hex_value2), "0x1.081828384858600p+3");
1190   EXPECT_EQ(format("%.16a", hex_value2), "0x1.0818283848586000p+3");
1191   EXPECT_EQ(format("%.17a", hex_value2), "0x1.08182838485860000p+3");
1192   EXPECT_EQ(format("%.18a", hex_value2), "0x1.081828384858600000p+3");
1193   EXPECT_EQ(format("%.19a", hex_value2), "0x1.0818283848586000000p+3");
1194   EXPECT_EQ(format("%.20a", hex_value2), "0x1.08182838485860000000p+3");
1195   EXPECT_EQ(format("%.21a", hex_value2), "0x1.081828384858600000000p+3");
1196 }
1197 
TEST_F(FormatConvertTest,LongDoubleRoundA)1198 TEST_F(FormatConvertTest, LongDoubleRoundA) {
1199   if (std::numeric_limits<long double>::digits % 4 != 0) {
1200     // This test doesn't really make sense to run on platforms where a long
1201     // double has a different mantissa size (mod 4) than Prod, since then the
1202     // leading digit will be formatted differently.
1203     return;
1204   }
1205   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
1206   std::string s;
1207   const auto format = [&](const char *fmt, long double d) -> std::string & {
1208     s.clear();
1209     FormatArgImpl args[1] = {FormatArgImpl(d)};
1210     AppendPack(&s, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
1211     if (native_traits.hex_float_has_glibc_rounding &&
1212         native_traits.hex_float_optimizes_leading_digit_bit_count) {
1213       EXPECT_EQ(StrPrint(fmt, d), s);
1214     }
1215     return s;
1216   };
1217 
1218   // 0x8.8p+4
1219   const long double on_boundary_even = 136.0;
1220   EXPECT_EQ(format("%.0La", on_boundary_even), "0x8p+4");
1221   EXPECT_EQ(format("%.1La", on_boundary_even), "0x8.8p+4");
1222   EXPECT_EQ(format("%.2La", on_boundary_even), "0x8.80p+4");
1223   EXPECT_EQ(format("%.3La", on_boundary_even), "0x8.800p+4");
1224   EXPECT_EQ(format("%.4La", on_boundary_even), "0x8.8000p+4");
1225   EXPECT_EQ(format("%.5La", on_boundary_even), "0x8.80000p+4");
1226   EXPECT_EQ(format("%.6La", on_boundary_even), "0x8.800000p+4");
1227 
1228   // 0x9.8p+4
1229   const long double on_boundary_odd = 152.0;
1230   EXPECT_EQ(format("%.0La", on_boundary_odd), "0xap+4");
1231   EXPECT_EQ(format("%.1La", on_boundary_odd), "0x9.8p+4");
1232   EXPECT_EQ(format("%.2La", on_boundary_odd), "0x9.80p+4");
1233   EXPECT_EQ(format("%.3La", on_boundary_odd), "0x9.800p+4");
1234   EXPECT_EQ(format("%.4La", on_boundary_odd), "0x9.8000p+4");
1235   EXPECT_EQ(format("%.5La", on_boundary_odd), "0x9.80000p+4");
1236   EXPECT_EQ(format("%.6La", on_boundary_odd), "0x9.800000p+4");
1237 
1238   // 0x8.80001p+24
1239   const long double slightly_over = 142606352.0;
1240   EXPECT_EQ(format("%.0La", slightly_over), "0x9p+24");
1241   EXPECT_EQ(format("%.1La", slightly_over), "0x8.8p+24");
1242   EXPECT_EQ(format("%.2La", slightly_over), "0x8.80p+24");
1243   EXPECT_EQ(format("%.3La", slightly_over), "0x8.800p+24");
1244   EXPECT_EQ(format("%.4La", slightly_over), "0x8.8000p+24");
1245   EXPECT_EQ(format("%.5La", slightly_over), "0x8.80001p+24");
1246   EXPECT_EQ(format("%.6La", slightly_over), "0x8.800010p+24");
1247 
1248   // 0x8.7ffffp+24
1249   const long double slightly_under = 142606320.0;
1250   EXPECT_EQ(format("%.0La", slightly_under), "0x8p+24");
1251   EXPECT_EQ(format("%.1La", slightly_under), "0x8.8p+24");
1252   EXPECT_EQ(format("%.2La", slightly_under), "0x8.80p+24");
1253   EXPECT_EQ(format("%.3La", slightly_under), "0x8.800p+24");
1254   EXPECT_EQ(format("%.4La", slightly_under), "0x8.8000p+24");
1255   EXPECT_EQ(format("%.5La", slightly_under), "0x8.7ffffp+24");
1256   EXPECT_EQ(format("%.6La", slightly_under), "0x8.7ffff0p+24");
1257   EXPECT_EQ(format("%.7La", slightly_under), "0x8.7ffff00p+24");
1258 
1259   // 0xc.0828384858688000p+128
1260   const long double eights = 4094231060438608800781871108094404067328.0;
1261   EXPECT_EQ(format("%.0La", eights), "0xcp+128");
1262   EXPECT_EQ(format("%.1La", eights), "0xc.1p+128");
1263   EXPECT_EQ(format("%.2La", eights), "0xc.08p+128");
1264   EXPECT_EQ(format("%.3La", eights), "0xc.083p+128");
1265   EXPECT_EQ(format("%.4La", eights), "0xc.0828p+128");
1266   EXPECT_EQ(format("%.5La", eights), "0xc.08284p+128");
1267   EXPECT_EQ(format("%.6La", eights), "0xc.082838p+128");
1268   EXPECT_EQ(format("%.7La", eights), "0xc.0828385p+128");
1269   EXPECT_EQ(format("%.8La", eights), "0xc.08283848p+128");
1270   EXPECT_EQ(format("%.9La", eights), "0xc.082838486p+128");
1271   EXPECT_EQ(format("%.10La", eights), "0xc.0828384858p+128");
1272   EXPECT_EQ(format("%.11La", eights), "0xc.08283848587p+128");
1273   EXPECT_EQ(format("%.12La", eights), "0xc.082838485868p+128");
1274   EXPECT_EQ(format("%.13La", eights), "0xc.0828384858688p+128");
1275   EXPECT_EQ(format("%.14La", eights), "0xc.08283848586880p+128");
1276   EXPECT_EQ(format("%.15La", eights), "0xc.082838485868800p+128");
1277   EXPECT_EQ(format("%.16La", eights), "0xc.0828384858688000p+128");
1278 }
1279 
1280 // We don't actually store the results. This is just to exercise the rest of the
1281 // machinery.
1282 struct NullSink {
AbslFormatFlush(NullSink *,string_view)1283   friend void AbslFormatFlush(NullSink *, string_view) {}
1284 };
1285 
1286 template <typename... T>
FormatWithNullSink(absl::string_view fmt,const T &...a)1287 bool FormatWithNullSink(absl::string_view fmt, const T &... a) {
1288   NullSink sink;
1289   FormatArgImpl args[] = {FormatArgImpl(a)...};
1290   return FormatUntyped(&sink, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
1291 }
1292 
TEST_F(FormatConvertTest,ExtremeWidthPrecision)1293 TEST_F(FormatConvertTest, ExtremeWidthPrecision) {
1294   for (const char *fmt : {"f"}) {
1295     for (double d : {1e-100, 1.0, 1e100}) {
1296       constexpr int max = std::numeric_limits<int>::max();
1297       EXPECT_TRUE(FormatWithNullSink(std::string("%.*") + fmt, max, d));
1298       EXPECT_TRUE(FormatWithNullSink(std::string("%1.*") + fmt, max, d));
1299       EXPECT_TRUE(FormatWithNullSink(std::string("%*") + fmt, max, d));
1300       EXPECT_TRUE(FormatWithNullSink(std::string("%*.*") + fmt, max, max, d));
1301     }
1302   }
1303 }
1304 
TEST_F(FormatConvertTest,LongDouble)1305 TEST_F(FormatConvertTest, LongDouble) {
1306   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
1307   const char *const kFormats[] = {"%",    "%.3", "%8.5", "%9",  "%.5000",
1308                                   "%.60", "%+",  "% ",   "%-10"};
1309 
1310   std::vector<long double> doubles = {
1311       0.0,
1312       -0.0,
1313       std::numeric_limits<long double>::max(),
1314       -std::numeric_limits<long double>::max(),
1315       std::numeric_limits<long double>::min(),
1316       -std::numeric_limits<long double>::min(),
1317       std::numeric_limits<long double>::infinity(),
1318       -std::numeric_limits<long double>::infinity()};
1319 
1320   for (long double base : {1.L, 12.L, 123.L, 1234.L, 12345.L, 123456.L,
1321                            1234567.L, 12345678.L, 123456789.L, 1234567890.L,
1322                            12345678901.L, 123456789012.L, 1234567890123.L,
1323                            // This value is not representable in double, but it
1324                            // is in long double that uses the extended format.
1325                            // This is to verify that we are not truncating the
1326                            // value mistakenly through a double.
1327                            10000000000000000.25L}) {
1328     for (int exp : {-1000, -500, 0, 500, 1000}) {
1329       for (int sign : {1, -1}) {
1330         doubles.push_back(sign * std::ldexp(base, exp));
1331         doubles.push_back(sign / std::ldexp(base, exp));
1332       }
1333     }
1334   }
1335 
1336   // Regression tests
1337   //
1338   // Using a string literal because not all platforms support hex literals or it
1339   // might be out of range.
1340   doubles.push_back(std::strtold("-0xf.ffffffb5feafffbp-16324L", nullptr));
1341 
1342   for (const char *fmt : kFormats) {
1343     for (char f : {'f', 'F',  //
1344                    'g', 'G',  //
1345                    'a', 'A',  //
1346                    'e', 'E'}) {
1347       std::string fmt_str = std::string(fmt) + 'L' + f;
1348 
1349       if (fmt == absl::string_view("%.5000") && f != 'f' && f != 'F' &&
1350           f != 'a' && f != 'A') {
1351         // This particular test takes way too long with snprintf.
1352         // Disable for the case we are not implementing natively.
1353         continue;
1354       }
1355 
1356       if (f == 'a' || f == 'A') {
1357         if (!native_traits.hex_float_has_glibc_rounding ||
1358             !native_traits.hex_float_optimizes_leading_digit_bit_count) {
1359           continue;
1360         }
1361       }
1362 
1363       for (auto d : doubles) {
1364         FormatArgImpl arg(d);
1365         UntypedFormatSpecImpl format(fmt_str);
1366         std::string result = FormatPack(format, {&arg, 1});
1367 
1368 #ifdef _MSC_VER
1369         // MSVC has a different rounding policy than us so we can't test our
1370         // implementation against the native one there.
1371         continue;
1372 #endif  // _MSC_VER
1373 
1374         // We use ASSERT_EQ here because failures are usually correlated and a
1375         // bug would print way too many failed expectations causing the test to
1376         // time out.
1377         ASSERT_EQ(StrPrint(fmt_str.c_str(), d), result)
1378             << fmt_str << " " << StrPrint("%.18Lg", d) << " "
1379             << StrPrint("%La", d) << " " << StrPrint("%.1080Lf", d);
1380       }
1381     }
1382   }
1383 }
1384 
TEST_F(FormatConvertTest,IntAsDouble)1385 TEST_F(FormatConvertTest, IntAsDouble) {
1386   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
1387   const int kMin = std::numeric_limits<int>::min();
1388   const int kMax = std::numeric_limits<int>::max();
1389   const int ia[] = {
1390     1, 2, 3, 123,
1391     -1, -2, -3, -123,
1392     0, kMax - 1, kMax, kMin + 1, kMin };
1393   for (const int fx : ia) {
1394     SCOPED_TRACE(fx);
1395     const FormatArgImpl args[] = {FormatArgImpl(fx)};
1396     struct Expectation {
1397       int line;
1398       std::string out;
1399       const char *fmt;
1400     };
1401     const double dx = static_cast<double>(fx);
1402     std::vector<Expectation> expect = {
1403         {__LINE__, StrPrint("%f", dx), "%f"},
1404         {__LINE__, StrPrint("%12f", dx), "%12f"},
1405         {__LINE__, StrPrint("%.12f", dx), "%.12f"},
1406         {__LINE__, StrPrint("%.12a", dx), "%.12a"},
1407     };
1408     if (native_traits.hex_float_uses_minimal_precision_when_not_specified) {
1409       Expectation ex = {__LINE__, StrPrint("%12a", dx), "%12a"};
1410       expect.push_back(ex);
1411     }
1412     for (const Expectation &e : expect) {
1413       SCOPED_TRACE(e.line);
1414       SCOPED_TRACE(e.fmt);
1415       UntypedFormatSpecImpl format(e.fmt);
1416       EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args)));
1417     }
1418   }
1419 }
1420 
1421 template <typename T>
FormatFails(const char * test_format,T value)1422 bool FormatFails(const char* test_format, T value) {
1423   std::string format_string = std::string("<<") + test_format + ">>";
1424   UntypedFormatSpecImpl format(format_string);
1425 
1426   int one = 1;
1427   const FormatArgImpl args[] = {FormatArgImpl(value), FormatArgImpl(one)};
1428   EXPECT_EQ(FormatPack(format, absl::MakeSpan(args)), "")
1429       << "format=" << test_format << " value=" << value;
1430   return FormatPack(format, absl::MakeSpan(args)).empty();
1431 }
1432 
TEST_F(FormatConvertTest,ExpectedFailures)1433 TEST_F(FormatConvertTest, ExpectedFailures) {
1434   // Int input
1435   EXPECT_TRUE(FormatFails("%p", 1));
1436   EXPECT_TRUE(FormatFails("%s", 1));
1437   EXPECT_TRUE(FormatFails("%n", 1));
1438 
1439   // Double input
1440   EXPECT_TRUE(FormatFails("%p", 1.));
1441   EXPECT_TRUE(FormatFails("%s", 1.));
1442   EXPECT_TRUE(FormatFails("%n", 1.));
1443   EXPECT_TRUE(FormatFails("%c", 1.));
1444   EXPECT_TRUE(FormatFails("%d", 1.));
1445   EXPECT_TRUE(FormatFails("%x", 1.));
1446   EXPECT_TRUE(FormatFails("%*d", 1.));
1447 
1448   // String input
1449   EXPECT_TRUE(FormatFails("%n", ""));
1450   EXPECT_TRUE(FormatFails("%c", ""));
1451   EXPECT_TRUE(FormatFails("%d", ""));
1452   EXPECT_TRUE(FormatFails("%x", ""));
1453   EXPECT_TRUE(FormatFails("%f", ""));
1454   EXPECT_TRUE(FormatFails("%*d", ""));
1455 }
1456 
1457 // Sanity check to make sure that we are testing what we think we're testing on
1458 // e.g. the x86_64+glibc platform.
TEST_F(FormatConvertTest,GlibcHasCorrectTraits)1459 TEST_F(FormatConvertTest, GlibcHasCorrectTraits) {
1460 #if defined(__GLIBC__) && defined(__x86_64__)
1461   constexpr bool kIsSupportedGlibc = true;
1462 #else
1463   constexpr bool kIsSupportedGlibc = false;
1464 #endif
1465 
1466   if (!kIsSupportedGlibc) {
1467     GTEST_SKIP() << "Test does not support this platform";
1468   }
1469 
1470   const NativePrintfTraits &native_traits = VerifyNativeImplementation();
1471   // If one of the following tests break then it is either because the above PP
1472   // macro guards failed to exclude a new platform (likely) or because something
1473   // has changed in the implementation of glibc sprintf float formatting
1474   // behavior.  If the latter, then the code that computes these flags needs to
1475   // be revisited and/or possibly the StrFormat implementation.
1476   EXPECT_TRUE(native_traits.hex_float_has_glibc_rounding);
1477   EXPECT_TRUE(native_traits.hex_float_prefers_denormal_repr);
1478   EXPECT_TRUE(
1479       native_traits.hex_float_uses_minimal_precision_when_not_specified);
1480   EXPECT_TRUE(native_traits.hex_float_optimizes_leading_digit_bit_count);
1481 }
1482 
1483 }  // namespace
1484 }  // namespace str_format_internal
1485 ABSL_NAMESPACE_END
1486 }  // namespace absl
1487