convert_test.cc
Go to the documentation of this file.
1 #include <errno.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <cctype>
5 #include <cmath>
6 #include <string>
7 
8 #include "gtest/gtest.h"
10 
11 namespace absl {
12 namespace str_format_internal {
13 namespace {
14 
15 template <typename T, size_t N>
16 size_t ArraySize(T (&)[N]) {
17  return N;
18 }
19 
20 std::string LengthModFor(float) { return ""; }
21 std::string LengthModFor(double) { return ""; }
22 std::string LengthModFor(long double) { return "L"; }
23 std::string LengthModFor(char) { return "hh"; }
24 std::string LengthModFor(signed char) { return "hh"; }
25 std::string LengthModFor(unsigned char) { return "hh"; }
26 std::string LengthModFor(short) { return "h"; } // NOLINT
27 std::string LengthModFor(unsigned short) { return "h"; } // NOLINT
28 std::string LengthModFor(int) { return ""; }
29 std::string LengthModFor(unsigned) { return ""; }
30 std::string LengthModFor(long) { return "l"; } // NOLINT
31 std::string LengthModFor(unsigned long) { return "l"; } // NOLINT
32 std::string LengthModFor(long long) { return "ll"; } // NOLINT
33 std::string LengthModFor(unsigned long long) { return "ll"; } // NOLINT
34 
35 std::string EscCharImpl(int v) {
36  if (std::isprint(static_cast<unsigned char>(v))) {
37  return std::string(1, static_cast<char>(v));
38  }
39  char buf[64];
40  int n = snprintf(buf, sizeof(buf), "\\%#.2x",
41  static_cast<unsigned>(v & 0xff));
42  assert(n > 0 && n < sizeof(buf));
43  return std::string(buf, n);
44 }
45 
46 std::string Esc(char v) { return EscCharImpl(v); }
47 std::string Esc(signed char v) { return EscCharImpl(v); }
48 std::string Esc(unsigned char v) { return EscCharImpl(v); }
49 
50 template <typename T>
51 std::string Esc(const T &v) {
52  std::ostringstream oss;
53  oss << v;
54  return oss.str();
55 }
56 
57 void StrAppend(std::string *dst, const char *format, va_list ap) {
58  // First try with a small fixed size buffer
59  static const int kSpaceLength = 1024;
60  char space[kSpaceLength];
61 
62  // It's possible for methods that use a va_list to invalidate
63  // the data in it upon use. The fix is to make a copy
64  // of the structure before using it and use that copy instead.
65  va_list backup_ap;
66  va_copy(backup_ap, ap);
67  int result = vsnprintf(space, kSpaceLength, format, backup_ap);
68  va_end(backup_ap);
69  if (result < kSpaceLength) {
70  if (result >= 0) {
71  // Normal case -- everything fit.
72  dst->append(space, result);
73  return;
74  }
75  if (result < 0) {
76  // Just an error.
77  return;
78  }
79  }
80 
81  // Increase the buffer size to the size requested by vsnprintf,
82  // plus one for the closing \0.
83  int length = result + 1;
84  char *buf = new char[length];
85 
86  // Restore the va_list before we use it again
87  va_copy(backup_ap, ap);
88  result = vsnprintf(buf, length, format, backup_ap);
89  va_end(backup_ap);
90 
91  if (result >= 0 && result < length) {
92  // It fit
93  dst->append(buf, result);
94  }
95  delete[] buf;
96 }
97 
98 std::string StrPrint(const char *format, ...) {
99  va_list ap;
100  va_start(ap, format);
101  std::string result;
102  StrAppend(&result, format, ap);
103  va_end(ap);
104  return result;
105 }
106 
107 class FormatConvertTest : public ::testing::Test { };
108 
109 template <typename T>
110 void TestStringConvert(const T& str) {
111  const FormatArgImpl args[] = {FormatArgImpl(str)};
112  struct Expectation {
113  const char *out;
114  const char *fmt;
115  };
116  const Expectation kExpect[] = {
117  {"hello", "%1$s" },
118  {"", "%1$.s" },
119  {"", "%1$.0s" },
120  {"h", "%1$.1s" },
121  {"he", "%1$.2s" },
122  {"hello", "%1$.10s" },
123  {" hello", "%1$6s" },
124  {" he", "%1$5.2s" },
125  {"he ", "%1$-5.2s" },
126  {"hello ", "%1$-6.10s" },
127  };
128  for (const Expectation &e : kExpect) {
129  UntypedFormatSpecImpl format(e.fmt);
130  EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args)));
131  }
132 }
133 
134 TEST_F(FormatConvertTest, BasicString) {
135  TestStringConvert("hello"); // As char array.
136  TestStringConvert(static_cast<const char*>("hello"));
137  TestStringConvert(std::string("hello"));
138  TestStringConvert(string_view("hello"));
139 }
140 
141 TEST_F(FormatConvertTest, NullString) {
142  const char* p = nullptr;
143  UntypedFormatSpecImpl format("%s");
144  EXPECT_EQ("", FormatPack(format, {FormatArgImpl(p)}));
145 }
146 
147 TEST_F(FormatConvertTest, StringPrecision) {
148  // We cap at the precision.
149  char c = 'a';
150  const char* p = &c;
151  UntypedFormatSpecImpl format("%.1s");
152  EXPECT_EQ("a", FormatPack(format, {FormatArgImpl(p)}));
153 
154  // We cap at the nul terminator.
155  p = "ABC";
156  UntypedFormatSpecImpl format2("%.10s");
157  EXPECT_EQ("ABC", FormatPack(format2, {FormatArgImpl(p)}));
158 }
159 
160 TEST_F(FormatConvertTest, Pointer) {
161 #ifdef _MSC_VER
162  // MSVC's printf implementation prints pointers differently. We can't easily
163  // compare our implementation to theirs.
164  return;
165 #endif
166  static int x = 0;
167  const int *xp = &x;
168  char c = 'h';
169  char *mcp = &c;
170  const char *cp = "hi";
171  const char *cnil = nullptr;
172  const int *inil = nullptr;
173  using VoidF = void (*)();
174  VoidF fp = [] {}, fnil = nullptr;
175  volatile char vc;
176  volatile char* vcp = &vc;
177  volatile char* vcnil = nullptr;
178  const FormatArgImpl args[] = {
179  FormatArgImpl(xp), FormatArgImpl(cp), FormatArgImpl(inil),
180  FormatArgImpl(cnil), FormatArgImpl(mcp), FormatArgImpl(fp),
181  FormatArgImpl(fnil), FormatArgImpl(vcp), FormatArgImpl(vcnil),
182  };
183  struct Expectation {
185  const char *fmt;
186  };
187  const Expectation kExpect[] = {
188  {StrPrint("%p", &x), "%p"},
189  {StrPrint("%20p", &x), "%20p"},
190  {StrPrint("%.1p", &x), "%.1p"},
191  {StrPrint("%.20p", &x), "%.20p"},
192  {StrPrint("%30.20p", &x), "%30.20p"},
193 
194  {StrPrint("%-p", &x), "%-p"},
195  {StrPrint("%-20p", &x), "%-20p"},
196  {StrPrint("%-.1p", &x), "%-.1p"},
197  {StrPrint("%.20p", &x), "%.20p"},
198  {StrPrint("%-30.20p", &x), "%-30.20p"},
199 
200  {StrPrint("%p", cp), "%2$p"}, // const char*
201  {"(nil)", "%3$p"}, // null const char *
202  {"(nil)", "%4$p"}, // null const int *
203  {StrPrint("%p", mcp), "%5$p"}, // nonconst char*
204 
205  {StrPrint("%p", fp), "%6$p"}, // function pointer
206  {StrPrint("%p", vcp), "%8$p"}, // function pointer
207 
208 #ifndef __APPLE__
209  // Apple's printf differs here (0x0 vs. nil)
210  {StrPrint("%p", fnil), "%7$p"}, // null function pointer
211  {StrPrint("%p", vcnil), "%9$p"}, // null function pointer
212 #endif
213  };
214  for (const Expectation &e : kExpect) {
215  UntypedFormatSpecImpl format(e.fmt);
216  EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args))) << e.fmt;
217  }
218 }
219 
220 struct Cardinal {
221  enum Pos { k1 = 1, k2 = 2, k3 = 3 };
222  enum Neg { kM1 = -1, kM2 = -2, kM3 = -3 };
223 };
224 
225 TEST_F(FormatConvertTest, Enum) {
226  const Cardinal::Pos k3 = Cardinal::k3;
227  const Cardinal::Neg km3 = Cardinal::kM3;
228  const FormatArgImpl args[] = {FormatArgImpl(k3), FormatArgImpl(km3)};
229  UntypedFormatSpecImpl format("%1$d");
230  UntypedFormatSpecImpl format2("%2$d");
231  EXPECT_EQ("3", FormatPack(format, absl::MakeSpan(args)));
232  EXPECT_EQ("-3", FormatPack(format2, absl::MakeSpan(args)));
233 }
234 
235 template <typename T>
236 class TypedFormatConvertTest : public FormatConvertTest { };
237 
238 TYPED_TEST_SUITE_P(TypedFormatConvertTest);
239 
240 std::vector<std::string> AllFlagCombinations() {
241  const char kFlags[] = {'-', '#', '0', '+', ' '};
242  std::vector<std::string> result;
243  for (size_t fsi = 0; fsi < (1ull << ArraySize(kFlags)); ++fsi) {
244  std::string flag_set;
245  for (size_t fi = 0; fi < ArraySize(kFlags); ++fi)
246  if (fsi & (1ull << fi))
247  flag_set += kFlags[fi];
248  result.push_back(flag_set);
249  }
250  return result;
251 }
252 
253 TYPED_TEST_P(TypedFormatConvertTest, AllIntsWithFlags) {
254  typedef TypeParam T;
255  typedef typename std::make_unsigned<T>::type UnsignedT;
256  using remove_volatile_t = typename std::remove_volatile<T>::type;
257  const T kMin = std::numeric_limits<remove_volatile_t>::min();
258  const T kMax = std::numeric_limits<remove_volatile_t>::max();
259  const T kVals[] = {
263  remove_volatile_t(123),
264  remove_volatile_t(-1),
265  remove_volatile_t(-2),
266  remove_volatile_t(-3),
267  remove_volatile_t(-123),
269  kMax - remove_volatile_t(1),
270  kMax,
271  kMin + remove_volatile_t(1),
272  kMin,
273  };
274  const char kConvChars[] = {'d', 'i', 'u', 'o', 'x', 'X'};
275  const std::string kWid[] = {"", "4", "10"};
276  const std::string kPrec[] = {"", ".", ".0", ".4", ".10"};
277 
278  const std::vector<std::string> flag_sets = AllFlagCombinations();
279 
280  for (size_t vi = 0; vi < ArraySize(kVals); ++vi) {
281  const T val = kVals[vi];
282  SCOPED_TRACE(Esc(val));
283  const FormatArgImpl args[] = {FormatArgImpl(val)};
284  for (size_t ci = 0; ci < ArraySize(kConvChars); ++ci) {
285  const char conv_char = kConvChars[ci];
286  for (size_t fsi = 0; fsi < flag_sets.size(); ++fsi) {
287  const std::string &flag_set = flag_sets[fsi];
288  for (size_t wi = 0; wi < ArraySize(kWid); ++wi) {
289  const std::string &wid = kWid[wi];
290  for (size_t pi = 0; pi < ArraySize(kPrec); ++pi) {
291  const std::string &prec = kPrec[pi];
292 
293  const bool is_signed_conv = (conv_char == 'd' || conv_char == 'i');
294  const bool is_unsigned_to_signed =
295  !std::is_signed<T>::value && is_signed_conv;
296  // Don't consider sign-related flags '+' and ' ' when doing
297  // unsigned to signed conversions.
298  if (is_unsigned_to_signed &&
299  flag_set.find_first_of("+ ") != std::string::npos) {
300  continue;
301  }
302 
303  std::string new_fmt("%");
304  new_fmt += flag_set;
305  new_fmt += wid;
306  new_fmt += prec;
307  // old and new always agree up to here.
308  std::string old_fmt = new_fmt;
309  new_fmt += conv_char;
310  std::string old_result;
311  if (is_unsigned_to_signed) {
312  // don't expect agreement on unsigned formatted as signed,
313  // as printf can't do that conversion properly. For those
314  // cases, we do expect agreement with printf with a "%u"
315  // and the unsigned equivalent of 'val'.
316  UnsignedT uval = val;
317  old_fmt += LengthModFor(uval);
318  old_fmt += "u";
319  old_result = StrPrint(old_fmt.c_str(), uval);
320  } else {
321  old_fmt += LengthModFor(val);
322  old_fmt += conv_char;
323  old_result = StrPrint(old_fmt.c_str(), val);
324  }
325 
326  SCOPED_TRACE(std::string() + " old_fmt: \"" + old_fmt +
327  "\"'"
328  " new_fmt: \"" +
329  new_fmt + "\"");
330  UntypedFormatSpecImpl format(new_fmt);
331  EXPECT_EQ(old_result, FormatPack(format, absl::MakeSpan(args)));
332  }
333  }
334  }
335  }
336  }
337 }
338 
339 TYPED_TEST_P(TypedFormatConvertTest, Char) {
340  typedef TypeParam T;
341  using remove_volatile_t = typename std::remove_volatile<T>::type;
342  static const T kMin = std::numeric_limits<remove_volatile_t>::min();
343  static const T kMax = std::numeric_limits<remove_volatile_t>::max();
344  T kVals[] = {
348  kMin + remove_volatile_t(1), kMin,
349  kMax - remove_volatile_t(1), kMax
350  };
351  for (const T &c : kVals) {
352  const FormatArgImpl args[] = {FormatArgImpl(c)};
353  UntypedFormatSpecImpl format("%c");
354  EXPECT_EQ(StrPrint("%c", c), FormatPack(format, absl::MakeSpan(args)));
355  }
356 }
357 
358 REGISTER_TYPED_TEST_CASE_P(TypedFormatConvertTest, AllIntsWithFlags, Char);
359 
360 typedef ::testing::Types<
361  int, unsigned, volatile int,
362  short, unsigned short,
363  long, unsigned long,
364  long long, unsigned long long,
365  signed char, unsigned char, char>
366  AllIntTypes;
367 INSTANTIATE_TYPED_TEST_CASE_P(TypedFormatConvertTestWithAllIntTypes,
368  TypedFormatConvertTest, AllIntTypes);
369 
370 TEST_F(FormatConvertTest, VectorBool) {
371  // Make sure vector<bool>'s values behave as bools.
372  std::vector<bool> v = {true, false};
373  const std::vector<bool> cv = {true, false};
374  EXPECT_EQ("1,0,1,0",
375  FormatPack(UntypedFormatSpecImpl("%d,%d,%d,%d"),
377  {FormatArgImpl(v[0]), FormatArgImpl(v[1]),
378  FormatArgImpl(cv[0]), FormatArgImpl(cv[1])})));
379 }
380 
381 TEST_F(FormatConvertTest, Uint128) {
382  absl::uint128 v = static_cast<absl::uint128>(0x1234567890abcdef) * 1979;
384  const FormatArgImpl args[] = {FormatArgImpl(v), FormatArgImpl(max)};
385 
386  struct Case {
387  const char* format;
388  const char* expected;
389  } cases[] = {
390  {"%1$d", "2595989796776606496405"},
391  {"%1$30d", " 2595989796776606496405"},
392  {"%1$-30d", "2595989796776606496405 "},
393  {"%1$u", "2595989796776606496405"},
394  {"%1$x", "8cba9876066020f695"},
395  {"%2$d", "340282366920938463463374607431768211455"},
396  {"%2$u", "340282366920938463463374607431768211455"},
397  {"%2$x", "ffffffffffffffffffffffffffffffff"},
398  };
399 
400  for (auto c : cases) {
401  UntypedFormatSpecImpl format(c.format);
402  EXPECT_EQ(c.expected, FormatPack(format, absl::MakeSpan(args)));
403  }
404 }
405 
406 TEST_F(FormatConvertTest, Float) {
407 #ifdef _MSC_VER
408  // MSVC has a different rounding policy than us so we can't test our
409  // implementation against the native one there.
410  return;
411 #endif // _MSC_VER
412 
413  const char *const kFormats[] = {
414  "%", "%.3", "%8.5", "%9", "%.60", "%.30", "%03", "%+",
415  "% ", "%-10", "%#15.3", "%#.0", "%.0", "%1$*2$", "%1$.*2$"};
416 
417  std::vector<double> doubles = {0.0,
418  -0.0,
419  .99999999999999,
420  99999999999999.,
421  std::numeric_limits<double>::max(),
422  -std::numeric_limits<double>::max(),
423  std::numeric_limits<double>::min(),
424  -std::numeric_limits<double>::min(),
425  std::numeric_limits<double>::lowest(),
426  -std::numeric_limits<double>::lowest(),
427  std::numeric_limits<double>::epsilon(),
428  std::numeric_limits<double>::epsilon() + 1,
429  std::numeric_limits<double>::infinity(),
430  -std::numeric_limits<double>::infinity()};
431 
432 #ifndef __APPLE__
433  // Apple formats NaN differently (+nan) vs. (nan)
434  doubles.push_back(std::nan(""));
435 #endif
436 
437  // Some regression tests.
438  doubles.push_back(0.99999999999999989);
439 
440  if (std::numeric_limits<double>::has_denorm != std::denorm_absent) {
441  doubles.push_back(std::numeric_limits<double>::denorm_min());
442  doubles.push_back(-std::numeric_limits<double>::denorm_min());
443  }
444 
445  for (double base :
446  {1., 12., 123., 1234., 12345., 123456., 1234567., 12345678., 123456789.,
447  1234567890., 12345678901., 123456789012., 1234567890123.}) {
448  for (int exp = -123; exp <= 123; ++exp) {
449  for (int sign : {1, -1}) {
450  doubles.push_back(sign * std::ldexp(base, exp));
451  }
452  }
453  }
454 
455  for (const char *fmt : kFormats) {
456  for (char f : {'f', 'F', //
457  'g', 'G', //
458  'a', 'A', //
459  'e', 'E'}) {
460  std::string fmt_str = std::string(fmt) + f;
461  for (double d : doubles) {
462  int i = -10;
463  FormatArgImpl args[2] = {FormatArgImpl(d), FormatArgImpl(i)};
464  UntypedFormatSpecImpl format(fmt_str);
465  // We use ASSERT_EQ here because failures are usually correlated and a
466  // bug would print way too many failed expectations causing the test to
467  // time out.
468  ASSERT_EQ(StrPrint(fmt_str.c_str(), d, i),
469  FormatPack(format, absl::MakeSpan(args)))
470  << fmt_str << " " << StrPrint("%.18g", d) << " "
471  << StrPrint("%.999f", d);
472  }
473  }
474  }
475 }
476 
477 TEST_F(FormatConvertTest, LongDouble) {
478  const char *const kFormats[] = {"%", "%.3", "%8.5", "%9",
479  "%.60", "%+", "% ", "%-10"};
480 
481  // This value is not representable in double, but it is in long double that
482  // uses the extended format.
483  // This is to verify that we are not truncating the value mistakenly through a
484  // double.
485  long double very_precise = 10000000000000000.25L;
486 
487  std::vector<long double> doubles = {
488  0.0,
489  -0.0,
490  very_precise,
491  1 / very_precise,
492  std::numeric_limits<long double>::max(),
493  -std::numeric_limits<long double>::max(),
494  std::numeric_limits<long double>::min(),
495  -std::numeric_limits<long double>::min(),
496  std::numeric_limits<long double>::infinity(),
497  -std::numeric_limits<long double>::infinity()};
498 
499  for (const char *fmt : kFormats) {
500  for (char f : {'f', 'F', //
501  'g', 'G', //
502  'a', 'A', //
503  'e', 'E'}) {
504  std::string fmt_str = std::string(fmt) + 'L' + f;
505  for (auto d : doubles) {
506  FormatArgImpl arg(d);
507  UntypedFormatSpecImpl format(fmt_str);
508  // We use ASSERT_EQ here because failures are usually correlated and a
509  // bug would print way too many failed expectations causing the test to
510  // time out.
511  ASSERT_EQ(StrPrint(fmt_str.c_str(), d),
512  FormatPack(format, {&arg, 1}))
513  << fmt_str << " " << StrPrint("%.18Lg", d) << " "
514  << StrPrint("%.999Lf", d);
515  }
516  }
517  }
518 }
519 
520 TEST_F(FormatConvertTest, IntAsFloat) {
521  const int kMin = std::numeric_limits<int>::min();
522  const int kMax = std::numeric_limits<int>::max();
523  const int ia[] = {
524  1, 2, 3, 123,
525  -1, -2, -3, -123,
526  0, kMax - 1, kMax, kMin + 1, kMin };
527  for (const int fx : ia) {
528  SCOPED_TRACE(fx);
529  const FormatArgImpl args[] = {FormatArgImpl(fx)};
530  struct Expectation {
531  int line;
533  const char *fmt;
534  };
535  const double dx = static_cast<double>(fx);
536  const Expectation kExpect[] = {
537  { __LINE__, StrPrint("%f", dx), "%f" },
538  { __LINE__, StrPrint("%12f", dx), "%12f" },
539  { __LINE__, StrPrint("%.12f", dx), "%.12f" },
540  { __LINE__, StrPrint("%12a", dx), "%12a" },
541  { __LINE__, StrPrint("%.12a", dx), "%.12a" },
542  };
543  for (const Expectation &e : kExpect) {
544  SCOPED_TRACE(e.line);
545  SCOPED_TRACE(e.fmt);
546  UntypedFormatSpecImpl format(e.fmt);
547  EXPECT_EQ(e.out, FormatPack(format, absl::MakeSpan(args)));
548  }
549  }
550 }
551 
552 template <typename T>
553 bool FormatFails(const char* test_format, T value) {
554  std::string format_string = std::string("<<") + test_format + ">>";
555  UntypedFormatSpecImpl format(format_string);
556 
557  int one = 1;
558  const FormatArgImpl args[] = {FormatArgImpl(value), FormatArgImpl(one)};
559  EXPECT_EQ(FormatPack(format, absl::MakeSpan(args)), "")
560  << "format=" << test_format << " value=" << value;
561  return FormatPack(format, absl::MakeSpan(args)).empty();
562 }
563 
564 TEST_F(FormatConvertTest, ExpectedFailures) {
565  // Int input
566  EXPECT_TRUE(FormatFails("%p", 1));
567  EXPECT_TRUE(FormatFails("%s", 1));
568  EXPECT_TRUE(FormatFails("%n", 1));
569 
570  // Double input
571  EXPECT_TRUE(FormatFails("%p", 1.));
572  EXPECT_TRUE(FormatFails("%s", 1.));
573  EXPECT_TRUE(FormatFails("%n", 1.));
574  EXPECT_TRUE(FormatFails("%c", 1.));
575  EXPECT_TRUE(FormatFails("%d", 1.));
576  EXPECT_TRUE(FormatFails("%x", 1.));
577  EXPECT_TRUE(FormatFails("%*d", 1.));
578 
579  // String input
580  EXPECT_TRUE(FormatFails("%n", ""));
581  EXPECT_TRUE(FormatFails("%c", ""));
582  EXPECT_TRUE(FormatFails("%d", ""));
583  EXPECT_TRUE(FormatFails("%x", ""));
584  EXPECT_TRUE(FormatFails("%f", ""));
585  EXPECT_TRUE(FormatFails("%*d", ""));
586 }
587 
588 } // namespace
589 } // namespace str_format_internal
590 } // namespace absl
int v
Definition: variant_test.cc:81
constexpr uint128 Uint128Max()
Definition: int128.h:242
void StrAppend(std::string *dest, const AlphaNum &a)
Definition: str_cat.cc:193
typename std::remove_volatile< T >::type remove_volatile_t
Definition: type_traits.h:501
static const uint64_t k1
Definition: city.cc:53
TYPED_TEST_SUITE_P(ConstructorTest)
char buf[N]
Definition: algorithm.h:29
size_t value
TEST_F(GraphCyclesTest, NoCycle)
std::string format(const std::string &, const time_point< seconds > &, const femtoseconds &, const time_zone &)
void * arg
Definition: mutex.cc:292
std::string FormatPack(const UntypedFormatSpecImpl format, absl::Span< const FormatArgImpl > args)
Definition: bind.h:167
TYPED_TEST_P(ConstructorTest, NoArgs)
static const uint64_t k2
Definition: city.cc:54
constexpr Span< T > MakeSpan(T *ptr, size_t size) noexcept
Definition: span.h:647
int prec
Definition: duration.cc:707
char * out
Definition: mutex.h:1013
std::size_t length
Definition: test_util.cc:52
REGISTER_TYPED_TEST_CASE_P(ConstructorTest, NoArgs, BucketCount, BucketCountHash, BucketCountHashEqual, BucketCountHashEqualAlloc, BucketCountAlloc, BucketCountHashAlloc, Alloc, InputIteratorBucketHashEqualAlloc, InputIteratorBucketAlloc, InputIteratorBucketHashAlloc, CopyConstructor, CopyConstructorAlloc, MoveConstructor, MoveConstructorAlloc, InitializerListBucketHashEqualAlloc, InitializerListBucketAlloc, InitializerListBucketHashAlloc, Assignment, MoveAssignment, AssignmentFromInitializerList, AssignmentOverwritesExisting, MoveAssignmentOverwritesExisting, AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf)


abseil_cpp
Author(s):
autogenerated on Tue Jun 18 2019 19:44:35