tor-browser

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

str_cat_test.cc (24160B)


      1 // Copyright 2017 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 // Unit tests for all str_cat.h functions
     16 
     17 #include "absl/strings/str_cat.h"
     18 
     19 #include <cstddef>
     20 #include <cstdint>
     21 #include <cstdlib>
     22 #include <limits>
     23 #include <string>
     24 #include <vector>
     25 
     26 #include "gtest/gtest.h"
     27 #include "absl/base/config.h"
     28 #include "absl/strings/str_format.h"
     29 #include "absl/strings/string_view.h"
     30 
     31 #if defined(ABSL_HAVE_STD_STRING_VIEW)
     32 #include <string_view>
     33 #endif
     34 
     35 #ifdef __ANDROID__
     36 // Android assert messages only go to system log, so death tests cannot inspect
     37 // the message for matching.
     38 #define ABSL_EXPECT_DEBUG_DEATH(statement, regex) \
     39  EXPECT_DEBUG_DEATH(statement, ".*")
     40 #else
     41 #define ABSL_EXPECT_DEBUG_DEATH(statement, regex) \
     42  EXPECT_DEBUG_DEATH(statement, regex)
     43 #endif
     44 
     45 namespace {
     46 
     47 // Test absl::StrCat of ints and longs of various sizes and signdedness.
     48 TEST(StrCat, Ints) {
     49  const short s = -1;  // NOLINT(runtime/int)
     50  const uint16_t us = 2;
     51  const int i = -3;
     52  const unsigned int ui = 4;
     53  const long l = -5;                 // NOLINT(runtime/int)
     54  const unsigned long ul = 6;        // NOLINT(runtime/int)
     55  const long long ll = -7;           // NOLINT(runtime/int)
     56  const unsigned long long ull = 8;  // NOLINT(runtime/int)
     57  const ptrdiff_t ptrdiff = -9;
     58  const size_t size = 10;
     59  const intptr_t intptr = -12;
     60  const uintptr_t uintptr = 13;
     61  std::string answer;
     62  answer = absl::StrCat(s, us);
     63  EXPECT_EQ(answer, "-12");
     64  answer = absl::StrCat(i, ui);
     65  EXPECT_EQ(answer, "-34");
     66  answer = absl::StrCat(l, ul);
     67  EXPECT_EQ(answer, "-56");
     68  answer = absl::StrCat(ll, ull);
     69  EXPECT_EQ(answer, "-78");
     70  answer = absl::StrCat(ptrdiff, size);
     71  EXPECT_EQ(answer, "-910");
     72  answer = absl::StrCat(ptrdiff, intptr);
     73  EXPECT_EQ(answer, "-9-12");
     74  answer = absl::StrCat(uintptr, 0);
     75  EXPECT_EQ(answer, "130");
     76 }
     77 
     78 TEST(StrCat, Enums) {
     79  enum SmallNumbers { One = 1, Ten = 10 } e = Ten;
     80  EXPECT_EQ("10", absl::StrCat(e));
     81  EXPECT_EQ("1", absl::StrCat(One));
     82 
     83  enum class Option { Boxers = 1, Briefs = -1 };
     84 
     85  EXPECT_EQ("-1", absl::StrCat(Option::Briefs));
     86 
     87  enum class Airplane : uint64_t {
     88    Airbus = 1,
     89    Boeing = 1000,
     90    Canary = 10000000000  // too big for "int"
     91  };
     92 
     93  EXPECT_EQ("10000000000", absl::StrCat(Airplane::Canary));
     94 
     95  enum class TwoGig : int32_t {
     96    TwoToTheZero = 1,
     97    TwoToTheSixteenth = 1 << 16,
     98    TwoToTheThirtyFirst = INT32_MIN
     99  };
    100  EXPECT_EQ("65536", absl::StrCat(TwoGig::TwoToTheSixteenth));
    101  EXPECT_EQ("-2147483648", absl::StrCat(TwoGig::TwoToTheThirtyFirst));
    102  EXPECT_EQ("-1", absl::StrCat(static_cast<TwoGig>(-1)));
    103 
    104  enum class FourGig : uint32_t {
    105    TwoToTheZero = 1,
    106    TwoToTheSixteenth = 1 << 16,
    107    TwoToTheThirtyFirst = 1U << 31  // too big for "int"
    108  };
    109  EXPECT_EQ("65536", absl::StrCat(FourGig::TwoToTheSixteenth));
    110  EXPECT_EQ("2147483648", absl::StrCat(FourGig::TwoToTheThirtyFirst));
    111  EXPECT_EQ("4294967295", absl::StrCat(static_cast<FourGig>(-1)));
    112 
    113  EXPECT_EQ("10000000000", absl::StrCat(Airplane::Canary));
    114 }
    115 
    116 TEST(StrCat, Basics) {
    117  std::string result;
    118 
    119  std::string strs[] = {"Hello", "Cruel", "World"};
    120 
    121  std::string stdstrs[] = {
    122    "std::Hello",
    123    "std::Cruel",
    124    "std::World"
    125  };
    126 
    127  absl::string_view pieces[] = {"Hello", "Cruel", "World"};
    128 
    129  const char* c_strs[] = {
    130    "Hello",
    131    "Cruel",
    132    "World"
    133  };
    134 
    135  int32_t i32s[] = {'H', 'C', 'W'};
    136  uint64_t ui64s[] = {12345678910LL, 10987654321LL};
    137 
    138  EXPECT_EQ(absl::StrCat(), "");
    139 
    140  result = absl::StrCat(false, true, 2, 3);
    141  EXPECT_EQ(result, "0123");
    142 
    143  result = absl::StrCat(-1);
    144  EXPECT_EQ(result, "-1");
    145 
    146  result = absl::StrCat(absl::SixDigits(0.5));
    147  EXPECT_EQ(result, "0.5");
    148 
    149  result = absl::StrCat(strs[1], pieces[2]);
    150  EXPECT_EQ(result, "CruelWorld");
    151 
    152  result = absl::StrCat(stdstrs[1], " ", stdstrs[2]);
    153  EXPECT_EQ(result, "std::Cruel std::World");
    154 
    155  result = absl::StrCat(strs[0], ", ", pieces[2]);
    156  EXPECT_EQ(result, "Hello, World");
    157 
    158  result = absl::StrCat(strs[0], ", ", strs[1], " ", strs[2], "!");
    159  EXPECT_EQ(result, "Hello, Cruel World!");
    160 
    161  result = absl::StrCat(pieces[0], ", ", pieces[1], " ", pieces[2]);
    162  EXPECT_EQ(result, "Hello, Cruel World");
    163 
    164  result = absl::StrCat(c_strs[0], ", ", c_strs[1], " ", c_strs[2]);
    165  EXPECT_EQ(result, "Hello, Cruel World");
    166 
    167  result = absl::StrCat("ASCII ", i32s[0], ", ", i32s[1], " ", i32s[2], "!");
    168  EXPECT_EQ(result, "ASCII 72, 67 87!");
    169 
    170  result = absl::StrCat(ui64s[0], ", ", ui64s[1], "!");
    171  EXPECT_EQ(result, "12345678910, 10987654321!");
    172 
    173  std::string one =
    174      "1";  // Actually, it's the size of this string that we want; a
    175            // 64-bit build distinguishes between size_t and uint64_t,
    176            // even though they're both unsigned 64-bit values.
    177  result = absl::StrCat("And a ", one.size(), " and a ",
    178                        &result[2] - &result[0], " and a ", one, " 2 3 4", "!");
    179  EXPECT_EQ(result, "And a 1 and a 2 and a 1 2 3 4!");
    180 
    181  // result = absl::StrCat("Single chars won't compile", '!');
    182  // result = absl::StrCat("Neither will nullptrs", nullptr);
    183  result =
    184      absl::StrCat("To output a char by ASCII/numeric value, use +: ", '!' + 0);
    185  EXPECT_EQ(result, "To output a char by ASCII/numeric value, use +: 33");
    186 
    187  float f = 100000.5;
    188  result = absl::StrCat("A hundred K and a half is ", absl::SixDigits(f));
    189  EXPECT_EQ(result, "A hundred K and a half is 100000");
    190 
    191  f = 100001.5;
    192  result =
    193      absl::StrCat("A hundred K and one and a half is ", absl::SixDigits(f));
    194  EXPECT_EQ(result, "A hundred K and one and a half is 100002");
    195 
    196  double d = 100000.5;
    197  d *= d;
    198  result =
    199      absl::StrCat("A hundred K and a half squared is ", absl::SixDigits(d));
    200  EXPECT_EQ(result, "A hundred K and a half squared is 1.00001e+10");
    201 
    202  result = absl::StrCat(1, 2, 333, 4444, 55555, 666666, 7777777, 88888888,
    203                        999999999);
    204  EXPECT_EQ(result, "12333444455555666666777777788888888999999999");
    205 }
    206 
    207 TEST(StrCat, CornerCases) {
    208  std::string result;
    209 
    210  result = absl::StrCat("");  // NOLINT
    211  EXPECT_EQ(result, "");
    212  result = absl::StrCat("", "");
    213  EXPECT_EQ(result, "");
    214  result = absl::StrCat("", "", "");
    215  EXPECT_EQ(result, "");
    216  result = absl::StrCat("", "", "", "");
    217  EXPECT_EQ(result, "");
    218  result = absl::StrCat("", "", "", "", "");
    219  EXPECT_EQ(result, "");
    220 }
    221 
    222 #if defined(ABSL_HAVE_STD_STRING_VIEW)
    223 TEST(StrCat, StdStringView) {
    224  std::string_view pieces[] = {"Hello", ", ", "World", "!"};
    225  EXPECT_EQ(absl::StrCat(pieces[0], pieces[1], pieces[2], pieces[3]),
    226                         "Hello, World!");
    227 }
    228 #endif  // ABSL_HAVE_STD_STRING_VIEW
    229 
    230 TEST(StrCat, NullConstCharPtr) {
    231  const char* null = nullptr;
    232  EXPECT_EQ(absl::StrCat("mon", null, "key"), "monkey");
    233 }
    234 
    235 // A minimal allocator that uses malloc().
    236 template <typename T>
    237 struct Mallocator {
    238  typedef T value_type;
    239  typedef size_t size_type;
    240  typedef ptrdiff_t difference_type;
    241  typedef T* pointer;
    242  typedef const T* const_pointer;
    243  typedef T& reference;
    244  typedef const T& const_reference;
    245 
    246  size_type max_size() const {
    247    return size_t(std::numeric_limits<size_type>::max()) / sizeof(value_type);
    248  }
    249  template <typename U>
    250  struct rebind {
    251    typedef Mallocator<U> other;
    252  };
    253  Mallocator() = default;
    254  template <class U>
    255  Mallocator(const Mallocator<U>&) {}  // NOLINT(runtime/explicit)
    256 
    257  T* allocate(size_t n) { return static_cast<T*>(std::malloc(n * sizeof(T))); }
    258  void deallocate(T* p, size_t) { std::free(p); }
    259 };
    260 template <typename T, typename U>
    261 bool operator==(const Mallocator<T>&, const Mallocator<U>&) {
    262  return true;
    263 }
    264 template <typename T, typename U>
    265 bool operator!=(const Mallocator<T>&, const Mallocator<U>&) {
    266  return false;
    267 }
    268 
    269 TEST(StrCat, CustomAllocator) {
    270  using mstring =
    271      std::basic_string<char, std::char_traits<char>, Mallocator<char>>;
    272  const mstring str1("PARACHUTE OFF A BLIMP INTO MOSCONE!!");
    273 
    274  const mstring str2("Read this book about coffee tables");
    275 
    276  std::string result = absl::StrCat(str1, str2);
    277  EXPECT_EQ(result,
    278            "PARACHUTE OFF A BLIMP INTO MOSCONE!!"
    279            "Read this book about coffee tables");
    280 }
    281 
    282 TEST(StrCat, MaxArgs) {
    283  std::string result;
    284  // Test 10 up to 26 arguments, the old maximum
    285  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a");
    286  EXPECT_EQ(result, "123456789a");
    287  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b");
    288  EXPECT_EQ(result, "123456789ab");
    289  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c");
    290  EXPECT_EQ(result, "123456789abc");
    291  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d");
    292  EXPECT_EQ(result, "123456789abcd");
    293  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e");
    294  EXPECT_EQ(result, "123456789abcde");
    295  result =
    296      absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f");
    297  EXPECT_EQ(result, "123456789abcdef");
    298  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
    299                        "g");
    300  EXPECT_EQ(result, "123456789abcdefg");
    301  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
    302                        "g", "h");
    303  EXPECT_EQ(result, "123456789abcdefgh");
    304  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
    305                        "g", "h", "i");
    306  EXPECT_EQ(result, "123456789abcdefghi");
    307  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
    308                        "g", "h", "i", "j");
    309  EXPECT_EQ(result, "123456789abcdefghij");
    310  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
    311                        "g", "h", "i", "j", "k");
    312  EXPECT_EQ(result, "123456789abcdefghijk");
    313  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
    314                        "g", "h", "i", "j", "k", "l");
    315  EXPECT_EQ(result, "123456789abcdefghijkl");
    316  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
    317                        "g", "h", "i", "j", "k", "l", "m");
    318  EXPECT_EQ(result, "123456789abcdefghijklm");
    319  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
    320                        "g", "h", "i", "j", "k", "l", "m", "n");
    321  EXPECT_EQ(result, "123456789abcdefghijklmn");
    322  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
    323                        "g", "h", "i", "j", "k", "l", "m", "n", "o");
    324  EXPECT_EQ(result, "123456789abcdefghijklmno");
    325  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
    326                        "g", "h", "i", "j", "k", "l", "m", "n", "o", "p");
    327  EXPECT_EQ(result, "123456789abcdefghijklmnop");
    328  result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
    329                        "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q");
    330  EXPECT_EQ(result, "123456789abcdefghijklmnopq");
    331  // No limit thanks to C++11's variadic templates
    332  result = absl::StrCat(
    333      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "a", "b", "c", "d", "e", "f", "g", "h",
    334      "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
    335      "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
    336      "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z");
    337  EXPECT_EQ(result,
    338            "12345678910abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
    339 }
    340 
    341 TEST(StrAppend, Basics) {
    342  std::string result = "existing text";
    343 
    344  std::string strs[] = {"Hello", "Cruel", "World"};
    345 
    346  std::string stdstrs[] = {
    347    "std::Hello",
    348    "std::Cruel",
    349    "std::World"
    350  };
    351 
    352  absl::string_view pieces[] = {"Hello", "Cruel", "World"};
    353 
    354  const char* c_strs[] = {
    355    "Hello",
    356    "Cruel",
    357    "World"
    358  };
    359 
    360  int32_t i32s[] = {'H', 'C', 'W'};
    361  uint64_t ui64s[] = {12345678910LL, 10987654321LL};
    362 
    363  std::string::size_type old_size = result.size();
    364  absl::StrAppend(&result);
    365  EXPECT_EQ(result.size(), old_size);
    366 
    367  old_size = result.size();
    368  absl::StrAppend(&result, strs[0]);
    369  EXPECT_EQ(result.substr(old_size), "Hello");
    370 
    371  old_size = result.size();
    372  absl::StrAppend(&result, strs[1], pieces[2]);
    373  EXPECT_EQ(result.substr(old_size), "CruelWorld");
    374 
    375  old_size = result.size();
    376  absl::StrAppend(&result, stdstrs[0], ", ", pieces[2]);
    377  EXPECT_EQ(result.substr(old_size), "std::Hello, World");
    378 
    379  old_size = result.size();
    380  absl::StrAppend(&result, strs[0], ", ", stdstrs[1], " ", strs[2], "!");
    381  EXPECT_EQ(result.substr(old_size), "Hello, std::Cruel World!");
    382 
    383  old_size = result.size();
    384  absl::StrAppend(&result, pieces[0], ", ", pieces[1], " ", pieces[2]);
    385  EXPECT_EQ(result.substr(old_size), "Hello, Cruel World");
    386 
    387  old_size = result.size();
    388  absl::StrAppend(&result, c_strs[0], ", ", c_strs[1], " ", c_strs[2]);
    389  EXPECT_EQ(result.substr(old_size), "Hello, Cruel World");
    390 
    391  old_size = result.size();
    392  absl::StrAppend(&result, "ASCII ", i32s[0], ", ", i32s[1], " ", i32s[2], "!");
    393  EXPECT_EQ(result.substr(old_size), "ASCII 72, 67 87!");
    394 
    395  old_size = result.size();
    396  absl::StrAppend(&result, ui64s[0], ", ", ui64s[1], "!");
    397  EXPECT_EQ(result.substr(old_size), "12345678910, 10987654321!");
    398 
    399  std::string one =
    400      "1";  // Actually, it's the size of this string that we want; a
    401            // 64-bit build distinguishes between size_t and uint64_t,
    402            // even though they're both unsigned 64-bit values.
    403  old_size = result.size();
    404  absl::StrAppend(&result, "And a ", one.size(), " and a ",
    405                  &result[2] - &result[0], " and a ", one, " 2 3 4", "!");
    406  EXPECT_EQ(result.substr(old_size), "And a 1 and a 2 and a 1 2 3 4!");
    407 
    408  // result = absl::StrCat("Single chars won't compile", '!');
    409  // result = absl::StrCat("Neither will nullptrs", nullptr);
    410  old_size = result.size();
    411  absl::StrAppend(&result,
    412                  "To output a char by ASCII/numeric value, use +: ", '!' + 0);
    413  EXPECT_EQ(result.substr(old_size),
    414            "To output a char by ASCII/numeric value, use +: 33");
    415 
    416  // Test 9 arguments, the old maximum
    417  old_size = result.size();
    418  absl::StrAppend(&result, 1, 22, 333, 4444, 55555, 666666, 7777777, 88888888,
    419                  9);
    420  EXPECT_EQ(result.substr(old_size), "1223334444555556666667777777888888889");
    421 
    422  // No limit thanks to C++11's variadic templates
    423  old_size = result.size();
    424  absl::StrAppend(
    425      &result, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,                           //
    426      "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",  //
    427      "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",  //
    428      "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",  //
    429      "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",  //
    430      "No limit thanks to C++11's variadic templates");
    431  EXPECT_EQ(result.substr(old_size),
    432            "12345678910abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    433            "No limit thanks to C++11's variadic templates");
    434 }
    435 
    436 TEST(StrCat, VectorBoolReferenceTypes) {
    437  std::vector<bool> v;
    438  v.push_back(true);
    439  v.push_back(false);
    440  std::vector<bool> const& cv = v;
    441  // Test that vector<bool>::reference and vector<bool>::const_reference
    442  // are handled as if the were really bool types and not the proxy types
    443  // they really are.
    444  std::string result = absl::StrCat(v[0], v[1], cv[0], cv[1]); // NOLINT
    445  EXPECT_EQ(result, "1010");
    446 }
    447 
    448 // Passing nullptr to memcpy is undefined behavior and this test
    449 // provides coverage of codepaths that handle empty strings with nullptrs.
    450 TEST(StrCat, AvoidsMemcpyWithNullptr) {
    451  EXPECT_EQ(absl::StrCat(42, absl::string_view{}), "42");
    452 
    453  // Cover CatPieces code.
    454  EXPECT_EQ(absl::StrCat(1, 2, 3, 4, 5, absl::string_view{}), "12345");
    455 
    456  // Cover AppendPieces.
    457  std::string result;
    458  absl::StrAppend(&result, 1, 2, 3, 4, 5, absl::string_view{});
    459  EXPECT_EQ(result, "12345");
    460 }
    461 
    462 #if GTEST_HAS_DEATH_TEST
    463 TEST(StrAppend, Death) {
    464  std::string s = "self";
    465  // on linux it's "assertion", on mac it's "Assertion",
    466  // on chromiumos it's "Assertion ... failed".
    467  ABSL_EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s.c_str() + 1),
    468                          "ssertion.*failed");
    469  ABSL_EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s), "ssertion.*failed");
    470 }
    471 #endif  // GTEST_HAS_DEATH_TEST
    472 
    473 TEST(StrAppend, CornerCases) {
    474  std::string result;
    475  absl::StrAppend(&result, "");
    476  EXPECT_EQ(result, "");
    477  absl::StrAppend(&result, "", "");
    478  EXPECT_EQ(result, "");
    479  absl::StrAppend(&result, "", "", "");
    480  EXPECT_EQ(result, "");
    481  absl::StrAppend(&result, "", "", "", "");
    482  EXPECT_EQ(result, "");
    483  absl::StrAppend(&result, "", "", "", "", "");
    484  EXPECT_EQ(result, "");
    485 }
    486 
    487 TEST(StrAppend, CornerCasesNonEmptyAppend) {
    488  for (std::string result : {"hello", "a string too long to fit in the SSO"}) {
    489    const std::string expected = result;
    490    absl::StrAppend(&result, "");
    491    EXPECT_EQ(result, expected);
    492    absl::StrAppend(&result, "", "");
    493    EXPECT_EQ(result, expected);
    494    absl::StrAppend(&result, "", "", "");
    495    EXPECT_EQ(result, expected);
    496    absl::StrAppend(&result, "", "", "", "");
    497    EXPECT_EQ(result, expected);
    498    absl::StrAppend(&result, "", "", "", "", "");
    499    EXPECT_EQ(result, expected);
    500  }
    501 }
    502 
    503 template <typename IntType>
    504 void CheckHex(IntType v, const char* nopad_format, const char* zeropad_format,
    505              const char* spacepad_format) {
    506  char expected[256];
    507 
    508  std::string actual = absl::StrCat(absl::Hex(v, absl::kNoPad));
    509  snprintf(expected, sizeof(expected), nopad_format, v);
    510  EXPECT_EQ(expected, actual) << " decimal value " << v;
    511 
    512  for (int spec = absl::kZeroPad2; spec <= absl::kZeroPad20; ++spec) {
    513    std::string actual =
    514        absl::StrCat(absl::Hex(v, static_cast<absl::PadSpec>(spec)));
    515    snprintf(expected, sizeof(expected), zeropad_format,
    516             spec - absl::kZeroPad2 + 2, v);
    517    EXPECT_EQ(expected, actual) << " decimal value " << v;
    518  }
    519 
    520  for (int spec = absl::kSpacePad2; spec <= absl::kSpacePad20; ++spec) {
    521    std::string actual =
    522        absl::StrCat(absl::Hex(v, static_cast<absl::PadSpec>(spec)));
    523    snprintf(expected, sizeof(expected), spacepad_format,
    524             spec - absl::kSpacePad2 + 2, v);
    525    EXPECT_EQ(expected, actual) << " decimal value " << v;
    526  }
    527 }
    528 
    529 template <typename IntType>
    530 void CheckDec(IntType v, const char* nopad_format, const char* zeropad_format,
    531              const char* spacepad_format) {
    532  char expected[256];
    533 
    534  std::string actual = absl::StrCat(absl::Dec(v, absl::kNoPad));
    535  snprintf(expected, sizeof(expected), nopad_format, v);
    536  EXPECT_EQ(expected, actual) << " decimal value " << v;
    537 
    538  for (int spec = absl::kZeroPad2; spec <= absl::kZeroPad20; ++spec) {
    539    std::string actual =
    540        absl::StrCat(absl::Dec(v, static_cast<absl::PadSpec>(spec)));
    541    snprintf(expected, sizeof(expected), zeropad_format,
    542             spec - absl::kZeroPad2 + 2, v);
    543    EXPECT_EQ(expected, actual)
    544        << " decimal value " << v << " format '" << zeropad_format
    545        << "' digits " << (spec - absl::kZeroPad2 + 2);
    546  }
    547 
    548  for (int spec = absl::kSpacePad2; spec <= absl::kSpacePad20; ++spec) {
    549    std::string actual =
    550        absl::StrCat(absl::Dec(v, static_cast<absl::PadSpec>(spec)));
    551    snprintf(expected, sizeof(expected), spacepad_format,
    552             spec - absl::kSpacePad2 + 2, v);
    553    EXPECT_EQ(expected, actual)
    554        << " decimal value " << v << " format '" << spacepad_format
    555        << "' digits " << (spec - absl::kSpacePad2 + 2);
    556  }
    557 }
    558 
    559 void CheckHexDec64(uint64_t v) {
    560  unsigned long long ullv = v;  // NOLINT(runtime/int)
    561 
    562  CheckHex(ullv, "%llx", "%0*llx", "%*llx");
    563  CheckDec(ullv, "%llu", "%0*llu", "%*llu");
    564 
    565  long long llv = static_cast<long long>(ullv);  // NOLINT(runtime/int)
    566  CheckDec(llv, "%lld", "%0*lld", "%*lld");
    567 
    568  if (sizeof(v) == sizeof(&v)) {
    569    auto uintptr = static_cast<uintptr_t>(v);
    570    void* ptr = reinterpret_cast<void*>(uintptr);
    571    CheckHex(ptr, "%llx", "%0*llx", "%*llx");
    572  }
    573 }
    574 
    575 void CheckHexDec32(uint32_t uv) {
    576  CheckHex(uv, "%x", "%0*x", "%*x");
    577  CheckDec(uv, "%u", "%0*u", "%*u");
    578  int32_t v = static_cast<int32_t>(uv);
    579  CheckDec(v, "%d", "%0*d", "%*d");
    580 
    581  if (sizeof(v) == sizeof(&v)) {
    582    auto uintptr = static_cast<uintptr_t>(v);
    583    void* ptr = reinterpret_cast<void*>(uintptr);
    584    CheckHex(ptr, "%x", "%0*x", "%*x");
    585  }
    586 }
    587 
    588 void CheckAll(uint64_t v) {
    589  CheckHexDec64(v);
    590  CheckHexDec32(static_cast<uint32_t>(v));
    591 }
    592 
    593 void TestFastPrints() {
    594  // Test all small ints; there aren't many and they're common.
    595  for (int i = 0; i < 10000; i++) {
    596    CheckAll(i);
    597  }
    598 
    599  CheckAll(std::numeric_limits<uint64_t>::max());
    600  CheckAll(std::numeric_limits<uint64_t>::max() - 1);
    601  CheckAll(std::numeric_limits<int64_t>::min());
    602  CheckAll(std::numeric_limits<int64_t>::min() + 1);
    603  CheckAll(std::numeric_limits<uint32_t>::max());
    604  CheckAll(std::numeric_limits<uint32_t>::max() - 1);
    605  CheckAll(std::numeric_limits<int32_t>::min());
    606  CheckAll(std::numeric_limits<int32_t>::min() + 1);
    607  CheckAll(999999999);              // fits in 32 bits
    608  CheckAll(1000000000);             // fits in 32 bits
    609  CheckAll(9999999999);             // doesn't fit in 32 bits
    610  CheckAll(10000000000);            // doesn't fit in 32 bits
    611  CheckAll(999999999999999999);     // fits in signed 64-bit
    612  CheckAll(9999999999999999999u);   // fits in unsigned 64-bit, but not signed.
    613  CheckAll(1000000000000000000);    // fits in signed 64-bit
    614  CheckAll(10000000000000000000u);  // fits in unsigned 64-bit, but not signed.
    615 
    616  CheckAll(999999999876543210);    // check all decimal digits, signed
    617  CheckAll(9999999999876543210u);  // check all decimal digits, unsigned.
    618  CheckAll(0x123456789abcdef0);    // check all hex digits
    619  CheckAll(0x12345678);
    620 
    621  int8_t minus_one_8bit = -1;
    622  EXPECT_EQ("ff", absl::StrCat(absl::Hex(minus_one_8bit)));
    623 
    624  int16_t minus_one_16bit = -1;
    625  EXPECT_EQ("ffff", absl::StrCat(absl::Hex(minus_one_16bit)));
    626 }
    627 
    628 TEST(Numbers, TestFunctionsMovedOverFromNumbersMain) {
    629  TestFastPrints();
    630 }
    631 
    632 struct PointStringify {
    633  template <typename FormatSink>
    634  friend void AbslStringify(FormatSink& sink, const PointStringify& p) {
    635    sink.Append("(");
    636    sink.Append(absl::StrCat(p.x));
    637    sink.Append(", ");
    638    sink.Append(absl::StrCat(p.y));
    639    sink.Append(")");
    640  }
    641 
    642  double x = 10.0;
    643  double y = 20.0;
    644 };
    645 
    646 TEST(StrCat, AbslStringifyExample) {
    647  PointStringify p;
    648  EXPECT_EQ(absl::StrCat(p), "(10, 20)");
    649  EXPECT_EQ(absl::StrCat("a ", p, " z"), "a (10, 20) z");
    650 }
    651 
    652 struct PointStringifyUsingFormat {
    653  template <typename FormatSink>
    654  friend void AbslStringify(FormatSink& sink,
    655                            const PointStringifyUsingFormat& p) {
    656    absl::Format(&sink, "(%g, %g)", p.x, p.y);
    657  }
    658 
    659  double x = 10.0;
    660  double y = 20.0;
    661 };
    662 
    663 TEST(StrCat, AbslStringifyExampleUsingFormat) {
    664  PointStringifyUsingFormat p;
    665  EXPECT_EQ(absl::StrCat(p), "(10, 20)");
    666  EXPECT_EQ(absl::StrCat("a ", p, " z"), "a (10, 20) z");
    667 }
    668 
    669 enum class EnumWithStringify { Many = 0, Choices = 1 };
    670 
    671 template <typename Sink>
    672 void AbslStringify(Sink& sink, EnumWithStringify e) {
    673  absl::Format(&sink, "%s", e == EnumWithStringify::Many ? "Many" : "Choices");
    674 }
    675 
    676 TEST(StrCat, AbslStringifyWithEnum) {
    677  const auto e = EnumWithStringify::Choices;
    678  EXPECT_EQ(absl::StrCat(e), "Choices");
    679 }
    680 
    681 template <typename Integer>
    682 void CheckSingleArgumentIntegerLimits() {
    683  Integer max = std::numeric_limits<Integer>::max();
    684  Integer min = std::numeric_limits<Integer>::min();
    685 
    686  EXPECT_EQ(absl::StrCat(max), std::to_string(max));
    687  EXPECT_EQ(absl::StrCat(min), std::to_string(min));
    688 }
    689 
    690 TEST(StrCat, SingleArgumentLimits) {
    691  CheckSingleArgumentIntegerLimits<int32_t>();
    692  CheckSingleArgumentIntegerLimits<uint32_t>();
    693  CheckSingleArgumentIntegerLimits<int64_t>();
    694  CheckSingleArgumentIntegerLimits<uint64_t>();
    695 }
    696 
    697 }  // namespace