tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

convert_test.cc (57379B)


      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>
     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>
     74 std::string LengthModFor() {
     75  static_assert(AlwaysFalse<T>::value, "Unsupported type");
     76  return "";
     77 }
     78 template <>
     79 std::string LengthModFor<char>() {
     80  return "hh";
     81 }
     82 template <>
     83 std::string LengthModFor<signed char>() {
     84  return "hh";
     85 }
     86 template <>
     87 std::string LengthModFor<unsigned char>() {
     88  return "hh";
     89 }
     90 template <>
     91 std::string LengthModFor<short>() {  // NOLINT
     92  return "h";
     93 }
     94 template <>
     95 std::string LengthModFor<unsigned short>() {  // NOLINT
     96  return "h";
     97 }
     98 template <>
     99 std::string LengthModFor<int>() {
    100  return "";
    101 }
    102 template <>
    103 std::string LengthModFor<unsigned>() {
    104  return "";
    105 }
    106 template <>
    107 std::string LengthModFor<long>() {  // NOLINT
    108  return "l";
    109 }
    110 template <>
    111 std::string LengthModFor<unsigned long>() {  // NOLINT
    112  return "l";
    113 }
    114 template <>
    115 std::string LengthModFor<long long>() {  // NOLINT
    116  return "ll";
    117 }
    118 template <>
    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 
    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 
    151 std::string Esc(char v) { return EscCharImpl(v); }
    152 std::string Esc(signed char v) { return EscCharImpl(v); }
    153 std::string Esc(unsigned char v) { return EscCharImpl(v); }
    154 
    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>
    168 std::string Esc(const T &v) {
    169  std::ostringstream oss;
    170  oss << v;
    171  return oss.str();
    172 }
    173 
    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);
    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);
    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 
    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 
    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>
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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>
    596 absl::optional<std::string> StrPrintChar(T c) {
    597  return StrPrint("%c", static_cast<int>(c));
    598 }
    599 template <>
    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>
    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 <>
    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 
    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);
    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 
    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 
    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 
    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>
    788 void TestWithMultipleFormatsHelper(Floating tested_float) {
    789  const NativePrintfTraits &native_traits = VerifyNativeImplementation();
    790  // Reserve the space to ensure we don't allocate memory in the output itself.
    791  std::string str_format_result;
    792  str_format_result.reserve(1 << 20);
    793  std::string string_printf_result;
    794  string_printf_result.reserve(1 << 20);
    795 
    796  const char *const kFormats[] = {
    797      "%",  "%.3", "%8.5", "%500",   "%.5000", "%.60", "%.30",   "%03",
    798      "%+", "% ",  "%-10", "%#15.3", "%#.0",   "%.0",  "%1$*2$", "%1$.*2$"};
    799 
    800  for (const char *fmt : kFormats) {
    801    for (char f : {'f', 'F',  //
    802                   'g', 'G',  //
    803                   'a', 'A',  //
    804                   'e', 'E'}) {
    805      std::string fmt_str = std::string(fmt) + f;
    806 
    807      if (fmt == absl::string_view("%.5000") && f != 'f' && f != 'F' &&
    808          f != 'a' && f != 'A') {
    809        // This particular test takes way too long with snprintf.
    810        // Disable for the case we are not implementing natively.
    811        continue;
    812      }
    813 
    814      if ((f == 'a' || f == 'A') &&
    815          !native_traits.hex_float_has_glibc_rounding) {
    816        continue;
    817      }
    818 
    819      if (!native_traits.hex_float_prefers_denormal_repr &&
    820          (f == 'a' || f == 'A') &&
    821          std::fpclassify(tested_float) == FP_SUBNORMAL) {
    822        continue;
    823      }
    824        int i = -10;
    825        FormatArgImpl args[2] = {FormatArgImpl(tested_float), FormatArgImpl(i)};
    826        UntypedFormatSpecImpl format(fmt_str);
    827 
    828        string_printf_result.clear();
    829        StrAppend(&string_printf_result, fmt_str.c_str(), tested_float, i);
    830        str_format_result.clear();
    831 
    832        {
    833          AppendPack(&str_format_result, format, absl::MakeSpan(args));
    834        }
    835 
    836        // For values that we know won't match the standard library
    837        // implementation we skip verification, but still run the algorithm to
    838        // catch asserts/sanitizer bugs.
    839 #ifdef _MSC_VER
    840        // MSVC has a different rounding policy than us so we can't test our
    841        // implementation against the native one there.
    842        continue;
    843 #elif defined(__APPLE__)
    844        // Apple formats NaN differently (+nan) vs. (nan)
    845        if (std::isnan(tested_float)) continue;
    846 #endif
    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", tested_float) << " "
    852            << StrPrint("%a", tested_float) << " "
    853            << StrPrint("%.50f", tested_float);
    854    }
    855  }
    856 }
    857 
    858 TEST_F(FormatConvertTest, Float) {
    859  std::vector<float> floats = {0.0f,
    860                               -0.0f,
    861                               .9999999f,
    862                               9999999.f,
    863                               std::numeric_limits<float>::max(),
    864                               -std::numeric_limits<float>::max(),
    865                               std::numeric_limits<float>::min(),
    866                               -std::numeric_limits<float>::min(),
    867                               std::numeric_limits<float>::lowest(),
    868                               -std::numeric_limits<float>::lowest(),
    869                               std::numeric_limits<float>::epsilon(),
    870                               std::numeric_limits<float>::epsilon() + 1.0f,
    871                               std::numeric_limits<float>::infinity(),
    872                               -std::numeric_limits<float>::infinity(),
    873                               std::nanf("")};
    874 
    875  // Some regression tests.
    876  floats.push_back(0.999999989f);
    877 
    878  if (std::numeric_limits<float>::has_denorm != std::denorm_absent) {
    879    floats.push_back(std::numeric_limits<float>::denorm_min());
    880    floats.push_back(-std::numeric_limits<float>::denorm_min());
    881  }
    882 
    883  for (float base :
    884       {1.f, 12.f, 123.f, 1234.f, 12345.f, 123456.f, 1234567.f, 12345678.f,
    885        123456789.f, 1234567890.f, 12345678901.f, 12345678.f, 12345678.f}) {
    886    for (int exp = -123; exp <= 123; ++exp) {
    887      for (int sign : {1, -1}) {
    888        floats.push_back(sign * std::ldexp(base, exp));
    889      }
    890    }
    891  }
    892 
    893  for (int exp = -300; exp <= 300; ++exp) {
    894    const float all_ones_mantissa = 0xffffff;
    895    floats.push_back(std::ldexp(all_ones_mantissa, exp));
    896  }
    897 
    898  // Remove duplicates to speed up the logic below.
    899  std::sort(floats.begin(), floats.end(), [](const float a, const float b) {
    900    if (std::isnan(a)) return false;
    901    if (std::isnan(b)) return true;
    902    return a < b;
    903  });
    904  floats.erase(std::unique(floats.begin(), floats.end()), floats.end());
    905 
    906  for (float f : floats) {
    907    TestWithMultipleFormatsHelper(f);
    908  }
    909 }
    910 
    911 TEST_F(FormatConvertTest, Double) {
    912  std::vector<double> doubles = {0.0,
    913                                 -0.0,
    914                                 .99999999999999,
    915                                 99999999999999.,
    916                                 std::numeric_limits<double>::max(),
    917                                 -std::numeric_limits<double>::max(),
    918                                 std::numeric_limits<double>::min(),
    919                                 -std::numeric_limits<double>::min(),
    920                                 std::numeric_limits<double>::lowest(),
    921                                 -std::numeric_limits<double>::lowest(),
    922                                 std::numeric_limits<double>::epsilon(),
    923                                 std::numeric_limits<double>::epsilon() + 1,
    924                                 std::numeric_limits<double>::infinity(),
    925                                 -std::numeric_limits<double>::infinity(),
    926                                 std::nan("")};
    927 
    928  // Some regression tests.
    929  doubles.push_back(0.99999999999999989);
    930 
    931  if (std::numeric_limits<double>::has_denorm != std::denorm_absent) {
    932    doubles.push_back(std::numeric_limits<double>::denorm_min());
    933    doubles.push_back(-std::numeric_limits<double>::denorm_min());
    934  }
    935 
    936  for (double base :
    937       {1., 12., 123., 1234., 12345., 123456., 1234567., 12345678., 123456789.,
    938        1234567890., 12345678901., 123456789012., 1234567890123.}) {
    939    for (int exp = -123; exp <= 123; ++exp) {
    940      for (int sign : {1, -1}) {
    941        doubles.push_back(sign * std::ldexp(base, exp));
    942      }
    943    }
    944  }
    945 
    946  for (int exp = -300; exp <= 300; ++exp) {
    947    const double all_ones_mantissa = 0x1fffffffffffff;
    948    doubles.push_back(std::ldexp(all_ones_mantissa, exp));
    949  }
    950 
    951  // Remove duplicates to speed up the logic below.
    952  std::sort(doubles.begin(), doubles.end(), [](const double a, const double b) {
    953    if (std::isnan(a)) return false;
    954    if (std::isnan(b)) return true;
    955    return a < b;
    956  });
    957  doubles.erase(std::unique(doubles.begin(), doubles.end()), doubles.end());
    958 
    959  for (double d : doubles) {
    960    TestWithMultipleFormatsHelper(d);
    961  }
    962 }
    963 
    964 TEST_F(FormatConvertTest, DoubleRound) {
    965  std::string s;
    966  const auto format = [&](const char *fmt, double d) -> std::string & {
    967    s.clear();
    968    FormatArgImpl args[1] = {FormatArgImpl(d)};
    969    AppendPack(&s, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
    970 #if !defined(_MSC_VER)
    971    // MSVC has a different rounding policy than us so we can't test our
    972    // implementation against the native one there.
    973    EXPECT_EQ(StrPrint(fmt, d), s);
    974 #endif  // _MSC_VER
    975 
    976    return s;
    977  };
    978  // All of these values have to be exactly represented.
    979  // Otherwise we might not be testing what we think we are testing.
    980 
    981  // These values can fit in a 64bit "fast" representation.
    982  const double exact_value = 0.00000000000005684341886080801486968994140625;
    983  assert(exact_value == std::pow(2, -44));
    984  // Round up at a 5xx.
    985  EXPECT_EQ(format("%.13f", exact_value), "0.0000000000001");
    986  // Round up at a >5
    987  EXPECT_EQ(format("%.14f", exact_value), "0.00000000000006");
    988  // Round down at a <5
    989  EXPECT_EQ(format("%.16f", exact_value), "0.0000000000000568");
    990  // Nine handling
    991  EXPECT_EQ(format("%.35f", exact_value),
    992            "0.00000000000005684341886080801486969");
    993  EXPECT_EQ(format("%.36f", exact_value),
    994            "0.000000000000056843418860808014869690");
    995  // Round down the last nine.
    996  EXPECT_EQ(format("%.37f", exact_value),
    997            "0.0000000000000568434188608080148696899");
    998  EXPECT_EQ(format("%.10f", 0.000003814697265625), "0.0000038147");
    999  // Round up the last nine
   1000  EXPECT_EQ(format("%.11f", 0.000003814697265625), "0.00000381470");
   1001  EXPECT_EQ(format("%.12f", 0.000003814697265625), "0.000003814697");
   1002 
   1003  // Round to even (down)
   1004  EXPECT_EQ(format("%.43f", exact_value),
   1005            "0.0000000000000568434188608080148696899414062");
   1006  // Exact
   1007  EXPECT_EQ(format("%.44f", exact_value),
   1008            "0.00000000000005684341886080801486968994140625");
   1009  // Round to even (up), let make the last digits 75 instead of 25
   1010  EXPECT_EQ(format("%.43f", exact_value + std::pow(2, -43)),
   1011            "0.0000000000001705302565824240446090698242188");
   1012  // Exact, just to check.
   1013  EXPECT_EQ(format("%.44f", exact_value + std::pow(2, -43)),
   1014            "0.00000000000017053025658242404460906982421875");
   1015 
   1016  // This value has to be small enough that it won't fit in the uint128
   1017  // representation for printing.
   1018  const double small_exact_value =
   1019      0.000000000000000000000000000000000000752316384526264005099991383822237233803945956334136013765601092018187046051025390625;  // NOLINT
   1020  assert(small_exact_value == std::pow(2, -120));
   1021  // Round up at a 5xx.
   1022  EXPECT_EQ(format("%.37f", small_exact_value),
   1023            "0.0000000000000000000000000000000000008");
   1024  // Round down at a <5
   1025  EXPECT_EQ(format("%.38f", small_exact_value),
   1026            "0.00000000000000000000000000000000000075");
   1027  // Round up at a >5
   1028  EXPECT_EQ(format("%.41f", small_exact_value),
   1029            "0.00000000000000000000000000000000000075232");
   1030  // Nine handling
   1031  EXPECT_EQ(format("%.55f", small_exact_value),
   1032            "0.0000000000000000000000000000000000007523163845262640051");
   1033  EXPECT_EQ(format("%.56f", small_exact_value),
   1034            "0.00000000000000000000000000000000000075231638452626400510");
   1035  EXPECT_EQ(format("%.57f", small_exact_value),
   1036            "0.000000000000000000000000000000000000752316384526264005100");
   1037  EXPECT_EQ(format("%.58f", small_exact_value),
   1038            "0.0000000000000000000000000000000000007523163845262640051000");
   1039  // Round down the last nine
   1040  EXPECT_EQ(format("%.59f", small_exact_value),
   1041            "0.00000000000000000000000000000000000075231638452626400509999");
   1042  // Round up the last nine
   1043  EXPECT_EQ(format("%.79f", small_exact_value),
   1044            "0.000000000000000000000000000000000000"
   1045            "7523163845262640050999913838222372338039460");
   1046 
   1047  // Round to even (down)
   1048  EXPECT_EQ(format("%.119f", small_exact_value),
   1049            "0.000000000000000000000000000000000000"
   1050            "75231638452626400509999138382223723380"
   1051            "394595633413601376560109201818704605102539062");
   1052  // Exact
   1053  EXPECT_EQ(format("%.120f", small_exact_value),
   1054            "0.000000000000000000000000000000000000"
   1055            "75231638452626400509999138382223723380"
   1056            "3945956334136013765601092018187046051025390625");
   1057  // Round to even (up), let make the last digits 75 instead of 25
   1058  EXPECT_EQ(format("%.119f", small_exact_value + std::pow(2, -119)),
   1059            "0.000000000000000000000000000000000002"
   1060            "25694915357879201529997415146671170141"
   1061            "183786900240804129680327605456113815307617188");
   1062  // Exact, just to check.
   1063  EXPECT_EQ(format("%.120f", small_exact_value + std::pow(2, -119)),
   1064            "0.000000000000000000000000000000000002"
   1065            "25694915357879201529997415146671170141"
   1066            "1837869002408041296803276054561138153076171875");
   1067 }
   1068 
   1069 TEST_F(FormatConvertTest, DoubleRoundA) {
   1070  const NativePrintfTraits &native_traits = VerifyNativeImplementation();
   1071  std::string s;
   1072  const auto format = [&](const char *fmt, double d) -> std::string & {
   1073    s.clear();
   1074    FormatArgImpl args[1] = {FormatArgImpl(d)};
   1075    AppendPack(&s, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
   1076    if (native_traits.hex_float_has_glibc_rounding) {
   1077      EXPECT_EQ(StrPrint(fmt, d), s);
   1078    }
   1079    return s;
   1080  };
   1081 
   1082  // 0x1.00018000p+100
   1083  const double on_boundary_odd = 1267679614447900152596896153600.0;
   1084  EXPECT_EQ(format("%.0a", on_boundary_odd), "0x1p+100");
   1085  EXPECT_EQ(format("%.1a", on_boundary_odd), "0x1.0p+100");
   1086  EXPECT_EQ(format("%.2a", on_boundary_odd), "0x1.00p+100");
   1087  EXPECT_EQ(format("%.3a", on_boundary_odd), "0x1.000p+100");
   1088  EXPECT_EQ(format("%.4a", on_boundary_odd), "0x1.0002p+100");  // round
   1089  EXPECT_EQ(format("%.5a", on_boundary_odd), "0x1.00018p+100");
   1090  EXPECT_EQ(format("%.6a", on_boundary_odd), "0x1.000180p+100");
   1091 
   1092  // 0x1.00028000p-2
   1093  const double on_boundary_even = 0.250009536743164062500;
   1094  EXPECT_EQ(format("%.0a", on_boundary_even), "0x1p-2");
   1095  EXPECT_EQ(format("%.1a", on_boundary_even), "0x1.0p-2");
   1096  EXPECT_EQ(format("%.2a", on_boundary_even), "0x1.00p-2");
   1097  EXPECT_EQ(format("%.3a", on_boundary_even), "0x1.000p-2");
   1098  EXPECT_EQ(format("%.4a", on_boundary_even), "0x1.0002p-2");  // no round
   1099  EXPECT_EQ(format("%.5a", on_boundary_even), "0x1.00028p-2");
   1100  EXPECT_EQ(format("%.6a", on_boundary_even), "0x1.000280p-2");
   1101 
   1102  // 0x1.00018001p+1
   1103  const double slightly_over = 2.00004577683284878730773925781250;
   1104  EXPECT_EQ(format("%.0a", slightly_over), "0x1p+1");
   1105  EXPECT_EQ(format("%.1a", slightly_over), "0x1.0p+1");
   1106  EXPECT_EQ(format("%.2a", slightly_over), "0x1.00p+1");
   1107  EXPECT_EQ(format("%.3a", slightly_over), "0x1.000p+1");
   1108  EXPECT_EQ(format("%.4a", slightly_over), "0x1.0002p+1");
   1109  EXPECT_EQ(format("%.5a", slightly_over), "0x1.00018p+1");
   1110  EXPECT_EQ(format("%.6a", slightly_over), "0x1.000180p+1");
   1111 
   1112  // 0x1.00017fffp+0
   1113  const double slightly_under = 1.000022887950763106346130371093750;
   1114  EXPECT_EQ(format("%.0a", slightly_under), "0x1p+0");
   1115  EXPECT_EQ(format("%.1a", slightly_under), "0x1.0p+0");
   1116  EXPECT_EQ(format("%.2a", slightly_under), "0x1.00p+0");
   1117  EXPECT_EQ(format("%.3a", slightly_under), "0x1.000p+0");
   1118  EXPECT_EQ(format("%.4a", slightly_under), "0x1.0001p+0");
   1119  EXPECT_EQ(format("%.5a", slightly_under), "0x1.00018p+0");
   1120  EXPECT_EQ(format("%.6a", slightly_under), "0x1.000180p+0");
   1121  EXPECT_EQ(format("%.7a", slightly_under), "0x1.0001800p+0");
   1122 
   1123  // 0x1.1b3829ac28058p+3
   1124  const double hex_value = 8.85060580848964661981881363317370414733886718750;
   1125  EXPECT_EQ(format("%.0a", hex_value), "0x1p+3");
   1126  EXPECT_EQ(format("%.1a", hex_value), "0x1.2p+3");
   1127  EXPECT_EQ(format("%.2a", hex_value), "0x1.1bp+3");
   1128  EXPECT_EQ(format("%.3a", hex_value), "0x1.1b4p+3");
   1129  EXPECT_EQ(format("%.4a", hex_value), "0x1.1b38p+3");
   1130  EXPECT_EQ(format("%.5a", hex_value), "0x1.1b383p+3");
   1131  EXPECT_EQ(format("%.6a", hex_value), "0x1.1b382ap+3");
   1132  EXPECT_EQ(format("%.7a", hex_value), "0x1.1b3829bp+3");
   1133  EXPECT_EQ(format("%.8a", hex_value), "0x1.1b3829acp+3");
   1134  EXPECT_EQ(format("%.9a", hex_value), "0x1.1b3829ac3p+3");
   1135  EXPECT_EQ(format("%.10a", hex_value), "0x1.1b3829ac28p+3");
   1136  EXPECT_EQ(format("%.11a", hex_value), "0x1.1b3829ac280p+3");
   1137  EXPECT_EQ(format("%.12a", hex_value), "0x1.1b3829ac2806p+3");
   1138  EXPECT_EQ(format("%.13a", hex_value), "0x1.1b3829ac28058p+3");
   1139  EXPECT_EQ(format("%.14a", hex_value), "0x1.1b3829ac280580p+3");
   1140  EXPECT_EQ(format("%.15a", hex_value), "0x1.1b3829ac2805800p+3");
   1141  EXPECT_EQ(format("%.16a", hex_value), "0x1.1b3829ac28058000p+3");
   1142  EXPECT_EQ(format("%.17a", hex_value), "0x1.1b3829ac280580000p+3");
   1143  EXPECT_EQ(format("%.18a", hex_value), "0x1.1b3829ac2805800000p+3");
   1144  EXPECT_EQ(format("%.19a", hex_value), "0x1.1b3829ac28058000000p+3");
   1145  EXPECT_EQ(format("%.20a", hex_value), "0x1.1b3829ac280580000000p+3");
   1146  EXPECT_EQ(format("%.21a", hex_value), "0x1.1b3829ac2805800000000p+3");
   1147 
   1148  // 0x1.0818283848586p+3
   1149  const double hex_value2 = 8.2529488658208371987257123691961169242858886718750;
   1150  EXPECT_EQ(format("%.0a", hex_value2), "0x1p+3");
   1151  EXPECT_EQ(format("%.1a", hex_value2), "0x1.1p+3");
   1152  EXPECT_EQ(format("%.2a", hex_value2), "0x1.08p+3");
   1153  EXPECT_EQ(format("%.3a", hex_value2), "0x1.082p+3");
   1154  EXPECT_EQ(format("%.4a", hex_value2), "0x1.0818p+3");
   1155  EXPECT_EQ(format("%.5a", hex_value2), "0x1.08183p+3");
   1156  EXPECT_EQ(format("%.6a", hex_value2), "0x1.081828p+3");
   1157  EXPECT_EQ(format("%.7a", hex_value2), "0x1.0818284p+3");
   1158  EXPECT_EQ(format("%.8a", hex_value2), "0x1.08182838p+3");
   1159  EXPECT_EQ(format("%.9a", hex_value2), "0x1.081828385p+3");
   1160  EXPECT_EQ(format("%.10a", hex_value2), "0x1.0818283848p+3");
   1161  EXPECT_EQ(format("%.11a", hex_value2), "0x1.08182838486p+3");
   1162  EXPECT_EQ(format("%.12a", hex_value2), "0x1.081828384858p+3");
   1163  EXPECT_EQ(format("%.13a", hex_value2), "0x1.0818283848586p+3");
   1164  EXPECT_EQ(format("%.14a", hex_value2), "0x1.08182838485860p+3");
   1165  EXPECT_EQ(format("%.15a", hex_value2), "0x1.081828384858600p+3");
   1166  EXPECT_EQ(format("%.16a", hex_value2), "0x1.0818283848586000p+3");
   1167  EXPECT_EQ(format("%.17a", hex_value2), "0x1.08182838485860000p+3");
   1168  EXPECT_EQ(format("%.18a", hex_value2), "0x1.081828384858600000p+3");
   1169  EXPECT_EQ(format("%.19a", hex_value2), "0x1.0818283848586000000p+3");
   1170  EXPECT_EQ(format("%.20a", hex_value2), "0x1.08182838485860000000p+3");
   1171  EXPECT_EQ(format("%.21a", hex_value2), "0x1.081828384858600000000p+3");
   1172 }
   1173 
   1174 TEST_F(FormatConvertTest, LongDoubleRoundA) {
   1175  if (std::numeric_limits<long double>::digits % 4 != 0) {
   1176    // This test doesn't really make sense to run on platforms where a long
   1177    // double has a different mantissa size (mod 4) than Prod, since then the
   1178    // leading digit will be formatted differently.
   1179    return;
   1180  }
   1181  const NativePrintfTraits &native_traits = VerifyNativeImplementation();
   1182  std::string s;
   1183  const auto format = [&](const char *fmt, long double d) -> std::string & {
   1184    s.clear();
   1185    FormatArgImpl args[1] = {FormatArgImpl(d)};
   1186    AppendPack(&s, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
   1187    if (native_traits.hex_float_has_glibc_rounding &&
   1188        native_traits.hex_float_optimizes_leading_digit_bit_count) {
   1189      EXPECT_EQ(StrPrint(fmt, d), s);
   1190    }
   1191    return s;
   1192  };
   1193 
   1194  // 0x8.8p+4
   1195  const long double on_boundary_even = 136.0;
   1196  EXPECT_EQ(format("%.0La", on_boundary_even), "0x8p+4");
   1197  EXPECT_EQ(format("%.1La", on_boundary_even), "0x8.8p+4");
   1198  EXPECT_EQ(format("%.2La", on_boundary_even), "0x8.80p+4");
   1199  EXPECT_EQ(format("%.3La", on_boundary_even), "0x8.800p+4");
   1200  EXPECT_EQ(format("%.4La", on_boundary_even), "0x8.8000p+4");
   1201  EXPECT_EQ(format("%.5La", on_boundary_even), "0x8.80000p+4");
   1202  EXPECT_EQ(format("%.6La", on_boundary_even), "0x8.800000p+4");
   1203 
   1204  // 0x9.8p+4
   1205  const long double on_boundary_odd = 152.0;
   1206  EXPECT_EQ(format("%.0La", on_boundary_odd), "0xap+4");
   1207  EXPECT_EQ(format("%.1La", on_boundary_odd), "0x9.8p+4");
   1208  EXPECT_EQ(format("%.2La", on_boundary_odd), "0x9.80p+4");
   1209  EXPECT_EQ(format("%.3La", on_boundary_odd), "0x9.800p+4");
   1210  EXPECT_EQ(format("%.4La", on_boundary_odd), "0x9.8000p+4");
   1211  EXPECT_EQ(format("%.5La", on_boundary_odd), "0x9.80000p+4");
   1212  EXPECT_EQ(format("%.6La", on_boundary_odd), "0x9.800000p+4");
   1213 
   1214  // 0x8.80001p+24
   1215  const long double slightly_over = 142606352.0;
   1216  EXPECT_EQ(format("%.0La", slightly_over), "0x9p+24");
   1217  EXPECT_EQ(format("%.1La", slightly_over), "0x8.8p+24");
   1218  EXPECT_EQ(format("%.2La", slightly_over), "0x8.80p+24");
   1219  EXPECT_EQ(format("%.3La", slightly_over), "0x8.800p+24");
   1220  EXPECT_EQ(format("%.4La", slightly_over), "0x8.8000p+24");
   1221  EXPECT_EQ(format("%.5La", slightly_over), "0x8.80001p+24");
   1222  EXPECT_EQ(format("%.6La", slightly_over), "0x8.800010p+24");
   1223 
   1224  // 0x8.7ffffp+24
   1225  const long double slightly_under = 142606320.0;
   1226  EXPECT_EQ(format("%.0La", slightly_under), "0x8p+24");
   1227  EXPECT_EQ(format("%.1La", slightly_under), "0x8.8p+24");
   1228  EXPECT_EQ(format("%.2La", slightly_under), "0x8.80p+24");
   1229  EXPECT_EQ(format("%.3La", slightly_under), "0x8.800p+24");
   1230  EXPECT_EQ(format("%.4La", slightly_under), "0x8.8000p+24");
   1231  EXPECT_EQ(format("%.5La", slightly_under), "0x8.7ffffp+24");
   1232  EXPECT_EQ(format("%.6La", slightly_under), "0x8.7ffff0p+24");
   1233  EXPECT_EQ(format("%.7La", slightly_under), "0x8.7ffff00p+24");
   1234 
   1235  // 0xc.0828384858688000p+128
   1236  const long double eights = 4094231060438608800781871108094404067328.0;
   1237  EXPECT_EQ(format("%.0La", eights), "0xcp+128");
   1238  EXPECT_EQ(format("%.1La", eights), "0xc.1p+128");
   1239  EXPECT_EQ(format("%.2La", eights), "0xc.08p+128");
   1240  EXPECT_EQ(format("%.3La", eights), "0xc.083p+128");
   1241  EXPECT_EQ(format("%.4La", eights), "0xc.0828p+128");
   1242  EXPECT_EQ(format("%.5La", eights), "0xc.08284p+128");
   1243  EXPECT_EQ(format("%.6La", eights), "0xc.082838p+128");
   1244  EXPECT_EQ(format("%.7La", eights), "0xc.0828385p+128");
   1245  EXPECT_EQ(format("%.8La", eights), "0xc.08283848p+128");
   1246  EXPECT_EQ(format("%.9La", eights), "0xc.082838486p+128");
   1247  EXPECT_EQ(format("%.10La", eights), "0xc.0828384858p+128");
   1248  EXPECT_EQ(format("%.11La", eights), "0xc.08283848587p+128");
   1249  EXPECT_EQ(format("%.12La", eights), "0xc.082838485868p+128");
   1250  EXPECT_EQ(format("%.13La", eights), "0xc.0828384858688p+128");
   1251  EXPECT_EQ(format("%.14La", eights), "0xc.08283848586880p+128");
   1252  EXPECT_EQ(format("%.15La", eights), "0xc.082838485868800p+128");
   1253  EXPECT_EQ(format("%.16La", eights), "0xc.0828384858688000p+128");
   1254 }
   1255 
   1256 // We don't actually store the results. This is just to exercise the rest of the
   1257 // machinery.
   1258 struct NullSink {
   1259  friend void AbslFormatFlush(NullSink *, string_view) {}
   1260 };
   1261 
   1262 template <typename... T>
   1263 bool FormatWithNullSink(absl::string_view fmt, const T &... a) {
   1264  NullSink sink;
   1265  FormatArgImpl args[] = {FormatArgImpl(a)...};
   1266  return FormatUntyped(&sink, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
   1267 }
   1268 
   1269 TEST_F(FormatConvertTest, ExtremeWidthPrecision) {
   1270  for (const char *fmt : {"f"}) {
   1271    for (double d : {1e-100, 1.0, 1e100}) {
   1272      constexpr int max = std::numeric_limits<int>::max();
   1273      EXPECT_TRUE(FormatWithNullSink(std::string("%.*") + fmt, max, d));
   1274      EXPECT_TRUE(FormatWithNullSink(std::string("%1.*") + fmt, max, d));
   1275      EXPECT_TRUE(FormatWithNullSink(std::string("%*") + fmt, max, d));
   1276      EXPECT_TRUE(FormatWithNullSink(std::string("%*.*") + fmt, max, max, d));
   1277    }
   1278  }
   1279 }
   1280 
   1281 TEST_F(FormatConvertTest, LongDouble) {
   1282  const NativePrintfTraits &native_traits = VerifyNativeImplementation();
   1283  const char *const kFormats[] = {"%",    "%.3", "%8.5", "%9",  "%.5000",
   1284                                  "%.60", "%+",  "% ",   "%-10"};
   1285 
   1286  std::vector<long double> doubles = {
   1287      0.0,
   1288      -0.0,
   1289      std::numeric_limits<long double>::max(),
   1290      -std::numeric_limits<long double>::max(),
   1291      std::numeric_limits<long double>::min(),
   1292      -std::numeric_limits<long double>::min(),
   1293      std::numeric_limits<long double>::infinity(),
   1294      -std::numeric_limits<long double>::infinity()};
   1295 
   1296  for (long double base : {1.L, 12.L, 123.L, 1234.L, 12345.L, 123456.L,
   1297                           1234567.L, 12345678.L, 123456789.L, 1234567890.L,
   1298                           12345678901.L, 123456789012.L, 1234567890123.L,
   1299                           // This value is not representable in double, but it
   1300                           // is in long double that uses the extended format.
   1301                           // This is to verify that we are not truncating the
   1302                           // value mistakenly through a double.
   1303                           10000000000000000.25L}) {
   1304    for (int exp : {-1000, -500, 0, 500, 1000}) {
   1305      for (int sign : {1, -1}) {
   1306        doubles.push_back(sign * std::ldexp(base, exp));
   1307        doubles.push_back(sign / std::ldexp(base, exp));
   1308      }
   1309    }
   1310  }
   1311 
   1312  // Regression tests
   1313  //
   1314  // Using a string literal because not all platforms support hex literals or it
   1315  // might be out of range.
   1316  doubles.push_back(std::strtold("-0xf.ffffffb5feafffbp-16324L", nullptr));
   1317 
   1318  for (const char *fmt : kFormats) {
   1319    for (char f : {'f', 'F',  //
   1320                   'g', 'G',  //
   1321                   'a', 'A',  //
   1322                   'e', 'E'}) {
   1323      std::string fmt_str = std::string(fmt) + 'L' + f;
   1324 
   1325      if (fmt == absl::string_view("%.5000") && f != 'f' && f != 'F' &&
   1326          f != 'a' && f != 'A') {
   1327        // This particular test takes way too long with snprintf.
   1328        // Disable for the case we are not implementing natively.
   1329        continue;
   1330      }
   1331 
   1332      if (f == 'a' || f == 'A') {
   1333        if (!native_traits.hex_float_has_glibc_rounding ||
   1334            !native_traits.hex_float_optimizes_leading_digit_bit_count) {
   1335          continue;
   1336        }
   1337      }
   1338 
   1339      for (auto d : doubles) {
   1340        FormatArgImpl arg(d);
   1341        UntypedFormatSpecImpl format(fmt_str);
   1342        std::string result = FormatPack(format, {&arg, 1});
   1343 
   1344 #ifdef _MSC_VER
   1345        // MSVC has a different rounding policy than us so we can't test our
   1346        // implementation against the native one there.
   1347        continue;
   1348 #endif  // _MSC_VER
   1349 
   1350        // We use ASSERT_EQ here because failures are usually correlated and a
   1351        // bug would print way too many failed expectations causing the test to
   1352        // time out.
   1353        ASSERT_EQ(StrPrint(fmt_str.c_str(), d), result)
   1354            << fmt_str << " " << StrPrint("%.18Lg", d) << " "
   1355            << StrPrint("%La", d) << " " << StrPrint("%.1080Lf", d);
   1356      }
   1357    }
   1358  }
   1359 }
   1360 
   1361 TEST_F(FormatConvertTest, IntAsDouble) {
   1362  const NativePrintfTraits &native_traits = VerifyNativeImplementation();
   1363  const int kMin = std::numeric_limits<int>::min();
   1364  const int kMax = std::numeric_limits<int>::max();
   1365  const int ia[] = {
   1366    1, 2, 3, 123,
   1367    -1, -2, -3, -123,
   1368    0, kMax - 1, kMax, kMin + 1, kMin };
   1369  for (const int fx : ia) {
   1370    SCOPED_TRACE(fx);
   1371    const FormatArgImpl args[] = {FormatArgImpl(fx)};
   1372    struct Expectation {
   1373      int line;
   1374      std::string out;
   1375      const char *fmt;
   1376    };
   1377    const double dx = static_cast<double>(fx);
   1378    std::vector<Expectation> expect = {
   1379        {__LINE__, StrPrint("%f", dx), "%f"},
   1380        {__LINE__, StrPrint("%12f", dx), "%12f"},
   1381        {__LINE__, StrPrint("%.12f", dx), "%.12f"},
   1382        {__LINE__, StrPrint("%.12a", dx), "%.12a"},
   1383    };
   1384    if (native_traits.hex_float_uses_minimal_precision_when_not_specified) {
   1385      Expectation ex = {__LINE__, StrPrint("%12a", dx), "%12a"};
   1386      expect.push_back(ex);
   1387    }
   1388    for (const Expectation &e : expect) {
   1389      SCOPED_TRACE(e.line);
   1390      SCOPED_TRACE(e.fmt);
   1391      UntypedFormatSpecImpl format(e.fmt);
   1392      EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args)));
   1393    }
   1394  }
   1395 }
   1396 
   1397 template <typename T>
   1398 bool FormatFails(const char* test_format, T value) {
   1399  std::string format_string = std::string("<<") + test_format + ">>";
   1400  UntypedFormatSpecImpl format(format_string);
   1401 
   1402  int one = 1;
   1403  const FormatArgImpl args[] = {FormatArgImpl(value), FormatArgImpl(one)};
   1404  EXPECT_EQ(FormatPack(format, absl::MakeSpan(args)), "")
   1405      << "format=" << test_format << " value=" << value;
   1406  return FormatPack(format, absl::MakeSpan(args)).empty();
   1407 }
   1408 
   1409 TEST_F(FormatConvertTest, ExpectedFailures) {
   1410  // Int input
   1411  EXPECT_TRUE(FormatFails("%p", 1));
   1412  EXPECT_TRUE(FormatFails("%s", 1));
   1413  EXPECT_TRUE(FormatFails("%n", 1));
   1414 
   1415  // Double input
   1416  EXPECT_TRUE(FormatFails("%p", 1.));
   1417  EXPECT_TRUE(FormatFails("%s", 1.));
   1418  EXPECT_TRUE(FormatFails("%n", 1.));
   1419  EXPECT_TRUE(FormatFails("%c", 1.));
   1420  EXPECT_TRUE(FormatFails("%d", 1.));
   1421  EXPECT_TRUE(FormatFails("%x", 1.));
   1422  EXPECT_TRUE(FormatFails("%*d", 1.));
   1423 
   1424  // String input
   1425  EXPECT_TRUE(FormatFails("%n", ""));
   1426  EXPECT_TRUE(FormatFails("%c", ""));
   1427  EXPECT_TRUE(FormatFails("%d", ""));
   1428  EXPECT_TRUE(FormatFails("%x", ""));
   1429  EXPECT_TRUE(FormatFails("%f", ""));
   1430  EXPECT_TRUE(FormatFails("%*d", ""));
   1431 }
   1432 
   1433 // Sanity check to make sure that we are testing what we think we're testing on
   1434 // e.g. the x86_64+glibc platform.
   1435 TEST_F(FormatConvertTest, GlibcHasCorrectTraits) {
   1436 #if defined(__GLIBC__) && defined(__x86_64__)
   1437  constexpr bool kIsSupportedGlibc = true;
   1438 #else
   1439  constexpr bool kIsSupportedGlibc = false;
   1440 #endif
   1441 
   1442  if (!kIsSupportedGlibc) {
   1443    GTEST_SKIP() << "Test does not support this platform";
   1444  }
   1445 
   1446  const NativePrintfTraits &native_traits = VerifyNativeImplementation();
   1447  // If one of the following tests break then it is either because the above PP
   1448  // macro guards failed to exclude a new platform (likely) or because something
   1449  // has changed in the implementation of glibc sprintf float formatting
   1450  // behavior.  If the latter, then the code that computes these flags needs to
   1451  // be revisited and/or possibly the StrFormat implementation.
   1452  EXPECT_TRUE(native_traits.hex_float_has_glibc_rounding);
   1453  EXPECT_TRUE(native_traits.hex_float_prefers_denormal_repr);
   1454  EXPECT_TRUE(
   1455      native_traits.hex_float_uses_minimal_precision_when_not_specified);
   1456  EXPECT_TRUE(native_traits.hex_float_optimizes_leading_digit_bit_count);
   1457 }
   1458 
   1459 }  // namespace
   1460 }  // namespace str_format_internal
   1461 ABSL_NAMESPACE_END
   1462 }  // namespace absl