comparison dep/fmt/test/format-test.cc @ 343:1faa72660932

*: transfer back to cmake from autotools autotools just made lots of things more complicated than they should have and many things broke (i.e. translations)
author Paper <paper@paper.us.eu.org>
date Thu, 20 Jun 2024 05:56:06 -0400
parents
children
comparison
equal deleted inserted replaced
342:adb79bdde329 343:1faa72660932
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
8 // Check if fmt/format.h compiles with windows.h included before it.
9 #ifdef _WIN32
10 # include <windows.h>
11 #endif
12 // clang-format off
13 #include "fmt/format.h"
14 // clang-format on
15
16 #include <stdint.h> // uint32_t
17
18 #include <climits> // INT_MAX
19 #include <cmath> // std::signbit
20 #include <cstring> // std::strlen
21 #include <iterator> // std::back_inserter
22 #include <list> // std::list
23 #include <memory> // std::unique_ptr
24 #include <type_traits> // std::is_default_constructible
25
26 #include "gtest-extra.h"
27 #include "mock-allocator.h"
28 #include "util.h"
29
30 using fmt::basic_memory_buffer;
31 using fmt::format_error;
32 using fmt::memory_buffer;
33 using fmt::runtime;
34 using fmt::string_view;
35 using fmt::detail::max_value;
36 using fmt::detail::uint128_fallback;
37
38 using testing::Return;
39 using testing::StrictMock;
40
41 enum { buffer_size = 256 };
42
43 TEST(uint128_test, ctor) {
44 auto n = uint128_fallback();
45 EXPECT_EQ(n, 0);
46 n = uint128_fallback(42);
47 EXPECT_EQ(n, 42);
48 EXPECT_EQ(static_cast<uint64_t>(n), 42);
49 }
50
51 TEST(uint128_test, shift) {
52 auto n = uint128_fallback(42);
53 n = n << 64;
54 EXPECT_EQ(static_cast<uint64_t>(n), 0);
55 n = n >> 64;
56 EXPECT_EQ(static_cast<uint64_t>(n), 42);
57 n = n << 62;
58 EXPECT_EQ(static_cast<uint64_t>(n >> 64), 0xa);
59 EXPECT_EQ(static_cast<uint64_t>(n), 0x8000000000000000);
60 n = n >> 62;
61 EXPECT_EQ(static_cast<uint64_t>(n), 42);
62 EXPECT_EQ(uint128_fallback(1) << 112, uint128_fallback(0x1000000000000, 0));
63 EXPECT_EQ(uint128_fallback(0x1000000000000, 0) >> 112, uint128_fallback(1));
64 }
65
66 TEST(uint128_test, minus) {
67 auto n = uint128_fallback(42);
68 EXPECT_EQ(n - 2, 40);
69 }
70
71 TEST(uint128_test, plus_assign) {
72 auto n = uint128_fallback(32);
73 n += uint128_fallback(10);
74 EXPECT_EQ(n, 42);
75 n = uint128_fallback(max_value<uint64_t>());
76 n += uint128_fallback(1);
77 EXPECT_EQ(n, uint128_fallback(1) << 64);
78 }
79
80 TEST(uint128_test, multiply) {
81 auto n = uint128_fallback(2251799813685247);
82 n = n * 3611864890;
83 EXPECT_EQ(static_cast<uint64_t>(n >> 64), 440901);
84 }
85
86 template <typename Float> void check_isfinite() {
87 using fmt::detail::isfinite;
88 EXPECT_TRUE(isfinite(Float(0.0)));
89 EXPECT_TRUE(isfinite(Float(42.0)));
90 EXPECT_TRUE(isfinite(Float(-42.0)));
91 EXPECT_TRUE(isfinite(Float(fmt::detail::max_value<double>())));
92 // Use double because std::numeric_limits is broken for __float128.
93 using limits = std::numeric_limits<double>;
94 FMT_CONSTEXPR20 auto result = isfinite(Float(limits::infinity()));
95 EXPECT_FALSE(result);
96 EXPECT_FALSE(isfinite(Float(limits::infinity())));
97 EXPECT_FALSE(isfinite(Float(-limits::infinity())));
98 EXPECT_FALSE(isfinite(Float(limits::quiet_NaN())));
99 EXPECT_FALSE(isfinite(Float(-limits::quiet_NaN())));
100 }
101
102 TEST(float_test, isfinite) {
103 check_isfinite<double>();
104 #if FMT_USE_FLOAT128
105 check_isfinite<fmt::detail::float128>();
106 #endif
107 }
108
109 template <typename Float> void check_isnan() {
110 using fmt::detail::isnan;
111 EXPECT_FALSE(isnan(Float(0.0)));
112 EXPECT_FALSE(isnan(Float(42.0)));
113 EXPECT_FALSE(isnan(Float(-42.0)));
114 EXPECT_FALSE(isnan(Float(fmt::detail::max_value<double>())));
115 // Use double because std::numeric_limits is broken for __float128.
116 using limits = std::numeric_limits<double>;
117 EXPECT_FALSE(isnan(Float(limits::infinity())));
118 EXPECT_FALSE(isnan(Float(-limits::infinity())));
119 EXPECT_TRUE(isnan(Float(limits::quiet_NaN())));
120 EXPECT_TRUE(isnan(Float(-limits::quiet_NaN())));
121 }
122
123 TEST(float_test, isnan) {
124 check_isnan<double>();
125 #if FMT_USE_FLOAT128
126 check_isnan<fmt::detail::float128>();
127 #endif
128 }
129
130 struct uint32_pair {
131 uint32_t u[2];
132 };
133
134 TEST(util_test, bit_cast) {
135 auto s = fmt::detail::bit_cast<uint32_pair>(uint64_t{42});
136 EXPECT_EQ(fmt::detail::bit_cast<uint64_t>(s), 42ull);
137 s = fmt::detail::bit_cast<uint32_pair>(~uint64_t{0});
138 EXPECT_EQ(fmt::detail::bit_cast<uint64_t>(s), ~0ull);
139 }
140
141 // Increment a number in a string.
142 void increment(char* s) {
143 for (int i = static_cast<int>(std::strlen(s)) - 1; i >= 0; --i) {
144 if (s[i] != '9') {
145 ++s[i];
146 break;
147 }
148 s[i] = '0';
149 }
150 }
151
152 TEST(util_test, increment) {
153 char s[10] = "123";
154 increment(s);
155 EXPECT_STREQ("124", s);
156 s[2] = '8';
157 increment(s);
158 EXPECT_STREQ("129", s);
159 increment(s);
160 EXPECT_STREQ("130", s);
161 s[1] = s[2] = '9';
162 increment(s);
163 EXPECT_STREQ("200", s);
164 }
165
166 TEST(util_test, parse_nonnegative_int) {
167 auto s = fmt::string_view("10000000000");
168 auto begin = s.begin(), end = s.end();
169 EXPECT_EQ(fmt::detail::parse_nonnegative_int(begin, end, -1), -1);
170 s = "2147483649";
171 begin = s.begin();
172 end = s.end();
173 EXPECT_EQ(fmt::detail::parse_nonnegative_int(begin, end, -1), -1);
174 }
175
176 TEST(format_impl_test, compute_width) {
177 EXPECT_EQ(fmt::detail::compute_width("вожык"), 5);
178 }
179
180 TEST(util_test, utf8_to_utf16) {
181 auto u = fmt::detail::utf8_to_utf16("лошадка");
182 EXPECT_EQ(L"\x043B\x043E\x0448\x0430\x0434\x043A\x0430", u.str());
183 EXPECT_EQ(7, u.size());
184 // U+10437 { DESERET SMALL LETTER YEE }
185 EXPECT_EQ(L"\xD801\xDC37", fmt::detail::utf8_to_utf16("𐐷").str());
186 EXPECT_THROW_MSG(fmt::detail::utf8_to_utf16("\xc3\x28"), std::runtime_error,
187 "invalid utf8");
188 EXPECT_THROW_MSG(fmt::detail::utf8_to_utf16(fmt::string_view("л", 1)),
189 std::runtime_error, "invalid utf8");
190 EXPECT_EQ(L"123456", fmt::detail::utf8_to_utf16("123456").str());
191 }
192
193 TEST(util_test, utf8_to_utf16_empty_string) {
194 auto s = std::string();
195 auto u = fmt::detail::utf8_to_utf16(s.c_str());
196 EXPECT_EQ(L"", u.str());
197 EXPECT_EQ(s.size(), u.size());
198 }
199
200 TEST(util_test, allocator_ref) {
201 using test_allocator_ref = allocator_ref<mock_allocator<int>>;
202 auto check_forwarding = [](mock_allocator<int>& alloc,
203 test_allocator_ref& ref) {
204 int mem;
205 // Check if value_type is properly defined.
206 allocator_ref<mock_allocator<int>>::value_type* ptr = &mem;
207 // Check forwarding.
208 EXPECT_CALL(alloc, allocate(42)).WillOnce(Return(ptr));
209 ref.allocate(42);
210 EXPECT_CALL(alloc, deallocate(ptr, 42));
211 ref.deallocate(ptr, 42);
212 };
213
214 StrictMock<mock_allocator<int>> alloc;
215 auto ref = test_allocator_ref(&alloc);
216 // Check if allocator_ref forwards to the underlying allocator.
217 check_forwarding(alloc, ref);
218 test_allocator_ref ref2(ref);
219 check_forwarding(alloc, ref2);
220 test_allocator_ref ref3;
221 EXPECT_EQ(nullptr, ref3.get());
222 ref3 = ref;
223 check_forwarding(alloc, ref3);
224 }
225
226 TEST(util_test, format_system_error) {
227 fmt::memory_buffer message;
228 fmt::format_system_error(message, EDOM, "test");
229 auto ec = std::error_code(EDOM, std::generic_category());
230 EXPECT_EQ(to_string(message), std::system_error(ec, "test").what());
231 message = fmt::memory_buffer();
232
233 // Check if std::allocator throws on allocating max size_t / 2 chars.
234 size_t max_size = max_value<size_t>() / 2;
235 bool throws_on_alloc = false;
236 try {
237 auto alloc = std::allocator<char>();
238 alloc.deallocate(alloc.allocate(max_size), max_size);
239 } catch (const std::bad_alloc&) {
240 throws_on_alloc = true;
241 }
242 if (!throws_on_alloc) {
243 fmt::print("warning: std::allocator allocates {} chars\n", max_size);
244 return;
245 }
246 }
247
248 TEST(util_test, system_error) {
249 auto test_error = fmt::system_error(EDOM, "test");
250 auto ec = std::error_code(EDOM, std::generic_category());
251 EXPECT_STREQ(test_error.what(), std::system_error(ec, "test").what());
252 EXPECT_EQ(test_error.code(), ec);
253
254 auto error = std::system_error(std::error_code());
255 try {
256 throw fmt::system_error(EDOM, "test {}", "error");
257 } catch (const std::system_error& e) {
258 error = e;
259 }
260 fmt::memory_buffer message;
261 fmt::format_system_error(message, EDOM, "test error");
262 EXPECT_EQ(error.what(), to_string(message));
263 EXPECT_EQ(error.code(), std::error_code(EDOM, std::generic_category()));
264 }
265
266 TEST(util_test, report_system_error) {
267 fmt::memory_buffer out;
268 fmt::format_system_error(out, EDOM, "test error");
269 out.push_back('\n');
270 EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"),
271 to_string(out));
272 }
273
274 TEST(memory_buffer_test, ctor) {
275 basic_memory_buffer<char, 123> buffer;
276 EXPECT_EQ(static_cast<size_t>(0), buffer.size());
277 EXPECT_EQ(123u, buffer.capacity());
278 }
279
280 using std_allocator = allocator_ref<std::allocator<char>>;
281
282 TEST(memory_buffer_test, move_ctor_inline_buffer) {
283 auto check_move_buffer =
284 [](const char* str, basic_memory_buffer<char, 5, std_allocator>& buffer) {
285 std::allocator<char>* alloc = buffer.get_allocator().get();
286 basic_memory_buffer<char, 5, std_allocator> buffer2(std::move(buffer));
287 // Move shouldn't destroy the inline content of the first buffer.
288 EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
289 EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size()));
290 EXPECT_EQ(5u, buffer2.capacity());
291 // Move should transfer allocator.
292 EXPECT_EQ(nullptr, buffer.get_allocator().get());
293 EXPECT_EQ(alloc, buffer2.get_allocator().get());
294 };
295
296 auto alloc = std::allocator<char>();
297 basic_memory_buffer<char, 5, std_allocator> buffer((std_allocator(&alloc)));
298 const char test[] = "test";
299 buffer.append(string_view(test, 4));
300 check_move_buffer("test", buffer);
301 // Adding one more character fills the inline buffer, but doesn't cause
302 // dynamic allocation.
303 buffer.push_back('a');
304 check_move_buffer("testa", buffer);
305 }
306
307 TEST(memory_buffer_test, move_ctor_dynamic_buffer) {
308 auto alloc = std::allocator<char>();
309 basic_memory_buffer<char, 4, std_allocator> buffer((std_allocator(&alloc)));
310 const char test[] = "test";
311 buffer.append(test, test + 4);
312 const char* inline_buffer_ptr = &buffer[0];
313 // Adding one more character causes the content to move from the inline to
314 // a dynamically allocated buffer.
315 buffer.push_back('a');
316 basic_memory_buffer<char, 4, std_allocator> buffer2(std::move(buffer));
317 // Move should rip the guts of the first buffer.
318 EXPECT_EQ(&buffer[0], inline_buffer_ptr);
319 EXPECT_EQ(buffer.size(), 0);
320 EXPECT_EQ(std::string(&buffer2[0], buffer2.size()), "testa");
321 EXPECT_GT(buffer2.capacity(), 4u);
322 }
323
324 void check_move_assign_buffer(const char* str,
325 basic_memory_buffer<char, 5>& buffer) {
326 basic_memory_buffer<char, 5> buffer2;
327 buffer2 = std::move(buffer);
328 // Move shouldn't destroy the inline content of the first buffer.
329 EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
330 EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size()));
331 EXPECT_EQ(5u, buffer2.capacity());
332 }
333
334 TEST(memory_buffer_test, move_assignment) {
335 basic_memory_buffer<char, 5> buffer;
336 const char test[] = "test";
337 buffer.append(test, test + 4);
338 check_move_assign_buffer("test", buffer);
339 // Adding one more character fills the inline buffer, but doesn't cause
340 // dynamic allocation.
341 buffer.push_back('a');
342 check_move_assign_buffer("testa", buffer);
343 const char* inline_buffer_ptr = &buffer[0];
344 // Adding one more character causes the content to move from the inline to
345 // a dynamically allocated buffer.
346 buffer.push_back('b');
347 basic_memory_buffer<char, 5> buffer2;
348 buffer2 = std::move(buffer);
349 // Move should rip the guts of the first buffer.
350 EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
351 EXPECT_EQ("testab", std::string(&buffer2[0], buffer2.size()));
352 EXPECT_GT(buffer2.capacity(), 5u);
353 }
354
355 TEST(memory_buffer_test, grow) {
356 using allocator = allocator_ref<mock_allocator<int>>;
357 mock_allocator<int> alloc;
358 basic_memory_buffer<int, 10, allocator> buffer((allocator(&alloc)));
359 buffer.resize(7);
360 using fmt::detail::to_unsigned;
361 for (int i = 0; i < 7; ++i) buffer[to_unsigned(i)] = i * i;
362 EXPECT_EQ(10u, buffer.capacity());
363 int mem[20];
364 mem[7] = 0xdead;
365 EXPECT_CALL(alloc, allocate(20)).WillOnce(Return(mem));
366 buffer.try_reserve(20);
367 EXPECT_EQ(20u, buffer.capacity());
368 // Check if size elements have been copied
369 for (int i = 0; i < 7; ++i) EXPECT_EQ(i * i, buffer[to_unsigned(i)]);
370 // and no more than that.
371 EXPECT_EQ(0xdead, buffer[7]);
372 EXPECT_CALL(alloc, deallocate(mem, 20));
373 }
374
375 TEST(memory_buffer_test, allocator) {
376 using test_allocator = allocator_ref<mock_allocator<char>>;
377 basic_memory_buffer<char, 10, test_allocator> buffer;
378 EXPECT_EQ(nullptr, buffer.get_allocator().get());
379 StrictMock<mock_allocator<char>> alloc;
380 char mem;
381 {
382 basic_memory_buffer<char, 10, test_allocator> buffer2(
383 (test_allocator(&alloc)));
384 EXPECT_EQ(&alloc, buffer2.get_allocator().get());
385 size_t size = 2 * fmt::inline_buffer_size;
386 EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem));
387 buffer2.reserve(size);
388 EXPECT_CALL(alloc, deallocate(&mem, size));
389 }
390 }
391
392 TEST(memory_buffer_test, exception_in_deallocate) {
393 using test_allocator = allocator_ref<mock_allocator<char>>;
394 StrictMock<mock_allocator<char>> alloc;
395 basic_memory_buffer<char, 10, test_allocator> buffer(
396 (test_allocator(&alloc)));
397 size_t size = 2 * fmt::inline_buffer_size;
398 auto mem = std::vector<char>(size);
399 {
400 EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem[0]));
401 buffer.resize(size);
402 std::fill(&buffer[0], &buffer[0] + size, 'x');
403 }
404 auto mem2 = std::vector<char>(2 * size);
405 {
406 EXPECT_CALL(alloc, allocate(2 * size)).WillOnce(Return(&mem2[0]));
407 auto e = std::exception();
408 EXPECT_CALL(alloc, deallocate(&mem[0], size)).WillOnce(testing::Throw(e));
409 EXPECT_THROW(buffer.reserve(2 * size), std::exception);
410 EXPECT_EQ(&mem2[0], &buffer[0]);
411 // Check that the data has been copied.
412 for (size_t i = 0; i < size; ++i) EXPECT_EQ('x', buffer[i]);
413 }
414 EXPECT_CALL(alloc, deallocate(&mem2[0], 2 * size));
415 }
416
417 template <typename Allocator, size_t MaxSize>
418 class max_size_allocator : public Allocator {
419 public:
420 using typename Allocator::value_type;
421 size_t max_size() const noexcept { return MaxSize; }
422 value_type* allocate(size_t n) {
423 if (n > max_size()) {
424 throw std::length_error("size > max_size");
425 }
426 return std::allocator_traits<Allocator>::allocate(
427 *static_cast<Allocator*>(this), n);
428 }
429 void deallocate(value_type* p, size_t n) {
430 std::allocator_traits<Allocator>::deallocate(*static_cast<Allocator*>(this),
431 p, n);
432 }
433 };
434
435 TEST(memory_buffer_test, max_size_allocator) {
436 // 160 = 128 + 32
437 using test_allocator = max_size_allocator<std::allocator<char>, 160>;
438 basic_memory_buffer<char, 10, test_allocator> buffer;
439 buffer.resize(128);
440 // new_capacity = 128 + 128/2 = 192 > 160
441 buffer.resize(160); // Shouldn't throw.
442 }
443
444 TEST(memory_buffer_test, max_size_allocator_overflow) {
445 using test_allocator = max_size_allocator<std::allocator<char>, 160>;
446 basic_memory_buffer<char, 10, test_allocator> buffer;
447 EXPECT_THROW(buffer.resize(161), std::exception);
448 }
449
450 TEST(format_test, exception_from_lib) {
451 EXPECT_THROW_MSG(fmt::throw_format_error("test"), format_error, "test");
452 }
453
454 TEST(format_test, escape) {
455 EXPECT_EQ(fmt::format("{{"), "{");
456 EXPECT_EQ(fmt::format("before {{"), "before {");
457 EXPECT_EQ(fmt::format("{{ after"), "{ after");
458 EXPECT_EQ(fmt::format("before {{ after"), "before { after");
459
460 EXPECT_EQ(fmt::format("}}"), "}");
461 EXPECT_EQ(fmt::format("before }}"), "before }");
462 EXPECT_EQ(fmt::format("}} after"), "} after");
463 EXPECT_EQ(fmt::format("before }} after"), "before } after");
464
465 EXPECT_EQ(fmt::format("{{}}"), "{}");
466 EXPECT_EQ(fmt::format("{{{0}}}", 42), "{42}");
467 }
468
469 TEST(format_test, unmatched_braces) {
470 EXPECT_THROW_MSG((void)fmt::format(runtime("{")), format_error,
471 "invalid format string");
472 EXPECT_THROW_MSG((void)fmt::format(runtime("}")), format_error,
473 "unmatched '}' in format string");
474 EXPECT_THROW_MSG((void)fmt::format(runtime("{0{}")), format_error,
475 "invalid format string");
476 }
477
478 TEST(format_test, no_args) { EXPECT_EQ(fmt::format("test"), "test"); }
479
480 TEST(format_test, args_in_different_positions) {
481 EXPECT_EQ(fmt::format("{0}", 42), "42");
482 EXPECT_EQ(fmt::format("before {0}", 42), "before 42");
483 EXPECT_EQ(fmt::format("{0} after", 42), "42 after");
484 EXPECT_EQ(fmt::format("before {0} after", 42), "before 42 after");
485 EXPECT_EQ(fmt::format("{0} = {1}", "answer", 42), "answer = 42");
486 EXPECT_EQ(fmt::format("{1} is the {0}", "answer", 42), "42 is the answer");
487 EXPECT_EQ(fmt::format("{0}{1}{0}", "abra", "cad"), "abracadabra");
488 }
489
490 TEST(format_test, arg_errors) {
491 EXPECT_THROW_MSG((void)fmt::format(runtime("{")), format_error,
492 "invalid format string");
493 EXPECT_THROW_MSG((void)fmt::format(runtime("{?}")), format_error,
494 "invalid format string");
495 EXPECT_THROW_MSG((void)fmt::format(runtime("{0")), format_error,
496 "invalid format string");
497 EXPECT_THROW_MSG((void)fmt::format(runtime("{0}")), format_error,
498 "argument not found");
499 EXPECT_THROW_MSG((void)fmt::format(runtime("{00}"), 42), format_error,
500 "invalid format string");
501
502 auto int_max = std::to_string(INT_MAX);
503 EXPECT_THROW_MSG((void)fmt::format(runtime("{" + int_max)), format_error,
504 "invalid format string");
505 EXPECT_THROW_MSG((void)fmt::format(runtime("{" + int_max + "}")),
506 format_error, "argument not found");
507
508 auto int_maxer = std::to_string(INT_MAX + 1u);
509 EXPECT_THROW_MSG((void)fmt::format(runtime("{" + int_maxer)), format_error,
510 "invalid format string");
511 EXPECT_THROW_MSG((void)fmt::format(runtime("{" + int_maxer + "}")),
512 format_error, "argument not found");
513 }
514
515 template <int N> struct test_format {
516 template <typename... T>
517 static auto format(fmt::string_view fmt, const T&... args) -> std::string {
518 return test_format<N - 1>::format(fmt, N - 1, args...);
519 }
520 };
521
522 template <> struct test_format<0> {
523 template <typename... T>
524 static auto format(fmt::string_view fmt, const T&... args) -> std::string {
525 return fmt::format(runtime(fmt), args...);
526 }
527 };
528
529 TEST(format_test, many_args) {
530 EXPECT_EQ("19", test_format<20>::format("{19}"));
531 EXPECT_THROW_MSG(test_format<20>::format("{20}"), format_error,
532 "argument not found");
533 EXPECT_THROW_MSG(test_format<21>::format("{21}"), format_error,
534 "argument not found");
535 using fmt::detail::max_packed_args;
536 std::string format_str = fmt::format("{{{}}}", max_packed_args + 1);
537 EXPECT_THROW_MSG(test_format<max_packed_args>::format(format_str),
538 format_error, "argument not found");
539 }
540
541 TEST(format_test, named_arg) {
542 EXPECT_EQ("1/a/A", fmt::format("{_1}/{a_}/{A_}", fmt::arg("a_", 'a'),
543 fmt::arg("A_", "A"), fmt::arg("_1", 1)));
544 EXPECT_EQ(fmt::format("{0:{width}}", -42, fmt::arg("width", 4)), " -42");
545 EXPECT_EQ("st",
546 fmt::format("{0:.{precision}}", "str", fmt::arg("precision", 2)));
547 EXPECT_EQ(fmt::format("{} {two}", 1, fmt::arg("two", 2)), "1 2");
548 EXPECT_EQ("42",
549 fmt::format("{c}", fmt::arg("a", 0), fmt::arg("b", 0),
550 fmt::arg("c", 42), fmt::arg("d", 0), fmt::arg("e", 0),
551 fmt::arg("f", 0), fmt::arg("g", 0), fmt::arg("h", 0),
552 fmt::arg("i", 0), fmt::arg("j", 0), fmt::arg("k", 0),
553 fmt::arg("l", 0), fmt::arg("m", 0), fmt::arg("n", 0),
554 fmt::arg("o", 0), fmt::arg("p", 0)));
555 EXPECT_THROW_MSG((void)fmt::format(runtime("{a}")), format_error,
556 "argument not found");
557 EXPECT_THROW_MSG((void)fmt::format(runtime("{a}"), 42), format_error,
558 "argument not found");
559 }
560
561 TEST(format_test, auto_arg_index) {
562 EXPECT_EQ(fmt::format("{}{}{}", 'a', 'b', 'c'), "abc");
563 EXPECT_THROW_MSG((void)fmt::format(runtime("{0}{}"), 'a', 'b'), format_error,
564 "cannot switch from manual to automatic argument indexing");
565 EXPECT_THROW_MSG((void)fmt::format(runtime("{}{0}"), 'a', 'b'), format_error,
566 "cannot switch from automatic to manual argument indexing");
567 EXPECT_EQ(fmt::format("{:.{}}", 1.2345, 2), "1.2");
568 EXPECT_THROW_MSG((void)fmt::format(runtime("{0}:.{}"), 1.2345, 2),
569 format_error,
570 "cannot switch from manual to automatic argument indexing");
571 EXPECT_THROW_MSG((void)fmt::format(runtime("{:.{0}}"), 1.2345, 2),
572 format_error,
573 "cannot switch from automatic to manual argument indexing");
574 EXPECT_THROW_MSG((void)fmt::format(runtime("{}")), format_error,
575 "argument not found");
576 }
577
578 TEST(format_test, empty_specs) { EXPECT_EQ(fmt::format("{0:}", 42), "42"); }
579
580 TEST(format_test, left_align) {
581 EXPECT_EQ(fmt::format("{0:<4}", 42), "42 ");
582 EXPECT_EQ(fmt::format("{0:<4o}", 042), "42 ");
583 EXPECT_EQ(fmt::format("{0:<4x}", 0x42), "42 ");
584 EXPECT_EQ(fmt::format("{0:<5}", -42), "-42 ");
585 EXPECT_EQ(fmt::format("{0:<5}", 42u), "42 ");
586 EXPECT_EQ(fmt::format("{0:<5}", -42l), "-42 ");
587 EXPECT_EQ(fmt::format("{0:<5}", 42ul), "42 ");
588 EXPECT_EQ(fmt::format("{0:<5}", -42ll), "-42 ");
589 EXPECT_EQ(fmt::format("{0:<5}", 42ull), "42 ");
590 EXPECT_EQ(fmt::format("{0:<5}", -42.0), "-42 ");
591 EXPECT_EQ(fmt::format("{0:<5}", -42.0l), "-42 ");
592 EXPECT_EQ(fmt::format("{0:<5}", 'c'), "c ");
593 EXPECT_EQ(fmt::format("{0:<5}", "abc"), "abc ");
594 EXPECT_EQ(fmt::format("{0:<8}", reinterpret_cast<void*>(0xface)), "0xface ");
595 }
596
597 TEST(format_test, right_align) {
598 EXPECT_EQ(fmt::format("{0:>4}", 42), " 42");
599 EXPECT_EQ(fmt::format("{0:>4o}", 042), " 42");
600 EXPECT_EQ(fmt::format("{0:>4x}", 0x42), " 42");
601 EXPECT_EQ(fmt::format("{0:>5}", -42), " -42");
602 EXPECT_EQ(fmt::format("{0:>5}", 42u), " 42");
603 EXPECT_EQ(fmt::format("{0:>5}", -42l), " -42");
604 EXPECT_EQ(fmt::format("{0:>5}", 42ul), " 42");
605 EXPECT_EQ(fmt::format("{0:>5}", -42ll), " -42");
606 EXPECT_EQ(fmt::format("{0:>5}", 42ull), " 42");
607 EXPECT_EQ(fmt::format("{0:>5}", -42.0), " -42");
608 EXPECT_EQ(fmt::format("{0:>5}", -42.0l), " -42");
609 EXPECT_EQ(fmt::format("{0:>5}", 'c'), " c");
610 EXPECT_EQ(fmt::format("{0:>5}", "abc"), " abc");
611 EXPECT_EQ(fmt::format("{0:>8}", reinterpret_cast<void*>(0xface)), " 0xface");
612 }
613
614 TEST(format_test, center_align) {
615 EXPECT_EQ(fmt::format("{0:^5}", 42), " 42 ");
616 EXPECT_EQ(fmt::format("{0:^5o}", 042), " 42 ");
617 EXPECT_EQ(fmt::format("{0:^5x}", 0x42), " 42 ");
618 EXPECT_EQ(fmt::format("{0:^5}", -42), " -42 ");
619 EXPECT_EQ(fmt::format("{0:^5}", 42u), " 42 ");
620 EXPECT_EQ(fmt::format("{0:^5}", -42l), " -42 ");
621 EXPECT_EQ(fmt::format("{0:^5}", 42ul), " 42 ");
622 EXPECT_EQ(fmt::format("{0:^5}", -42ll), " -42 ");
623 EXPECT_EQ(fmt::format("{0:^5}", 42ull), " 42 ");
624 EXPECT_EQ(fmt::format("{0:^5}", -42.0), " -42 ");
625 EXPECT_EQ(fmt::format("{0:^5}", -42.0l), " -42 ");
626 EXPECT_EQ(fmt::format("{0:^5}", 'c'), " c ");
627 EXPECT_EQ(fmt::format("{0:^6}", "abc"), " abc ");
628 EXPECT_EQ(fmt::format("{0:^8}", reinterpret_cast<void*>(0xface)), " 0xface ");
629 }
630
631 TEST(format_test, fill) {
632 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{<5}"), 'c'), format_error,
633 "invalid fill character '{'");
634 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{<5}}"), 'c'), format_error,
635 "invalid fill character '{'");
636 EXPECT_EQ(fmt::format("{0:*>4}", 42), "**42");
637 EXPECT_EQ(fmt::format("{0:*>5}", -42), "**-42");
638 EXPECT_EQ(fmt::format("{0:*>5}", 42u), "***42");
639 EXPECT_EQ(fmt::format("{0:*>5}", -42l), "**-42");
640 EXPECT_EQ(fmt::format("{0:*>5}", 42ul), "***42");
641 EXPECT_EQ(fmt::format("{0:*>5}", -42ll), "**-42");
642 EXPECT_EQ(fmt::format("{0:*>5}", 42ull), "***42");
643 EXPECT_EQ(fmt::format("{0:*>5}", -42.0), "**-42");
644 EXPECT_EQ(fmt::format("{0:*>5}", -42.0l), "**-42");
645 EXPECT_EQ(fmt::format("{0:*<5}", 'c'), "c****");
646 EXPECT_EQ(fmt::format("{0:*<5}", "abc"), "abc**");
647 EXPECT_EQ("**0xface",
648 fmt::format("{0:*>8}", reinterpret_cast<void*>(0xface)));
649 EXPECT_EQ(fmt::format("{:}=", "foo"), "foo=");
650 EXPECT_EQ(std::string("\0\0\0*", 4),
651 fmt::format(string_view("{:\0>4}", 6), '*'));
652 EXPECT_EQ(fmt::format("{0:ж>4}", 42), "жж42");
653 EXPECT_THROW_MSG((void)fmt::format(runtime("{:\x80\x80\x80\x80\x80>}"), 0),
654 format_error, "invalid format specifier");
655 }
656
657 TEST(format_test, plus_sign) {
658 EXPECT_EQ(fmt::format("{0:+}", 42), "+42");
659 EXPECT_EQ(fmt::format("{0:+}", -42), "-42");
660 EXPECT_EQ(fmt::format("{0:+}", 42), "+42");
661 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+}"), 42u), format_error,
662 "invalid format specifier");
663 EXPECT_EQ(fmt::format("{0:+}", 42l), "+42");
664 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+}"), 42ul), format_error,
665 "invalid format specifier");
666 EXPECT_EQ(fmt::format("{0:+}", 42ll), "+42");
667 #if FMT_USE_INT128
668 EXPECT_EQ(fmt::format("{0:+}", __int128_t(42)), "+42");
669 #endif
670 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+}"), 42ull), format_error,
671 "invalid format specifier");
672 EXPECT_EQ(fmt::format("{0:+}", 42.0), "+42");
673 EXPECT_EQ(fmt::format("{0:+}", 42.0l), "+42");
674 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+}"), 'c'), format_error,
675 "invalid format specifier");
676 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:+}"), "abc"), format_error,
677 "invalid format specifier");
678 EXPECT_THROW_MSG(
679 (void)fmt::format(runtime("{0:+}"), reinterpret_cast<void*>(0x42)),
680 format_error, "invalid format specifier");
681 }
682
683 TEST(format_test, minus_sign) {
684 EXPECT_EQ(fmt::format("{0:-}", 42), "42");
685 EXPECT_EQ(fmt::format("{0:-}", -42), "-42");
686 EXPECT_EQ(fmt::format("{0:-}", 42), "42");
687 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-}"), 42u), format_error,
688 "invalid format specifier");
689 EXPECT_EQ(fmt::format("{0:-}", 42l), "42");
690 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-}"), 42ul), format_error,
691 "invalid format specifier");
692 EXPECT_EQ(fmt::format("{0:-}", 42ll), "42");
693 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-}"), 42ull), format_error,
694 "invalid format specifier");
695 EXPECT_EQ(fmt::format("{0:-}", 42.0), "42");
696 EXPECT_EQ(fmt::format("{0:-}", 42.0l), "42");
697 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-}"), 'c'), format_error,
698 "invalid format specifier");
699 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:-}"), "abc"), format_error,
700 "invalid format specifier");
701 EXPECT_THROW_MSG(
702 (void)fmt::format(runtime("{0:-}"), reinterpret_cast<void*>(0x42)),
703 format_error, "invalid format specifier");
704 }
705
706 TEST(format_test, space_sign) {
707 EXPECT_EQ(fmt::format("{0: }", 42), " 42");
708 EXPECT_EQ(fmt::format("{0: }", -42), "-42");
709 EXPECT_EQ(fmt::format("{0: }", 42), " 42");
710 EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), 42u), format_error,
711 "invalid format specifier");
712 EXPECT_EQ(fmt::format("{0: }", 42l), " 42");
713 EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), 42ul), format_error,
714 "invalid format specifier");
715 EXPECT_EQ(fmt::format("{0: }", 42ll), " 42");
716 EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), 42ull), format_error,
717 "invalid format specifier");
718 EXPECT_EQ(fmt::format("{0: }", 42.0), " 42");
719 EXPECT_EQ(fmt::format("{0: }", 42.0l), " 42");
720 EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), 'c'), format_error,
721 "invalid format specifier");
722 EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), "abc"), format_error,
723 "invalid format specifier");
724 EXPECT_THROW_MSG(
725 (void)fmt::format(runtime("{0: }"), reinterpret_cast<void*>(0x42)),
726 format_error, "invalid format specifier");
727 }
728
729 TEST(format_test, hash_flag) {
730 EXPECT_EQ(fmt::format("{0:#}", 42), "42");
731 EXPECT_EQ(fmt::format("{0:#}", -42), "-42");
732 EXPECT_EQ(fmt::format("{0:#b}", 42), "0b101010");
733 EXPECT_EQ(fmt::format("{0:#B}", 42), "0B101010");
734 EXPECT_EQ(fmt::format("{0:#b}", -42), "-0b101010");
735 EXPECT_EQ(fmt::format("{0:#x}", 0x42), "0x42");
736 EXPECT_EQ(fmt::format("{0:#X}", 0x42), "0X42");
737 EXPECT_EQ(fmt::format("{0:#x}", -0x42), "-0x42");
738 EXPECT_EQ(fmt::format("{0:#o}", 0), "0");
739 EXPECT_EQ(fmt::format("{0:#o}", 042), "042");
740 EXPECT_EQ(fmt::format("{0:#o}", -042), "-042");
741 EXPECT_EQ(fmt::format("{0:#}", 42u), "42");
742 EXPECT_EQ(fmt::format("{0:#x}", 0x42u), "0x42");
743 EXPECT_EQ(fmt::format("{0:#o}", 042u), "042");
744
745 EXPECT_EQ(fmt::format("{0:#}", -42l), "-42");
746 EXPECT_EQ(fmt::format("{0:#x}", 0x42l), "0x42");
747 EXPECT_EQ(fmt::format("{0:#x}", -0x42l), "-0x42");
748 EXPECT_EQ(fmt::format("{0:#o}", 042l), "042");
749 EXPECT_EQ(fmt::format("{0:#o}", -042l), "-042");
750 EXPECT_EQ(fmt::format("{0:#}", 42ul), "42");
751 EXPECT_EQ(fmt::format("{0:#x}", 0x42ul), "0x42");
752 EXPECT_EQ(fmt::format("{0:#o}", 042ul), "042");
753
754 EXPECT_EQ(fmt::format("{0:#}", -42ll), "-42");
755 EXPECT_EQ(fmt::format("{0:#x}", 0x42ll), "0x42");
756 EXPECT_EQ(fmt::format("{0:#x}", -0x42ll), "-0x42");
757 EXPECT_EQ(fmt::format("{0:#o}", 042ll), "042");
758 EXPECT_EQ(fmt::format("{0:#o}", -042ll), "-042");
759 EXPECT_EQ(fmt::format("{0:#}", 42ull), "42");
760 EXPECT_EQ(fmt::format("{0:#x}", 0x42ull), "0x42");
761 EXPECT_EQ(fmt::format("{0:#o}", 042ull), "042");
762
763 EXPECT_EQ(fmt::format("{0:#}", -42.0), "-42.");
764 EXPECT_EQ(fmt::format("{0:#}", -42.0l), "-42.");
765 EXPECT_EQ(fmt::format("{:#.0e}", 42.0), "4.e+01");
766 EXPECT_EQ(fmt::format("{:#.0f}", 0.01), "0.");
767 EXPECT_EQ(fmt::format("{:#.2g}", 0.5), "0.50");
768 EXPECT_EQ(fmt::format("{:#.0f}", 0.5), "0.");
769 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:#"), 'c'), format_error,
770 "missing '}' in format string");
771 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:#}"), 'c'), format_error,
772 "invalid format specifier for char");
773 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:#}"), "abc"), format_error,
774 "invalid format specifier");
775 EXPECT_THROW_MSG(
776 (void)fmt::format(runtime("{0:#}"), reinterpret_cast<void*>(0x42)),
777 format_error, "invalid format specifier");
778 }
779
780 TEST(format_test, zero_flag) {
781 EXPECT_EQ(fmt::format("{0:0}", 42), "42");
782 EXPECT_EQ(fmt::format("{0:05}", -42), "-0042");
783 EXPECT_EQ(fmt::format("{0:05}", 42u), "00042");
784 EXPECT_EQ(fmt::format("{0:05}", -42l), "-0042");
785 EXPECT_EQ(fmt::format("{0:05}", 42ul), "00042");
786 EXPECT_EQ(fmt::format("{0:05}", -42ll), "-0042");
787 EXPECT_EQ(fmt::format("{0:05}", 42ull), "00042");
788 EXPECT_EQ(fmt::format("{0:07}", -42.0), "-000042");
789 EXPECT_EQ(fmt::format("{0:07}", -42.0l), "-000042");
790 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:0"), 'c'), format_error,
791 "missing '}' in format string");
792 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:05}"), 'c'), format_error,
793 "invalid format specifier for char");
794 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:05}"), "abc"), format_error,
795 "format specifier requires numeric argument");
796 EXPECT_THROW_MSG(
797 (void)fmt::format(runtime("{0:05}"), reinterpret_cast<void*>(0x42)),
798 format_error, "format specifier requires numeric argument");
799 }
800
801 TEST(format_test, zero_flag_and_align) {
802 // If the 0 character and an align option both appear, the 0 character is
803 // ignored.
804 EXPECT_EQ(fmt::format("{:<05}", 42), "42 ");
805 EXPECT_EQ(fmt::format("{:<05}", -42), "-42 ");
806 EXPECT_EQ(fmt::format("{:^05}", 42), " 42 ");
807 EXPECT_EQ(fmt::format("{:^05}", -42), " -42 ");
808 EXPECT_EQ(fmt::format("{:>05}", 42), " 42");
809 EXPECT_EQ(fmt::format("{:>05}", -42), " -42");
810 }
811
812 TEST(format_test, width) {
813 auto int_maxer = std::to_string(INT_MAX + 1u);
814 EXPECT_THROW_MSG((void)fmt::format(runtime("{:" + int_maxer), 0),
815 format_error, "number is too big");
816 EXPECT_THROW_MSG((void)fmt::format(runtime("{:" + int_maxer + "}"), 0),
817 format_error, "number is too big");
818
819 EXPECT_EQ(fmt::format("{:4}", -42), " -42");
820 EXPECT_EQ(fmt::format("{:5}", 42u), " 42");
821 EXPECT_EQ(fmt::format("{:6}", -42l), " -42");
822 EXPECT_EQ(fmt::format("{:7}", 42ul), " 42");
823 EXPECT_EQ(fmt::format("{:6}", -42ll), " -42");
824 EXPECT_EQ(fmt::format("{:7}", 42ull), " 42");
825 EXPECT_EQ(fmt::format("{:8}", -1.23), " -1.23");
826 EXPECT_EQ(fmt::format("{:9}", -1.23l), " -1.23");
827 EXPECT_EQ(fmt::format("{:10}", reinterpret_cast<void*>(0xcafe)),
828 " 0xcafe");
829 EXPECT_EQ(fmt::format("{:11}", 'x'), "x ");
830 EXPECT_EQ(fmt::format("{:12}", "str"), "str ");
831 EXPECT_EQ(fmt::format("{:*^6}", "🤡"), "**🤡**");
832 EXPECT_EQ(fmt::format("{:*^8}", "你好"), "**你好**");
833 EXPECT_EQ(fmt::format("{:#6}", 42.0), " 42.");
834 EXPECT_EQ(fmt::format("{:6c}", static_cast<int>('x')), "x ");
835 EXPECT_EQ(fmt::format("{:>06.0f}", 0.00884311), " 0");
836 }
837
838 TEST(format_test, runtime_width) {
839 auto int_maxer = std::to_string(INT_MAX + 1u);
840 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{" + int_maxer), 0),
841 format_error, "invalid format string");
842 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{" + int_maxer + "}"), 0),
843 format_error, "argument not found");
844 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{" + int_maxer + "}}"), 0),
845 format_error, "argument not found");
846
847 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{"), 0), format_error,
848 "invalid format string");
849 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{}"), 0), format_error,
850 "cannot switch from manual to automatic argument indexing");
851 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{?}}"), 0), format_error,
852 "invalid format string");
853 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0), format_error,
854 "argument not found");
855
856 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{0:}}"), 0), format_error,
857 "invalid format string");
858
859 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, -1), format_error,
860 "negative width");
861 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, (INT_MAX + 1u)),
862 format_error, "number is too big");
863 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, -1l), format_error,
864 "negative width");
865 if (fmt::detail::const_check(sizeof(long) > sizeof(int))) {
866 long value = INT_MAX;
867 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, (value + 1)),
868 format_error, "number is too big");
869 }
870 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, (INT_MAX + 1ul)),
871 format_error, "number is too big");
872
873 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, '0'), format_error,
874 "width is not integer");
875 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:{1}}"), 0, 0.0), format_error,
876 "width is not integer");
877
878 EXPECT_EQ(fmt::format("{0:{1}}", -42, 4), " -42");
879 EXPECT_EQ(fmt::format("{0:{1}}", 42u, 5), " 42");
880 EXPECT_EQ(fmt::format("{0:{1}}", -42l, 6), " -42");
881 EXPECT_EQ(fmt::format("{0:{1}}", 42ul, 7), " 42");
882 EXPECT_EQ(fmt::format("{0:{1}}", -42ll, 6), " -42");
883 EXPECT_EQ(fmt::format("{0:{1}}", 42ull, 7), " 42");
884 EXPECT_EQ(fmt::format("{0:{1}}", -1.23, 8), " -1.23");
885 EXPECT_EQ(fmt::format("{0:{1}}", -1.23l, 9), " -1.23");
886 EXPECT_EQ(" 0xcafe",
887 fmt::format("{0:{1}}", reinterpret_cast<void*>(0xcafe), 10));
888 EXPECT_EQ(fmt::format("{0:{1}}", 'x', 11), "x ");
889 EXPECT_EQ(fmt::format("{0:{1}}", "str", 12), "str ");
890 EXPECT_EQ(fmt::format("{:{}}", 42, short(4)), " 42");
891 }
892
893 TEST(format_test, precision) {
894 char format_str[buffer_size];
895 safe_sprintf(format_str, "{0:.%u", UINT_MAX);
896 increment(format_str + 4);
897 EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0.0), format_error,
898 "number is too big");
899 size_t size = std::strlen(format_str);
900 format_str[size] = '}';
901 format_str[size + 1] = 0;
902 EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0.0), format_error,
903 "number is too big");
904
905 safe_sprintf(format_str, "{0:.%u", INT_MAX + 1u);
906 EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0.0), format_error,
907 "number is too big");
908 safe_sprintf(format_str, "{0:.%u}", INT_MAX + 1u);
909 EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0.0), format_error,
910 "number is too big");
911
912 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:."), 0.0), format_error,
913 "invalid precision");
914 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.}"), 0.0), format_error,
915 "invalid precision");
916
917 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2"), 0), format_error,
918 "invalid format specifier");
919 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42), format_error,
920 "invalid format specifier");
921 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42), format_error,
922 "invalid format specifier");
923 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42u), format_error,
924 "invalid format specifier");
925 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42u), format_error,
926 "invalid format specifier");
927 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42l), format_error,
928 "invalid format specifier");
929 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42l), format_error,
930 "invalid format specifier");
931 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42ul), format_error,
932 "invalid format specifier");
933 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42ul), format_error,
934 "invalid format specifier");
935 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42ll), format_error,
936 "invalid format specifier");
937 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42ll), format_error,
938 "invalid format specifier");
939 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42ull), format_error,
940 "invalid format specifier");
941 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42ull), format_error,
942 "invalid format specifier");
943 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:3.0}"), 'x'), format_error,
944 "invalid format specifier");
945 EXPECT_EQ(fmt::format("{0:.2}", 1.2345), "1.2");
946 EXPECT_EQ(fmt::format("{0:.2}", 1.2345l), "1.2");
947 EXPECT_EQ(fmt::format("{:.2}", 1.234e56), "1.2e+56");
948 EXPECT_EQ(fmt::format("{0:.3}", 1.1), "1.1");
949 EXPECT_EQ(fmt::format("{:.0e}", 1.0L), "1e+00");
950 EXPECT_EQ(fmt::format("{:9.1e}", 0.0), " 0.0e+00");
951 EXPECT_EQ(
952 fmt::format("{:.494}", 4.9406564584124654E-324),
953 "4.9406564584124654417656879286822137236505980261432476442558568250067550"
954 "727020875186529983636163599237979656469544571773092665671035593979639877"
955 "479601078187812630071319031140452784581716784898210368871863605699873072"
956 "305000638740915356498438731247339727316961514003171538539807412623856559"
957 "117102665855668676818703956031062493194527159149245532930545654440112748"
958 "012970999954193198940908041656332452475714786901472678015935523861155013"
959 "480352649347201937902681071074917033322268447533357208324319361e-324");
960 EXPECT_EQ(
961 fmt::format("{:.1074f}", 1.1125369292536e-308),
962 "0.0000000000000000000000000000000000000000000000000000000000000000000000"
963 "000000000000000000000000000000000000000000000000000000000000000000000000"
964 "000000000000000000000000000000000000000000000000000000000000000000000000"
965 "000000000000000000000000000000000000000000000000000000000000000000000000"
966 "000000000000000000000111253692925360019747947051741965785554081512200979"
967 "355021686109411883779182127659725163430929750364498219730822952552570601"
968 "152163505899912777129583674906301179059298598412303893909188340988729019"
969 "014361467448914817838555156840459458527907308695109202499990850735085304"
970 "478476991912072201449236975063640913461919914396877093174125167509869762"
971 "482369631100360266123742648159508919592746619553246586039571522788247697"
972 "156360766271842991667238355464496455107749716934387136380536472531224398"
973 "559833794807213172371254492216255558078524900147957309382830827524104234"
974 "530961756787819847850302379672357738807808384667004752163416921762619527"
975 "462847642037420991432005657440259928195996762610375541867198059294212446"
976 "81962777939941034720757232455434770912461317493580281734466552734375");
977
978 std::string outputs[] = {
979 "-0X1.41FE3FFE71C9E000000000000000000000000000000000000000000000000000000"
980 "000000000000000000000000000000000000000000000000000000000000000000000000"
981 "000000000000000000000000000000000000000000000000000000000000000000000000"
982 "000000000000000000000000000000000000000000000000000000000000000000000000"
983 "000000000000000000000000000000000000000000000000000000000000000000000000"
984 "000000000000000000000000000000000000000000000000000000000000000000000000"
985 "000000000000000000000000000000000000000000000000000000000000000000000000"
986 "000000000000000000000000000000000000000000000000000000000000000000000000"
987 "000000000000000000000000000000000000000000000000000000000000000000000000"
988 "000000000000000000000000000000000000000000000000000000000000000000000000"
989 "000000000000000000000000000000000000000000000000000000000000000000000000"
990 "000000000000000000000000000000000000000000000000000P+127",
991 "-0XA.0FF1FFF38E4F0000000000000000000000000000000000000000000000000000000"
992 "000000000000000000000000000000000000000000000000000000000000000000000000"
993 "000000000000000000000000000000000000000000000000000000000000000000000000"
994 "000000000000000000000000000000000000000000000000000000000000000000000000"
995 "000000000000000000000000000000000000000000000000000000000000000000000000"
996 "000000000000000000000000000000000000000000000000000000000000000000000000"
997 "000000000000000000000000000000000000000000000000000000000000000000000000"
998 "000000000000000000000000000000000000000000000000000000000000000000000000"
999 "000000000000000000000000000000000000000000000000000000000000000000000000"
1000 "000000000000000000000000000000000000000000000000000000000000000000000000"
1001 "000000000000000000000000000000000000000000000000000000000000000000000000"
1002 "000000000000000000000000000000000000000000000000000P+124"};
1003 EXPECT_THAT(outputs,
1004 testing::Contains(fmt::format("{:.838A}", -2.14001164E+38)));
1005
1006 if (std::numeric_limits<long double>::digits == 64) {
1007 auto ld = (std::numeric_limits<long double>::min)();
1008 EXPECT_EQ(fmt::format("{:.0}", ld), "3e-4932");
1009 EXPECT_EQ(
1010 fmt::format("{:0g}", std::numeric_limits<long double>::denorm_min()),
1011 "3.6452e-4951");
1012 }
1013
1014 EXPECT_EQ(fmt::format("{:#.0f}", 123.0), "123.");
1015 EXPECT_EQ(fmt::format("{:.02f}", 1.234), "1.23");
1016 EXPECT_EQ(fmt::format("{:.1g}", 0.001), "0.001");
1017 EXPECT_EQ(fmt::format("{}", 1019666432.0f), "1019666400");
1018 EXPECT_EQ(fmt::format("{:.0e}", 9.5), "1e+01");
1019 EXPECT_EQ(fmt::format("{:.1e}", 1e-34), "1.0e-34");
1020
1021 EXPECT_THROW_MSG(
1022 (void)fmt::format(runtime("{0:.2}"), reinterpret_cast<void*>(0xcafe)),
1023 format_error, "invalid format specifier");
1024 EXPECT_THROW_MSG(
1025 (void)fmt::format(runtime("{0:.2f}"), reinterpret_cast<void*>(0xcafe)),
1026 format_error, "invalid format specifier");
1027 EXPECT_THROW_MSG((void)fmt::format(runtime("{:.{}e}"), 42.0,
1028 fmt::detail::max_value<int>()),
1029 format_error, "number is too big");
1030 EXPECT_THROW_MSG(
1031 (void)fmt::format("{:.2147483646f}", -2.2121295195081227E+304),
1032 format_error, "number is too big");
1033
1034 EXPECT_EQ(fmt::format("{0:.2}", "str"), "st");
1035 EXPECT_EQ(fmt::format("{0:.5}", "вожыкі"), "вожык");
1036 EXPECT_EQ(fmt::format("{0:.6}", "123456\xad"), "123456");
1037 }
1038
1039 TEST(xchar_test, utf8_precision) {
1040 auto result = fmt::format("{:.4}", "caf\u00e9s"); // cafés
1041 EXPECT_EQ(fmt::detail::compute_width(result), 4);
1042 EXPECT_EQ(result, "caf\u00e9");
1043 }
1044
1045 TEST(format_test, runtime_precision) {
1046 char format_str[buffer_size];
1047 safe_sprintf(format_str, "{0:.{%u", UINT_MAX);
1048 increment(format_str + 5);
1049 EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0.0), format_error,
1050 "invalid format string");
1051 size_t size = std::strlen(format_str);
1052 format_str[size] = '}';
1053 format_str[size + 1] = 0;
1054 EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0.0), format_error,
1055 "argument not found");
1056 format_str[size + 1] = '}';
1057 format_str[size + 2] = 0;
1058 EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0.0), format_error,
1059 "argument not found");
1060
1061 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{"), 0.0), format_error,
1062 "invalid format string");
1063 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{}"), 0.0), format_error,
1064 "cannot switch from manual to automatic argument indexing");
1065 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{?}}"), 0.0), format_error,
1066 "invalid format string");
1067 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}"), 0, 0), format_error,
1068 "invalid format specifier");
1069 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0.0), format_error,
1070 "argument not found");
1071
1072 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{0:}}"), 0.0), format_error,
1073 "invalid format string");
1074
1075 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0.0, -1),
1076 format_error, "negative precision");
1077 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0.0, (INT_MAX + 1u)),
1078 format_error, "number is too big");
1079 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0.0, -1l),
1080 format_error, "negative precision");
1081 if (fmt::detail::const_check(sizeof(long) > sizeof(int))) {
1082 long value = INT_MAX;
1083 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0.0, (value + 1)),
1084 format_error, "number is too big");
1085 }
1086 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0.0, (INT_MAX + 1ul)),
1087 format_error, "number is too big");
1088
1089 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0.0, '0'),
1090 format_error, "precision is not integer");
1091 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0.0, 0.0),
1092 format_error, "precision is not integer");
1093
1094 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42, 2), format_error,
1095 "invalid format specifier");
1096 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42, 2), format_error,
1097 "invalid format specifier");
1098 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42u, 2), format_error,
1099 "invalid format specifier");
1100 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42u, 2),
1101 format_error, "invalid format specifier");
1102 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42l, 2), format_error,
1103 "invalid format specifier");
1104 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42l, 2),
1105 format_error, "invalid format specifier");
1106 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42ul, 2),
1107 format_error, "invalid format specifier");
1108 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42ul, 2),
1109 format_error, "invalid format specifier");
1110 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42ll, 2),
1111 format_error, "invalid format specifier");
1112 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42ll, 2),
1113 format_error, "invalid format specifier");
1114 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42ull, 2),
1115 format_error, "invalid format specifier");
1116 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42ull, 2),
1117 format_error, "invalid format specifier");
1118 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:3.{1}}"), 'x', 0),
1119 format_error, "invalid format specifier");
1120 EXPECT_EQ(fmt::format("{0:.{1}}", 1.2345, 2), "1.2");
1121 EXPECT_EQ(fmt::format("{1:.{0}}", 2, 1.2345l), "1.2");
1122
1123 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"),
1124 reinterpret_cast<void*>(0xcafe), 2),
1125 format_error, "invalid format specifier");
1126 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"),
1127 reinterpret_cast<void*>(0xcafe), 2),
1128 format_error, "invalid format specifier");
1129
1130 EXPECT_EQ(fmt::format("{0:.{1}}", "str", 2), "st");
1131 }
1132
1133 TEST(format_test, format_bool) {
1134 EXPECT_EQ(fmt::format("{}", true), "true");
1135 EXPECT_EQ(fmt::format("{}", false), "false");
1136 EXPECT_EQ(fmt::format("{:d}", true), "1");
1137 EXPECT_EQ(fmt::format("{:5}", true), "true ");
1138 EXPECT_EQ(fmt::format("{:s}", true), "true");
1139 EXPECT_EQ(fmt::format("{:s}", false), "false");
1140 EXPECT_EQ(fmt::format("{:6s}", false), "false ");
1141 EXPECT_THROW_MSG((void)fmt::format(runtime("{:c}"), false), format_error,
1142 "invalid format specifier");
1143 }
1144
1145 TEST(format_test, format_short) {
1146 short s = 42;
1147 EXPECT_EQ(fmt::format("{0:d}", s), "42");
1148 unsigned short us = 42;
1149 EXPECT_EQ(fmt::format("{0:d}", us), "42");
1150 }
1151
1152 template <typename T>
1153 void check_unknown_types(const T& value, const char* types, const char*) {
1154 char format_str[buffer_size];
1155 const char* special = ".0123456789L?}";
1156 for (int i = CHAR_MIN; i <= CHAR_MAX; ++i) {
1157 char c = static_cast<char>(i);
1158 if (std::strchr(types, c) || std::strchr(special, c) || !c) continue;
1159 safe_sprintf(format_str, "{0:10%c}", c);
1160 const char* message = "invalid format specifier";
1161 EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), value),
1162 format_error, message)
1163 << format_str << " " << message;
1164 }
1165 }
1166
1167 TEST(format_test, format_int) {
1168 EXPECT_THROW_MSG((void)fmt::format(runtime("{0:v"), 42), format_error,
1169 "invalid format specifier");
1170 check_unknown_types(42, "bBdoxXnLc", "integer");
1171 EXPECT_EQ(fmt::format("{:c}", static_cast<int>('x')), "x");
1172 }
1173
1174 TEST(format_test, format_bin) {
1175 EXPECT_EQ(fmt::format("{0:b}", 0), "0");
1176 EXPECT_EQ(fmt::format("{0:b}", 42), "101010");
1177 EXPECT_EQ(fmt::format("{0:b}", 42u), "101010");
1178 EXPECT_EQ(fmt::format("{0:b}", -42), "-101010");
1179 EXPECT_EQ(fmt::format("{0:b}", 12345), "11000000111001");
1180 EXPECT_EQ(fmt::format("{0:b}", 0x12345678), "10010001101000101011001111000");
1181 EXPECT_EQ("10010000101010111100110111101111",
1182 fmt::format("{0:b}", 0x90ABCDEF));
1183 EXPECT_EQ("11111111111111111111111111111111",
1184 fmt::format("{0:b}", max_value<uint32_t>()));
1185 }
1186
1187 #if FMT_USE_INT128
1188 constexpr auto int128_max = static_cast<__int128_t>(
1189 (static_cast<__uint128_t>(1) << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1);
1190 constexpr auto int128_min = -int128_max - 1;
1191
1192 constexpr auto uint128_max = ~static_cast<__uint128_t>(0);
1193 #endif
1194
1195 TEST(format_test, format_dec) {
1196 EXPECT_EQ(fmt::format("{0}", 0), "0");
1197 EXPECT_EQ(fmt::format("{0}", 42), "42");
1198 EXPECT_EQ(fmt::format("{:}>", 42), "42>");
1199 EXPECT_EQ(fmt::format("{0:d}", 42), "42");
1200 EXPECT_EQ(fmt::format("{0}", 42u), "42");
1201 EXPECT_EQ(fmt::format("{0}", -42), "-42");
1202 EXPECT_EQ(fmt::format("{0}", 12345), "12345");
1203 EXPECT_EQ(fmt::format("{0}", 67890), "67890");
1204 #if FMT_USE_INT128
1205 EXPECT_EQ(fmt::format("{0}", static_cast<__int128_t>(0)), "0");
1206 EXPECT_EQ(fmt::format("{0}", static_cast<__uint128_t>(0)), "0");
1207 EXPECT_EQ("9223372036854775808",
1208 fmt::format("{0}", static_cast<__int128_t>(INT64_MAX) + 1));
1209 EXPECT_EQ("-9223372036854775809",
1210 fmt::format("{0}", static_cast<__int128_t>(INT64_MIN) - 1));
1211 EXPECT_EQ("18446744073709551616",
1212 fmt::format("{0}", static_cast<__int128_t>(UINT64_MAX) + 1));
1213 EXPECT_EQ("170141183460469231731687303715884105727",
1214 fmt::format("{0}", int128_max));
1215 EXPECT_EQ("-170141183460469231731687303715884105728",
1216 fmt::format("{0}", int128_min));
1217 EXPECT_EQ("340282366920938463463374607431768211455",
1218 fmt::format("{0}", uint128_max));
1219 #endif
1220
1221 char buffer[buffer_size];
1222 safe_sprintf(buffer, "%d", INT_MIN);
1223 EXPECT_EQ(buffer, fmt::format("{0}", INT_MIN));
1224 safe_sprintf(buffer, "%d", INT_MAX);
1225 EXPECT_EQ(buffer, fmt::format("{0}", INT_MAX));
1226 safe_sprintf(buffer, "%u", UINT_MAX);
1227 EXPECT_EQ(buffer, fmt::format("{0}", UINT_MAX));
1228 safe_sprintf(buffer, "%ld", 0 - static_cast<unsigned long>(LONG_MIN));
1229 EXPECT_EQ(buffer, fmt::format("{0}", LONG_MIN));
1230 safe_sprintf(buffer, "%ld", LONG_MAX);
1231 EXPECT_EQ(buffer, fmt::format("{0}", LONG_MAX));
1232 safe_sprintf(buffer, "%lu", ULONG_MAX);
1233 EXPECT_EQ(buffer, fmt::format("{0}", ULONG_MAX));
1234 }
1235
1236 TEST(format_test, format_hex) {
1237 EXPECT_EQ(fmt::format("{0:x}", 0), "0");
1238 EXPECT_EQ(fmt::format("{0:x}", 0x42), "42");
1239 EXPECT_EQ(fmt::format("{0:x}", 0x42u), "42");
1240 EXPECT_EQ(fmt::format("{0:x}", -0x42), "-42");
1241 EXPECT_EQ(fmt::format("{0:x}", 0x12345678), "12345678");
1242 EXPECT_EQ(fmt::format("{0:x}", 0x90abcdef), "90abcdef");
1243 EXPECT_EQ(fmt::format("{0:X}", 0x12345678), "12345678");
1244 EXPECT_EQ(fmt::format("{0:X}", 0x90ABCDEF), "90ABCDEF");
1245 #if FMT_USE_INT128
1246 EXPECT_EQ(fmt::format("{0:x}", static_cast<__int128_t>(0)), "0");
1247 EXPECT_EQ(fmt::format("{0:x}", static_cast<__uint128_t>(0)), "0");
1248 EXPECT_EQ("8000000000000000",
1249 fmt::format("{0:x}", static_cast<__int128_t>(INT64_MAX) + 1));
1250 EXPECT_EQ("-8000000000000001",
1251 fmt::format("{0:x}", static_cast<__int128_t>(INT64_MIN) - 1));
1252 EXPECT_EQ("10000000000000000",
1253 fmt::format("{0:x}", static_cast<__int128_t>(UINT64_MAX) + 1));
1254 EXPECT_EQ("7fffffffffffffffffffffffffffffff",
1255 fmt::format("{0:x}", int128_max));
1256 EXPECT_EQ("-80000000000000000000000000000000",
1257 fmt::format("{0:x}", int128_min));
1258 EXPECT_EQ("ffffffffffffffffffffffffffffffff",
1259 fmt::format("{0:x}", uint128_max));
1260 #endif
1261
1262 char buffer[buffer_size];
1263 safe_sprintf(buffer, "-%x", 0 - static_cast<unsigned>(INT_MIN));
1264 EXPECT_EQ(buffer, fmt::format("{0:x}", INT_MIN));
1265 safe_sprintf(buffer, "%x", INT_MAX);
1266 EXPECT_EQ(buffer, fmt::format("{0:x}", INT_MAX));
1267 safe_sprintf(buffer, "%x", UINT_MAX);
1268 EXPECT_EQ(buffer, fmt::format("{0:x}", UINT_MAX));
1269 safe_sprintf(buffer, "-%lx", 0 - static_cast<unsigned long>(LONG_MIN));
1270 EXPECT_EQ(buffer, fmt::format("{0:x}", LONG_MIN));
1271 safe_sprintf(buffer, "%lx", LONG_MAX);
1272 EXPECT_EQ(buffer, fmt::format("{0:x}", LONG_MAX));
1273 safe_sprintf(buffer, "%lx", ULONG_MAX);
1274 EXPECT_EQ(buffer, fmt::format("{0:x}", ULONG_MAX));
1275 }
1276
1277 TEST(format_test, format_oct) {
1278 EXPECT_EQ(fmt::format("{0:o}", 0), "0");
1279 EXPECT_EQ(fmt::format("{0:o}", 042), "42");
1280 EXPECT_EQ(fmt::format("{0:o}", 042u), "42");
1281 EXPECT_EQ(fmt::format("{0:o}", -042), "-42");
1282 EXPECT_EQ(fmt::format("{0:o}", 012345670), "12345670");
1283 #if FMT_USE_INT128
1284 EXPECT_EQ(fmt::format("{0:o}", static_cast<__int128_t>(0)), "0");
1285 EXPECT_EQ(fmt::format("{0:o}", static_cast<__uint128_t>(0)), "0");
1286 EXPECT_EQ("1000000000000000000000",
1287 fmt::format("{0:o}", static_cast<__int128_t>(INT64_MAX) + 1));
1288 EXPECT_EQ("-1000000000000000000001",
1289 fmt::format("{0:o}", static_cast<__int128_t>(INT64_MIN) - 1));
1290 EXPECT_EQ("2000000000000000000000",
1291 fmt::format("{0:o}", static_cast<__int128_t>(UINT64_MAX) + 1));
1292 EXPECT_EQ("1777777777777777777777777777777777777777777",
1293 fmt::format("{0:o}", int128_max));
1294 EXPECT_EQ("-2000000000000000000000000000000000000000000",
1295 fmt::format("{0:o}", int128_min));
1296 EXPECT_EQ("3777777777777777777777777777777777777777777",
1297 fmt::format("{0:o}", uint128_max));
1298 #endif
1299
1300 char buffer[buffer_size];
1301 safe_sprintf(buffer, "-%o", 0 - static_cast<unsigned>(INT_MIN));
1302 EXPECT_EQ(buffer, fmt::format("{0:o}", INT_MIN));
1303 safe_sprintf(buffer, "%o", INT_MAX);
1304 EXPECT_EQ(buffer, fmt::format("{0:o}", INT_MAX));
1305 safe_sprintf(buffer, "%o", UINT_MAX);
1306 EXPECT_EQ(buffer, fmt::format("{0:o}", UINT_MAX));
1307 safe_sprintf(buffer, "-%lo", 0 - static_cast<unsigned long>(LONG_MIN));
1308 EXPECT_EQ(buffer, fmt::format("{0:o}", LONG_MIN));
1309 safe_sprintf(buffer, "%lo", LONG_MAX);
1310 EXPECT_EQ(buffer, fmt::format("{0:o}", LONG_MAX));
1311 safe_sprintf(buffer, "%lo", ULONG_MAX);
1312 EXPECT_EQ(buffer, fmt::format("{0:o}", ULONG_MAX));
1313 }
1314
1315 TEST(format_test, format_int_locale) {
1316 EXPECT_EQ(fmt::format("{:L}", 1234), "1234");
1317 }
1318
1319 TEST(format_test, format_float) {
1320 EXPECT_EQ(fmt::format("{}", 0.0f), "0");
1321 EXPECT_EQ(fmt::format("{0:f}", 392.5f), "392.500000");
1322 }
1323
1324 TEST(format_test, format_double) {
1325 EXPECT_EQ(fmt::format("{}", 0.0), "0");
1326 check_unknown_types(1.2, "eEfFgGaAnL%", "double");
1327 EXPECT_EQ(fmt::format("{:}", 0.0), "0");
1328 EXPECT_EQ(fmt::format("{:f}", 0.0), "0.000000");
1329 EXPECT_EQ(fmt::format("{:g}", 0.0), "0");
1330 EXPECT_EQ(fmt::format("{:}", 392.65), "392.65");
1331 EXPECT_EQ(fmt::format("{:g}", 392.65), "392.65");
1332 EXPECT_EQ(fmt::format("{:G}", 392.65), "392.65");
1333 EXPECT_EQ(fmt::format("{:g}", 4.9014e6), "4.9014e+06");
1334 EXPECT_EQ(fmt::format("{:f}", 392.65), "392.650000");
1335 EXPECT_EQ(fmt::format("{:F}", 392.65), "392.650000");
1336 EXPECT_EQ(fmt::format("{:L}", 42.0), "42");
1337 EXPECT_EQ(fmt::format("{:24a}", 4.2f), " 0x1.0cccccp+2");
1338 EXPECT_EQ(fmt::format("{:24a}", 4.2), " 0x1.0cccccccccccdp+2");
1339 EXPECT_EQ(fmt::format("{:<24a}", 4.2), "0x1.0cccccccccccdp+2 ");
1340 EXPECT_EQ(fmt::format("{0:e}", 392.65), "3.926500e+02");
1341 EXPECT_EQ(fmt::format("{0:E}", 392.65), "3.926500E+02");
1342 EXPECT_EQ(fmt::format("{0:+010.4g}", 392.65), "+0000392.6");
1343
1344 #if FMT_CPLUSPLUS >= 201703L
1345 double xd = 0x1.ffffffffffp+2;
1346 EXPECT_EQ(fmt::format("{:.10a}", xd), "0x1.ffffffffffp+2");
1347 EXPECT_EQ(fmt::format("{:.9a}", xd), "0x2.000000000p+2");
1348
1349 if (std::numeric_limits<long double>::digits == 64) {
1350 auto ld = 0xf.ffffffffffp-3l;
1351 EXPECT_EQ(fmt::format("{:a}", ld), "0xf.ffffffffffp-3");
1352 EXPECT_EQ(fmt::format("{:.10a}", ld), "0xf.ffffffffffp-3");
1353 EXPECT_EQ(fmt::format("{:.9a}", ld), "0x1.000000000p+1");
1354 }
1355 #endif
1356
1357 if (fmt::detail::const_check(std::numeric_limits<double>::is_iec559)) {
1358 double d = (std::numeric_limits<double>::min)();
1359 EXPECT_EQ(fmt::format("{:a}", d), "0x1p-1022");
1360 EXPECT_EQ(fmt::format("{:#a}", d), "0x1.p-1022");
1361
1362 d = (std::numeric_limits<double>::max)();
1363 EXPECT_EQ(fmt::format("{:a}", d), "0x1.fffffffffffffp+1023");
1364
1365 d = std::numeric_limits<double>::denorm_min();
1366 EXPECT_EQ(fmt::format("{:a}", d), "0x0.0000000000001p-1022");
1367 }
1368
1369 if (std::numeric_limits<long double>::digits == 64) {
1370 auto ld = (std::numeric_limits<long double>::min)();
1371 EXPECT_EQ(fmt::format("{:a}", ld), "0x8p-16385");
1372
1373 ld = (std::numeric_limits<long double>::max)();
1374 EXPECT_EQ(fmt::format("{:a}", ld), "0xf.fffffffffffffffp+16380");
1375
1376 ld = std::numeric_limits<long double>::denorm_min();
1377 EXPECT_EQ(fmt::format("{:a}", ld), "0x0.000000000000001p-16382");
1378 }
1379
1380 EXPECT_EQ(fmt::format("{:.10a}", 4.2), "0x1.0ccccccccdp+2");
1381
1382 EXPECT_EQ(fmt::format("{:a}", -42.0), "-0x1.5p+5");
1383 EXPECT_EQ(fmt::format("{:A}", -42.0), "-0X1.5P+5");
1384
1385 EXPECT_EQ(fmt::format("{:f}", 9223372036854775807.0),
1386 "9223372036854775808.000000");
1387 }
1388
1389 TEST(format_test, precision_rounding) {
1390 EXPECT_EQ(fmt::format("{:.0f}", 0.0), "0");
1391 EXPECT_EQ(fmt::format("{:.0f}", 0.01), "0");
1392 EXPECT_EQ(fmt::format("{:.0f}", 0.1), "0");
1393 EXPECT_EQ(fmt::format("{:.3f}", 0.00049), "0.000");
1394 EXPECT_EQ(fmt::format("{:.3f}", 0.0005), "0.001");
1395 EXPECT_EQ(fmt::format("{:.3f}", 0.00149), "0.001");
1396 EXPECT_EQ(fmt::format("{:.3f}", 0.0015), "0.002");
1397 EXPECT_EQ(fmt::format("{:.3f}", 0.9999), "1.000");
1398 EXPECT_EQ(fmt::format("{:.3}", 0.00123), "0.00123");
1399 EXPECT_EQ(fmt::format("{:.16g}", 0.1), "0.1");
1400 EXPECT_EQ(fmt::format("{:.0}", 1.0), "1");
1401 EXPECT_EQ("225.51575035152063720",
1402 fmt::format("{:.17f}", 225.51575035152064));
1403 EXPECT_EQ(fmt::format("{:.1f}", -761519619559038.2), "-761519619559038.2");
1404 EXPECT_EQ("1.9156918820264798e-56",
1405 fmt::format("{}", 1.9156918820264798e-56));
1406 EXPECT_EQ(fmt::format("{:.4f}", 7.2809479766055470e-15), "0.0000");
1407 }
1408
1409 TEST(format_test, prettify_float) {
1410 EXPECT_EQ(fmt::format("{}", 1e-4), "0.0001");
1411 EXPECT_EQ(fmt::format("{}", 1e-5), "1e-05");
1412 EXPECT_EQ(fmt::format("{}", 1e15), "1000000000000000");
1413 EXPECT_EQ(fmt::format("{}", 1e16), "1e+16");
1414 EXPECT_EQ(fmt::format("{}", 9.999e-5), "9.999e-05");
1415 EXPECT_EQ(fmt::format("{}", 1e10), "10000000000");
1416 EXPECT_EQ(fmt::format("{}", 1e11), "100000000000");
1417 EXPECT_EQ(fmt::format("{}", 1234e7), "12340000000");
1418 EXPECT_EQ(fmt::format("{}", 1234e-2), "12.34");
1419 EXPECT_EQ(fmt::format("{}", 1234e-6), "0.001234");
1420 EXPECT_EQ(fmt::format("{}", 0.1f), "0.1");
1421 EXPECT_EQ(fmt::format("{}", 1.35631564e-19f), "1.3563156e-19");
1422 }
1423
1424 TEST(format_test, format_nan) {
1425 double nan = std::numeric_limits<double>::quiet_NaN();
1426 EXPECT_EQ(fmt::format("{}", nan), "nan");
1427 EXPECT_EQ(fmt::format("{:+}", nan), "+nan");
1428 EXPECT_EQ(fmt::format("{:+06}", nan), " +nan");
1429 EXPECT_EQ(fmt::format("{:<+06}", nan), "+nan ");
1430 EXPECT_EQ(fmt::format("{:^+06}", nan), " +nan ");
1431 EXPECT_EQ(fmt::format("{:>+06}", nan), " +nan");
1432 if (std::signbit(-nan)) {
1433 EXPECT_EQ(fmt::format("{}", -nan), "-nan");
1434 EXPECT_EQ(fmt::format("{:+06}", -nan), " -nan");
1435 } else {
1436 fmt::print("Warning: compiler doesn't handle negative NaN correctly");
1437 }
1438 EXPECT_EQ(fmt::format("{: }", nan), " nan");
1439 EXPECT_EQ(fmt::format("{:F}", nan), "NAN");
1440 EXPECT_EQ(fmt::format("{:<7}", nan), "nan ");
1441 EXPECT_EQ(fmt::format("{:^7}", nan), " nan ");
1442 EXPECT_EQ(fmt::format("{:>7}", nan), " nan");
1443 }
1444
1445 TEST(format_test, format_infinity) {
1446 double inf = std::numeric_limits<double>::infinity();
1447 EXPECT_EQ(fmt::format("{}", inf), "inf");
1448 EXPECT_EQ(fmt::format("{:+}", inf), "+inf");
1449 EXPECT_EQ(fmt::format("{}", -inf), "-inf");
1450 EXPECT_EQ(fmt::format("{:+06}", inf), " +inf");
1451 EXPECT_EQ(fmt::format("{:+06}", -inf), " -inf");
1452 EXPECT_EQ(fmt::format("{:<+06}", inf), "+inf ");
1453 EXPECT_EQ(fmt::format("{:^+06}", inf), " +inf ");
1454 EXPECT_EQ(fmt::format("{:>+06}", inf), " +inf");
1455 EXPECT_EQ(fmt::format("{: }", inf), " inf");
1456 EXPECT_EQ(fmt::format("{:F}", inf), "INF");
1457 EXPECT_EQ(fmt::format("{:<7}", inf), "inf ");
1458 EXPECT_EQ(fmt::format("{:^7}", inf), " inf ");
1459 EXPECT_EQ(fmt::format("{:>7}", inf), " inf");
1460 }
1461
1462 TEST(format_test, format_long_double) {
1463 EXPECT_EQ(fmt::format("{0:}", 0.0l), "0");
1464 EXPECT_EQ(fmt::format("{0:f}", 0.0l), "0.000000");
1465 EXPECT_EQ(fmt::format("{:.1f}", 0.000000001l), "0.0");
1466 EXPECT_EQ(fmt::format("{:.2f}", 0.099l), "0.10");
1467 EXPECT_EQ(fmt::format("{0:}", 392.65l), "392.65");
1468 EXPECT_EQ(fmt::format("{0:g}", 392.65l), "392.65");
1469 EXPECT_EQ(fmt::format("{0:G}", 392.65l), "392.65");
1470 EXPECT_EQ(fmt::format("{0:f}", 392.65l), "392.650000");
1471 EXPECT_EQ(fmt::format("{0:F}", 392.65l), "392.650000");
1472 char buffer[buffer_size];
1473 safe_sprintf(buffer, "%Le", 392.65l);
1474 EXPECT_EQ(buffer, fmt::format("{0:e}", 392.65l));
1475 EXPECT_EQ(fmt::format("{0:+010.4g}", 392.64l), "+0000392.6");
1476
1477 auto ld = 3.31l;
1478 if (fmt::detail::is_double_double<decltype(ld)>::value) {
1479 safe_sprintf(buffer, "%a", static_cast<double>(ld));
1480 EXPECT_EQ(buffer, fmt::format("{:a}", ld));
1481 } else if (std::numeric_limits<long double>::digits == 64) {
1482 EXPECT_EQ(fmt::format("{:a}", ld), "0xd.3d70a3d70a3d70ap-2");
1483 }
1484 }
1485
1486 TEST(format_test, format_char) {
1487 const char types[] = "cbBdoxX";
1488 check_unknown_types('a', types, "char");
1489 EXPECT_EQ(fmt::format("{0}", 'a'), "a");
1490 EXPECT_EQ(fmt::format("{0:c}", 'z'), "z");
1491 int n = 'x';
1492 for (const char* type = types + 1; *type; ++type) {
1493 std::string format_str = fmt::format("{{:{}}}", *type);
1494 EXPECT_EQ(fmt::format(runtime(format_str), n),
1495 fmt::format(runtime(format_str), 'x'))
1496 << format_str;
1497 }
1498 EXPECT_EQ(fmt::format("{:02X}", n), fmt::format("{:02X}", 'x'));
1499
1500 EXPECT_EQ(fmt::format("{}", '\n'), "\n");
1501 EXPECT_EQ(fmt::format("{:?}", '\n'), "'\\n'");
1502 EXPECT_EQ(fmt::format("{:x}", '\xff'), "ff");
1503 }
1504
1505 TEST(format_test, format_volatile_char) {
1506 volatile char c = 'x';
1507 EXPECT_EQ(fmt::format("{}", c), "x");
1508 }
1509
1510 TEST(format_test, format_unsigned_char) {
1511 EXPECT_EQ(fmt::format("{}", static_cast<unsigned char>(42)), "42");
1512 EXPECT_EQ(fmt::format("{}", static_cast<uint8_t>(42)), "42");
1513 }
1514
1515 TEST(format_test, format_cstring) {
1516 check_unknown_types("test", "sp", "string");
1517 EXPECT_EQ(fmt::format("{0}", "test"), "test");
1518 EXPECT_EQ(fmt::format("{0:s}", "test"), "test");
1519 char nonconst[] = "nonconst";
1520 EXPECT_EQ(fmt::format("{0}", nonconst), "nonconst");
1521 auto nullstr = static_cast<const char*>(nullptr);
1522 EXPECT_THROW_MSG((void)fmt::format("{}", nullstr), format_error,
1523 "string pointer is null");
1524 EXPECT_THROW_MSG((void)fmt::format("{:s}", nullstr), format_error,
1525 "string pointer is null");
1526 }
1527
1528 void function_pointer_test(int, double, std::string) {}
1529
1530 TEST(format_test, format_pointer) {
1531 check_unknown_types(reinterpret_cast<void*>(0x1234), "p", "pointer");
1532 EXPECT_EQ(fmt::format("{0}", static_cast<void*>(nullptr)), "0x0");
1533 EXPECT_EQ(fmt::format("{0}", reinterpret_cast<void*>(0x1234)), "0x1234");
1534 EXPECT_EQ(fmt::format("{0:p}", reinterpret_cast<void*>(0x1234)), "0x1234");
1535 // On CHERI (or other fat-pointer) systems, the size of a pointer is greater
1536 // than the size an integer that can hold a virtual address. There is no
1537 // portable address-as-an-integer type (yet) in C++, so we use `size_t` as
1538 // the closest equivalent for now.
1539 EXPECT_EQ("0x" + std::string(sizeof(size_t) * CHAR_BIT / 4, 'f'),
1540 fmt::format("{0}", reinterpret_cast<void*>(~uintptr_t())));
1541 EXPECT_EQ("0x1234",
1542 fmt::format("{}", fmt::ptr(reinterpret_cast<int*>(0x1234))));
1543 std::unique_ptr<int> up(new int(1));
1544 EXPECT_EQ(fmt::format("{}", fmt::ptr(up.get())),
1545 fmt::format("{}", fmt::ptr(up)));
1546 struct custom_deleter {
1547 void operator()(int* p) const { delete p; }
1548 };
1549 std::unique_ptr<int, custom_deleter> upcd(new int(1));
1550 EXPECT_EQ(fmt::format("{}", fmt::ptr(upcd.get())),
1551 fmt::format("{}", fmt::ptr(upcd)));
1552 std::shared_ptr<int> sp(new int(1));
1553 EXPECT_EQ(fmt::format("{}", fmt::ptr(sp.get())),
1554 fmt::format("{}", fmt::ptr(sp)));
1555 EXPECT_EQ(fmt::format("{}", fmt::detail::bit_cast<const void*>(
1556 &function_pointer_test)),
1557 fmt::format("{}", fmt::ptr(function_pointer_test)));
1558 EXPECT_EQ(fmt::format("{}", nullptr), "0x0");
1559 }
1560
1561 TEST(format_test, write_uintptr_fallback) {
1562 // Test that formatting a pointer by converting it to uint128_fallback works.
1563 // This is needed to support systems without uintptr_t.
1564 auto s = std::string();
1565 fmt::detail::write_ptr<char>(
1566 std::back_inserter(s),
1567 fmt::detail::bit_cast<fmt::detail::uint128_fallback>(
1568 reinterpret_cast<void*>(0xface)),
1569 nullptr);
1570 EXPECT_EQ(s, "0xface");
1571 }
1572
1573 enum class color { red, green, blue };
1574
1575 namespace test_ns {
1576 enum class color { red, green, blue };
1577 using fmt::enums::format_as;
1578 } // namespace test_ns
1579
1580 TEST(format_test, format_enum_class) {
1581 EXPECT_EQ(fmt::format("{}", fmt::underlying(color::red)), "0");
1582 EXPECT_EQ(fmt::format("{}", test_ns::color::red), "0");
1583 }
1584
1585 TEST(format_test, format_string) {
1586 EXPECT_EQ(fmt::format("{0}", std::string("test")), "test");
1587 EXPECT_EQ(fmt::format("{0}", std::string("test")), "test");
1588 EXPECT_EQ(fmt::format("{:?}", std::string("test")), "\"test\"");
1589 EXPECT_EQ(fmt::format("{:*^10?}", std::string("test")), "**\"test\"**");
1590 EXPECT_EQ(fmt::format("{:?}", std::string("\test")), "\"\\test\"");
1591 EXPECT_THROW((void)fmt::format(fmt::runtime("{:x}"), std::string("test")),
1592 fmt::format_error);
1593 }
1594
1595 TEST(format_test, format_string_view) {
1596 EXPECT_EQ(fmt::format("{}", string_view("test")), "test");
1597 EXPECT_EQ(fmt::format("{:?}", string_view("t\nst")), "\"t\\nst\"");
1598 EXPECT_EQ(fmt::format("{}", string_view()), "");
1599 }
1600
1601 #ifdef FMT_USE_STRING_VIEW
1602 struct string_viewable {};
1603
1604 FMT_BEGIN_NAMESPACE
1605 template <> struct formatter<string_viewable> : formatter<std::string_view> {
1606 auto format(string_viewable, format_context& ctx) -> decltype(ctx.out()) {
1607 return formatter<std::string_view>::format("foo", ctx);
1608 }
1609 };
1610 FMT_END_NAMESPACE
1611
1612 TEST(format_test, format_std_string_view) {
1613 EXPECT_EQ(fmt::format("{}", std::string_view("test")), "test");
1614 EXPECT_EQ(fmt::format("{}", string_viewable()), "foo");
1615 }
1616
1617 struct explicitly_convertible_to_std_string_view {
1618 explicit operator std::string_view() const { return "foo"; }
1619 };
1620
1621 template <>
1622 struct fmt::formatter<explicitly_convertible_to_std_string_view>
1623 : formatter<std::string_view> {
1624 auto format(explicitly_convertible_to_std_string_view v, format_context& ctx)
1625 -> decltype(ctx.out()) {
1626 return fmt::format_to(ctx.out(), "'{}'", std::string_view(v));
1627 }
1628 };
1629
1630 TEST(format_test, format_explicitly_convertible_to_std_string_view) {
1631 EXPECT_EQ("'foo'",
1632 fmt::format("{}", explicitly_convertible_to_std_string_view()));
1633 }
1634 #endif
1635
1636 class Answer {};
1637
1638 FMT_BEGIN_NAMESPACE
1639 template <> struct formatter<date> {
1640 template <typename ParseContext>
1641 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
1642 auto it = ctx.begin();
1643 if (it != ctx.end() && *it == 'd') ++it;
1644 return it;
1645 }
1646
1647 auto format(const date& d, format_context& ctx) -> decltype(ctx.out()) {
1648 // Namespace-qualify to avoid ambiguity with std::format_to.
1649 fmt::format_to(ctx.out(), "{}-{}-{}", d.year(), d.month(), d.day());
1650 return ctx.out();
1651 }
1652 };
1653
1654 template <> struct formatter<Answer> : formatter<int> {
1655 template <typename FormatContext>
1656 auto format(Answer, FormatContext& ctx) -> decltype(ctx.out()) {
1657 return formatter<int>::format(42, ctx);
1658 }
1659 };
1660 FMT_END_NAMESPACE
1661
1662 TEST(format_test, format_custom) {
1663 EXPECT_THROW_MSG((void)fmt::format(runtime("{:s}"), date(2012, 12, 9)),
1664 format_error, "unknown format specifier");
1665 EXPECT_EQ(fmt::format("{0}", Answer()), "42");
1666 EXPECT_EQ(fmt::format("{:04}", Answer()), "0042");
1667 }
1668
1669 TEST(format_test, format_to_custom) {
1670 char buf[10] = {};
1671 auto end = fmt::format_to(buf, "{}", Answer());
1672 EXPECT_EQ(end, buf + 2);
1673 EXPECT_STREQ(buf, "42");
1674 }
1675
1676 TEST(format_test, format_string_from_speed_test) {
1677 EXPECT_EQ("1.2340000000:0042:+3.13:str:0x3e8:X:%",
1678 fmt::format("{0:0.10f}:{1:04}:{2:+g}:{3}:{4}:{5}:%", 1.234, 42,
1679 3.13, "str", reinterpret_cast<void*>(1000), 'X'));
1680 }
1681
1682 TEST(format_test, format_examples) {
1683 std::string message = fmt::format("The answer is {}", 42);
1684 EXPECT_EQ("The answer is 42", message);
1685
1686 EXPECT_EQ(fmt::format("{}", 42), "42");
1687
1688 memory_buffer out;
1689 fmt::format_to(std::back_inserter(out), "The answer is {}.", 42);
1690 EXPECT_EQ("The answer is 42.", to_string(out));
1691
1692 const char* filename = "nonexistent";
1693 FILE* ftest = safe_fopen(filename, "r");
1694 if (ftest) fclose(ftest);
1695 int error_code = errno;
1696 EXPECT_TRUE(ftest == nullptr);
1697 EXPECT_SYSTEM_ERROR(
1698 {
1699 FILE* f = safe_fopen(filename, "r");
1700 if (!f)
1701 throw fmt::system_error(errno, "Cannot open file '{}'", filename);
1702 fclose(f);
1703 },
1704 error_code, "Cannot open file 'nonexistent'");
1705
1706 EXPECT_EQ("First, thou shalt count to three",
1707 fmt::format("First, thou shalt count to {0}", "three"));
1708 EXPECT_EQ(fmt::format("Bring me a {}", "shrubbery"), "Bring me a shrubbery");
1709 EXPECT_EQ(fmt::format("From {} to {}", 1, 3), "From 1 to 3");
1710
1711 char buffer[buffer_size];
1712 safe_sprintf(buffer, "%03.2f", -1.2);
1713 EXPECT_EQ(buffer, fmt::format("{:03.2f}", -1.2));
1714
1715 EXPECT_EQ(fmt::format("{0}, {1}, {2}", 'a', 'b', 'c'), "a, b, c");
1716 EXPECT_EQ(fmt::format("{}, {}, {}", 'a', 'b', 'c'), "a, b, c");
1717 EXPECT_EQ(fmt::format("{2}, {1}, {0}", 'a', 'b', 'c'), "c, b, a");
1718 EXPECT_EQ(fmt::format("{0}{1}{0}", "abra", "cad"), "abracadabra");
1719
1720 EXPECT_EQ("left aligned ",
1721 fmt::format("{:<30}", "left aligned"));
1722 EXPECT_EQ(" right aligned",
1723 fmt::format("{:>30}", "right aligned"));
1724 EXPECT_EQ(" centered ",
1725 fmt::format("{:^30}", "centered"));
1726 EXPECT_EQ("***********centered***********",
1727 fmt::format("{:*^30}", "centered"));
1728
1729 EXPECT_EQ(fmt::format("{:+f}; {:+f}", 3.14, -3.14), "+3.140000; -3.140000");
1730 EXPECT_EQ(fmt::format("{: f}; {: f}", 3.14, -3.14), " 3.140000; -3.140000");
1731 EXPECT_EQ(fmt::format("{:-f}; {:-f}", 3.14, -3.14), "3.140000; -3.140000");
1732
1733 EXPECT_EQ("int: 42; hex: 2a; oct: 52",
1734 fmt::format("int: {0:d}; hex: {0:x}; oct: {0:o}", 42));
1735 EXPECT_EQ("int: 42; hex: 0x2a; oct: 052",
1736 fmt::format("int: {0:d}; hex: {0:#x}; oct: {0:#o}", 42));
1737
1738 EXPECT_EQ(fmt::format("The answer is {}", 42), "The answer is 42");
1739 EXPECT_THROW_MSG(
1740 (void)fmt::format(runtime("The answer is {:d}"), "forty-two"),
1741 format_error, "invalid format specifier");
1742
1743 EXPECT_WRITE(
1744 stdout, fmt::print("{}", std::numeric_limits<double>::infinity()), "inf");
1745 }
1746
1747 TEST(format_test, print) {
1748 EXPECT_WRITE(stdout, fmt::print("Don't {}!", "panic"), "Don't panic!");
1749 EXPECT_WRITE(stderr, fmt::print(stderr, "Don't {}!", "panic"),
1750 "Don't panic!");
1751 EXPECT_WRITE(stdout, fmt::println("Don't {}!", "panic"), "Don't panic!\n");
1752 EXPECT_WRITE(stderr, fmt::println(stderr, "Don't {}!", "panic"),
1753 "Don't panic!\n");
1754 }
1755
1756 TEST(format_test, variadic) {
1757 EXPECT_EQ(fmt::format("{}c{}", "ab", 1), "abc1");
1758 }
1759
1760 TEST(format_test, bytes) {
1761 auto s = fmt::format("{:10}", fmt::bytes("ёжик"));
1762 EXPECT_EQ("ёжик ", s);
1763 EXPECT_EQ(10, s.size());
1764 }
1765
1766 TEST(format_test, group_digits_view) {
1767 EXPECT_EQ(fmt::format("{}", fmt::group_digits(10000000)), "10,000,000");
1768 EXPECT_EQ(fmt::format("{:8}", fmt::group_digits(1000)), " 1,000");
1769 }
1770
1771 #ifdef __cpp_generic_lambdas
1772 struct point {
1773 double x, y;
1774 };
1775
1776 FMT_BEGIN_NAMESPACE
1777 template <> struct formatter<point> : nested_formatter<double> {
1778 auto format(point p, format_context& ctx) const -> decltype(ctx.out()) {
1779 return write_padded(ctx, [this, p](auto out) -> decltype(out) {
1780 return fmt::format_to(out, "({}, {})", nested(p.x), nested(p.y));
1781 });
1782 }
1783 };
1784 FMT_END_NAMESPACE
1785
1786 TEST(format_test, nested_formatter) {
1787 EXPECT_EQ(fmt::format("{:>16.2f}", point{1, 2}), " (1.00, 2.00)");
1788 }
1789 #endif // __cpp_generic_lambdas
1790
1791 enum test_enum { foo, bar };
1792 auto format_as(test_enum e) -> int { return e; }
1793
1794 TEST(format_test, join) {
1795 using fmt::join;
1796 int v1[3] = {1, 2, 3};
1797 auto v2 = std::vector<float>();
1798 v2.push_back(1.2f);
1799 v2.push_back(3.4f);
1800 void* v3[2] = {&v1[0], &v1[1]};
1801
1802 EXPECT_EQ(fmt::format("({})", join(v1, v1 + 3, ", ")), "(1, 2, 3)");
1803 EXPECT_EQ(fmt::format("({})", join(v1, v1 + 1, ", ")), "(1)");
1804 EXPECT_EQ(fmt::format("({})", join(v1, v1, ", ")), "()");
1805 EXPECT_EQ(fmt::format("({:03})", join(v1, v1 + 3, ", ")), "(001, 002, 003)");
1806 EXPECT_EQ("(+01.20, +03.40)",
1807 fmt::format("({:+06.2f})", join(v2.begin(), v2.end(), ", ")));
1808
1809 EXPECT_EQ(fmt::format("{0:{1}}", join(v1, v1 + 3, ", "), 1), "1, 2, 3");
1810
1811 EXPECT_EQ(fmt::format("{}, {}", v3[0], v3[1]),
1812 fmt::format("{}", join(v3, v3 + 2, ", ")));
1813
1814 EXPECT_EQ(fmt::format("({})", join(v1, ", ")), "(1, 2, 3)");
1815 EXPECT_EQ(fmt::format("({:+06.2f})", join(v2, ", ")), "(+01.20, +03.40)");
1816
1817 auto v4 = std::vector<test_enum>{foo, bar, foo};
1818 EXPECT_EQ(fmt::format("{}", join(v4, " ")), "0 1 0");
1819 }
1820
1821 #ifdef __cpp_lib_byte
1822 TEST(format_test, join_bytes) {
1823 auto v = std::vector<std::byte>{std::byte(1), std::byte(2), std::byte(3)};
1824 EXPECT_EQ(fmt::format("{}", fmt::join(v, ", ")), "1, 2, 3");
1825 }
1826 #endif
1827
1828 std::string vformat_message(int id, const char* format, fmt::format_args args) {
1829 auto buffer = fmt::memory_buffer();
1830 fmt::format_to(fmt::appender(buffer), "[{}] ", id);
1831 vformat_to(fmt::appender(buffer), format, args);
1832 return to_string(buffer);
1833 }
1834
1835 template <typename... Args>
1836 std::string format_message(int id, const char* format, const Args&... args) {
1837 auto va = fmt::make_format_args(args...);
1838 return vformat_message(id, format, va);
1839 }
1840
1841 TEST(format_test, format_message_example) {
1842 EXPECT_EQ("[42] something happened",
1843 format_message(42, "{} happened", "something"));
1844 }
1845
1846 template <typename... Args>
1847 void print_error(const char* file, int line, const char* format,
1848 const Args&... args) {
1849 fmt::print("{}: {}: ", file, line);
1850 fmt::print(format, args...);
1851 }
1852
1853 TEST(format_test, unpacked_args) {
1854 EXPECT_EQ("0123456789abcdefg",
1855 fmt::format("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 0, 1, 2, 3, 4, 5,
1856 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g'));
1857 }
1858
1859 constexpr char with_null[3] = {'{', '}', '\0'};
1860 constexpr char no_null[2] = {'{', '}'};
1861 static constexpr const char static_with_null[3] = {'{', '}', '\0'};
1862 static constexpr const char static_no_null[2] = {'{', '}'};
1863
1864 TEST(format_test, compile_time_string) {
1865 EXPECT_EQ(fmt::format(FMT_STRING("foo")), "foo");
1866 EXPECT_EQ(fmt::format(FMT_STRING("{}"), 42), "42");
1867
1868 #if FMT_USE_NONTYPE_TEMPLATE_ARGS
1869 using namespace fmt::literals;
1870 EXPECT_EQ("foobar", fmt::format(FMT_STRING("{foo}{bar}"), "bar"_a = "bar",
1871 "foo"_a = "foo"));
1872 EXPECT_EQ(fmt::format(FMT_STRING("")), "");
1873 EXPECT_EQ(fmt::format(FMT_STRING(""), "arg"_a = 42), "");
1874 EXPECT_EQ(fmt::format(FMT_STRING("{answer}"), "answer"_a = Answer()), "42");
1875 EXPECT_EQ(fmt::format(FMT_STRING("{} {two}"), 1, "two"_a = 2), "1 2");
1876 #endif
1877
1878 (void)static_with_null;
1879 (void)static_no_null;
1880 #ifndef _MSC_VER
1881 EXPECT_EQ(fmt::format(FMT_STRING(static_with_null), 42), "42");
1882 EXPECT_EQ(fmt::format(FMT_STRING(static_no_null), 42), "42");
1883 #endif
1884
1885 (void)with_null;
1886 (void)no_null;
1887 #if FMT_CPLUSPLUS >= 201703L
1888 EXPECT_EQ(fmt::format(FMT_STRING(with_null), 42), "42");
1889 EXPECT_EQ(fmt::format(FMT_STRING(no_null), 42), "42");
1890 #endif
1891 #if defined(FMT_USE_STRING_VIEW) && FMT_CPLUSPLUS >= 201703L
1892 EXPECT_EQ(fmt::format(FMT_STRING(std::string_view("{}")), 42), "42");
1893 #endif
1894 }
1895
1896 TEST(format_test, custom_format_compile_time_string) {
1897 EXPECT_EQ(fmt::format(FMT_STRING("{}"), Answer()), "42");
1898 auto answer = Answer();
1899 EXPECT_EQ(fmt::format(FMT_STRING("{}"), answer), "42");
1900 char buf[10] = {};
1901 fmt::format_to(buf, FMT_STRING("{}"), answer);
1902 const Answer const_answer = Answer();
1903 EXPECT_EQ(fmt::format(FMT_STRING("{}"), const_answer), "42");
1904 }
1905
1906 #if FMT_USE_USER_DEFINED_LITERALS
1907 TEST(format_test, named_arg_udl) {
1908 using namespace fmt::literals;
1909 auto udl_a = fmt::format("{first}{second}{first}{third}", "first"_a = "abra",
1910 "second"_a = "cad", "third"_a = 99);
1911 EXPECT_EQ(
1912 fmt::format("{first}{second}{first}{third}", fmt::arg("first", "abra"),
1913 fmt::arg("second", "cad"), fmt::arg("third", 99)),
1914 udl_a);
1915
1916 EXPECT_EQ(fmt::format("{answer}", "answer"_a = Answer()), "42");
1917 }
1918 #endif // FMT_USE_USER_DEFINED_LITERALS
1919
1920 TEST(format_test, enum) { EXPECT_EQ(fmt::format("{}", foo), "0"); }
1921
1922 TEST(format_test, formatter_not_specialized) {
1923 static_assert(!fmt::has_formatter<fmt::formatter<test_enum>,
1924 fmt::format_context>::value,
1925 "");
1926 }
1927
1928 #if FMT_HAS_FEATURE(cxx_strong_enums)
1929 enum big_enum : unsigned long long { big_enum_value = 5000000000ULL };
1930 auto format_as(big_enum e) -> unsigned long long { return e; }
1931
1932 TEST(format_test, strong_enum) {
1933 EXPECT_EQ(fmt::format("{}", big_enum_value), "5000000000");
1934 }
1935 #endif
1936
1937 TEST(format_test, non_null_terminated_format_string) {
1938 EXPECT_EQ(fmt::format(string_view("{}foo", 2), 42), "42");
1939 }
1940
1941 namespace adl_test {
1942 namespace fmt {
1943 namespace detail {
1944 struct foo {};
1945 template <typename, typename OutputIt> void write(OutputIt, foo) = delete;
1946 } // namespace detail
1947 } // namespace fmt
1948 } // namespace adl_test
1949
1950 FMT_BEGIN_NAMESPACE
1951 template <>
1952 struct formatter<adl_test::fmt::detail::foo> : formatter<std::string> {
1953 auto format(adl_test::fmt::detail::foo, format_context& ctx)
1954 -> decltype(ctx.out()) {
1955 return formatter<std::string>::format("foo", ctx);
1956 }
1957 };
1958 FMT_END_NAMESPACE
1959
1960 TEST(format_test, to_string) {
1961 EXPECT_EQ(fmt::to_string(42), "42");
1962 EXPECT_EQ(fmt::to_string(reinterpret_cast<void*>(0x1234)), "0x1234");
1963 EXPECT_EQ(fmt::to_string(adl_test::fmt::detail::foo()), "foo");
1964 EXPECT_EQ(fmt::to_string(foo), "0");
1965
1966 #if FMT_USE_FLOAT128
1967 EXPECT_EQ(fmt::to_string(__float128(0.5)), "0.5");
1968 #endif
1969
1970 #if defined(FMT_USE_STRING_VIEW) && FMT_CPLUSPLUS >= 201703L
1971 EXPECT_EQ(fmt::to_string(std::string_view()), "");
1972 #endif
1973 }
1974
1975 TEST(format_test, output_iterators) {
1976 std::list<char> out;
1977 fmt::format_to(std::back_inserter(out), "{}", 42);
1978 EXPECT_EQ("42", std::string(out.begin(), out.end()));
1979 std::stringstream s;
1980 fmt::format_to(std::ostream_iterator<char>(s), "{}", 42);
1981 EXPECT_EQ("42", s.str());
1982 }
1983
1984 TEST(format_test, formatted_size) {
1985 EXPECT_EQ(2u, fmt::formatted_size("{}", 42));
1986 EXPECT_EQ(2u, fmt::formatted_size(std::locale(), "{}", 42));
1987 }
1988
1989 TEST(format_test, format_to_no_args) {
1990 std::string s;
1991 fmt::format_to(std::back_inserter(s), "test");
1992 EXPECT_EQ("test", s);
1993 }
1994
1995 TEST(format_test, format_to) {
1996 std::string s;
1997 fmt::format_to(std::back_inserter(s), "part{0}", 1);
1998 EXPECT_EQ("part1", s);
1999 fmt::format_to(std::back_inserter(s), "part{0}", 2);
2000 EXPECT_EQ("part1part2", s);
2001 }
2002
2003 TEST(format_test, format_to_memory_buffer) {
2004 auto buf = fmt::basic_memory_buffer<char, 100>();
2005 fmt::format_to(fmt::appender(buf), "{}", "foo");
2006 EXPECT_EQ("foo", to_string(buf));
2007 }
2008
2009 TEST(format_test, format_to_vector) {
2010 std::vector<char> v;
2011 fmt::format_to(std::back_inserter(v), "{}", "foo");
2012 EXPECT_EQ(string_view(v.data(), v.size()), "foo");
2013 }
2014
2015 struct nongrowing_container {
2016 using value_type = char;
2017 void push_back(char) { throw std::runtime_error("can't take it any more"); }
2018 };
2019
2020 TEST(format_test, format_to_propagates_exceptions) {
2021 auto c = nongrowing_container();
2022 EXPECT_THROW(fmt::format_to(std::back_inserter(c), "{}", 42),
2023 std::runtime_error);
2024 }
2025
2026 TEST(format_test, format_to_n) {
2027 char buffer[4];
2028 buffer[3] = 'x';
2029 auto result = fmt::format_to_n(buffer, 3, "{}", 12345);
2030 EXPECT_EQ(5u, result.size);
2031 EXPECT_EQ(buffer + 3, result.out);
2032 EXPECT_EQ("123x", fmt::string_view(buffer, 4));
2033
2034 result = fmt::format_to_n(buffer, 3, "{:s}", "foobar");
2035 EXPECT_EQ(6u, result.size);
2036 EXPECT_EQ(buffer + 3, result.out);
2037 EXPECT_EQ("foox", fmt::string_view(buffer, 4));
2038
2039 buffer[0] = 'x';
2040 buffer[1] = 'x';
2041 buffer[2] = 'x';
2042 result = fmt::format_to_n(buffer, 3, "{}", 'A');
2043 EXPECT_EQ(1u, result.size);
2044 EXPECT_EQ(buffer + 1, result.out);
2045 EXPECT_EQ("Axxx", fmt::string_view(buffer, 4));
2046
2047 result = fmt::format_to_n(buffer, 3, "{}{} ", 'B', 'C');
2048 EXPECT_EQ(3u, result.size);
2049 EXPECT_EQ(buffer + 3, result.out);
2050 EXPECT_EQ("BC x", fmt::string_view(buffer, 4));
2051
2052 result = fmt::format_to_n(buffer, 4, "{}", "ABCDE");
2053 EXPECT_EQ(5u, result.size);
2054 EXPECT_EQ("ABCD", fmt::string_view(buffer, 4));
2055
2056 buffer[3] = 'x';
2057 result = fmt::format_to_n(buffer, 3, "{}", std::string(1000, '*'));
2058 EXPECT_EQ(1000u, result.size);
2059 EXPECT_EQ("***x", fmt::string_view(buffer, 4));
2060 }
2061
2062 struct test_output_iterator {
2063 char* data;
2064
2065 using iterator_category = std::output_iterator_tag;
2066 using value_type = void;
2067 using difference_type = void;
2068 using pointer = void;
2069 using reference = void;
2070
2071 auto operator++() -> test_output_iterator& {
2072 ++data;
2073 return *this;
2074 }
2075 auto operator++(int) -> test_output_iterator {
2076 auto tmp = *this;
2077 ++data;
2078 return tmp;
2079 }
2080 auto operator*() -> char& { return *data; }
2081 };
2082
2083 TEST(format_test, format_to_n_output_iterator) {
2084 char buf[10] = {};
2085 fmt::format_to_n(test_output_iterator{buf}, 10, "{}", 42);
2086 EXPECT_STREQ(buf, "42");
2087 }
2088
2089 TEST(format_test, vformat_to) {
2090 using context = fmt::format_context;
2091 int n = 42;
2092 auto args = fmt::make_format_args<context>(n);
2093 auto s = std::string();
2094 fmt::vformat_to(std::back_inserter(s), "{}", args);
2095 EXPECT_EQ(s, "42");
2096 s.clear();
2097 fmt::vformat_to(std::back_inserter(s), FMT_STRING("{}"), args);
2098 EXPECT_EQ(s, "42");
2099 }
2100
2101 TEST(format_test, char_traits_not_ambiguous) {
2102 // Test that we don't inject detail names into the std namespace.
2103 using namespace std;
2104 auto c = char_traits<char>::char_type();
2105 (void)c;
2106 #if FMT_CPLUSPLUS >= 201103L
2107 auto s = std::string();
2108 auto lval = begin(s);
2109 (void)lval;
2110 #endif
2111 }
2112
2113 struct check_back_appender {};
2114
2115 FMT_BEGIN_NAMESPACE
2116 template <> struct formatter<check_back_appender> {
2117 FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
2118 return ctx.begin();
2119 }
2120
2121 template <typename Context>
2122 auto format(check_back_appender, Context& ctx) -> decltype(ctx.out()) {
2123 auto out = ctx.out();
2124 static_assert(std::is_same<decltype(++out), decltype(out)&>::value,
2125 "needs to satisfy weakly_incrementable");
2126 *out = 'y';
2127 return ++out;
2128 }
2129 };
2130 FMT_END_NAMESPACE
2131
2132 TEST(format_test, back_insert_slicing) {
2133 EXPECT_EQ(fmt::format("{}", check_back_appender{}), "y");
2134 }
2135
2136 namespace test {
2137 enum class scoped_enum_as_int {};
2138 auto format_as(scoped_enum_as_int) -> int { return 42; }
2139
2140 enum class scoped_enum_as_string_view {};
2141 auto format_as(scoped_enum_as_string_view) -> fmt::string_view { return "foo"; }
2142
2143 enum class scoped_enum_as_string {};
2144 auto format_as(scoped_enum_as_string) -> std::string { return "foo"; }
2145
2146 struct struct_as_int {};
2147 auto format_as(struct_as_int) -> int { return 42; }
2148
2149 struct struct_as_const_reference {
2150 const std::string name = "foo";
2151 };
2152 auto format_as(const struct_as_const_reference& s) -> const std::string& {
2153 return s.name;
2154 }
2155 } // namespace test
2156
2157 TEST(format_test, format_as) {
2158 EXPECT_EQ(fmt::format("{}", test::scoped_enum_as_int()), "42");
2159 EXPECT_EQ(fmt::format("{}", test::scoped_enum_as_string_view()), "foo");
2160 EXPECT_EQ(fmt::format("{}", test::scoped_enum_as_string()), "foo");
2161 EXPECT_EQ(fmt::format("{}", test::struct_as_int()), "42");
2162 EXPECT_EQ(fmt::format("{}", test::struct_as_const_reference()), "foo");
2163 }
2164
2165 TEST(format_test, format_as_to_string) {
2166 EXPECT_EQ(fmt::to_string(test::scoped_enum_as_int()), "42");
2167 EXPECT_EQ(fmt::to_string(test::scoped_enum_as_string_view()), "foo");
2168 EXPECT_EQ(fmt::to_string(test::scoped_enum_as_string()), "foo");
2169 EXPECT_EQ(fmt::to_string(test::struct_as_int()), "42");
2170 }
2171
2172 template <typename Char, typename T> auto check_enabled_formatter() -> bool {
2173 static_assert(std::is_default_constructible<fmt::formatter<T, Char>>::value,
2174 "");
2175 return true;
2176 }
2177
2178 template <typename Char, typename... T> void check_enabled_formatters() {
2179 auto dummy = {check_enabled_formatter<Char, T>()...};
2180 (void)dummy;
2181 }
2182
2183 TEST(format_test, test_formatters_enabled) {
2184 check_enabled_formatters<char, bool, char, signed char, unsigned char, short,
2185 unsigned short, int, unsigned, long, unsigned long,
2186 long long, unsigned long long, float, double,
2187 long double, void*, const void*, char*, const char*,
2188 std::string, std::nullptr_t>();
2189 check_enabled_formatters<wchar_t, bool, wchar_t, signed char, unsigned char,
2190 short, unsigned short, int, unsigned, long,
2191 unsigned long, long long, unsigned long long, float,
2192 double, long double, void*, const void*, wchar_t*,
2193 const wchar_t*, std::wstring, std::nullptr_t>();
2194 }
2195
2196 TEST(format_int_test, data) {
2197 fmt::format_int format_int(42);
2198 EXPECT_EQ(std::string(format_int.data(), format_int.size()), "42");
2199 }
2200
2201 TEST(format_int_test, format_int) {
2202 EXPECT_EQ(fmt::format_int(42).str(), "42");
2203 EXPECT_EQ(fmt::format_int(42).size(), 2u);
2204 EXPECT_EQ(fmt::format_int(-42).str(), "-42");
2205 EXPECT_EQ(fmt::format_int(-42).size(), 3u);
2206 EXPECT_EQ(fmt::format_int(42ul).str(), "42");
2207 EXPECT_EQ(fmt::format_int(-42l).str(), "-42");
2208 EXPECT_EQ(fmt::format_int(42ull).str(), "42");
2209 EXPECT_EQ(fmt::format_int(-42ll).str(), "-42");\
2210 EXPECT_EQ(fmt::format_int(max_value<int64_t>()).str(),
2211 std::to_string(max_value<int64_t>()));
2212 }
2213
2214 #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
2215
2216 # include <locale>
2217
2218 class format_facet : public fmt::format_facet<std::locale> {
2219 protected:
2220 struct int_formatter {
2221 fmt::appender out;
2222
2223 template <typename T, FMT_ENABLE_IF(fmt::detail::is_integer<T>::value)>
2224 auto operator()(T value) -> bool {
2225 fmt::format_to(out, "[{}]", value);
2226 return true;
2227 }
2228
2229 template <typename T, FMT_ENABLE_IF(!fmt::detail::is_integer<T>::value)>
2230 auto operator()(T) -> bool {
2231 return false;
2232 }
2233 };
2234
2235 auto do_put(fmt::appender out, fmt::loc_value val,
2236 const fmt::format_specs<>&) const -> bool override;
2237 };
2238
2239 auto format_facet::do_put(fmt::appender out, fmt::loc_value val,
2240 const fmt::format_specs<>&) const -> bool {
2241 return val.visit(int_formatter{out});
2242 }
2243
2244 TEST(format_test, format_facet) {
2245 auto loc = std::locale(std::locale(), new format_facet());
2246 EXPECT_EQ(fmt::format(loc, "{:L}", 42), "[42]");
2247 EXPECT_EQ(fmt::format(loc, "{:L}", -42), "[-42]");
2248 }
2249
2250 TEST(format_test, format_facet_separator) {
2251 // U+2019 RIGHT SINGLE QUOTATION MARK is a digit separator in the de_CH
2252 // locale.
2253 auto loc =
2254 std::locale({}, new fmt::format_facet<std::locale>("\xe2\x80\x99"));
2255 EXPECT_EQ(fmt::format(loc, "{:L}", 1000),
2256 "1\xe2\x80\x99"
2257 "000");
2258 }
2259
2260 TEST(format_test, format_facet_grouping) {
2261 auto loc =
2262 std::locale({}, new fmt::format_facet<std::locale>(",", {1, 2, 3}));
2263 EXPECT_EQ(fmt::format(loc, "{:L}", 1234567890), "1,234,567,89,0");
2264 }
2265
2266 TEST(format_test, format_named_arg_with_locale) {
2267 EXPECT_EQ(fmt::format(std::locale(), "{answer}", fmt::arg("answer", 42)),
2268 "42");
2269 }
2270
2271 TEST(format_test, format_locale) {
2272 auto loc = std::locale({}, new fmt::format_facet<std::locale>(","));
2273 EXPECT_EQ(fmt::format(loc, "{:Lx}", 123456789), "7,5bc,d15");
2274 EXPECT_EQ(fmt::format(loc, "{:#Lb}", -123456789),
2275 "-0b111,010,110,111,100,110,100,010,101");
2276 EXPECT_EQ(fmt::format(loc, "{:10Lo}", 12345), " 30,071");
2277 }
2278
2279 #endif // FMT_STATIC_THOUSANDS_SEPARATOR
2280
2281 struct convertible_to_nonconst_cstring {
2282 operator char*() const {
2283 static char c[] = "bar";
2284 return c;
2285 }
2286 };
2287
2288 FMT_BEGIN_NAMESPACE
2289 template <>
2290 struct formatter<convertible_to_nonconst_cstring> : formatter<char*> {};
2291 FMT_END_NAMESPACE
2292
2293 TEST(format_test, formatter_nonconst_char) {
2294 EXPECT_EQ(fmt::format("{}", convertible_to_nonconst_cstring()), "bar");
2295 }