]> git.proxmox.com Git - ceph.git/blame - ceph/src/fmt/test/format-test.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / fmt / test / format-test.cc
CommitLineData
11fdf7f2
TL
1// Formatting library for C++ - formatting library tests
2//
3// Copyright (c) 2012 - present, Victor Zverovich
4// All rights reserved.
5//
6// For the license information refer to format.h.
7
9f95a23c 8#include <stdint.h>
f67539c2 9
11fdf7f2
TL
10#include <cctype>
11#include <cfloat>
12#include <climits>
13#include <cmath>
14#include <cstring>
15#include <list>
16#include <memory>
eafe8130 17#include <string>
11fdf7f2
TL
18
19// Check if fmt/format.h compiles with windows.h included before it.
20#ifdef _WIN32
9f95a23c 21# include <windows.h>
11fdf7f2
TL
22#endif
23
f67539c2
TL
24// Check if fmt/format.h compiles with the X11 index macro defined.
25#define index(x, y) no nice things
26
9f95a23c 27#include "fmt/color.h"
f67539c2
TL
28#include "fmt/format.h"
29
30#undef index
31
11fdf7f2
TL
32#include "gmock.h"
33#include "gtest-extra.h"
34#include "mock-allocator.h"
35#include "util.h"
36
37#undef ERROR
11fdf7f2
TL
38
39using fmt::basic_memory_buffer;
11fdf7f2
TL
40using fmt::format;
41using fmt::format_error;
11fdf7f2 42using fmt::memory_buffer;
9f95a23c 43using fmt::string_view;
11fdf7f2 44using fmt::wmemory_buffer;
f67539c2
TL
45using fmt::wstring_view;
46using fmt::detail::max_value;
11fdf7f2
TL
47
48using testing::Return;
49using testing::StrictMock;
50
51namespace {
52
eafe8130 53#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 408
9f95a23c
TL
54template <typename Char, typename T> bool check_enabled_formatter() {
55 static_assert(std::is_default_constructible<fmt::formatter<T, Char>>::value,
56 "");
eafe8130
TL
57 return true;
58}
59
9f95a23c 60template <typename Char, typename... T> void check_enabled_formatters() {
eafe8130
TL
61 auto dummy = {check_enabled_formatter<Char, T>()...};
62 (void)dummy;
63}
64
65TEST(FormatterTest, TestFormattersEnabled) {
9f95a23c
TL
66 check_enabled_formatters<char, bool, char, signed char, unsigned char, short,
67 unsigned short, int, unsigned, long, unsigned long,
68 long long, unsigned long long, float, double,
69 long double, void*, const void*, char*, const char*,
f67539c2 70 std::string, std::nullptr_t>();
9f95a23c
TL
71 check_enabled_formatters<wchar_t, bool, wchar_t, signed char, unsigned char,
72 short, unsigned short, int, unsigned, long,
73 unsigned long, long long, unsigned long long, float,
74 double, long double, void*, const void*, wchar_t*,
f67539c2 75 const wchar_t*, std::wstring, std::nullptr_t>();
eafe8130
TL
76}
77#endif
78
11fdf7f2
TL
79// Format value using the standard library.
80template <typename Char, typename T>
9f95a23c 81void std_format(const T& value, std::basic_string<Char>& result) {
11fdf7f2
TL
82 std::basic_ostringstream<Char> os;
83 os << value;
84 result = os.str();
85}
86
87#ifdef __MINGW32__
88// Workaround a bug in formatting long double in MinGW.
9f95a23c 89void std_format(long double value, std::string& result) {
11fdf7f2
TL
90 char buffer[100];
91 safe_sprintf(buffer, "%Lg", value);
92 result = buffer;
93}
9f95a23c 94void std_format(long double value, std::wstring& result) {
11fdf7f2
TL
95 wchar_t buffer[100];
96 swprintf(buffer, L"%Lg", value);
97 result = buffer;
98}
99#endif
11fdf7f2
TL
100} // namespace
101
11fdf7f2
TL
102struct uint32_pair {
103 uint32_t u[2];
104};
105
106TEST(UtilTest, BitCast) {
f67539c2
TL
107 auto s = fmt::detail::bit_cast<uint32_pair>(uint64_t{42});
108 EXPECT_EQ(fmt::detail::bit_cast<uint64_t>(s), 42ull);
109 s = fmt::detail::bit_cast<uint32_pair>(uint64_t(~0ull));
110 EXPECT_EQ(fmt::detail::bit_cast<uint64_t>(s), ~0ull);
11fdf7f2
TL
111}
112
113TEST(UtilTest, Increment) {
114 char s[10] = "123";
115 increment(s);
116 EXPECT_STREQ("124", s);
117 s[2] = '8';
118 increment(s);
119 EXPECT_STREQ("129", s);
120 increment(s);
121 EXPECT_STREQ("130", s);
122 s[1] = s[2] = '9';
123 increment(s);
124 EXPECT_STREQ("200", s);
125}
126
127TEST(UtilTest, ParseNonnegativeInt) {
f67539c2 128 if (max_value<int>() != static_cast<int>(static_cast<unsigned>(1) << 31)) {
11fdf7f2
TL
129 fmt::print("Skipping parse_nonnegative_int test\n");
130 return;
131 }
9f95a23c
TL
132 fmt::string_view s = "10000000000";
133 auto begin = s.begin(), end = s.end();
11fdf7f2 134 EXPECT_THROW_MSG(
f67539c2 135 parse_nonnegative_int(begin, end, fmt::detail::error_handler()),
9f95a23c 136 fmt::format_error, "number is too big");
11fdf7f2 137 s = "2147483649";
9f95a23c
TL
138 begin = s.begin();
139 end = s.end();
11fdf7f2 140 EXPECT_THROW_MSG(
f67539c2 141 parse_nonnegative_int(begin, end, fmt::detail::error_handler()),
9f95a23c 142 fmt::format_error, "number is too big");
11fdf7f2
TL
143}
144
145TEST(IteratorTest, CountingIterator) {
f67539c2 146 fmt::detail::counting_iterator it;
11fdf7f2
TL
147 auto prev = it++;
148 EXPECT_EQ(prev.count(), 0);
149 EXPECT_EQ(it.count(), 1);
150}
151
152TEST(IteratorTest, TruncatingIterator) {
f67539c2
TL
153 char* p = nullptr;
154 fmt::detail::truncating_iterator<char*> it(p, 3);
11fdf7f2
TL
155 auto prev = it++;
156 EXPECT_EQ(prev.base(), p);
157 EXPECT_EQ(it.base(), p + 1);
158}
159
eafe8130
TL
160TEST(IteratorTest, TruncatingBackInserter) {
161 std::string buffer;
162 auto bi = std::back_inserter(buffer);
f67539c2 163 fmt::detail::truncating_iterator<decltype(bi)> it(bi, 2);
eafe8130
TL
164 *it++ = '4';
165 *it++ = '2';
166 *it++ = '1';
167 EXPECT_EQ(buffer.size(), 2);
168 EXPECT_EQ(buffer, "42");
169}
170
171TEST(IteratorTest, IsOutputIterator) {
f67539c2
TL
172 EXPECT_TRUE(fmt::detail::is_output_iterator<char*>::value);
173 EXPECT_FALSE(fmt::detail::is_output_iterator<const char*>::value);
174 EXPECT_FALSE(fmt::detail::is_output_iterator<std::string>::value);
175 EXPECT_TRUE(fmt::detail::is_output_iterator<
eafe8130 176 std::back_insert_iterator<std::string>>::value);
f67539c2 177 EXPECT_TRUE(fmt::detail::is_output_iterator<std::string::iterator>::value);
9f95a23c 178 EXPECT_FALSE(
f67539c2
TL
179 fmt::detail::is_output_iterator<std::string::const_iterator>::value);
180 EXPECT_FALSE(fmt::detail::is_output_iterator<std::list<char>>::value);
9f95a23c 181 EXPECT_TRUE(
f67539c2
TL
182 fmt::detail::is_output_iterator<std::list<char>::iterator>::value);
183 EXPECT_FALSE(
184 fmt::detail::is_output_iterator<std::list<char>::const_iterator>::value);
185 EXPECT_FALSE(fmt::detail::is_output_iterator<uint32_pair>::value);
eafe8130
TL
186}
187
11fdf7f2
TL
188TEST(MemoryBufferTest, Ctor) {
189 basic_memory_buffer<char, 123> buffer;
190 EXPECT_EQ(static_cast<size_t>(0), buffer.size());
191 EXPECT_EQ(123u, buffer.capacity());
192}
193
9f95a23c
TL
194static void check_forwarding(mock_allocator<int>& alloc,
195 allocator_ref<mock_allocator<int>>& ref) {
11fdf7f2
TL
196 int mem;
197 // Check if value_type is properly defined.
9f95a23c 198 allocator_ref<mock_allocator<int>>::value_type* ptr = &mem;
11fdf7f2
TL
199 // Check forwarding.
200 EXPECT_CALL(alloc, allocate(42)).WillOnce(testing::Return(ptr));
201 ref.allocate(42);
202 EXPECT_CALL(alloc, deallocate(ptr, 42));
203 ref.deallocate(ptr, 42);
204}
205
206TEST(AllocatorTest, allocator_ref) {
9f95a23c
TL
207 StrictMock<mock_allocator<int>> alloc;
208 typedef allocator_ref<mock_allocator<int>> test_allocator_ref;
11fdf7f2
TL
209 test_allocator_ref ref(&alloc);
210 // Check if allocator_ref forwards to the underlying allocator.
211 check_forwarding(alloc, ref);
212 test_allocator_ref ref2(ref);
213 check_forwarding(alloc, ref2);
214 test_allocator_ref ref3;
f67539c2 215 EXPECT_EQ(nullptr, ref3.get());
11fdf7f2
TL
216 ref3 = ref;
217 check_forwarding(alloc, ref3);
218}
219
9f95a23c 220typedef allocator_ref<std::allocator<char>> TestAllocator;
11fdf7f2 221
9f95a23c
TL
222static void check_move_buffer(
223 const char* str, basic_memory_buffer<char, 5, TestAllocator>& buffer) {
224 std::allocator<char>* alloc = buffer.get_allocator().get();
11fdf7f2
TL
225 basic_memory_buffer<char, 5, TestAllocator> buffer2(std::move(buffer));
226 // Move shouldn't destroy the inline content of the first buffer.
227 EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
228 EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size()));
229 EXPECT_EQ(5u, buffer2.capacity());
230 // Move should transfer allocator.
f67539c2 231 EXPECT_EQ(nullptr, buffer.get_allocator().get());
11fdf7f2
TL
232 EXPECT_EQ(alloc, buffer2.get_allocator().get());
233}
234
f67539c2 235TEST(MemoryBufferTest, MoveCtorInlineBuffer) {
11fdf7f2
TL
236 std::allocator<char> alloc;
237 basic_memory_buffer<char, 5, TestAllocator> buffer((TestAllocator(&alloc)));
238 const char test[] = "test";
239 buffer.append(test, test + 4);
240 check_move_buffer("test", buffer);
241 // Adding one more character fills the inline buffer, but doesn't cause
242 // dynamic allocation.
243 buffer.push_back('a');
244 check_move_buffer("testa", buffer);
f67539c2
TL
245}
246
247TEST(MemoryBufferTest, MoveCtorDynamicBuffer) {
248 std::allocator<char> alloc;
249 basic_memory_buffer<char, 4, TestAllocator> buffer((TestAllocator(&alloc)));
250 const char test[] = "test";
251 buffer.append(test, test + 4);
9f95a23c 252 const char* inline_buffer_ptr = &buffer[0];
11fdf7f2
TL
253 // Adding one more character causes the content to move from the inline to
254 // a dynamically allocated buffer.
f67539c2
TL
255 buffer.push_back('a');
256 basic_memory_buffer<char, 4, TestAllocator> buffer2(std::move(buffer));
11fdf7f2
TL
257 // Move should rip the guts of the first buffer.
258 EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
f67539c2
TL
259 EXPECT_EQ("testa", std::string(&buffer2[0], buffer2.size()));
260 EXPECT_GT(buffer2.capacity(), 4u);
11fdf7f2
TL
261}
262
9f95a23c
TL
263static void check_move_assign_buffer(const char* str,
264 basic_memory_buffer<char, 5>& buffer) {
11fdf7f2
TL
265 basic_memory_buffer<char, 5> buffer2;
266 buffer2 = std::move(buffer);
267 // Move shouldn't destroy the inline content of the first buffer.
268 EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
269 EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size()));
270 EXPECT_EQ(5u, buffer2.capacity());
271}
272
273TEST(MemoryBufferTest, MoveAssignment) {
274 basic_memory_buffer<char, 5> buffer;
275 const char test[] = "test";
276 buffer.append(test, test + 4);
277 check_move_assign_buffer("test", buffer);
278 // Adding one more character fills the inline buffer, but doesn't cause
279 // dynamic allocation.
280 buffer.push_back('a');
281 check_move_assign_buffer("testa", buffer);
9f95a23c 282 const char* inline_buffer_ptr = &buffer[0];
11fdf7f2
TL
283 // Adding one more character causes the content to move from the inline to
284 // a dynamically allocated buffer.
285 buffer.push_back('b');
286 basic_memory_buffer<char, 5> buffer2;
287 buffer2 = std::move(buffer);
288 // Move should rip the guts of the first buffer.
289 EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
290 EXPECT_EQ("testab", std::string(&buffer2[0], buffer2.size()));
291 EXPECT_GT(buffer2.capacity(), 5u);
292}
293
294TEST(MemoryBufferTest, Grow) {
9f95a23c 295 typedef allocator_ref<mock_allocator<int>> Allocator;
11fdf7f2
TL
296 typedef basic_memory_buffer<int, 10, Allocator> Base;
297 mock_allocator<int> alloc;
298 struct TestMemoryBuffer : Base {
299 TestMemoryBuffer(Allocator alloc) : Base(alloc) {}
f67539c2 300 void grow(size_t size) { Base::grow(size); }
11fdf7f2
TL
301 } buffer((Allocator(&alloc)));
302 buffer.resize(7);
f67539c2 303 using fmt::detail::to_unsigned;
9f95a23c 304 for (int i = 0; i < 7; ++i) buffer[to_unsigned(i)] = i * i;
11fdf7f2
TL
305 EXPECT_EQ(10u, buffer.capacity());
306 int mem[20];
307 mem[7] = 0xdead;
308 EXPECT_CALL(alloc, allocate(20)).WillOnce(Return(mem));
309 buffer.grow(20);
310 EXPECT_EQ(20u, buffer.capacity());
311 // Check if size elements have been copied
9f95a23c 312 for (int i = 0; i < 7; ++i) EXPECT_EQ(i * i, buffer[to_unsigned(i)]);
11fdf7f2
TL
313 // and no more than that.
314 EXPECT_EQ(0xdead, buffer[7]);
315 EXPECT_CALL(alloc, deallocate(mem, 20));
316}
317
318TEST(MemoryBufferTest, Allocator) {
9f95a23c 319 typedef allocator_ref<mock_allocator<char>> TestAllocator;
11fdf7f2 320 basic_memory_buffer<char, 10, TestAllocator> buffer;
f67539c2 321 EXPECT_EQ(nullptr, buffer.get_allocator().get());
9f95a23c 322 StrictMock<mock_allocator<char>> alloc;
11fdf7f2
TL
323 char mem;
324 {
9f95a23c
TL
325 basic_memory_buffer<char, 10, TestAllocator> buffer2(
326 (TestAllocator(&alloc)));
11fdf7f2 327 EXPECT_EQ(&alloc, buffer2.get_allocator().get());
f67539c2 328 size_t size = 2 * fmt::inline_buffer_size;
11fdf7f2
TL
329 EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem));
330 buffer2.reserve(size);
331 EXPECT_CALL(alloc, deallocate(&mem, size));
332 }
333}
334
335TEST(MemoryBufferTest, ExceptionInDeallocate) {
9f95a23c
TL
336 typedef allocator_ref<mock_allocator<char>> TestAllocator;
337 StrictMock<mock_allocator<char>> alloc;
11fdf7f2 338 basic_memory_buffer<char, 10, TestAllocator> buffer((TestAllocator(&alloc)));
f67539c2 339 size_t size = 2 * fmt::inline_buffer_size;
11fdf7f2
TL
340 std::vector<char> mem(size);
341 {
342 EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem[0]));
343 buffer.resize(size);
344 std::fill(&buffer[0], &buffer[0] + size, 'x');
345 }
346 std::vector<char> mem2(2 * size);
347 {
348 EXPECT_CALL(alloc, allocate(2 * size)).WillOnce(Return(&mem2[0]));
349 std::exception e;
350 EXPECT_CALL(alloc, deallocate(&mem[0], size)).WillOnce(testing::Throw(e));
351 EXPECT_THROW(buffer.reserve(2 * size), std::exception);
352 EXPECT_EQ(&mem2[0], &buffer[0]);
353 // Check that the data has been copied.
f67539c2 354 for (size_t i = 0; i < size; ++i) EXPECT_EQ('x', buffer[i]);
11fdf7f2
TL
355 }
356 EXPECT_CALL(alloc, deallocate(&mem2[0], 2 * size));
357}
358
11fdf7f2 359TEST(UtilTest, UTF8ToUTF16) {
f67539c2 360 fmt::detail::utf8_to_utf16 u("лошадка");
11fdf7f2
TL
361 EXPECT_EQ(L"\x043B\x043E\x0448\x0430\x0434\x043A\x0430", u.str());
362 EXPECT_EQ(7, u.size());
f67539c2
TL
363 // U+10437 { DESERET SMALL LETTER YEE }
364 EXPECT_EQ(L"\xD801\xDC37", fmt::detail::utf8_to_utf16("𐐷").str());
365 EXPECT_THROW_MSG(fmt::detail::utf8_to_utf16("\xc3\x28"), std::runtime_error,
366 "invalid utf8");
367 EXPECT_THROW_MSG(fmt::detail::utf8_to_utf16(fmt::string_view("л", 1)),
368 std::runtime_error, "invalid utf8");
369 EXPECT_EQ(L"123456", fmt::detail::utf8_to_utf16("123456").str());
11fdf7f2
TL
370}
371
372TEST(UtilTest, UTF8ToUTF16EmptyString) {
373 std::string s = "";
f67539c2 374 fmt::detail::utf8_to_utf16 u(s.c_str());
11fdf7f2
TL
375 EXPECT_EQ(L"", u.str());
376 EXPECT_EQ(s.size(), u.size());
377}
378
11fdf7f2
TL
379TEST(UtilTest, FormatSystemError) {
380 fmt::memory_buffer message;
381 fmt::format_system_error(message, EDOM, "test");
382 EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)),
383 to_string(message));
384 message = fmt::memory_buffer();
385
386 // Check if std::allocator throws on allocating max size_t / 2 chars.
f67539c2 387 size_t max_size = max_value<size_t>() / 2;
11fdf7f2
TL
388 bool throws_on_alloc = false;
389 try {
390 std::allocator<char> alloc;
391 alloc.deallocate(alloc.allocate(max_size), max_size);
392 } catch (const std::bad_alloc&) {
393 throws_on_alloc = true;
394 }
395 if (!throws_on_alloc) {
396 fmt::print("warning: std::allocator allocates {} chars", max_size);
397 return;
398 }
f67539c2 399 fmt::format_system_error(message, EDOM, fmt::string_view(nullptr, max_size));
11fdf7f2
TL
400 EXPECT_EQ(fmt::format("error {}", EDOM), to_string(message));
401}
402
403TEST(UtilTest, SystemError) {
404 fmt::system_error e(EDOM, "test");
405 EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)), e.what());
406 EXPECT_EQ(EDOM, e.error_code());
f67539c2
TL
407
408 fmt::system_error error(0, "");
409 try {
410 throw fmt::system_error(EDOM, "test {}", "error");
411 } catch (const fmt::system_error& e) {
412 error = e;
413 }
414 fmt::memory_buffer message;
415 fmt::format_system_error(message, EDOM, "test error");
416 EXPECT_EQ(to_string(message), error.what());
417 EXPECT_EQ(EDOM, error.error_code());
11fdf7f2
TL
418}
419
420TEST(UtilTest, ReportSystemError) {
421 fmt::memory_buffer out;
422 fmt::format_system_error(out, EDOM, "test error");
423 out.push_back('\n');
424 EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"),
425 to_string(out));
426}
427
11fdf7f2
TL
428TEST(StringViewTest, Ctor) {
429 EXPECT_STREQ("abc", string_view("abc").data());
430 EXPECT_EQ(3u, string_view("abc").size());
431
432 EXPECT_STREQ("defg", string_view(std::string("defg")).data());
433 EXPECT_EQ(4u, string_view(std::string("defg")).size());
434}
435
11fdf7f2
TL
436TEST(FormatToTest, FormatWithoutArgs) {
437 std::string s;
438 fmt::format_to(std::back_inserter(s), "test");
439 EXPECT_EQ("test", s);
440}
441
442TEST(FormatToTest, Format) {
443 std::string s;
444 fmt::format_to(std::back_inserter(s), "part{0}", 1);
445 EXPECT_EQ("part1", s);
446 fmt::format_to(std::back_inserter(s), "part{0}", 2);
447 EXPECT_EQ("part1part2", s);
448}
449
eafe8130
TL
450TEST(FormatToTest, WideString) {
451 std::vector<wchar_t> buf;
452 fmt::format_to(std::back_inserter(buf), L"{}{}", 42, L'\0');
453 EXPECT_STREQ(buf.data(), L"42");
454}
455
11fdf7f2
TL
456TEST(FormatToTest, FormatToMemoryBuffer) {
457 fmt::basic_memory_buffer<char, 100> buffer;
458 fmt::format_to(buffer, "{}", "foo");
459 EXPECT_EQ("foo", to_string(buffer));
460 fmt::wmemory_buffer wbuffer;
461 fmt::format_to(wbuffer, L"{}", L"foo");
462 EXPECT_EQ(L"foo", to_string(wbuffer));
463}
464
465TEST(FormatterTest, Escape) {
466 EXPECT_EQ("{", format("{{"));
467 EXPECT_EQ("before {", format("before {{"));
468 EXPECT_EQ("{ after", format("{{ after"));
469 EXPECT_EQ("before { after", format("before {{ after"));
470
471 EXPECT_EQ("}", format("}}"));
472 EXPECT_EQ("before }", format("before }}"));
473 EXPECT_EQ("} after", format("}} after"));
474 EXPECT_EQ("before } after", format("before }} after"));
475
476 EXPECT_EQ("{}", format("{{}}"));
477 EXPECT_EQ("{42}", format("{{{0}}}", 42));
478}
479
480TEST(FormatterTest, UnmatchedBraces) {
481 EXPECT_THROW_MSG(format("{"), format_error, "invalid format string");
482 EXPECT_THROW_MSG(format("}"), format_error, "unmatched '}' in format string");
483 EXPECT_THROW_MSG(format("{0{}"), format_error, "invalid format string");
484}
485
9f95a23c 486TEST(FormatterTest, NoArgs) { EXPECT_EQ("test", format("test")); }
11fdf7f2
TL
487
488TEST(FormatterTest, ArgsInDifferentPositions) {
489 EXPECT_EQ("42", format("{0}", 42));
490 EXPECT_EQ("before 42", format("before {0}", 42));
491 EXPECT_EQ("42 after", format("{0} after", 42));
492 EXPECT_EQ("before 42 after", format("before {0} after", 42));
493 EXPECT_EQ("answer = 42", format("{0} = {1}", "answer", 42));
494 EXPECT_EQ("42 is the answer", format("{1} is the {0}", "answer", 42));
495 EXPECT_EQ("abracadabra", format("{0}{1}{0}", "abra", "cad"));
496}
497
498TEST(FormatterTest, ArgErrors) {
499 EXPECT_THROW_MSG(format("{"), format_error, "invalid format string");
500 EXPECT_THROW_MSG(format("{?}"), format_error, "invalid format string");
501 EXPECT_THROW_MSG(format("{0"), format_error, "invalid format string");
f67539c2 502 EXPECT_THROW_MSG(format("{0}"), format_error, "argument not found");
eafe8130 503 EXPECT_THROW_MSG(format("{00}", 42), format_error, "invalid format string");
11fdf7f2
TL
504
505 char format_str[BUFFER_SIZE];
506 safe_sprintf(format_str, "{%u", INT_MAX);
507 EXPECT_THROW_MSG(format(format_str), format_error, "invalid format string");
508 safe_sprintf(format_str, "{%u}", INT_MAX);
f67539c2 509 EXPECT_THROW_MSG(format(format_str), format_error, "argument not found");
11fdf7f2
TL
510
511 safe_sprintf(format_str, "{%u", INT_MAX + 1u);
512 EXPECT_THROW_MSG(format(format_str), format_error, "number is too big");
513 safe_sprintf(format_str, "{%u}", INT_MAX + 1u);
514 EXPECT_THROW_MSG(format(format_str), format_error, "number is too big");
515}
516
9f95a23c 517template <int N> struct TestFormat {
11fdf7f2 518 template <typename... Args>
9f95a23c 519 static std::string format(fmt::string_view format_str, const Args&... args) {
11fdf7f2
TL
520 return TestFormat<N - 1>::format(format_str, N - 1, args...);
521 }
522};
523
9f95a23c 524template <> struct TestFormat<0> {
11fdf7f2 525 template <typename... Args>
9f95a23c 526 static std::string format(fmt::string_view format_str, const Args&... args) {
11fdf7f2
TL
527 return fmt::format(format_str, args...);
528 }
529};
530
531TEST(FormatterTest, ManyArgs) {
532 EXPECT_EQ("19", TestFormat<20>::format("{19}"));
9f95a23c 533 EXPECT_THROW_MSG(TestFormat<20>::format("{20}"), format_error,
f67539c2 534 "argument not found");
9f95a23c 535 EXPECT_THROW_MSG(TestFormat<21>::format("{21}"), format_error,
f67539c2
TL
536 "argument not found");
537 enum { max_packed_args = fmt::detail::max_packed_args };
11fdf7f2
TL
538 std::string format_str = fmt::format("{{{}}}", max_packed_args + 1);
539 EXPECT_THROW_MSG(TestFormat<max_packed_args>::format(format_str),
f67539c2 540 format_error, "argument not found");
11fdf7f2
TL
541}
542
543TEST(FormatterTest, NamedArg) {
544 EXPECT_EQ("1/a/A", format("{_1}/{a_}/{A_}", fmt::arg("a_", 'a'),
545 fmt::arg("A_", "A"), fmt::arg("_1", 1)));
546 EXPECT_THROW_MSG(format("{a}"), format_error, "argument not found");
547 EXPECT_EQ(" -42", format("{0:{width}}", -42, fmt::arg("width", 4)));
548 EXPECT_EQ("st", format("{0:.{precision}}", "str", fmt::arg("precision", 2)));
549 EXPECT_EQ("1 2", format("{} {two}", 1, fmt::arg("two", 2)));
9f95a23c
TL
550 EXPECT_EQ("42", format("{c}", fmt::arg("a", 0), fmt::arg("b", 0),
551 fmt::arg("c", 42), fmt::arg("d", 0), fmt::arg("e", 0),
552 fmt::arg("f", 0), fmt::arg("g", 0), fmt::arg("h", 0),
553 fmt::arg("i", 0), fmt::arg("j", 0), fmt::arg("k", 0),
554 fmt::arg("l", 0), fmt::arg("m", 0), fmt::arg("n", 0),
555 fmt::arg("o", 0), fmt::arg("p", 0)));
11fdf7f2
TL
556}
557
558TEST(FormatterTest, AutoArgIndex) {
559 EXPECT_EQ("abc", format("{}{}{}", 'a', 'b', 'c'));
9f95a23c
TL
560 EXPECT_THROW_MSG(format("{0}{}", 'a', 'b'), format_error,
561 "cannot switch from manual to automatic argument indexing");
562 EXPECT_THROW_MSG(format("{}{0}", 'a', 'b'), format_error,
563 "cannot switch from automatic to manual argument indexing");
11fdf7f2 564 EXPECT_EQ("1.2", format("{:.{}}", 1.2345, 2));
9f95a23c
TL
565 EXPECT_THROW_MSG(format("{0}:.{}", 1.2345, 2), format_error,
566 "cannot switch from manual to automatic argument indexing");
567 EXPECT_THROW_MSG(format("{:.{0}}", 1.2345, 2), format_error,
568 "cannot switch from automatic to manual argument indexing");
f67539c2 569 EXPECT_THROW_MSG(format("{}"), format_error, "argument not found");
11fdf7f2
TL
570}
571
9f95a23c 572TEST(FormatterTest, EmptySpecs) { EXPECT_EQ("42", format("{0:}", 42)); }
11fdf7f2
TL
573
574TEST(FormatterTest, LeftAlign) {
575 EXPECT_EQ("42 ", format("{0:<4}", 42));
576 EXPECT_EQ("42 ", format("{0:<4o}", 042));
577 EXPECT_EQ("42 ", format("{0:<4x}", 0x42));
578 EXPECT_EQ("-42 ", format("{0:<5}", -42));
579 EXPECT_EQ("42 ", format("{0:<5}", 42u));
580 EXPECT_EQ("-42 ", format("{0:<5}", -42l));
581 EXPECT_EQ("42 ", format("{0:<5}", 42ul));
582 EXPECT_EQ("-42 ", format("{0:<5}", -42ll));
583 EXPECT_EQ("42 ", format("{0:<5}", 42ull));
9f95a23c
TL
584 EXPECT_EQ("-42.0 ", format("{0:<7}", -42.0));
585 EXPECT_EQ("-42.0 ", format("{0:<7}", -42.0l));
11fdf7f2
TL
586 EXPECT_EQ("c ", format("{0:<5}", 'c'));
587 EXPECT_EQ("abc ", format("{0:<5}", "abc"));
588 EXPECT_EQ("0xface ", format("{0:<8}", reinterpret_cast<void*>(0xface)));
589}
590
591TEST(FormatterTest, RightAlign) {
592 EXPECT_EQ(" 42", format("{0:>4}", 42));
593 EXPECT_EQ(" 42", format("{0:>4o}", 042));
594 EXPECT_EQ(" 42", format("{0:>4x}", 0x42));
595 EXPECT_EQ(" -42", format("{0:>5}", -42));
596 EXPECT_EQ(" 42", format("{0:>5}", 42u));
597 EXPECT_EQ(" -42", format("{0:>5}", -42l));
598 EXPECT_EQ(" 42", format("{0:>5}", 42ul));
599 EXPECT_EQ(" -42", format("{0:>5}", -42ll));
600 EXPECT_EQ(" 42", format("{0:>5}", 42ull));
9f95a23c
TL
601 EXPECT_EQ(" -42.0", format("{0:>7}", -42.0));
602 EXPECT_EQ(" -42.0", format("{0:>7}", -42.0l));
11fdf7f2
TL
603 EXPECT_EQ(" c", format("{0:>5}", 'c'));
604 EXPECT_EQ(" abc", format("{0:>5}", "abc"));
605 EXPECT_EQ(" 0xface", format("{0:>8}", reinterpret_cast<void*>(0xface)));
606}
607
f67539c2
TL
608#if FMT_NUMERIC_ALIGN
609TEST(FormatterTest, NumericAlign) { EXPECT_EQ("0042", format("{0:=4}", 42)); }
610#endif
11fdf7f2
TL
611
612TEST(FormatterTest, CenterAlign) {
613 EXPECT_EQ(" 42 ", format("{0:^5}", 42));
614 EXPECT_EQ(" 42 ", format("{0:^5o}", 042));
615 EXPECT_EQ(" 42 ", format("{0:^5x}", 0x42));
616 EXPECT_EQ(" -42 ", format("{0:^5}", -42));
617 EXPECT_EQ(" 42 ", format("{0:^5}", 42u));
618 EXPECT_EQ(" -42 ", format("{0:^5}", -42l));
619 EXPECT_EQ(" 42 ", format("{0:^5}", 42ul));
620 EXPECT_EQ(" -42 ", format("{0:^5}", -42ll));
621 EXPECT_EQ(" 42 ", format("{0:^5}", 42ull));
9f95a23c
TL
622 EXPECT_EQ(" -42.0 ", format("{0:^7}", -42.0));
623 EXPECT_EQ(" -42.0 ", format("{0:^7}", -42.0l));
11fdf7f2
TL
624 EXPECT_EQ(" c ", format("{0:^5}", 'c'));
625 EXPECT_EQ(" abc ", format("{0:^6}", "abc"));
626 EXPECT_EQ(" 0xface ", format("{0:^8}", reinterpret_cast<void*>(0xface)));
627}
628
629TEST(FormatterTest, Fill) {
9f95a23c
TL
630 EXPECT_THROW_MSG(format("{0:{<5}", 'c'), format_error,
631 "invalid fill character '{'");
632 EXPECT_THROW_MSG(format("{0:{<5}}", 'c'), format_error,
633 "invalid fill character '{'");
11fdf7f2
TL
634 EXPECT_EQ("**42", format("{0:*>4}", 42));
635 EXPECT_EQ("**-42", format("{0:*>5}", -42));
636 EXPECT_EQ("***42", format("{0:*>5}", 42u));
637 EXPECT_EQ("**-42", format("{0:*>5}", -42l));
638 EXPECT_EQ("***42", format("{0:*>5}", 42ul));
639 EXPECT_EQ("**-42", format("{0:*>5}", -42ll));
640 EXPECT_EQ("***42", format("{0:*>5}", 42ull));
9f95a23c
TL
641 EXPECT_EQ("**-42.0", format("{0:*>7}", -42.0));
642 EXPECT_EQ("**-42.0", format("{0:*>7}", -42.0l));
11fdf7f2
TL
643 EXPECT_EQ("c****", format("{0:*<5}", 'c'));
644 EXPECT_EQ("abc**", format("{0:*<5}", "abc"));
645 EXPECT_EQ("**0xface", format("{0:*>8}", reinterpret_cast<void*>(0xface)));
646 EXPECT_EQ("foo=", format("{:}=", "foo"));
9f95a23c 647 EXPECT_EQ(std::string("\0\0\0*", 4), format(string_view("{:\0>4}", 6), '*'));
f67539c2
TL
648 EXPECT_EQ("жж42", format("{0:ж>4}", 42));
649 EXPECT_THROW_MSG(format("{:\x80\x80\x80\x80\x80>}", 0), format_error,
650 "invalid fill");
11fdf7f2
TL
651}
652
653TEST(FormatterTest, PlusSign) {
654 EXPECT_EQ("+42", format("{0:+}", 42));
655 EXPECT_EQ("-42", format("{0:+}", -42));
656 EXPECT_EQ("+42", format("{0:+}", 42));
9f95a23c
TL
657 EXPECT_THROW_MSG(format("{0:+}", 42u), format_error,
658 "format specifier requires signed argument");
11fdf7f2 659 EXPECT_EQ("+42", format("{0:+}", 42l));
9f95a23c
TL
660 EXPECT_THROW_MSG(format("{0:+}", 42ul), format_error,
661 "format specifier requires signed argument");
11fdf7f2 662 EXPECT_EQ("+42", format("{0:+}", 42ll));
9f95a23c
TL
663 EXPECT_THROW_MSG(format("{0:+}", 42ull), format_error,
664 "format specifier requires signed argument");
665 EXPECT_EQ("+42.0", format("{0:+}", 42.0));
666 EXPECT_EQ("+42.0", format("{0:+}", 42.0l));
667 EXPECT_THROW_MSG(format("{0:+", 'c'), format_error,
668 "missing '}' in format string");
669 EXPECT_THROW_MSG(format("{0:+}", 'c'), format_error,
670 "invalid format specifier for char");
671 EXPECT_THROW_MSG(format("{0:+}", "abc"), format_error,
672 "format specifier requires numeric argument");
673 EXPECT_THROW_MSG(format("{0:+}", reinterpret_cast<void*>(0x42)), format_error,
674 "format specifier requires numeric argument");
11fdf7f2
TL
675}
676
677TEST(FormatterTest, MinusSign) {
678 EXPECT_EQ("42", format("{0:-}", 42));
679 EXPECT_EQ("-42", format("{0:-}", -42));
680 EXPECT_EQ("42", format("{0:-}", 42));
9f95a23c
TL
681 EXPECT_THROW_MSG(format("{0:-}", 42u), format_error,
682 "format specifier requires signed argument");
11fdf7f2 683 EXPECT_EQ("42", format("{0:-}", 42l));
9f95a23c
TL
684 EXPECT_THROW_MSG(format("{0:-}", 42ul), format_error,
685 "format specifier requires signed argument");
11fdf7f2 686 EXPECT_EQ("42", format("{0:-}", 42ll));
9f95a23c
TL
687 EXPECT_THROW_MSG(format("{0:-}", 42ull), format_error,
688 "format specifier requires signed argument");
689 EXPECT_EQ("42.0", format("{0:-}", 42.0));
690 EXPECT_EQ("42.0", format("{0:-}", 42.0l));
691 EXPECT_THROW_MSG(format("{0:-", 'c'), format_error,
692 "missing '}' in format string");
693 EXPECT_THROW_MSG(format("{0:-}", 'c'), format_error,
694 "invalid format specifier for char");
695 EXPECT_THROW_MSG(format("{0:-}", "abc"), format_error,
696 "format specifier requires numeric argument");
697 EXPECT_THROW_MSG(format("{0:-}", reinterpret_cast<void*>(0x42)), format_error,
698 "format specifier requires numeric argument");
11fdf7f2
TL
699}
700
701TEST(FormatterTest, SpaceSign) {
702 EXPECT_EQ(" 42", format("{0: }", 42));
703 EXPECT_EQ("-42", format("{0: }", -42));
704 EXPECT_EQ(" 42", format("{0: }", 42));
9f95a23c
TL
705 EXPECT_THROW_MSG(format("{0: }", 42u), format_error,
706 "format specifier requires signed argument");
11fdf7f2 707 EXPECT_EQ(" 42", format("{0: }", 42l));
9f95a23c
TL
708 EXPECT_THROW_MSG(format("{0: }", 42ul), format_error,
709 "format specifier requires signed argument");
11fdf7f2 710 EXPECT_EQ(" 42", format("{0: }", 42ll));
9f95a23c
TL
711 EXPECT_THROW_MSG(format("{0: }", 42ull), format_error,
712 "format specifier requires signed argument");
713 EXPECT_EQ(" 42.0", format("{0: }", 42.0));
714 EXPECT_EQ(" 42.0", format("{0: }", 42.0l));
715 EXPECT_THROW_MSG(format("{0: ", 'c'), format_error,
716 "missing '}' in format string");
717 EXPECT_THROW_MSG(format("{0: }", 'c'), format_error,
718 "invalid format specifier for char");
719 EXPECT_THROW_MSG(format("{0: }", "abc"), format_error,
720 "format specifier requires numeric argument");
721 EXPECT_THROW_MSG(format("{0: }", reinterpret_cast<void*>(0x42)), format_error,
722 "format specifier requires numeric argument");
11fdf7f2
TL
723}
724
725TEST(FormatterTest, HashFlag) {
726 EXPECT_EQ("42", format("{0:#}", 42));
727 EXPECT_EQ("-42", format("{0:#}", -42));
728 EXPECT_EQ("0b101010", format("{0:#b}", 42));
729 EXPECT_EQ("0B101010", format("{0:#B}", 42));
730 EXPECT_EQ("-0b101010", format("{0:#b}", -42));
731 EXPECT_EQ("0x42", format("{0:#x}", 0x42));
732 EXPECT_EQ("0X42", format("{0:#X}", 0x42));
733 EXPECT_EQ("-0x42", format("{0:#x}", -0x42));
f67539c2 734 EXPECT_EQ("0", format("{0:#o}", 0));
11fdf7f2
TL
735 EXPECT_EQ("042", format("{0:#o}", 042));
736 EXPECT_EQ("-042", format("{0:#o}", -042));
737 EXPECT_EQ("42", format("{0:#}", 42u));
738 EXPECT_EQ("0x42", format("{0:#x}", 0x42u));
739 EXPECT_EQ("042", format("{0:#o}", 042u));
740
741 EXPECT_EQ("-42", format("{0:#}", -42l));
742 EXPECT_EQ("0x42", format("{0:#x}", 0x42l));
743 EXPECT_EQ("-0x42", format("{0:#x}", -0x42l));
744 EXPECT_EQ("042", format("{0:#o}", 042l));
745 EXPECT_EQ("-042", format("{0:#o}", -042l));
746 EXPECT_EQ("42", format("{0:#}", 42ul));
747 EXPECT_EQ("0x42", format("{0:#x}", 0x42ul));
748 EXPECT_EQ("042", format("{0:#o}", 042ul));
749
750 EXPECT_EQ("-42", format("{0:#}", -42ll));
751 EXPECT_EQ("0x42", format("{0:#x}", 0x42ll));
752 EXPECT_EQ("-0x42", format("{0:#x}", -0x42ll));
753 EXPECT_EQ("042", format("{0:#o}", 042ll));
754 EXPECT_EQ("-042", format("{0:#o}", -042ll));
755 EXPECT_EQ("42", format("{0:#}", 42ull));
756 EXPECT_EQ("0x42", format("{0:#x}", 0x42ull));
757 EXPECT_EQ("042", format("{0:#o}", 042ull));
758
9f95a23c
TL
759 EXPECT_EQ("-42.0", format("{0:#}", -42.0));
760 EXPECT_EQ("-42.0", format("{0:#}", -42.0l));
f67539c2
TL
761 EXPECT_EQ("4.e+01", format("{:#.0e}", 42.0));
762 EXPECT_EQ("0.", format("{:#.0f}", 0.01));
763 auto s = format("{:#.0f}", 0.5); // MSVC's printf uses wrong rounding mode.
764 EXPECT_TRUE(s == "0." || s == "1.");
9f95a23c
TL
765 EXPECT_THROW_MSG(format("{0:#", 'c'), format_error,
766 "missing '}' in format string");
767 EXPECT_THROW_MSG(format("{0:#}", 'c'), format_error,
768 "invalid format specifier for char");
769 EXPECT_THROW_MSG(format("{0:#}", "abc"), format_error,
770 "format specifier requires numeric argument");
771 EXPECT_THROW_MSG(format("{0:#}", reinterpret_cast<void*>(0x42)), format_error,
772 "format specifier requires numeric argument");
11fdf7f2
TL
773}
774
775TEST(FormatterTest, ZeroFlag) {
776 EXPECT_EQ("42", format("{0:0}", 42));
777 EXPECT_EQ("-0042", format("{0:05}", -42));
778 EXPECT_EQ("00042", format("{0:05}", 42u));
779 EXPECT_EQ("-0042", format("{0:05}", -42l));
780 EXPECT_EQ("00042", format("{0:05}", 42ul));
781 EXPECT_EQ("-0042", format("{0:05}", -42ll));
782 EXPECT_EQ("00042", format("{0:05}", 42ull));
9f95a23c
TL
783 EXPECT_EQ("-0042.0", format("{0:07}", -42.0));
784 EXPECT_EQ("-0042.0", format("{0:07}", -42.0l));
785 EXPECT_THROW_MSG(format("{0:0", 'c'), format_error,
786 "missing '}' in format string");
787 EXPECT_THROW_MSG(format("{0:05}", 'c'), format_error,
788 "invalid format specifier for char");
789 EXPECT_THROW_MSG(format("{0:05}", "abc"), format_error,
790 "format specifier requires numeric argument");
11fdf7f2 791 EXPECT_THROW_MSG(format("{0:05}", reinterpret_cast<void*>(0x42)),
9f95a23c 792 format_error, "format specifier requires numeric argument");
11fdf7f2
TL
793}
794
795TEST(FormatterTest, Width) {
796 char format_str[BUFFER_SIZE];
797 safe_sprintf(format_str, "{0:%u", UINT_MAX);
798 increment(format_str + 3);
799 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
f67539c2 800 size_t size = std::strlen(format_str);
11fdf7f2
TL
801 format_str[size] = '}';
802 format_str[size + 1] = 0;
803 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
804
805 safe_sprintf(format_str, "{0:%u", INT_MAX + 1u);
806 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
807 safe_sprintf(format_str, "{0:%u}", INT_MAX + 1u);
808 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
809 EXPECT_EQ(" -42", format("{0:4}", -42));
810 EXPECT_EQ(" 42", format("{0:5}", 42u));
811 EXPECT_EQ(" -42", format("{0:6}", -42l));
812 EXPECT_EQ(" 42", format("{0:7}", 42ul));
813 EXPECT_EQ(" -42", format("{0:6}", -42ll));
814 EXPECT_EQ(" 42", format("{0:7}", 42ull));
815 EXPECT_EQ(" -1.23", format("{0:8}", -1.23));
816 EXPECT_EQ(" -1.23", format("{0:9}", -1.23l));
817 EXPECT_EQ(" 0xcafe", format("{0:10}", reinterpret_cast<void*>(0xcafe)));
818 EXPECT_EQ("x ", format("{0:11}", 'x'));
819 EXPECT_EQ("str ", format("{0:12}", "str"));
f67539c2 820 EXPECT_EQ(fmt::format("{:*^5}", "🤡"), "**🤡**");
11fdf7f2 821}
f67539c2 822
9f95a23c 823template <typename T> inline T const_check(T value) { return value; }
11fdf7f2
TL
824
825TEST(FormatterTest, RuntimeWidth) {
826 char format_str[BUFFER_SIZE];
827 safe_sprintf(format_str, "{0:{%u", UINT_MAX);
828 increment(format_str + 4);
829 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
f67539c2 830 size_t size = std::strlen(format_str);
11fdf7f2
TL
831 format_str[size] = '}';
832 format_str[size + 1] = 0;
833 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
834 format_str[size + 1] = '}';
835 format_str[size + 2] = 0;
836 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
837
9f95a23c
TL
838 EXPECT_THROW_MSG(format("{0:{", 0), format_error, "invalid format string");
839 EXPECT_THROW_MSG(format("{0:{}", 0), format_error,
840 "cannot switch from manual to automatic argument indexing");
841 EXPECT_THROW_MSG(format("{0:{?}}", 0), format_error, "invalid format string");
f67539c2 842 EXPECT_THROW_MSG(format("{0:{1}}", 0), format_error, "argument not found");
9f95a23c
TL
843
844 EXPECT_THROW_MSG(format("{0:{0:}}", 0), format_error,
845 "invalid format string");
846
847 EXPECT_THROW_MSG(format("{0:{1}}", 0, -1), format_error, "negative width");
848 EXPECT_THROW_MSG(format("{0:{1}}", 0, (INT_MAX + 1u)), format_error,
849 "number is too big");
850 EXPECT_THROW_MSG(format("{0:{1}}", 0, -1l), format_error, "negative width");
851 if (const_check(sizeof(long) > sizeof(int))) {
11fdf7f2 852 long value = INT_MAX;
9f95a23c
TL
853 EXPECT_THROW_MSG(format("{0:{1}}", 0, (value + 1)), format_error,
854 "number is too big");
11fdf7f2 855 }
9f95a23c
TL
856 EXPECT_THROW_MSG(format("{0:{1}}", 0, (INT_MAX + 1ul)), format_error,
857 "number is too big");
11fdf7f2 858
9f95a23c
TL
859 EXPECT_THROW_MSG(format("{0:{1}}", 0, '0'), format_error,
860 "width is not integer");
861 EXPECT_THROW_MSG(format("{0:{1}}", 0, 0.0), format_error,
862 "width is not integer");
11fdf7f2
TL
863
864 EXPECT_EQ(" -42", format("{0:{1}}", -42, 4));
865 EXPECT_EQ(" 42", format("{0:{1}}", 42u, 5));
866 EXPECT_EQ(" -42", format("{0:{1}}", -42l, 6));
867 EXPECT_EQ(" 42", format("{0:{1}}", 42ul, 7));
868 EXPECT_EQ(" -42", format("{0:{1}}", -42ll, 6));
869 EXPECT_EQ(" 42", format("{0:{1}}", 42ull, 7));
870 EXPECT_EQ(" -1.23", format("{0:{1}}", -1.23, 8));
871 EXPECT_EQ(" -1.23", format("{0:{1}}", -1.23l, 9));
872 EXPECT_EQ(" 0xcafe",
873 format("{0:{1}}", reinterpret_cast<void*>(0xcafe), 10));
874 EXPECT_EQ("x ", format("{0:{1}}", 'x', 11));
875 EXPECT_EQ("str ", format("{0:{1}}", "str", 12));
876}
877
878TEST(FormatterTest, Precision) {
879 char format_str[BUFFER_SIZE];
880 safe_sprintf(format_str, "{0:.%u", UINT_MAX);
881 increment(format_str + 4);
882 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
f67539c2 883 size_t size = std::strlen(format_str);
11fdf7f2
TL
884 format_str[size] = '}';
885 format_str[size + 1] = 0;
886 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
887
888 safe_sprintf(format_str, "{0:.%u", INT_MAX + 1u);
889 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
890 safe_sprintf(format_str, "{0:.%u}", INT_MAX + 1u);
891 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
892
9f95a23c
TL
893 EXPECT_THROW_MSG(format("{0:.", 0), format_error,
894 "missing precision specifier");
895 EXPECT_THROW_MSG(format("{0:.}", 0), format_error,
896 "missing precision specifier");
897
898 EXPECT_THROW_MSG(format("{0:.2", 0), format_error,
899 "precision not allowed for this argument type");
900 EXPECT_THROW_MSG(format("{0:.2}", 42), format_error,
901 "precision not allowed for this argument type");
902 EXPECT_THROW_MSG(format("{0:.2f}", 42), format_error,
903 "precision not allowed for this argument type");
904 EXPECT_THROW_MSG(format("{0:.2}", 42u), format_error,
905 "precision not allowed for this argument type");
906 EXPECT_THROW_MSG(format("{0:.2f}", 42u), format_error,
907 "precision not allowed for this argument type");
908 EXPECT_THROW_MSG(format("{0:.2}", 42l), format_error,
909 "precision not allowed for this argument type");
910 EXPECT_THROW_MSG(format("{0:.2f}", 42l), format_error,
911 "precision not allowed for this argument type");
912 EXPECT_THROW_MSG(format("{0:.2}", 42ul), format_error,
913 "precision not allowed for this argument type");
914 EXPECT_THROW_MSG(format("{0:.2f}", 42ul), format_error,
915 "precision not allowed for this argument type");
916 EXPECT_THROW_MSG(format("{0:.2}", 42ll), format_error,
917 "precision not allowed for this argument type");
918 EXPECT_THROW_MSG(format("{0:.2f}", 42ll), format_error,
919 "precision not allowed for this argument type");
920 EXPECT_THROW_MSG(format("{0:.2}", 42ull), format_error,
921 "precision not allowed for this argument type");
922 EXPECT_THROW_MSG(format("{0:.2f}", 42ull), format_error,
923 "precision not allowed for this argument type");
9f95a23c
TL
924 EXPECT_THROW_MSG(format("{0:3.0}", 'x'), format_error,
925 "precision not allowed for this argument type");
11fdf7f2
TL
926 EXPECT_EQ("1.2", format("{0:.2}", 1.2345));
927 EXPECT_EQ("1.2", format("{0:.2}", 1.2345l));
f67539c2
TL
928 EXPECT_EQ("1.2e+56", format("{:.2}", 1.234e56));
929 EXPECT_EQ("1e+00", format("{:.0e}", 1.0L));
930 EXPECT_EQ(" 0.0e+00", format("{:9.1e}", 0.0));
931 EXPECT_EQ(
932 "4.9406564584124654417656879286822137236505980261432476442558568250067550"
933 "727020875186529983636163599237979656469544571773092665671035593979639877"
934 "479601078187812630071319031140452784581716784898210368871863605699873072"
935 "305000638740915356498438731247339727316961514003171538539807412623856559"
936 "117102665855668676818703956031062493194527159149245532930545654440112748"
937 "012970999954193198940908041656332452475714786901472678015935523861155013"
938 "480352649347201937902681071074917033322268447533357208324319361e-324",
939 format("{:.494}", 4.9406564584124654E-324));
940 EXPECT_EQ(
941 "-0X1.41FE3FFE71C9E000000000000000000000000000000000000000000000000000000"
942 "000000000000000000000000000000000000000000000000000000000000000000000000"
943 "000000000000000000000000000000000000000000000000000000000000000000000000"
944 "000000000000000000000000000000000000000000000000000000000000000000000000"
945 "000000000000000000000000000000000000000000000000000000000000000000000000"
946 "000000000000000000000000000000000000000000000000000000000000000000000000"
947 "000000000000000000000000000000000000000000000000000000000000000000000000"
948 "000000000000000000000000000000000000000000000000000000000000000000000000"
949 "000000000000000000000000000000000000000000000000000000000000000000000000"
950 "000000000000000000000000000000000000000000000000000000000000000000000000"
951 "000000000000000000000000000000000000000000000000000000000000000000000000"
952 "000000000000000000000000000000000000000000000000000P+127",
953 format("{:.838A}", -2.14001164E+38));
954 EXPECT_EQ("123.", format("{:#.0f}", 123.0));
955 EXPECT_EQ("1.23", format("{:.02f}", 1.234));
956 EXPECT_EQ("0.001", format("{:.1g}", 0.001));
11fdf7f2
TL
957
958 EXPECT_THROW_MSG(format("{0:.2}", reinterpret_cast<void*>(0xcafe)),
9f95a23c
TL
959 format_error,
960 "precision not allowed for this argument type");
11fdf7f2 961 EXPECT_THROW_MSG(format("{0:.2f}", reinterpret_cast<void*>(0xcafe)),
9f95a23c
TL
962 format_error,
963 "precision not allowed for this argument type");
f67539c2
TL
964 EXPECT_THROW_MSG(format("{:.{}e}", 42.0, fmt::detail::max_value<int>()),
965 format_error, "number is too big");
11fdf7f2
TL
966
967 EXPECT_EQ("st", format("{0:.2}", "str"));
968}
969
970TEST(FormatterTest, RuntimePrecision) {
971 char format_str[BUFFER_SIZE];
972 safe_sprintf(format_str, "{0:.{%u", UINT_MAX);
973 increment(format_str + 5);
974 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
f67539c2 975 size_t size = std::strlen(format_str);
11fdf7f2
TL
976 format_str[size] = '}';
977 format_str[size + 1] = 0;
978 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
979 format_str[size + 1] = '}';
980 format_str[size + 2] = 0;
981 EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big");
982
9f95a23c
TL
983 EXPECT_THROW_MSG(format("{0:.{", 0), format_error, "invalid format string");
984 EXPECT_THROW_MSG(format("{0:.{}", 0), format_error,
985 "cannot switch from manual to automatic argument indexing");
986 EXPECT_THROW_MSG(format("{0:.{?}}", 0), format_error,
987 "invalid format string");
988 EXPECT_THROW_MSG(format("{0:.{1}", 0, 0), format_error,
989 "precision not allowed for this argument type");
f67539c2 990 EXPECT_THROW_MSG(format("{0:.{1}}", 0), format_error, "argument not found");
9f95a23c
TL
991
992 EXPECT_THROW_MSG(format("{0:.{0:}}", 0), format_error,
993 "invalid format string");
994
995 EXPECT_THROW_MSG(format("{0:.{1}}", 0, -1), format_error,
996 "negative precision");
997 EXPECT_THROW_MSG(format("{0:.{1}}", 0, (INT_MAX + 1u)), format_error,
998 "number is too big");
999 EXPECT_THROW_MSG(format("{0:.{1}}", 0, -1l), format_error,
1000 "negative precision");
1001 if (const_check(sizeof(long) > sizeof(int))) {
11fdf7f2 1002 long value = INT_MAX;
9f95a23c
TL
1003 EXPECT_THROW_MSG(format("{0:.{1}}", 0, (value + 1)), format_error,
1004 "number is too big");
11fdf7f2 1005 }
9f95a23c
TL
1006 EXPECT_THROW_MSG(format("{0:.{1}}", 0, (INT_MAX + 1ul)), format_error,
1007 "number is too big");
1008
1009 EXPECT_THROW_MSG(format("{0:.{1}}", 0, '0'), format_error,
1010 "precision is not integer");
1011 EXPECT_THROW_MSG(format("{0:.{1}}", 0, 0.0), format_error,
1012 "precision is not integer");
1013
1014 EXPECT_THROW_MSG(format("{0:.{1}}", 42, 2), format_error,
1015 "precision not allowed for this argument type");
1016 EXPECT_THROW_MSG(format("{0:.{1}f}", 42, 2), format_error,
1017 "precision not allowed for this argument type");
1018 EXPECT_THROW_MSG(format("{0:.{1}}", 42u, 2), format_error,
1019 "precision not allowed for this argument type");
1020 EXPECT_THROW_MSG(format("{0:.{1}f}", 42u, 2), format_error,
1021 "precision not allowed for this argument type");
1022 EXPECT_THROW_MSG(format("{0:.{1}}", 42l, 2), format_error,
1023 "precision not allowed for this argument type");
1024 EXPECT_THROW_MSG(format("{0:.{1}f}", 42l, 2), format_error,
1025 "precision not allowed for this argument type");
1026 EXPECT_THROW_MSG(format("{0:.{1}}", 42ul, 2), format_error,
1027 "precision not allowed for this argument type");
1028 EXPECT_THROW_MSG(format("{0:.{1}f}", 42ul, 2), format_error,
1029 "precision not allowed for this argument type");
1030 EXPECT_THROW_MSG(format("{0:.{1}}", 42ll, 2), format_error,
1031 "precision not allowed for this argument type");
1032 EXPECT_THROW_MSG(format("{0:.{1}f}", 42ll, 2), format_error,
1033 "precision not allowed for this argument type");
1034 EXPECT_THROW_MSG(format("{0:.{1}}", 42ull, 2), format_error,
1035 "precision not allowed for this argument type");
1036 EXPECT_THROW_MSG(format("{0:.{1}f}", 42ull, 2), format_error,
1037 "precision not allowed for this argument type");
1038 EXPECT_THROW_MSG(format("{0:3.{1}}", 'x', 0), format_error,
1039 "precision not allowed for this argument type");
11fdf7f2
TL
1040 EXPECT_EQ("1.2", format("{0:.{1}}", 1.2345, 2));
1041 EXPECT_EQ("1.2", format("{1:.{0}}", 2, 1.2345l));
1042
1043 EXPECT_THROW_MSG(format("{0:.{1}}", reinterpret_cast<void*>(0xcafe), 2),
9f95a23c
TL
1044 format_error,
1045 "precision not allowed for this argument type");
11fdf7f2 1046 EXPECT_THROW_MSG(format("{0:.{1}f}", reinterpret_cast<void*>(0xcafe), 2),
9f95a23c
TL
1047 format_error,
1048 "precision not allowed for this argument type");
11fdf7f2
TL
1049
1050 EXPECT_EQ("st", format("{0:.{1}}", "str", 2));
1051}
1052
1053template <typename T>
9f95a23c 1054void check_unknown_types(const T& value, const char* types, const char*) {
11fdf7f2 1055 char format_str[BUFFER_SIZE];
9f95a23c 1056 const char* special = ".0123456789}";
11fdf7f2
TL
1057 for (int i = CHAR_MIN; i <= CHAR_MAX; ++i) {
1058 char c = static_cast<char>(i);
1059 if (std::strchr(types, c) || std::strchr(special, c) || !c) continue;
1060 safe_sprintf(format_str, "{0:10%c}", c);
9f95a23c 1061 const char* message = "invalid type specifier";
11fdf7f2 1062 EXPECT_THROW_MSG(format(format_str, value), format_error, message)
9f95a23c 1063 << format_str << " " << message;
11fdf7f2
TL
1064 }
1065}
1066
1067TEST(BoolTest, FormatBool) {
1068 EXPECT_EQ("true", format("{}", true));
1069 EXPECT_EQ("false", format("{}", false));
1070 EXPECT_EQ("1", format("{:d}", true));
1071 EXPECT_EQ("true ", format("{:5}", true));
1072 EXPECT_EQ(L"true", format(L"{}", true));
1073}
1074
1075TEST(FormatterTest, FormatShort) {
1076 short s = 42;
1077 EXPECT_EQ("42", format("{0:d}", s));
1078 unsigned short us = 42;
1079 EXPECT_EQ("42", format("{0:d}", us));
1080}
1081
1082TEST(FormatterTest, FormatInt) {
9f95a23c
TL
1083 EXPECT_THROW_MSG(format("{0:v", 42), format_error,
1084 "missing '}' in format string");
f67539c2
TL
1085 check_unknown_types(42, "bBdoxXnLc", "integer");
1086 EXPECT_EQ("x", format("{:c}", static_cast<int>('x')));
11fdf7f2
TL
1087}
1088
1089TEST(FormatterTest, FormatBin) {
1090 EXPECT_EQ("0", format("{0:b}", 0));
1091 EXPECT_EQ("101010", format("{0:b}", 42));
1092 EXPECT_EQ("101010", format("{0:b}", 42u));
1093 EXPECT_EQ("-101010", format("{0:b}", -42));
1094 EXPECT_EQ("11000000111001", format("{0:b}", 12345));
1095 EXPECT_EQ("10010001101000101011001111000", format("{0:b}", 0x12345678));
1096 EXPECT_EQ("10010000101010111100110111101111", format("{0:b}", 0x90ABCDEF));
1097 EXPECT_EQ("11111111111111111111111111111111",
f67539c2 1098 format("{0:b}", max_value<uint32_t>()));
11fdf7f2
TL
1099}
1100
f67539c2
TL
1101#if FMT_USE_INT128
1102constexpr auto int128_max = static_cast<__int128_t>(
1103 (static_cast<__uint128_t>(1) << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1);
1104constexpr auto int128_min = -int128_max - 1;
1105
1106constexpr auto uint128_max = ~static_cast<__uint128_t>(0);
1107#endif
1108
11fdf7f2
TL
1109TEST(FormatterTest, FormatDec) {
1110 EXPECT_EQ("0", format("{0}", 0));
1111 EXPECT_EQ("42", format("{0}", 42));
1112 EXPECT_EQ("42", format("{0:d}", 42));
1113 EXPECT_EQ("42", format("{0}", 42u));
1114 EXPECT_EQ("-42", format("{0}", -42));
1115 EXPECT_EQ("12345", format("{0}", 12345));
1116 EXPECT_EQ("67890", format("{0}", 67890));
f67539c2
TL
1117#if FMT_USE_INT128
1118 EXPECT_EQ("0", format("{0}", static_cast<__int128_t>(0)));
1119 EXPECT_EQ("0", format("{0}", static_cast<__uint128_t>(0)));
1120 EXPECT_EQ("9223372036854775808",
1121 format("{0}", static_cast<__int128_t>(INT64_MAX) + 1));
1122 EXPECT_EQ("-9223372036854775809",
1123 format("{0}", static_cast<__int128_t>(INT64_MIN) - 1));
1124 EXPECT_EQ("18446744073709551616",
1125 format("{0}", static_cast<__int128_t>(UINT64_MAX) + 1));
1126 EXPECT_EQ("170141183460469231731687303715884105727",
1127 format("{0}", int128_max));
1128 EXPECT_EQ("-170141183460469231731687303715884105728",
1129 format("{0}", int128_min));
1130 EXPECT_EQ("340282366920938463463374607431768211455",
1131 format("{0}", uint128_max));
1132#endif
1133
11fdf7f2
TL
1134 char buffer[BUFFER_SIZE];
1135 safe_sprintf(buffer, "%d", INT_MIN);
1136 EXPECT_EQ(buffer, format("{0}", INT_MIN));
1137 safe_sprintf(buffer, "%d", INT_MAX);
1138 EXPECT_EQ(buffer, format("{0}", INT_MAX));
1139 safe_sprintf(buffer, "%u", UINT_MAX);
1140 EXPECT_EQ(buffer, format("{0}", UINT_MAX));
1141 safe_sprintf(buffer, "%ld", 0 - static_cast<unsigned long>(LONG_MIN));
1142 EXPECT_EQ(buffer, format("{0}", LONG_MIN));
1143 safe_sprintf(buffer, "%ld", LONG_MAX);
1144 EXPECT_EQ(buffer, format("{0}", LONG_MAX));
1145 safe_sprintf(buffer, "%lu", ULONG_MAX);
1146 EXPECT_EQ(buffer, format("{0}", ULONG_MAX));
1147}
1148
1149TEST(FormatterTest, FormatHex) {
1150 EXPECT_EQ("0", format("{0:x}", 0));
1151 EXPECT_EQ("42", format("{0:x}", 0x42));
1152 EXPECT_EQ("42", format("{0:x}", 0x42u));
1153 EXPECT_EQ("-42", format("{0:x}", -0x42));
1154 EXPECT_EQ("12345678", format("{0:x}", 0x12345678));
1155 EXPECT_EQ("90abcdef", format("{0:x}", 0x90abcdef));
1156 EXPECT_EQ("12345678", format("{0:X}", 0x12345678));
1157 EXPECT_EQ("90ABCDEF", format("{0:X}", 0x90ABCDEF));
f67539c2
TL
1158#if FMT_USE_INT128
1159 EXPECT_EQ("0", format("{0:x}", static_cast<__int128_t>(0)));
1160 EXPECT_EQ("0", format("{0:x}", static_cast<__uint128_t>(0)));
1161 EXPECT_EQ("8000000000000000",
1162 format("{0:x}", static_cast<__int128_t>(INT64_MAX) + 1));
1163 EXPECT_EQ("-8000000000000001",
1164 format("{0:x}", static_cast<__int128_t>(INT64_MIN) - 1));
1165 EXPECT_EQ("10000000000000000",
1166 format("{0:x}", static_cast<__int128_t>(UINT64_MAX) + 1));
1167 EXPECT_EQ("7fffffffffffffffffffffffffffffff", format("{0:x}", int128_max));
1168 EXPECT_EQ("-80000000000000000000000000000000", format("{0:x}", int128_min));
1169 EXPECT_EQ("ffffffffffffffffffffffffffffffff", format("{0:x}", uint128_max));
1170#endif
11fdf7f2
TL
1171
1172 char buffer[BUFFER_SIZE];
1173 safe_sprintf(buffer, "-%x", 0 - static_cast<unsigned>(INT_MIN));
1174 EXPECT_EQ(buffer, format("{0:x}", INT_MIN));
1175 safe_sprintf(buffer, "%x", INT_MAX);
1176 EXPECT_EQ(buffer, format("{0:x}", INT_MAX));
1177 safe_sprintf(buffer, "%x", UINT_MAX);
1178 EXPECT_EQ(buffer, format("{0:x}", UINT_MAX));
1179 safe_sprintf(buffer, "-%lx", 0 - static_cast<unsigned long>(LONG_MIN));
1180 EXPECT_EQ(buffer, format("{0:x}", LONG_MIN));
1181 safe_sprintf(buffer, "%lx", LONG_MAX);
1182 EXPECT_EQ(buffer, format("{0:x}", LONG_MAX));
1183 safe_sprintf(buffer, "%lx", ULONG_MAX);
1184 EXPECT_EQ(buffer, format("{0:x}", ULONG_MAX));
1185}
1186
1187TEST(FormatterTest, FormatOct) {
1188 EXPECT_EQ("0", format("{0:o}", 0));
1189 EXPECT_EQ("42", format("{0:o}", 042));
1190 EXPECT_EQ("42", format("{0:o}", 042u));
1191 EXPECT_EQ("-42", format("{0:o}", -042));
1192 EXPECT_EQ("12345670", format("{0:o}", 012345670));
f67539c2
TL
1193#if FMT_USE_INT128
1194 EXPECT_EQ("0", format("{0:o}", static_cast<__int128_t>(0)));
1195 EXPECT_EQ("0", format("{0:o}", static_cast<__uint128_t>(0)));
1196 EXPECT_EQ("1000000000000000000000",
1197 format("{0:o}", static_cast<__int128_t>(INT64_MAX) + 1));
1198 EXPECT_EQ("-1000000000000000000001",
1199 format("{0:o}", static_cast<__int128_t>(INT64_MIN) - 1));
1200 EXPECT_EQ("2000000000000000000000",
1201 format("{0:o}", static_cast<__int128_t>(UINT64_MAX) + 1));
1202 EXPECT_EQ("1777777777777777777777777777777777777777777",
1203 format("{0:o}", int128_max));
1204 EXPECT_EQ("-2000000000000000000000000000000000000000000",
1205 format("{0:o}", int128_min));
1206 EXPECT_EQ("3777777777777777777777777777777777777777777",
1207 format("{0:o}", uint128_max));
1208#endif
1209
11fdf7f2
TL
1210 char buffer[BUFFER_SIZE];
1211 safe_sprintf(buffer, "-%o", 0 - static_cast<unsigned>(INT_MIN));
1212 EXPECT_EQ(buffer, format("{0:o}", INT_MIN));
1213 safe_sprintf(buffer, "%o", INT_MAX);
1214 EXPECT_EQ(buffer, format("{0:o}", INT_MAX));
1215 safe_sprintf(buffer, "%o", UINT_MAX);
1216 EXPECT_EQ(buffer, format("{0:o}", UINT_MAX));
1217 safe_sprintf(buffer, "-%lo", 0 - static_cast<unsigned long>(LONG_MIN));
1218 EXPECT_EQ(buffer, format("{0:o}", LONG_MIN));
1219 safe_sprintf(buffer, "%lo", LONG_MAX);
1220 EXPECT_EQ(buffer, format("{0:o}", LONG_MAX));
1221 safe_sprintf(buffer, "%lo", ULONG_MAX);
1222 EXPECT_EQ(buffer, format("{0:o}", ULONG_MAX));
1223}
1224
1225TEST(FormatterTest, FormatIntLocale) {
f67539c2
TL
1226 EXPECT_EQ("1234", format("{:n}", 1234));
1227 EXPECT_EQ("1234", format("{:L}", 1234));
11fdf7f2
TL
1228}
1229
1230struct ConvertibleToLongLong {
1231 operator long long() const { return 1LL << 32; }
1232};
1233
1234TEST(FormatterTest, FormatConvertibleToLongLong) {
1235 EXPECT_EQ("100000000", format("{:x}", ConvertibleToLongLong()));
1236}
1237
1238TEST(FormatterTest, FormatFloat) {
1239 EXPECT_EQ("392.500000", format("{0:f}", 392.5f));
1240}
1241
1242TEST(FormatterTest, FormatDouble) {
f67539c2 1243 check_unknown_types(1.2, "eEfFgGaAnL%", "double");
9f95a23c 1244 EXPECT_EQ("0.0", format("{:}", 0.0));
eafe8130
TL
1245 EXPECT_EQ("0.000000", format("{:f}", 0.0));
1246 EXPECT_EQ("0", format("{:g}", 0.0));
1247 EXPECT_EQ("392.65", format("{:}", 392.65));
1248 EXPECT_EQ("392.65", format("{:g}", 392.65));
1249 EXPECT_EQ("392.65", format("{:G}", 392.65));
1250 EXPECT_EQ("392.650000", format("{:f}", 392.65));
1251 EXPECT_EQ("392.650000", format("{:F}", 392.65));
f67539c2 1252 EXPECT_EQ("42", format("{:L}", 42.0));
11fdf7f2
TL
1253 char buffer[BUFFER_SIZE];
1254 safe_sprintf(buffer, "%e", 392.65);
1255 EXPECT_EQ(buffer, format("{0:e}", 392.65));
1256 safe_sprintf(buffer, "%E", 392.65);
1257 EXPECT_EQ(buffer, format("{0:E}", 392.65));
1258 EXPECT_EQ("+0000392.6", format("{0:+010.4g}", 392.65));
1259 safe_sprintf(buffer, "%a", -42.0);
1260 EXPECT_EQ(buffer, format("{:a}", -42.0));
1261 safe_sprintf(buffer, "%A", -42.0);
1262 EXPECT_EQ(buffer, format("{:A}", -42.0));
1263}
1264
9f95a23c 1265TEST(FormatterTest, PrecisionRounding) {
f67539c2
TL
1266 EXPECT_EQ("0", format("{:.0f}", 0.0));
1267 EXPECT_EQ("0", format("{:.0f}", 0.01));
9f95a23c
TL
1268 EXPECT_EQ("0", format("{:.0f}", 0.1));
1269 EXPECT_EQ("0.000", format("{:.3f}", 0.00049));
1270 EXPECT_EQ("0.001", format("{:.3f}", 0.0005));
1271 EXPECT_EQ("0.001", format("{:.3f}", 0.00149));
1272 EXPECT_EQ("0.002", format("{:.3f}", 0.0015));
1273 EXPECT_EQ("1.000", format("{:.3f}", 0.9999));
1274 EXPECT_EQ("0.00123", format("{:.3}", 0.00123));
f67539c2 1275 EXPECT_EQ("0.1", format("{:.16g}", 0.1));
9f95a23c
TL
1276 // Trigger rounding error in Grisu by a carefully chosen number.
1277 auto n = 3788512123356.985352;
1278 char buffer[64];
f67539c2 1279 safe_sprintf(buffer, "%f", n);
9f95a23c 1280 EXPECT_EQ(buffer, format("{:f}", n));
eafe8130
TL
1281}
1282
11fdf7f2
TL
1283TEST(FormatterTest, FormatNaN) {
1284 double nan = std::numeric_limits<double>::quiet_NaN();
1285 EXPECT_EQ("nan", format("{}", nan));
1286 EXPECT_EQ("+nan", format("{:+}", nan));
1287 EXPECT_EQ(" nan", format("{: }", nan));
1288 EXPECT_EQ("NAN", format("{:F}", nan));
1289 EXPECT_EQ("nan ", format("{:<7}", nan));
1290 EXPECT_EQ(" nan ", format("{:^7}", nan));
1291 EXPECT_EQ(" nan", format("{:>7}", nan));
1292}
1293
1294TEST(FormatterTest, FormatInfinity) {
1295 double inf = std::numeric_limits<double>::infinity();
1296 EXPECT_EQ("inf", format("{}", inf));
1297 EXPECT_EQ("+inf", format("{:+}", inf));
1298 EXPECT_EQ("-inf", format("{}", -inf));
1299 EXPECT_EQ(" inf", format("{: }", inf));
1300 EXPECT_EQ("INF", format("{:F}", inf));
1301 EXPECT_EQ("inf ", format("{:<7}", inf));
1302 EXPECT_EQ(" inf ", format("{:^7}", inf));
1303 EXPECT_EQ(" inf", format("{:>7}", inf));
1304}
1305
1306TEST(FormatterTest, FormatLongDouble) {
9f95a23c 1307 EXPECT_EQ("0.0", format("{0:}", 0.0l));
11fdf7f2
TL
1308 EXPECT_EQ("0.000000", format("{0:f}", 0.0l));
1309 EXPECT_EQ("392.65", format("{0:}", 392.65l));
1310 EXPECT_EQ("392.65", format("{0:g}", 392.65l));
1311 EXPECT_EQ("392.65", format("{0:G}", 392.65l));
1312 EXPECT_EQ("392.650000", format("{0:f}", 392.65l));
1313 EXPECT_EQ("392.650000", format("{0:F}", 392.65l));
1314 char buffer[BUFFER_SIZE];
1315 safe_sprintf(buffer, "%Le", 392.65l);
1316 EXPECT_EQ(buffer, format("{0:e}", 392.65l));
1317 EXPECT_EQ("+0000392.6", format("{0:+010.4g}", 392.64l));
f67539c2
TL
1318 safe_sprintf(buffer, "%La", 3.31l);
1319 EXPECT_EQ(buffer, format("{:a}", 3.31l));
11fdf7f2
TL
1320}
1321
1322TEST(FormatterTest, FormatChar) {
f67539c2 1323 const char types[] = "cbBdoxXnL";
11fdf7f2
TL
1324 check_unknown_types('a', types, "char");
1325 EXPECT_EQ("a", format("{0}", 'a'));
1326 EXPECT_EQ("z", format("{0:c}", 'z'));
1327 EXPECT_EQ(L"a", format(L"{0}", 'a'));
1328 int n = 'x';
9f95a23c 1329 for (const char* type = types + 1; *type; ++type) {
11fdf7f2
TL
1330 std::string format_str = fmt::format("{{:{}}}", *type);
1331 EXPECT_EQ(fmt::format(format_str, n), fmt::format(format_str, 'x'));
1332 }
1333 EXPECT_EQ(fmt::format("{:02X}", n), fmt::format("{:02X}", 'x'));
1334}
1335
f67539c2
TL
1336TEST(FormatterTest, FormatVolatileChar) {
1337 volatile char c = 'x';
1338 EXPECT_EQ("x", format("{}", c));
1339}
1340
11fdf7f2
TL
1341TEST(FormatterTest, FormatUnsignedChar) {
1342 EXPECT_EQ("42", format("{}", static_cast<unsigned char>(42)));
1343 EXPECT_EQ("42", format("{}", static_cast<uint8_t>(42)));
1344}
1345
1346TEST(FormatterTest, FormatWChar) {
1347 EXPECT_EQ(L"a", format(L"{0}", L'a'));
1348 // This shouldn't compile:
9f95a23c 1349 // format("{}", L'a');
11fdf7f2
TL
1350}
1351
1352TEST(FormatterTest, FormatCString) {
1353 check_unknown_types("test", "sp", "string");
1354 EXPECT_EQ("test", format("{0}", "test"));
1355 EXPECT_EQ("test", format("{0:s}", "test"));
1356 char nonconst[] = "nonconst";
1357 EXPECT_EQ("nonconst", format("{0}", nonconst));
f67539c2 1358 EXPECT_THROW_MSG(format("{0}", static_cast<const char*>(nullptr)),
9f95a23c 1359 format_error, "string pointer is null");
11fdf7f2
TL
1360}
1361
1362TEST(FormatterTest, FormatSCharString) {
1363 signed char str[] = "test";
1364 EXPECT_EQ("test", format("{0:s}", str));
9f95a23c 1365 const signed char* const_str = str;
11fdf7f2
TL
1366 EXPECT_EQ("test", format("{0:s}", const_str));
1367}
1368
1369TEST(FormatterTest, FormatUCharString) {
1370 unsigned char str[] = "test";
1371 EXPECT_EQ("test", format("{0:s}", str));
9f95a23c 1372 const unsigned char* const_str = str;
11fdf7f2 1373 EXPECT_EQ("test", format("{0:s}", const_str));
9f95a23c 1374 unsigned char* ptr = str;
11fdf7f2
TL
1375 EXPECT_EQ("test", format("{0:s}", ptr));
1376}
1377
1378TEST(FormatterTest, FormatPointer) {
1379 check_unknown_types(reinterpret_cast<void*>(0x1234), "p", "pointer");
f67539c2 1380 EXPECT_EQ("0x0", format("{0}", static_cast<void*>(nullptr)));
11fdf7f2
TL
1381 EXPECT_EQ("0x1234", format("{0}", reinterpret_cast<void*>(0x1234)));
1382 EXPECT_EQ("0x1234", format("{0:p}", reinterpret_cast<void*>(0x1234)));
1383 EXPECT_EQ("0x" + std::string(sizeof(void*) * CHAR_BIT / 4, 'f'),
9f95a23c 1384 format("{0}", reinterpret_cast<void*>(~uintptr_t())));
11fdf7f2 1385 EXPECT_EQ("0x1234", format("{}", fmt::ptr(reinterpret_cast<int*>(0x1234))));
f67539c2
TL
1386 std::unique_ptr<int> up(new int(1));
1387 EXPECT_EQ(format("{}", fmt::ptr(up.get())), format("{}", fmt::ptr(up)));
1388 std::shared_ptr<int> sp(new int(1));
1389 EXPECT_EQ(format("{}", fmt::ptr(sp.get())), format("{}", fmt::ptr(sp)));
1390 EXPECT_EQ("0x0", format("{}", nullptr));
11fdf7f2
TL
1391}
1392
1393TEST(FormatterTest, FormatString) {
1394 EXPECT_EQ("test", format("{0}", std::string("test")));
1395}
1396
1397TEST(FormatterTest, FormatStringView) {
1398 EXPECT_EQ("test", format("{}", string_view("test")));
1399 EXPECT_EQ("", format("{}", string_view()));
1400}
1401
f67539c2
TL
1402#ifdef FMT_USE_STRING_VIEW
1403struct string_viewable {};
1404
1405FMT_BEGIN_NAMESPACE
1406template <> struct formatter<string_viewable> : formatter<std::string_view> {
1407 auto format(string_viewable, format_context& ctx) -> decltype(ctx.out()) {
1408 return formatter<std::string_view>::format("foo", ctx);
1409 }
1410};
1411FMT_END_NAMESPACE
1412
11fdf7f2 1413TEST(FormatterTest, FormatStdStringView) {
f67539c2
TL
1414 EXPECT_EQ("test", format("{}", std::string_view("test")));
1415 EXPECT_EQ("foo", format("{}", string_viewable()));
1416}
1417
1418struct explicitly_convertible_to_std_string_view {
1419 explicit operator std::string_view() const { return "foo"; }
1420};
1421
1422namespace fmt {
1423template <>
1424struct formatter<explicitly_convertible_to_std_string_view>
1425 : formatter<std::string_view> {
1426 auto format(const explicitly_convertible_to_std_string_view& v,
1427 format_context& ctx) -> decltype(ctx.out()) {
1428 return format_to(ctx.out(), "'{}'", std::string_view(v));
1429 }
1430};
1431} // namespace fmt
1432
1433TEST(FormatterTest, FormatExplicitlyConvertibleToStdStringView) {
1434 EXPECT_EQ("'foo'",
1435 fmt::format("{}", explicitly_convertible_to_std_string_view()));
1436}
1437#endif
1438
1439// std::is_constructible is broken in MSVC until version 2015.
1440#if !FMT_MSC_VER || FMT_MSC_VER >= 1900
1441struct explicitly_convertible_to_wstring_view {
1442 explicit operator fmt::wstring_view() const { return L"foo"; }
1443};
1444
1445TEST(FormatTest, FormatExplicitlyConvertibleToWStringView) {
1446 EXPECT_EQ(L"foo",
1447 fmt::format(L"{}", explicitly_convertible_to_wstring_view()));
11fdf7f2
TL
1448}
1449#endif
1450
f67539c2
TL
1451namespace fake_qt {
1452class QString {
1453 public:
1454 QString(const wchar_t* s) : s_(std::make_shared<std::wstring>(s)) {}
1455 const wchar_t* utf16() const FMT_NOEXCEPT { return s_->data(); }
1456 int size() const FMT_NOEXCEPT { return static_cast<int>(s_->size()); }
1457
1458 private:
1459 std::shared_ptr<std::wstring> s_;
1460};
1461
1462fmt::basic_string_view<wchar_t> to_string_view(const QString& s) FMT_NOEXCEPT {
1463 return {s.utf16(), static_cast<size_t>(s.size())};
1464}
1465} // namespace fake_qt
1466
1467TEST(FormatTest, FormatForeignStrings) {
1468 using fake_qt::QString;
1469 EXPECT_EQ(fmt::format(QString(L"{}"), 42), L"42");
1470 EXPECT_EQ(fmt::format(QString(L"{}"), QString(L"42")), L"42");
1471}
1472
11fdf7f2 1473FMT_BEGIN_NAMESPACE
9f95a23c 1474template <> struct formatter<Date> {
11fdf7f2 1475 template <typename ParseContext>
9f95a23c 1476 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
11fdf7f2 1477 auto it = ctx.begin();
9f95a23c 1478 if (*it == 'd') ++it;
11fdf7f2
TL
1479 return it;
1480 }
1481
9f95a23c 1482 auto format(const Date& d, format_context& ctx) -> decltype(ctx.out()) {
11fdf7f2
TL
1483 format_to(ctx.out(), "{}-{}-{}", d.year(), d.month(), d.day());
1484 return ctx.out();
1485 }
1486};
1487FMT_END_NAMESPACE
1488
1489TEST(FormatterTest, FormatCustom) {
1490 Date date(2012, 12, 9);
1491 EXPECT_THROW_MSG(fmt::format("{:s}", date), format_error,
1492 "unknown format specifier");
1493}
1494
1495class Answer {};
1496
1497FMT_BEGIN_NAMESPACE
9f95a23c 1498template <> struct formatter<Answer> : formatter<int> {
11fdf7f2 1499 template <typename FormatContext>
9f95a23c 1500 auto format(Answer, FormatContext& ctx) -> decltype(ctx.out()) {
11fdf7f2
TL
1501 return formatter<int>::format(42, ctx);
1502 }
1503};
1504FMT_END_NAMESPACE
1505
1506TEST(FormatterTest, CustomFormat) {
1507 EXPECT_EQ("42", format("{0}", Answer()));
1508 EXPECT_EQ("0042", format("{:04}", Answer()));
1509}
1510
1511TEST(FormatterTest, CustomFormatTo) {
1512 char buf[10] = {};
9f95a23c 1513 auto end =
f67539c2 1514 &*fmt::format_to(fmt::detail::make_checked(buf, 10), "{}", Answer());
11fdf7f2
TL
1515 EXPECT_EQ(end, buf + 2);
1516 EXPECT_STREQ(buf, "42");
1517}
1518
1519TEST(FormatterTest, WideFormatString) {
1520 EXPECT_EQ(L"42", format(L"{}", 42));
1521 EXPECT_EQ(L"4.2", format(L"{}", 4.2));
1522 EXPECT_EQ(L"abc", format(L"{}", L"abc"));
1523 EXPECT_EQ(L"z", format(L"{}", L'z'));
1524}
1525
1526TEST(FormatterTest, FormatStringFromSpeedTest) {
1527 EXPECT_EQ("1.2340000000:0042:+3.13:str:0x3e8:X:%",
9f95a23c
TL
1528 format("{0:0.10f}:{1:04}:{2:+g}:{3}:{4}:{5}:%", 1.234, 42, 3.13,
1529 "str", reinterpret_cast<void*>(1000), 'X'));
11fdf7f2
TL
1530}
1531
1532TEST(FormatterTest, FormatExamples) {
1533 std::string message = format("The answer is {}", 42);
1534 EXPECT_EQ("The answer is 42", message);
1535
1536 EXPECT_EQ("42", format("{}", 42));
1537 EXPECT_EQ("42", format(std::string("{}"), 42));
1538
1539 memory_buffer out;
1540 format_to(out, "The answer is {}.", 42);
1541 EXPECT_EQ("The answer is 42.", to_string(out));
1542
9f95a23c
TL
1543 const char* filename = "nonexistent";
1544 FILE* ftest = safe_fopen(filename, "r");
11fdf7f2
TL
1545 if (ftest) fclose(ftest);
1546 int error_code = errno;
f67539c2 1547 EXPECT_TRUE(ftest == nullptr);
9f95a23c
TL
1548 EXPECT_SYSTEM_ERROR(
1549 {
1550 FILE* f = safe_fopen(filename, "r");
1551 if (!f)
1552 throw fmt::system_error(errno, "Cannot open file '{}'", filename);
1553 fclose(f);
1554 },
1555 error_code, "Cannot open file 'nonexistent'");
11fdf7f2
TL
1556}
1557
1558TEST(FormatterTest, Examples) {
1559 EXPECT_EQ("First, thou shalt count to three",
9f95a23c
TL
1560 format("First, thou shalt count to {0}", "three"));
1561 EXPECT_EQ("Bring me a shrubbery", format("Bring me a {}", "shrubbery"));
11fdf7f2
TL
1562 EXPECT_EQ("From 1 to 3", format("From {} to {}", 1, 3));
1563
1564 char buffer[BUFFER_SIZE];
1565 safe_sprintf(buffer, "%03.2f", -1.2);
1566 EXPECT_EQ(buffer, format("{:03.2f}", -1.2));
1567
1568 EXPECT_EQ("a, b, c", format("{0}, {1}, {2}", 'a', 'b', 'c'));
1569 EXPECT_EQ("a, b, c", format("{}, {}, {}", 'a', 'b', 'c'));
1570 EXPECT_EQ("c, b, a", format("{2}, {1}, {0}", 'a', 'b', 'c'));
1571 EXPECT_EQ("abracadabra", format("{0}{1}{0}", "abra", "cad"));
1572
9f95a23c 1573 EXPECT_EQ("left aligned ", format("{:<30}", "left aligned"));
11fdf7f2 1574 EXPECT_EQ(" right aligned",
9f95a23c
TL
1575 format("{:>30}", "right aligned"));
1576 EXPECT_EQ(" centered ", format("{:^30}", "centered"));
1577 EXPECT_EQ("***********centered***********", format("{:*^30}", "centered"));
1578
1579 EXPECT_EQ("+3.140000; -3.140000", format("{:+f}; {:+f}", 3.14, -3.14));
1580 EXPECT_EQ(" 3.140000; -3.140000", format("{: f}; {: f}", 3.14, -3.14));
1581 EXPECT_EQ("3.140000; -3.140000", format("{:-f}; {:-f}", 3.14, -3.14));
11fdf7f2
TL
1582
1583 EXPECT_EQ("int: 42; hex: 2a; oct: 52",
9f95a23c 1584 format("int: {0:d}; hex: {0:x}; oct: {0:o}", 42));
11fdf7f2 1585 EXPECT_EQ("int: 42; hex: 0x2a; oct: 052",
9f95a23c 1586 format("int: {0:d}; hex: {0:#x}; oct: {0:#o}", 42));
11fdf7f2
TL
1587
1588 EXPECT_EQ("The answer is 42", format("The answer is {}", 42));
9f95a23c
TL
1589 EXPECT_THROW_MSG(format("The answer is {:d}", "forty-two"), format_error,
1590 "invalid type specifier");
11fdf7f2 1591
9f95a23c 1592 EXPECT_EQ(L"Cyrillic letter \x42e", format(L"Cyrillic letter {}", L'\x42e'));
11fdf7f2 1593
9f95a23c
TL
1594 EXPECT_WRITE(
1595 stdout, fmt::print("{}", std::numeric_limits<double>::infinity()), "inf");
11fdf7f2
TL
1596}
1597
1598TEST(FormatIntTest, Data) {
1599 fmt::format_int format_int(42);
1600 EXPECT_EQ("42", std::string(format_int.data(), format_int.size()));
1601}
1602
1603TEST(FormatIntTest, FormatInt) {
1604 EXPECT_EQ("42", fmt::format_int(42).str());
1605 EXPECT_EQ(2u, fmt::format_int(42).size());
1606 EXPECT_EQ("-42", fmt::format_int(-42).str());
1607 EXPECT_EQ(3u, fmt::format_int(-42).size());
1608 EXPECT_EQ("42", fmt::format_int(42ul).str());
1609 EXPECT_EQ("-42", fmt::format_int(-42l).str());
1610 EXPECT_EQ("42", fmt::format_int(42ull).str());
1611 EXPECT_EQ("-42", fmt::format_int(-42ll).str());
1612 std::ostringstream os;
f67539c2
TL
1613 os << max_value<int64_t>();
1614 EXPECT_EQ(os.str(), fmt::format_int(max_value<int64_t>()).str());
11fdf7f2
TL
1615}
1616
1617TEST(FormatTest, Print) {
f67539c2 1618#if FMT_USE_FCNTL
11fdf7f2 1619 EXPECT_WRITE(stdout, fmt::print("Don't {}!", "panic"), "Don't panic!");
9f95a23c
TL
1620 EXPECT_WRITE(stderr, fmt::print(stderr, "Don't {}!", "panic"),
1621 "Don't panic!");
11fdf7f2 1622#endif
f67539c2
TL
1623 // Check that the wide print overload compiles.
1624 if (fmt::detail::const_check(false)) fmt::print(L"test");
11fdf7f2
TL
1625}
1626
1627TEST(FormatTest, Variadic) {
1628 EXPECT_EQ("abc1", format("{}c{}", "ab", 1));
1629 EXPECT_EQ(L"abc1", format(L"{}c{}", L"ab", 1));
1630}
1631
1632TEST(FormatTest, Dynamic) {
eafe8130 1633 typedef fmt::format_context ctx;
11fdf7f2 1634 std::vector<fmt::basic_format_arg<ctx>> args;
f67539c2
TL
1635 args.emplace_back(fmt::detail::make_arg<ctx>(42));
1636 args.emplace_back(fmt::detail::make_arg<ctx>("abc1"));
1637 args.emplace_back(fmt::detail::make_arg<ctx>(1.5f));
11fdf7f2 1638
9f95a23c 1639 std::string result = fmt::vformat(
f67539c2
TL
1640 "{} and {} and {}",
1641 fmt::basic_format_args<ctx>(args.data(), static_cast<int>(args.size())));
11fdf7f2 1642
9f95a23c 1643 EXPECT_EQ("42 and abc1 and 1.5", result);
11fdf7f2
TL
1644}
1645
f67539c2
TL
1646TEST(FormatTest, Bytes) {
1647 auto s = fmt::format("{:10}", fmt::bytes("ёжик"));
1648 EXPECT_EQ("ёжик ", s);
1649 EXPECT_EQ(10, s.size());
1650}
1651
11fdf7f2
TL
1652TEST(FormatTest, JoinArg) {
1653 using fmt::join;
9f95a23c 1654 int v1[3] = {1, 2, 3};
11fdf7f2
TL
1655 std::vector<float> v2;
1656 v2.push_back(1.2f);
1657 v2.push_back(3.4f);
9f95a23c 1658 void* v3[2] = {&v1[0], &v1[1]};
11fdf7f2
TL
1659
1660 EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, v1 + 3, ", ")));
1661 EXPECT_EQ("(1)", format("({})", join(v1, v1 + 1, ", ")));
1662 EXPECT_EQ("()", format("({})", join(v1, v1, ", ")));
1663 EXPECT_EQ("(001, 002, 003)", format("({:03})", join(v1, v1 + 3, ", ")));
1664 EXPECT_EQ("(+01.20, +03.40)",
1665 format("({:+06.2f})", join(v2.begin(), v2.end(), ", ")));
1666
1667 EXPECT_EQ(L"(1, 2, 3)", format(L"({})", join(v1, v1 + 3, L", ")));
1668 EXPECT_EQ("1, 2, 3", format("{0:{1}}", join(v1, v1 + 3, ", "), 1));
1669
1670 EXPECT_EQ(format("{}, {}", v3[0], v3[1]),
1671 format("{}", join(v3, v3 + 2, ", ")));
1672
f67539c2 1673#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 405
11fdf7f2
TL
1674 EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, ", ")));
1675 EXPECT_EQ("(+01.20, +03.40)", format("({:+06.2f})", join(v2, ", ")));
1676#endif
1677}
1678
9f95a23c 1679template <typename T> std::string str(const T& value) {
11fdf7f2
TL
1680 return fmt::format("{}", value);
1681}
1682
1683TEST(StrTest, Convert) {
1684 EXPECT_EQ("42", str(42));
1685 std::string s = str(Date(2012, 12, 9));
1686 EXPECT_EQ("2012-12-9", s);
1687}
1688
9f95a23c 1689std::string vformat_message(int id, const char* format, fmt::format_args args) {
11fdf7f2
TL
1690 fmt::memory_buffer buffer;
1691 format_to(buffer, "[{}] ", id);
1692 vformat_to(buffer, format, args);
1693 return to_string(buffer);
1694}
1695
1696template <typename... Args>
9f95a23c 1697std::string format_message(int id, const char* format, const Args&... args) {
11fdf7f2
TL
1698 auto va = fmt::make_format_args(args...);
1699 return vformat_message(id, format, va);
1700}
1701
1702TEST(FormatTest, FormatMessageExample) {
1703 EXPECT_EQ("[42] something happened",
9f95a23c 1704 format_message(42, "{} happened", "something"));
11fdf7f2
TL
1705}
1706
9f95a23c
TL
1707template <typename... Args>
1708void print_error(const char* file, int line, const char* format,
1709 const Args&... args) {
11fdf7f2
TL
1710 fmt::print("{}: {}: ", file, line);
1711 fmt::print(format, args...);
1712}
1713
1714TEST(FormatTest, UnpackedArgs) {
1715 EXPECT_EQ("0123456789abcdefg",
9f95a23c
TL
1716 fmt::format("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 0, 1, 2, 3, 4, 5,
1717 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g'));
11fdf7f2
TL
1718}
1719
f67539c2
TL
1720struct string_like {};
1721fmt::string_view to_string_view(string_like) { return "foo"; }
1722
1723constexpr char with_null[3] = {'{', '}', '\0'};
1724constexpr char no_null[2] = {'{', '}'};
1725
1726TEST(FormatTest, CompileTimeString) {
1727 EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), 42));
1728 EXPECT_EQ(L"42", fmt::format(FMT_STRING(L"{}"), 42));
1729 EXPECT_EQ("foo", fmt::format(FMT_STRING("{}"), string_like()));
1730 (void)with_null;
1731 (void)no_null;
1732#if __cplusplus >= 201703L
1733 EXPECT_EQ("42", fmt::format(FMT_STRING(with_null), 42));
1734 EXPECT_EQ("42", fmt::format(FMT_STRING(no_null), 42));
1735#endif
1736#if defined(FMT_USE_STRING_VIEW) && __cplusplus >= 201703L
1737 EXPECT_EQ("42", fmt::format(FMT_STRING(std::string_view("{}")), 42));
1738 EXPECT_EQ(L"42", fmt::format(FMT_STRING(std::wstring_view(L"{}")), 42));
1739#endif
1740}
1741
1742TEST(FormatTest, CustomFormatCompileTimeString) {
1743 EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), Answer()));
1744 Answer answer;
1745 EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), answer));
1746 char buf[10] = {};
1747 fmt::format_to(buf, FMT_STRING("{}"), answer);
1748 const Answer const_answer = Answer();
1749 EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), const_answer));
1750}
1751
11fdf7f2
TL
1752#if FMT_USE_USER_DEFINED_LITERALS
1753// Passing user-defined literals directly to EXPECT_EQ causes problems
1754// with macro argument stringification (#) on some versions of GCC.
1755// Workaround: Assing the UDL result to a variable before the macro.
1756
1757using namespace fmt::literals;
1758
1759TEST(LiteralsTest, Format) {
1760 auto udl_format = "{}c{}"_format("ab", 1);
1761 EXPECT_EQ(format("{}c{}", "ab", 1), udl_format);
1762 auto udl_format_w = L"{}c{}"_format(L"ab", 1);
1763 EXPECT_EQ(format(L"{}c{}", L"ab", 1), udl_format_w);
1764}
1765
1766TEST(LiteralsTest, NamedArg) {
9f95a23c
TL
1767 auto udl_a = format("{first}{second}{first}{third}", "first"_a = "abra",
1768 "second"_a = "cad", "third"_a = 99);
1769 EXPECT_EQ(format("{first}{second}{first}{third}", fmt::arg("first", "abra"),
1770 fmt::arg("second", "cad"), fmt::arg("third", 99)),
11fdf7f2 1771 udl_a);
9f95a23c
TL
1772 auto udl_a_w = format(L"{first}{second}{first}{third}", L"first"_a = L"abra",
1773 L"second"_a = L"cad", L"third"_a = 99);
1774 EXPECT_EQ(
1775 format(L"{first}{second}{first}{third}", fmt::arg(L"first", L"abra"),
1776 fmt::arg(L"second", L"cad"), fmt::arg(L"third", 99)),
1777 udl_a_w);
11fdf7f2
TL
1778}
1779
1780TEST(FormatTest, UdlTemplate) {
1781 EXPECT_EQ("foo", "foo"_format());
1782 EXPECT_EQ(" 42", "{0:10}"_format(42));
f67539c2
TL
1783}
1784
1785TEST(FormatTest, UdlPassUserDefinedObjectAsLvalue) {
1786 Date date(2015, 10, 21);
1787 EXPECT_EQ("2015-10-21", "{}"_format(date));
11fdf7f2 1788}
9f95a23c 1789#endif // FMT_USE_USER_DEFINED_LITERALS
11fdf7f2
TL
1790
1791enum TestEnum { A };
1792
9f95a23c 1793TEST(FormatTest, Enum) { EXPECT_EQ("0", fmt::format("{}", A)); }
11fdf7f2 1794
f67539c2
TL
1795TEST(FormatTest, FormatterNotSpecialized) {
1796 static_assert(
1797 !fmt::has_formatter<fmt::formatter<TestEnum>, fmt::format_context>::value,
1798 "");
11fdf7f2
TL
1799}
1800
1801#if FMT_HAS_FEATURE(cxx_strong_enums)
f67539c2 1802enum big_enum : unsigned long long { big_enum_value = 5000000000ULL };
11fdf7f2 1803
f67539c2
TL
1804TEST(FormatTest, StrongEnum) {
1805 EXPECT_EQ("5000000000", fmt::format("{}", big_enum_value));
1806}
11fdf7f2
TL
1807#endif
1808
f67539c2 1809using buffer_range = fmt::buffer_range<char>;
11fdf7f2 1810
9f95a23c 1811class mock_arg_formatter
f67539c2 1812 : public fmt::detail::arg_formatter_base<buffer_range> {
11fdf7f2 1813 private:
f67539c2
TL
1814#if FMT_USE_INT128
1815 MOCK_METHOD1(call, void(__int128_t value));
1816#else
9f95a23c 1817 MOCK_METHOD1(call, void(long long value));
f67539c2 1818#endif
11fdf7f2
TL
1819
1820 public:
f67539c2 1821 typedef fmt::detail::arg_formatter_base<buffer_range> base;
11fdf7f2
TL
1822 typedef buffer_range range;
1823
9f95a23c 1824 mock_arg_formatter(fmt::format_context& ctx, fmt::format_parse_context*,
f67539c2
TL
1825 fmt::format_specs* s = nullptr)
1826 : base(fmt::detail::get_container(ctx.out()), s, ctx.locale()) {
11fdf7f2
TL
1827 EXPECT_CALL(*this, call(42));
1828 }
1829
1830 template <typename T>
f67539c2 1831 typename std::enable_if<fmt::detail::is_integral<T>::value, iterator>::type
9f95a23c 1832 operator()(T value) {
11fdf7f2
TL
1833 call(value);
1834 return base::operator()(value);
1835 }
1836
1837 template <typename T>
f67539c2 1838 typename std::enable_if<!fmt::detail::is_integral<T>::value, iterator>::type
9f95a23c 1839 operator()(T value) {
11fdf7f2
TL
1840 return base::operator()(value);
1841 }
1842
1843 iterator operator()(fmt::basic_format_arg<fmt::format_context>::handle) {
1844 return base::operator()(fmt::monostate());
1845 }
1846};
1847
1848static void custom_vformat(fmt::string_view format_str, fmt::format_args args) {
1849 fmt::memory_buffer buffer;
1850 fmt::vformat_to<mock_arg_formatter>(buffer, format_str, args);
1851}
1852
1853template <typename... Args>
9f95a23c 1854void custom_format(const char* format_str, const Args&... args) {
11fdf7f2
TL
1855 auto va = fmt::make_format_args(args...);
1856 return custom_vformat(format_str, va);
1857}
1858
9f95a23c 1859TEST(FormatTest, CustomArgFormatter) { custom_format("{}", 42); }
11fdf7f2
TL
1860
1861TEST(FormatTest, NonNullTerminatedFormatString) {
1862 EXPECT_EQ("42", format(string_view("{}foo", 2), 42));
1863}
1864
1865struct variant {
9f95a23c 1866 enum { INT, STRING } type;
11fdf7f2 1867 explicit variant(int) : type(INT) {}
9f95a23c 1868 explicit variant(const char*) : type(STRING) {}
11fdf7f2
TL
1869};
1870
1871FMT_BEGIN_NAMESPACE
9f95a23c 1872template <> struct formatter<variant> : dynamic_formatter<> {
11fdf7f2 1873 auto format(variant value, format_context& ctx) -> decltype(ctx.out()) {
9f95a23c 1874 if (value.type == variant::INT) return dynamic_formatter<>::format(42, ctx);
11fdf7f2
TL
1875 return dynamic_formatter<>::format("foo", ctx);
1876 }
1877};
1878FMT_END_NAMESPACE
1879
1880TEST(FormatTest, DynamicFormatter) {
1881 auto num = variant(42);
1882 auto str = variant("foo");
1883 EXPECT_EQ("42", format("{:d}", num));
1884 EXPECT_EQ("foo", format("{:s}", str));
1885 EXPECT_EQ(" 42 foo ", format("{:{}} {:{}}", num, 3, str, 4));
9f95a23c
TL
1886 EXPECT_THROW_MSG(format("{0:{}}", num), format_error,
1887 "cannot switch from manual to automatic argument indexing");
1888 EXPECT_THROW_MSG(format("{:{0}}", num), format_error,
1889 "cannot switch from automatic to manual argument indexing");
f67539c2 1890#if FMT_NUMERIC_ALIGN
9f95a23c
TL
1891 EXPECT_THROW_MSG(format("{:=}", str), format_error,
1892 "format specifier requires numeric argument");
f67539c2 1893#endif
9f95a23c
TL
1894 EXPECT_THROW_MSG(format("{:+}", str), format_error,
1895 "format specifier requires numeric argument");
1896 EXPECT_THROW_MSG(format("{:-}", str), format_error,
1897 "format specifier requires numeric argument");
1898 EXPECT_THROW_MSG(format("{: }", str), format_error,
1899 "format specifier requires numeric argument");
1900 EXPECT_THROW_MSG(format("{:#}", str), format_error,
1901 "format specifier requires numeric argument");
1902 EXPECT_THROW_MSG(format("{:0}", str), format_error,
1903 "format specifier requires numeric argument");
1904 EXPECT_THROW_MSG(format("{:.2}", num), format_error,
1905 "precision not allowed for this argument type");
11fdf7f2
TL
1906}
1907
1908TEST(FormatTest, ToString) {
1909 EXPECT_EQ("42", fmt::to_string(42));
1910 EXPECT_EQ("0x1234", fmt::to_string(reinterpret_cast<void*>(0x1234)));
1911}
1912
9f95a23c 1913TEST(FormatTest, ToWString) { EXPECT_EQ(L"42", fmt::to_wstring(42)); }
11fdf7f2
TL
1914
1915TEST(FormatTest, OutputIterators) {
1916 std::list<char> out;
1917 fmt::format_to(std::back_inserter(out), "{}", 42);
1918 EXPECT_EQ("42", std::string(out.begin(), out.end()));
1919 std::stringstream s;
1920 fmt::format_to(std::ostream_iterator<char>(s), "{}", 42);
1921 EXPECT_EQ("42", s.str());
1922}
1923
1924TEST(FormatTest, FormattedSize) {
1925 EXPECT_EQ(2u, fmt::formatted_size("{}", 42));
1926}
1927
1928TEST(FormatTest, FormatToN) {
1929 char buffer[4];
1930 buffer[3] = 'x';
1931 auto result = fmt::format_to_n(buffer, 3, "{}", 12345);
1932 EXPECT_EQ(5u, result.size);
1933 EXPECT_EQ(buffer + 3, result.out);
1934 EXPECT_EQ("123x", fmt::string_view(buffer, 4));
1935 result = fmt::format_to_n(buffer, 3, "{:s}", "foobar");
1936 EXPECT_EQ(6u, result.size);
1937 EXPECT_EQ(buffer + 3, result.out);
1938 EXPECT_EQ("foox", fmt::string_view(buffer, 4));
9f95a23c
TL
1939 buffer[0] = 'x';
1940 buffer[1] = 'x';
1941 buffer[2] = 'x';
1942 result = fmt::format_to_n(buffer, 3, "{}", 'A');
1943 EXPECT_EQ(1u, result.size);
1944 EXPECT_EQ(buffer + 1, result.out);
1945 EXPECT_EQ("Axxx", fmt::string_view(buffer, 4));
1946 result = fmt::format_to_n(buffer, 3, "{}{} ", 'B', 'C');
1947 EXPECT_EQ(3u, result.size);
1948 EXPECT_EQ(buffer + 3, result.out);
1949 EXPECT_EQ("BC x", fmt::string_view(buffer, 4));
11fdf7f2
TL
1950}
1951
1952TEST(FormatTest, WideFormatToN) {
1953 wchar_t buffer[4];
1954 buffer[3] = L'x';
1955 auto result = fmt::format_to_n(buffer, 3, L"{}", 12345);
1956 EXPECT_EQ(5u, result.size);
1957 EXPECT_EQ(buffer + 3, result.out);
1958 EXPECT_EQ(L"123x", fmt::wstring_view(buffer, 4));
9f95a23c
TL
1959 buffer[0] = L'x';
1960 buffer[1] = L'x';
1961 buffer[2] = L'x';
1962 result = fmt::format_to_n(buffer, 3, L"{}", L'A');
1963 EXPECT_EQ(1u, result.size);
1964 EXPECT_EQ(buffer + 1, result.out);
1965 EXPECT_EQ(L"Axxx", fmt::wstring_view(buffer, 4));
1966 result = fmt::format_to_n(buffer, 3, L"{}{} ", L'B', L'C');
1967 EXPECT_EQ(3u, result.size);
1968 EXPECT_EQ(buffer + 3, result.out);
1969 EXPECT_EQ(L"BC x", fmt::wstring_view(buffer, 4));
11fdf7f2
TL
1970}
1971
f67539c2
TL
1972struct test_output_iterator {
1973 char* data;
1974
1975 using iterator_category = std::output_iterator_tag;
1976 using value_type = void;
1977 using difference_type = void;
1978 using pointer = void;
1979 using reference = void;
1980
1981 test_output_iterator& operator++() {
1982 ++data;
1983 return *this;
1984 }
1985 test_output_iterator operator++(int) {
1986 auto tmp = *this;
1987 ++data;
1988 return tmp;
1989 }
1990 char& operator*() { return *data; }
1991};
1992
1993TEST(FormatTest, FormatToNOutputIterator) {
1994 char buf[10] = {};
1995 fmt::format_to_n(test_output_iterator{buf}, 10, "{}", 42);
1996 EXPECT_STREQ(buf, "42");
1997}
1998
11fdf7f2
TL
1999#if FMT_USE_CONSTEXPR
2000struct test_arg_id_handler {
2001 enum result { NONE, EMPTY, INDEX, NAME, ERROR };
2002 result res = NONE;
f67539c2 2003 int index = 0;
11fdf7f2
TL
2004 string_view name;
2005
2006 FMT_CONSTEXPR void operator()() { res = EMPTY; }
2007
f67539c2 2008 FMT_CONSTEXPR void operator()(int i) {
11fdf7f2
TL
2009 res = INDEX;
2010 index = i;
2011 }
2012
2013 FMT_CONSTEXPR void operator()(string_view n) {
2014 res = NAME;
2015 name = n;
2016 }
2017
9f95a23c 2018 FMT_CONSTEXPR void on_error(const char*) { res = ERROR; }
11fdf7f2
TL
2019};
2020
9f95a23c
TL
2021template <size_t N>
2022FMT_CONSTEXPR test_arg_id_handler parse_arg_id(const char (&s)[N]) {
11fdf7f2 2023 test_arg_id_handler h;
f67539c2 2024 fmt::detail::parse_arg_id(s, s + N, h);
11fdf7f2
TL
2025 return h;
2026}
2027
2028TEST(FormatTest, ConstexprParseArgID) {
2029 static_assert(parse_arg_id(":").res == test_arg_id_handler::EMPTY, "");
2030 static_assert(parse_arg_id("}").res == test_arg_id_handler::EMPTY, "");
2031 static_assert(parse_arg_id("42:").res == test_arg_id_handler::INDEX, "");
2032 static_assert(parse_arg_id("42:").index == 42, "");
2033 static_assert(parse_arg_id("foo:").res == test_arg_id_handler::NAME, "");
2034 static_assert(parse_arg_id("foo:").name.size() == 3, "");
2035 static_assert(parse_arg_id("!").res == test_arg_id_handler::ERROR, "");
2036}
2037
2038struct test_format_specs_handler {
2039 enum Result { NONE, PLUS, MINUS, SPACE, HASH, ZERO, ERROR };
2040 Result res = NONE;
2041
f67539c2 2042 fmt::align_t align = fmt::align::none;
11fdf7f2 2043 char fill = 0;
f67539c2
TL
2044 int width = 0;
2045 fmt::detail::arg_ref<char> width_ref;
2046 int precision = 0;
2047 fmt::detail::arg_ref<char> precision_ref;
11fdf7f2
TL
2048 char type = 0;
2049
2050 // Workaround for MSVC2017 bug that results in "expression did not evaluate
2051 // to a constant" with compiler-generated copy ctor.
2052 FMT_CONSTEXPR test_format_specs_handler() {}
9f95a23c
TL
2053 FMT_CONSTEXPR test_format_specs_handler(
2054 const test_format_specs_handler& other)
2055 : res(other.res),
f67539c2 2056 align(other.align),
9f95a23c
TL
2057 fill(other.fill),
2058 width(other.width),
2059 width_ref(other.width_ref),
2060 precision(other.precision),
2061 precision_ref(other.precision_ref),
2062 type(other.type) {}
11fdf7f2 2063
f67539c2
TL
2064 FMT_CONSTEXPR void on_align(fmt::align_t a) { align = a; }
2065 FMT_CONSTEXPR void on_fill(fmt::string_view f) { fill = f[0]; }
11fdf7f2
TL
2066 FMT_CONSTEXPR void on_plus() { res = PLUS; }
2067 FMT_CONSTEXPR void on_minus() { res = MINUS; }
2068 FMT_CONSTEXPR void on_space() { res = SPACE; }
2069 FMT_CONSTEXPR void on_hash() { res = HASH; }
2070 FMT_CONSTEXPR void on_zero() { res = ZERO; }
2071
f67539c2
TL
2072 FMT_CONSTEXPR void on_width(int w) { width = w; }
2073 FMT_CONSTEXPR void on_dynamic_width(fmt::detail::auto_id) {}
2074 FMT_CONSTEXPR void on_dynamic_width(int index) { width_ref = index; }
11fdf7f2
TL
2075 FMT_CONSTEXPR void on_dynamic_width(string_view) {}
2076
f67539c2
TL
2077 FMT_CONSTEXPR void on_precision(int p) { precision = p; }
2078 FMT_CONSTEXPR void on_dynamic_precision(fmt::detail::auto_id) {}
2079 FMT_CONSTEXPR void on_dynamic_precision(int index) { precision_ref = index; }
11fdf7f2
TL
2080 FMT_CONSTEXPR void on_dynamic_precision(string_view) {}
2081
2082 FMT_CONSTEXPR void end_precision() {}
2083 FMT_CONSTEXPR void on_type(char t) { type = t; }
9f95a23c 2084 FMT_CONSTEXPR void on_error(const char*) { res = ERROR; }
11fdf7f2
TL
2085};
2086
9f95a23c
TL
2087template <size_t N>
2088FMT_CONSTEXPR test_format_specs_handler parse_test_specs(const char (&s)[N]) {
11fdf7f2 2089 test_format_specs_handler h;
f67539c2 2090 fmt::detail::parse_format_specs(s, s + N, h);
11fdf7f2
TL
2091 return h;
2092}
2093
2094TEST(FormatTest, ConstexprParseFormatSpecs) {
2095 typedef test_format_specs_handler handler;
f67539c2 2096 static_assert(parse_test_specs("<").align == fmt::align::left, "");
11fdf7f2
TL
2097 static_assert(parse_test_specs("*^").fill == '*', "");
2098 static_assert(parse_test_specs("+").res == handler::PLUS, "");
2099 static_assert(parse_test_specs("-").res == handler::MINUS, "");
2100 static_assert(parse_test_specs(" ").res == handler::SPACE, "");
2101 static_assert(parse_test_specs("#").res == handler::HASH, "");
2102 static_assert(parse_test_specs("0").res == handler::ZERO, "");
2103 static_assert(parse_test_specs("42").width == 42, "");
9f95a23c 2104 static_assert(parse_test_specs("{42}").width_ref.val.index == 42, "");
11fdf7f2 2105 static_assert(parse_test_specs(".42").precision == 42, "");
9f95a23c 2106 static_assert(parse_test_specs(".{42}").precision_ref.val.index == 42, "");
11fdf7f2
TL
2107 static_assert(parse_test_specs("d").type == 'd', "");
2108 static_assert(parse_test_specs("{<").res == handler::ERROR, "");
2109}
2110
9f95a23c
TL
2111struct test_parse_context {
2112 typedef char char_type;
2113
f67539c2 2114 FMT_CONSTEXPR int next_arg_id() { return 11; }
9f95a23c
TL
2115 template <typename Id> FMT_CONSTEXPR void check_arg_id(Id) {}
2116
f67539c2
TL
2117 FMT_CONSTEXPR const char* begin() { return nullptr; }
2118 FMT_CONSTEXPR const char* end() { return nullptr; }
9f95a23c
TL
2119
2120 void on_error(const char*) {}
2121};
2122
11fdf7f2 2123struct test_context {
f67539c2
TL
2124 using char_type = char;
2125 using format_arg = fmt::basic_format_arg<test_context>;
2126 using parse_context_type = fmt::format_parse_context;
11fdf7f2 2127
9f95a23c
TL
2128 template <typename T> struct formatter_type {
2129 typedef fmt::formatter<T, char_type> type;
2130 };
11fdf7f2
TL
2131
2132 template <typename Id>
9f95a23c 2133 FMT_CONSTEXPR fmt::basic_format_arg<test_context> arg(Id id) {
f67539c2 2134 return fmt::detail::make_arg<test_context>(id);
11fdf7f2
TL
2135 }
2136
9f95a23c 2137 void on_error(const char*) {}
11fdf7f2 2138
11fdf7f2
TL
2139 FMT_CONSTEXPR test_context error_handler() { return *this; }
2140};
2141
9f95a23c
TL
2142template <size_t N>
2143FMT_CONSTEXPR fmt::format_specs parse_specs(const char (&s)[N]) {
f67539c2
TL
2144 auto specs = fmt::format_specs();
2145 auto parse_ctx = test_parse_context();
2146 auto ctx = test_context();
2147 fmt::detail::specs_handler<test_parse_context, test_context> h(
9f95a23c
TL
2148 specs, parse_ctx, ctx);
2149 parse_format_specs(s, s + N, h);
11fdf7f2
TL
2150 return specs;
2151}
2152
2153TEST(FormatTest, ConstexprSpecsHandler) {
f67539c2
TL
2154 static_assert(parse_specs("<").align == fmt::align::left, "");
2155 static_assert(parse_specs("*^").fill[0] == '*', "");
2156 static_assert(parse_specs("+").sign == fmt::sign::plus, "");
2157 static_assert(parse_specs("-").sign == fmt::sign::minus, "");
2158 static_assert(parse_specs(" ").sign == fmt::sign::space, "");
2159 static_assert(parse_specs("#").alt, "");
2160 static_assert(parse_specs("0").align == fmt::align::numeric, "");
2161 static_assert(parse_specs("42").width == 42, "");
2162 static_assert(parse_specs("{}").width == 11, "");
2163 static_assert(parse_specs("{22}").width == 22, "");
eafe8130
TL
2164 static_assert(parse_specs(".42").precision == 42, "");
2165 static_assert(parse_specs(".{}").precision == 11, "");
9f95a23c 2166 static_assert(parse_specs(".{22}").precision == 22, "");
eafe8130 2167 static_assert(parse_specs("d").type == 'd', "");
11fdf7f2
TL
2168}
2169
9f95a23c 2170template <size_t N>
f67539c2 2171FMT_CONSTEXPR fmt::detail::dynamic_format_specs<char> parse_dynamic_specs(
9f95a23c 2172 const char (&s)[N]) {
f67539c2 2173 fmt::detail::dynamic_format_specs<char> specs;
9f95a23c 2174 test_parse_context ctx{};
f67539c2 2175 fmt::detail::dynamic_specs_handler<test_parse_context> h(specs, ctx);
9f95a23c 2176 parse_format_specs(s, s + N, h);
11fdf7f2
TL
2177 return specs;
2178}
2179
2180TEST(FormatTest, ConstexprDynamicSpecsHandler) {
f67539c2
TL
2181 static_assert(parse_dynamic_specs("<").align == fmt::align::left, "");
2182 static_assert(parse_dynamic_specs("*^").fill[0] == '*', "");
2183 static_assert(parse_dynamic_specs("+").sign == fmt::sign::plus, "");
2184 static_assert(parse_dynamic_specs("-").sign == fmt::sign::minus, "");
2185 static_assert(parse_dynamic_specs(" ").sign == fmt::sign::space, "");
2186 static_assert(parse_dynamic_specs("#").alt, "");
2187 static_assert(parse_dynamic_specs("0").align == fmt::align::numeric, "");
2188 static_assert(parse_dynamic_specs("42").width == 42, "");
9f95a23c
TL
2189 static_assert(parse_dynamic_specs("{}").width_ref.val.index == 11, "");
2190 static_assert(parse_dynamic_specs("{42}").width_ref.val.index == 42, "");
eafe8130 2191 static_assert(parse_dynamic_specs(".42").precision == 42, "");
9f95a23c
TL
2192 static_assert(parse_dynamic_specs(".{}").precision_ref.val.index == 11, "");
2193 static_assert(parse_dynamic_specs(".{42}").precision_ref.val.index == 42, "");
eafe8130 2194 static_assert(parse_dynamic_specs("d").type == 'd', "");
11fdf7f2
TL
2195}
2196
9f95a23c
TL
2197template <size_t N>
2198FMT_CONSTEXPR test_format_specs_handler check_specs(const char (&s)[N]) {
f67539c2
TL
2199 fmt::detail::specs_checker<test_format_specs_handler> checker(
2200 test_format_specs_handler(), fmt::detail::type::double_type);
9f95a23c 2201 parse_format_specs(s, s + N, checker);
11fdf7f2
TL
2202 return checker;
2203}
2204
2205TEST(FormatTest, ConstexprSpecsChecker) {
2206 typedef test_format_specs_handler handler;
f67539c2 2207 static_assert(check_specs("<").align == fmt::align::left, "");
11fdf7f2
TL
2208 static_assert(check_specs("*^").fill == '*', "");
2209 static_assert(check_specs("+").res == handler::PLUS, "");
2210 static_assert(check_specs("-").res == handler::MINUS, "");
2211 static_assert(check_specs(" ").res == handler::SPACE, "");
2212 static_assert(check_specs("#").res == handler::HASH, "");
2213 static_assert(check_specs("0").res == handler::ZERO, "");
2214 static_assert(check_specs("42").width == 42, "");
9f95a23c 2215 static_assert(check_specs("{42}").width_ref.val.index == 42, "");
11fdf7f2 2216 static_assert(check_specs(".42").precision == 42, "");
9f95a23c 2217 static_assert(check_specs(".{42}").precision_ref.val.index == 42, "");
11fdf7f2
TL
2218 static_assert(check_specs("d").type == 'd', "");
2219 static_assert(check_specs("{<").res == handler::ERROR, "");
2220}
2221
2222struct test_format_string_handler {
9f95a23c 2223 FMT_CONSTEXPR void on_text(const char*, const char*) {}
11fdf7f2
TL
2224
2225 FMT_CONSTEXPR void on_arg_id() {}
2226
9f95a23c 2227 template <typename T> FMT_CONSTEXPR void on_arg_id(T) {}
11fdf7f2 2228
9f95a23c 2229 FMT_CONSTEXPR void on_replacement_field(const char*) {}
11fdf7f2 2230
9f95a23c
TL
2231 FMT_CONSTEXPR const char* on_format_specs(const char* begin, const char*) {
2232 return begin;
2233 }
11fdf7f2 2234
9f95a23c 2235 FMT_CONSTEXPR void on_error(const char*) { error = true; }
11fdf7f2
TL
2236
2237 bool error = false;
2238};
2239
9f95a23c 2240template <size_t N> FMT_CONSTEXPR bool parse_string(const char (&s)[N]) {
11fdf7f2 2241 test_format_string_handler h;
f67539c2 2242 fmt::detail::parse_format_string<true>(fmt::string_view(s, N - 1), h);
11fdf7f2
TL
2243 return !h.error;
2244}
2245
2246TEST(FormatTest, ConstexprParseFormatString) {
2247 static_assert(parse_string("foo"), "");
2248 static_assert(!parse_string("}"), "");
2249 static_assert(parse_string("{}"), "");
2250 static_assert(parse_string("{42}"), "");
2251 static_assert(parse_string("{foo}"), "");
2252 static_assert(parse_string("{:}"), "");
2253}
2254
2255struct test_error_handler {
9f95a23c 2256 const char*& error;
11fdf7f2 2257
9f95a23c 2258 FMT_CONSTEXPR test_error_handler(const char*& err) : error(err) {}
11fdf7f2 2259
9f95a23c
TL
2260 FMT_CONSTEXPR test_error_handler(const test_error_handler& other)
2261 : error(other.error) {}
11fdf7f2 2262
9f95a23c
TL
2263 FMT_CONSTEXPR void on_error(const char* message) {
2264 if (!error) error = message;
11fdf7f2
TL
2265 }
2266};
2267
9f95a23c 2268FMT_CONSTEXPR size_t len(const char* s) {
11fdf7f2 2269 size_t len = 0;
9f95a23c 2270 while (*s++) ++len;
11fdf7f2
TL
2271 return len;
2272}
2273
9f95a23c
TL
2274FMT_CONSTEXPR bool equal(const char* s1, const char* s2) {
2275 if (!s1 || !s2) return s1 == s2;
11fdf7f2
TL
2276 while (*s1 && *s1 == *s2) {
2277 ++s1;
2278 ++s2;
2279 }
2280 return *s1 == *s2;
2281}
2282
2283template <typename... Args>
9f95a23c 2284FMT_CONSTEXPR bool test_error(const char* fmt, const char* expected_error) {
f67539c2
TL
2285 const char* actual_error = nullptr;
2286 string_view s(fmt, len(fmt));
2287 fmt::detail::format_string_checker<char, test_error_handler, Args...> checker(
2288 s, test_error_handler(actual_error));
2289 fmt::detail::parse_format_string<true>(s, checker);
11fdf7f2
TL
2290 return equal(actual_error, expected_error);
2291}
2292
9f95a23c
TL
2293# define EXPECT_ERROR_NOARGS(fmt, error) \
2294 static_assert(test_error(fmt, error), "")
2295# define EXPECT_ERROR(fmt, error, ...) \
2296 static_assert(test_error<__VA_ARGS__>(fmt, error), "")
11fdf7f2
TL
2297
2298TEST(FormatTest, FormatStringErrors) {
f67539c2 2299 EXPECT_ERROR_NOARGS("foo", nullptr);
11fdf7f2
TL
2300 EXPECT_ERROR_NOARGS("}", "unmatched '}' in format string");
2301 EXPECT_ERROR("{0:s", "unknown format specifier", Date);
f67539c2
TL
2302# if !FMT_MSC_VER || FMT_MSC_VER >= 1916
2303 // This causes an detail compiler error in MSVC2017.
11fdf7f2
TL
2304 EXPECT_ERROR("{:{<}", "invalid fill character '{'", int);
2305 EXPECT_ERROR("{:10000000000}", "number is too big", int);
2306 EXPECT_ERROR("{:.10000000000}", "number is too big", int);
f67539c2
TL
2307 EXPECT_ERROR_NOARGS("{:x}", "argument not found");
2308# if FMT_NUMERIC_ALIGN
2309 EXPECT_ERROR("{0:=5", "unknown format specifier", int);
11fdf7f2 2310 EXPECT_ERROR("{:=}", "format specifier requires numeric argument",
9f95a23c 2311 const char*);
f67539c2 2312# endif
11fdf7f2 2313 EXPECT_ERROR("{:+}", "format specifier requires numeric argument",
9f95a23c 2314 const char*);
11fdf7f2 2315 EXPECT_ERROR("{:-}", "format specifier requires numeric argument",
9f95a23c 2316 const char*);
11fdf7f2 2317 EXPECT_ERROR("{:#}", "format specifier requires numeric argument",
9f95a23c 2318 const char*);
11fdf7f2 2319 EXPECT_ERROR("{: }", "format specifier requires numeric argument",
9f95a23c 2320 const char*);
11fdf7f2 2321 EXPECT_ERROR("{:0}", "format specifier requires numeric argument",
9f95a23c 2322 const char*);
11fdf7f2
TL
2323 EXPECT_ERROR("{:+}", "format specifier requires signed argument", unsigned);
2324 EXPECT_ERROR("{:-}", "format specifier requires signed argument", unsigned);
2325 EXPECT_ERROR("{: }", "format specifier requires signed argument", unsigned);
f67539c2
TL
2326 EXPECT_ERROR("{:{}}", "argument not found", int);
2327 EXPECT_ERROR("{:.{}}", "argument not found", double);
11fdf7f2
TL
2328 EXPECT_ERROR("{:.2}", "precision not allowed for this argument type", int);
2329 EXPECT_ERROR("{:s}", "invalid type specifier", int);
2330 EXPECT_ERROR("{:s}", "invalid type specifier", bool);
2331 EXPECT_ERROR("{:s}", "invalid type specifier", char);
2332 EXPECT_ERROR("{:+}", "invalid format specifier for char", char);
2333 EXPECT_ERROR("{:s}", "invalid type specifier", double);
9f95a23c 2334 EXPECT_ERROR("{:d}", "invalid type specifier", const char*);
11fdf7f2 2335 EXPECT_ERROR("{:d}", "invalid type specifier", std::string);
9f95a23c 2336 EXPECT_ERROR("{:s}", "invalid type specifier", void*);
f67539c2
TL
2337# else
2338 fmt::print("warning: constexpr is broken in this version of MSVC\n");
9f95a23c
TL
2339# endif
2340 EXPECT_ERROR("{foo", "compile-time checks don't support named arguments",
2341 int);
11fdf7f2
TL
2342 EXPECT_ERROR_NOARGS("{10000000000}", "number is too big");
2343 EXPECT_ERROR_NOARGS("{0x}", "invalid format string");
2344 EXPECT_ERROR_NOARGS("{-}", "invalid format string");
2345 EXPECT_ERROR("{:{0x}}", "invalid format string", int);
2346 EXPECT_ERROR("{:{-}}", "invalid format string", int);
2347 EXPECT_ERROR("{:.{0x}}", "invalid format string", int);
2348 EXPECT_ERROR("{:.{-}}", "invalid format string", int);
2349 EXPECT_ERROR("{:.x}", "missing precision specifier", int);
f67539c2
TL
2350 EXPECT_ERROR_NOARGS("{}", "argument not found");
2351 EXPECT_ERROR("{1}", "argument not found", int);
11fdf7f2 2352 EXPECT_ERROR("{1}{}",
9f95a23c
TL
2353 "cannot switch from manual to automatic argument indexing", int,
2354 int);
11fdf7f2 2355 EXPECT_ERROR("{}{1}",
9f95a23c
TL
2356 "cannot switch from automatic to manual argument indexing", int,
2357 int);
11fdf7f2 2358}
eafe8130
TL
2359
2360TEST(FormatTest, VFormatTo) {
2361 typedef fmt::format_context context;
f67539c2 2362 fmt::basic_format_arg<context> arg = fmt::detail::make_arg<context>(42);
eafe8130
TL
2363 fmt::basic_format_args<context> args(&arg, 1);
2364 std::string s;
2365 fmt::vformat_to(std::back_inserter(s), "{}", args);
2366 EXPECT_EQ("42", s);
2367 s.clear();
2368 fmt::vformat_to(std::back_inserter(s), FMT_STRING("{}"), args);
2369 EXPECT_EQ("42", s);
2370
2371 typedef fmt::wformat_context wcontext;
f67539c2 2372 fmt::basic_format_arg<wcontext> warg = fmt::detail::make_arg<wcontext>(42);
eafe8130
TL
2373 fmt::basic_format_args<wcontext> wargs(&warg, 1);
2374 std::wstring w;
2375 fmt::vformat_to(std::back_inserter(w), L"{}", wargs);
2376 EXPECT_EQ(L"42", w);
2377 w.clear();
2378 fmt::vformat_to(std::back_inserter(w), FMT_STRING(L"{}"), wargs);
2379 EXPECT_EQ(L"42", w);
2380}
2381
9f95a23c
TL
2382template <typename T> static std::string FmtToString(const T& t) {
2383 return fmt::format(FMT_STRING("{}"), t);
2384}
2385
2386TEST(FormatTest, FmtStringInTemplate) {
2387 EXPECT_EQ(FmtToString(1), "1");
2388 EXPECT_EQ(FmtToString(0), "0");
2389}
2390
11fdf7f2
TL
2391#endif // FMT_USE_CONSTEXPR
2392
f67539c2
TL
2393TEST(FormatTest, EmphasisNonHeaderOnly) {
2394 // Ensure this compiles even if FMT_HEADER_ONLY is not defined.
2395 EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold error"),
2396 "\x1b[1mbold error\x1b[0m");
11fdf7f2
TL
2397}
2398
f67539c2
TL
2399TEST(FormatTest, CharTraitsIsNotAmbiguous) {
2400 // Test that we don't inject detail names into the std namespace.
2401 using namespace std;
2402 char_traits<char>::char_type c;
2403 (void)c;
2404#if __cplusplus >= 201103L
2405 std::string s;
2406 auto lval = begin(s);
2407 (void)lval;
2408#endif
11fdf7f2
TL
2409}
2410
f67539c2
TL
2411struct mychar {
2412 int value;
2413 mychar() = default;
2414
2415 template <typename T> mychar(T val) : value(static_cast<int>(val)) {}
2416
2417 operator int() const { return value; }
2418};
2419
2420FMT_BEGIN_NAMESPACE
2421template <> struct is_char<mychar> : std::true_type {};
2422FMT_END_NAMESPACE
2423
2424TEST(FormatTest, FormatCustomChar) {
2425 const mychar format[] = {'{', '}', 0};
2426 auto result = fmt::format(format, mychar('x'));
2427 EXPECT_EQ(result.size(), 1);
2428 EXPECT_EQ(result[0], mychar('x'));
11fdf7f2 2429}
eafe8130 2430
f67539c2
TL
2431// Convert a char8_t string to std::string. Otherwise GTest will insist on
2432// inserting `char8_t` NTBS into a `char` stream which is disabled by P1423.
2433template <typename S> std::string from_u8str(const S& str) {
2434 return std::string(str.begin(), str.end());
eafe8130 2435}
9f95a23c 2436
f67539c2
TL
2437TEST(FormatTest, FormatUTF8Precision) {
2438 using str_type = std::basic_string<fmt::detail::char8_type>;
2439 str_type format(reinterpret_cast<const fmt::detail::char8_type*>(u8"{:.4}"));
2440 str_type str(reinterpret_cast<const fmt::detail::char8_type*>(
2441 u8"caf\u00e9s")); // cafés
2442 auto result = fmt::format(format, str);
2443 EXPECT_EQ(fmt::detail::count_code_points(result), 4);
2444 EXPECT_EQ(result.size(), 5);
2445 EXPECT_EQ(from_u8str(result), from_u8str(str.substr(0, 5)));
9f95a23c 2446}