8 #include "gtest/gtest.h" 15 template <
typename T,
size_t N>
16 size_t ArraySize(T (&)[N]) {
22 std::string LengthModFor(
long double) {
return "L"; }
24 std::string LengthModFor(
signed char) {
return "hh"; }
25 std::string LengthModFor(
unsigned char) {
return "hh"; }
27 std::string LengthModFor(
unsigned short) {
return "h"; }
31 std::string LengthModFor(
unsigned long) {
return "l"; }
32 std::string LengthModFor(
long long) {
return "ll"; }
33 std::string LengthModFor(
unsigned long long) {
return "ll"; }
36 if (std::isprint(static_cast<unsigned char>(v))) {
40 int n = snprintf(buf,
sizeof(buf),
"\\%#.2x",
41 static_cast<unsigned>(v & 0xff));
42 assert(n > 0 && n <
sizeof(buf));
47 std::string Esc(
signed char v) {
return EscCharImpl(v); }
48 std::string Esc(
unsigned char v) {
return EscCharImpl(v); }
52 std::ostringstream oss;
59 static const int kSpaceLength = 1024;
60 char space[kSpaceLength];
66 va_copy(backup_ap, ap);
67 int result = vsnprintf(space, kSpaceLength, format, backup_ap);
69 if (result < kSpaceLength) {
72 dst->append(space, result);
84 char *buf =
new char[
length];
87 va_copy(backup_ap, ap);
88 result = vsnprintf(buf, length, format, backup_ap);
91 if (result >= 0 && result < length) {
93 dst->append(buf, result);
100 va_start(ap, format);
107 class FormatConvertTest :
public ::testing::Test { };
109 template <
typename T>
110 void TestStringConvert(
const T& str) {
111 const FormatArgImpl args[] = {FormatArgImpl(str)};
116 const Expectation kExpect[] = {
122 {
"hello",
"%1$.10s" },
123 {
" hello",
"%1$6s" },
125 {
"he ",
"%1$-5.2s" },
126 {
"hello ",
"%1$-6.10s" },
128 for (
const Expectation &e : kExpect) {
129 UntypedFormatSpecImpl
format(e.fmt);
134 TEST_F(FormatConvertTest, BasicString) {
135 TestStringConvert(
"hello");
136 TestStringConvert(static_cast<const char*>(
"hello"));
138 TestStringConvert(string_view(
"hello"));
141 TEST_F(FormatConvertTest, NullString) {
142 const char* p =
nullptr;
143 UntypedFormatSpecImpl
format(
"%s");
144 EXPECT_EQ(
"",
FormatPack(format, {FormatArgImpl(p)}));
147 TEST_F(FormatConvertTest, StringPrecision) {
151 UntypedFormatSpecImpl
format(
"%.1s");
152 EXPECT_EQ(
"a",
FormatPack(format, {FormatArgImpl(p)}));
156 UntypedFormatSpecImpl format2(
"%.10s");
157 EXPECT_EQ(
"ABC",
FormatPack(format2, {FormatArgImpl(p)}));
160 TEST_F(FormatConvertTest, Pointer) {
170 const char *cp =
"hi";
171 const char *cnil =
nullptr;
172 const int *inil =
nullptr;
173 using VoidF = void (*)();
174 VoidF fp = [] {}, fnil =
nullptr;
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),
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"},
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"},
200 {StrPrint(
"%p", cp),
"%2$p"},
203 {StrPrint(
"%p", mcp),
"%5$p"},
205 {StrPrint(
"%p", fp),
"%6$p"},
206 {StrPrint(
"%p", vcp),
"%8$p"},
210 {StrPrint(
"%p", fnil),
"%7$p"},
211 {StrPrint(
"%p", vcnil),
"%9$p"},
214 for (
const Expectation &e : kExpect) {
215 UntypedFormatSpecImpl
format(e.fmt);
221 enum Pos {
k1 = 1,
k2 = 2, k3 = 3 };
222 enum Neg { kM1 = -1, kM2 = -2, kM3 = -3 };
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");
235 template <
typename T>
236 class TypedFormatConvertTest :
public FormatConvertTest { };
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) {
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);
253 TYPED_TEST_P(TypedFormatConvertTest, AllIntsWithFlags) {
255 typedef typename std::make_unsigned<T>::type UnsignedT;
257 const T kMin = std::numeric_limits<remove_volatile_t>::min();
258 const T kMax = std::numeric_limits<remove_volatile_t>::max();
274 const char kConvChars[] = {
'd',
'i',
'u',
'o',
'x',
'X'};
276 const std::string kPrec[] = {
"",
".",
".0",
".4",
".10"};
278 const std::vector<std::string> flag_sets = AllFlagCombinations();
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) {
288 for (
size_t wi = 0; wi < ArraySize(kWid); ++wi) {
290 for (
size_t pi = 0; pi < ArraySize(kPrec); ++pi) {
293 const bool is_signed_conv = (conv_char ==
'd' || conv_char ==
'i');
294 const bool is_unsigned_to_signed =
298 if (is_unsigned_to_signed &&
299 flag_set.find_first_of(
"+ ") != std::string::npos) {
309 new_fmt += conv_char;
311 if (is_unsigned_to_signed) {
316 UnsignedT uval = val;
317 old_fmt += LengthModFor(uval);
319 old_result = StrPrint(old_fmt.c_str(), uval);
321 old_fmt += LengthModFor(val);
322 old_fmt += conv_char;
323 old_result = StrPrint(old_fmt.c_str(), val);
326 SCOPED_TRACE(
std::string() +
" old_fmt: \"" + old_fmt +
330 UntypedFormatSpecImpl
format(new_fmt);
342 static const T kMin = std::numeric_limits<remove_volatile_t>::min();
343 static const T kMax = std::numeric_limits<remove_volatile_t>::max();
351 for (
const T &c : kVals) {
352 const FormatArgImpl args[] = {FormatArgImpl(c)};
353 UntypedFormatSpecImpl
format(
"%c");
360 typedef ::testing::Types<
361 int, unsigned,
volatile int,
362 short,
unsigned short,
364 long long,
unsigned long long,
365 signed char,
unsigned char,
char>
367 INSTANTIATE_TYPED_TEST_CASE_P(TypedFormatConvertTestWithAllIntTypes,
368 TypedFormatConvertTest, AllIntTypes);
370 TEST_F(FormatConvertTest, VectorBool) {
372 std::vector<bool> v = {
true,
false};
373 const std::vector<bool> cv = {
true,
false};
375 FormatPack(UntypedFormatSpecImpl(
"%d,%d,%d,%d"),
377 {FormatArgImpl(v[0]), FormatArgImpl(v[1]),
378 FormatArgImpl(cv[0]), FormatArgImpl(cv[1])})));
381 TEST_F(FormatConvertTest, Uint128) {
384 const FormatArgImpl args[] = {FormatArgImpl(v), FormatArgImpl(max)};
388 const char* expected;
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"},
400 for (
auto c : cases) {
401 UntypedFormatSpecImpl
format(c.format);
406 TEST_F(FormatConvertTest, Float) {
413 const char *
const kFormats[] = {
414 "%",
"%.3",
"%8.5",
"%9",
"%.60",
"%.30",
"%03",
"%+",
415 "% ",
"%-10",
"%#15.3",
"%#.0",
"%.0",
"%1$*2$",
"%1$.*2$"};
417 std::vector<double> doubles = {0.0,
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()};
434 doubles.push_back(std::nan(
""));
438 doubles.push_back(0.99999999999999989);
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());
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));
455 for (
const char *fmt : kFormats) {
456 for (
char f : {
'f',
'F',
461 for (
double d : doubles) {
463 FormatArgImpl args[2] = {FormatArgImpl(d), FormatArgImpl(i)};
464 UntypedFormatSpecImpl
format(fmt_str);
468 ASSERT_EQ(StrPrint(fmt_str.c_str(), d,
i),
470 << fmt_str <<
" " << StrPrint(
"%.18g", d) <<
" " 471 << StrPrint(
"%.999f", d);
477 TEST_F(FormatConvertTest, LongDouble) {
478 const char *
const kFormats[] = {
"%",
"%.3",
"%8.5",
"%9",
479 "%.60",
"%+",
"% ",
"%-10"};
485 long double very_precise = 10000000000000000.25L;
487 std::vector<long double> doubles = {
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()};
499 for (
const char *fmt : kFormats) {
500 for (
char f : {
'f',
'F',
505 for (
auto d : doubles) {
506 FormatArgImpl
arg(d);
507 UntypedFormatSpecImpl
format(fmt_str);
511 ASSERT_EQ(StrPrint(fmt_str.c_str(), d),
513 << fmt_str <<
" " << StrPrint(
"%.18Lg", d) <<
" " 514 << StrPrint(
"%.999Lf", d);
520 TEST_F(FormatConvertTest, IntAsFloat) {
521 const int kMin = std::numeric_limits<int>::min();
522 const int kMax = std::numeric_limits<int>::max();
526 0, kMax - 1, kMax, kMin + 1, kMin };
527 for (
const int fx : ia) {
529 const FormatArgImpl args[] = {FormatArgImpl(fx)};
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" },
543 for (
const Expectation &e : kExpect) {
544 SCOPED_TRACE(e.line);
546 UntypedFormatSpecImpl
format(e.fmt);
552 template <
typename T>
553 bool FormatFails(
const char* test_format, T
value) {
555 UntypedFormatSpecImpl
format(format_string);
558 const FormatArgImpl args[] = {FormatArgImpl(value), FormatArgImpl(one)};
560 <<
"format=" << test_format <<
" value=" <<
value;
564 TEST_F(FormatConvertTest, ExpectedFailures) {
566 EXPECT_TRUE(FormatFails(
"%p", 1));
567 EXPECT_TRUE(FormatFails(
"%s", 1));
568 EXPECT_TRUE(FormatFails(
"%n", 1));
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.));
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",
""));
constexpr uint128 Uint128Max()
void StrAppend(std::string *dest, const AlphaNum &a)
typename std::remove_volatile< T >::type remove_volatile_t
TYPED_TEST_SUITE_P(ConstructorTest)
TEST_F(GraphCyclesTest, NoCycle)
std::string format(const std::string &, const time_point< seconds > &, const femtoseconds &, const time_zone &)
TYPED_TEST_P(ConstructorTest, NoArgs)
constexpr Span< T > MakeSpan(T *ptr, size_t size) noexcept
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)