1//===----------------------------------------------------------------------===//
2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3// See https://llvm.org/LICENSE.txt for license information.
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6//===----------------------------------------------------------------------===//
7
8#ifndef TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FORMATTER_FORMAT_FUNCTIONS_TESTS_H
9#define TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FORMATTER_FORMAT_FUNCTIONS_TESTS_H
10
11#include <algorithm>
12#include <array>
13#include <charconv>
14#include <concepts>
15#include <deque>
16#include <format>
17#include <list>
18#include <ranges>
19#include <span>
20#include <tuple>
21#include <vector>
22
23#include "format.functions.common.h"
24#include "make_string.h"
25#include "platform_support.h" // locale name macros
26#include "test_iterators.h"
27#include "test_macros.h"
28
29//
30// Char
31//
32
33template <class CharT, class TestFunction, class ExceptionTest>
34void test_char_default(TestFunction check, ExceptionTest check_exception, auto&& input) {
35 // Note when no range-underlying-spec is present the char is escaped,
36 check(SV("['H', 'e', 'l', 'l', 'o']"), SV("{}"), input);
37 check(SV("['H', 'e', 'l', 'l', 'o']^42"), SV("{}^42"), input);
38 check(SV("['H', 'e', 'l', 'l', 'o']^42"), SV("{:}^42"), input);
39
40 // when one is present there is no escaping,
41 check(SV("[H, e, l, l, o]"), SV("{::}"), input);
42 check(SV("[H, e, l, l, o]"), SV("{::<}"), input);
43 // unless forced by the type specifier.
44 check(SV("['H', 'e', 'l', 'l', 'o']"), SV("{::?}"), input);
45 check(SV("['H', 'e', 'l', 'l', 'o']"), SV("{::<?}"), input);
46
47 // ***** underlying has no format-spec
48
49 // *** align-fill & width ***
50 check(SV("['H', 'e', 'l', 'l', 'o'] "), SV("{:30}"), input);
51 check(SV("['H', 'e', 'l', 'l', 'o']*****"), SV("{:*<30}"), input);
52 check(SV("__['H', 'e', 'l', 'l', 'o']___"), SV("{:_^30}"), input);
53 check(SV("#####['H', 'e', 'l', 'l', 'o']"), SV("{:#>30}"), input);
54
55 check(SV("['H', 'e', 'l', 'l', 'o'] "), SV("{:{}}"), input, 30);
56 check(SV("['H', 'e', 'l', 'l', 'o']*****"), SV("{:*<{}}"), input, 30);
57 check(SV("__['H', 'e', 'l', 'l', 'o']___"), SV("{:_^{}}"), input, 30);
58 check(SV("#####['H', 'e', 'l', 'l', 'o']"), SV("{:#>{}}"), input, 30);
59
60 check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
61 check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
62
63 // *** sign ***
64 check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
65 check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
66 check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
67
68 // *** alternate form ***
69 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
70
71 // *** zero-padding ***
72 check_exception("The width option should not have a leading zero", SV("{:0}"), input);
73
74 // *** precision ***
75 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
76
77 // *** locale-specific form ***
78 check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
79
80 // *** n
81 check(SV("__'H', 'e', 'l', 'l', 'o'___"), SV("{:_^28n}"), input);
82
83 // *** type ***
84 check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
85 for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
86 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
87
88 // ***** Only underlying has a format-spec
89 check(SV("[H , e , l , l , o ]"), SV("{::4}"), input);
90 check(SV("[H***, e***, l***, l***, o***]"), SV("{::*<4}"), input);
91 check(SV("[_H__, _e__, _l__, _l__, _o__]"), SV("{::_^4}"), input);
92 check(SV("[:::H, :::e, :::l, :::l, :::o]"), SV("{:::>4}"), input);
93
94 check(SV("[H , e , l , l , o ]"), SV("{::{}}"), input, 4);
95 check(SV("[H***, e***, l***, l***, o***]"), SV("{::*<{}}"), input, 4);
96 check(SV("[_H__, _e__, _l__, _l__, _o__]"), SV("{::_^{}}"), input, 4);
97 check(SV("[:::H, :::e, :::l, :::l, :::o]"), SV("{:::>{}}"), input, 4);
98
99 check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
100 check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
101
102 // *** sign ***
103 check_exception("The format specifier for a character does not allow the sign option", SV("{::-}"), input);
104 check_exception("The format specifier for a character does not allow the sign option", SV("{::+}"), input);
105 check_exception("The format specifier for a character does not allow the sign option", SV("{:: }"), input);
106
107 check(SV("[72, 101, 108, 108, 111]"), SV("{::-d}"), input);
108 check(SV("[+72, +101, +108, +108, +111]"), SV("{::+d}"), input);
109 check(SV("[ 72, 101, 108, 108, 111]"), SV("{:: d}"), input);
110
111 // *** alternate form ***
112 check_exception("The format specifier for a character does not allow the alternate form option", SV("{::#}"), input);
113
114 check(SV("[0x48, 0x65, 0x6c, 0x6c, 0x6f]"), SV("{::#x}"), input);
115
116 // *** zero-padding ***
117 check_exception("The format specifier for a character does not allow the zero-padding option", SV("{::05}"), input);
118
119 check(SV("[00110, 00145, 00154, 00154, 00157]"), SV("{::05o}"), input);
120
121 // *** precision ***
122 check_exception("The format specifier should consume the input or end with a '}'", SV("{::.}"), input);
123
124 // *** locale-specific form ***
125 check(SV("[H, e, l, l, o]"), SV("{::L}"), input);
126
127 // *** type ***
128 for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX?"))
129 check_exception("The type option contains an invalid value for a character formatting argument", fmt, input);
130
131 // ***** Both have a format-spec
132 check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^25::>2}"), input);
133 check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^{}::>2}"), input, 25);
134 check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^{}::>{}}"), input, 25, 2);
135
136 check_exception(
137 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>2}"), input);
138 check_exception(
139 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}}"), input, 25);
140}
141
142template <class CharT, class TestFunction, class ExceptionTest>
143void test_char_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
144 check(SV("Hello"), SV("{:s}"), input);
145
146 // ***** underlying has no format-spec
147
148 // *** align-fill & width ***
149 check(SV("Hello "), SV("{:8s}"), input);
150 check(SV("Hello***"), SV("{:*<8s}"), input);
151 check(SV("_Hello__"), SV("{:_^8s}"), input);
152 check(SV("###Hello"), SV("{:#>8s}"), input);
153
154 check(SV("Hello "), SV("{:{}s}"), input, 8);
155 check(SV("Hello***"), SV("{:*<{}s}"), input, 8);
156 check(SV("_Hello__"), SV("{:_^{}s}"), input, 8);
157 check(SV("###Hello"), SV("{:#>{}s}"), input, 8);
158
159 check_exception("The format string contains an invalid escape sequence", SV("{:}<s}"), input);
160 check_exception("The fill option contains an invalid value", SV("{:{<s}"), input);
161
162 // *** sign ***
163 check_exception("The format specifier should consume the input or end with a '}'", SV("{:-s}"), input);
164 check_exception("The format specifier should consume the input or end with a '}'", SV("{:+s}"), input);
165 check_exception("The format specifier should consume the input or end with a '}'", SV("{: s}"), input);
166
167 // *** alternate form ***
168 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#s}"), input);
169
170 // *** zero-padding ***
171 check_exception("The width option should not have a leading zero", SV("{:0s}"), input);
172
173 // *** precision ***
174 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.s}"), input);
175
176 // *** locale-specific form ***
177 check_exception("The format specifier should consume the input or end with a '}'", SV("{:Ls}"), input);
178
179 // *** n
180 check_exception("The n option and type s can't be used together", SV("{:ns}"), input);
181
182 // *** type ***
183 check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
184 check_exception("The type option contains an invalid value for a character formatting argument", SV("{::<s}"), input);
185
186 // ***** Only underlying has a format-spec
187 check_exception("Type s and an underlying format specification can't be used together", SV("{:s:}"), input);
188 for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX?"))
189 check_exception("The type option contains an invalid value for a character formatting argument", fmt, input);
190
191 // ***** Both have a format-spec
192 check_exception("Type s and an underlying format specification can't be used together", SV("{:5s:5}"), input);
193}
194
195template <class CharT, class TestFunction, class ExceptionTest>
196void test_char_escaped_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
197 check(SV(R"("\"Hello'")"), SV("{:?s}"), input);
198
199 // ***** underlying has no format-spec
200
201 // *** align-fill & width ***
202 check(SV(R"("\"Hello'" )"), SV("{:13?s}"), input);
203 check(SV(R"("\"Hello'"***)"), SV("{:*<13?s}"), input);
204 check(SV(R"(_"\"Hello'"__)"), SV("{:_^13?s}"), input);
205 check(SV(R"(###"\"Hello'")"), SV("{:#>13?s}"), input);
206
207 check(SV(R"("\"Hello'" )"), SV("{:{}?s}"), input, 13);
208 check(SV(R"("\"Hello'"***)"), SV("{:*<{}?s}"), input, 13);
209 check(SV(R"(_"\"Hello'"__)"), SV("{:_^{}?s}"), input, 13);
210 check(SV(R"(###"\"Hello'")"), SV("{:#>{}?s}"), input, 13);
211
212 check_exception("The format string contains an invalid escape sequence", SV("{:}<?s}"), input);
213 check_exception("The fill option contains an invalid value", SV("{:{<?s}"), input);
214 check_exception("The format specifier should consume the input or end with a '}'", SV("{::<?s}"), input);
215
216 // *** sign ***
217 check_exception("The format specifier should consume the input or end with a '}'", SV("{:-?s}"), input);
218 check_exception("The format specifier should consume the input or end with a '}'", SV("{:+?s}"), input);
219 check_exception("The format specifier should consume the input or end with a '}'", SV("{: ?s}"), input);
220
221 // *** alternate form ***
222 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#?s}"), input);
223
224 // *** zero-padding ***
225 check_exception("The width option should not have a leading zero", SV("{:0?s}"), input);
226
227 // *** precision ***
228 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.?s}"), input);
229
230 // *** locale-specific form ***
231 check_exception("The format specifier should consume the input or end with a '}'", SV("{:L?s}"), input);
232
233 // *** n
234 check_exception("The n option and type ?s can't be used together", SV("{:n?s}"), input);
235
236 // *** type ***
237 check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
238
239 // ***** Only underlying has a format-spec
240 check_exception("Type ?s and an underlying format specification can't be used together", SV("{:?s:}"), input);
241
242 // ***** Both have a format-spec
243 check_exception("Type ?s and an underlying format specification can't be used together", SV("{:5?s:5}"), input);
244}
245
246template <class CharT, class TestFunction, class ExceptionTest>
247void test_char(TestFunction check, ExceptionTest check_exception) {
248 test_char_default<CharT>(
249 check, check_exception, std::array{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')});
250
251 // This tests two different implementations in libc++. A basic_string_view
252 // formatter if the range is contiguous, a basic_string otherwise.
253 test_char_escaped_string<CharT>(
254 check,
255 check_exception,
256 std::array{CharT('"'), CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o'), CharT('\'')});
257 test_char_escaped_string<CharT>(
258 check,
259 check_exception,
260 std::list{CharT('"'), CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o'), CharT('\'')});
261
262 // This tests two different implementations in libc++. A basic_string_view
263 // formatter if the range is contiguous, a basic_string otherwise.
264 test_char_string<CharT>(
265 check, check_exception, std::array{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')});
266 test_char_string<CharT>(
267 check, check_exception, std::list{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')});
268}
269
270//
271// char -> wchar_t
272//
273
274#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
275template <class TestFunction, class ExceptionTest>
276void test_char_to_wchar(TestFunction check, ExceptionTest check_exception) {
277 test_char_default<wchar_t>(check, check_exception, std::array{'H', 'e', 'l', 'l', 'o'});
278
279 // The types s and ?s may only be used when using range_formatter<T, charT>
280 // where the types T and charT are the same. This means this can't be used for
281 // range_formatter<wchar_t, char> even when formatter<wchar_t, char> has a
282 // debug-enabled specialization.
283
284 using CharT = wchar_t;
285 check_exception(
286 "Type s requires character type as formatting argument", SV("{:s}"), std::array{'H', 'e', 'l', 'l', 'o'});
287 check_exception(
288 "Type ?s requires character type as formatting argument", SV("{:?s}"), std::array{'H', 'e', 'l', 'l', 'o'});
289}
290#endif
291
292//
293// Bool
294//
295
296template <class CharT, class TestFunction, class ExceptionTest>
297void test_bool(TestFunction check, ExceptionTest check_exception) {
298 std::array input{true, true, false};
299
300 check(SV("[true, true, false]"), SV("{}"), input);
301 check(SV("[true, true, false]^42"), SV("{}^42"), input);
302 check(SV("[true, true, false]^42"), SV("{:}^42"), input);
303
304 // ***** underlying has no format-spec
305
306 // *** align-fill & width ***
307 check(SV("[true, true, false] "), SV("{:24}"), input);
308 check(SV("[true, true, false]*****"), SV("{:*<24}"), input);
309 check(SV("__[true, true, false]___"), SV("{:_^24}"), input);
310 check(SV("#####[true, true, false]"), SV("{:#>24}"), input);
311
312 check(SV("[true, true, false] "), SV("{:{}}"), input, 24);
313 check(SV("[true, true, false]*****"), SV("{:*<{}}"), input, 24);
314 check(SV("__[true, true, false]___"), SV("{:_^{}}"), input, 24);
315 check(SV("#####[true, true, false]"), SV("{:#>{}}"), input, 24);
316
317 check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
318 check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
319
320 // *** sign ***
321 check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
322 check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
323 check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
324
325 // *** alternate form ***
326 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
327
328 // *** zero-padding ***
329 check_exception("The width option should not have a leading zero", SV("{:0}"), input);
330
331 // *** precision ***
332 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
333
334 // *** locale-specific form ***
335 check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
336
337 // *** n
338 check(SV("__true, true, false___"), SV("{:_^22n}"), input);
339
340 // *** type ***
341 check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
342 check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
343 check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
344 for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
345 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
346
347 // ***** Only underlying has a format-spec
348 check(SV("[true , true , false ]"), SV("{::7}"), input);
349 check(SV("[true***, true***, false**]"), SV("{::*<7}"), input);
350 check(SV("[_true__, _true__, _false_]"), SV("{::_^7}"), input);
351 check(SV("[:::true, :::true, ::false]"), SV("{:::>7}"), input);
352
353 check(SV("[true , true , false ]"), SV("{::{}}"), input, 7);
354 check(SV("[true***, true***, false**]"), SV("{::*<{}}"), input, 7);
355 check(SV("[_true__, _true__, _false_]"), SV("{::_^{}}"), input, 7);
356 check(SV("[:::true, :::true, ::false]"), SV("{:::>{}}"), input, 7);
357
358 check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
359 check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
360
361 // *** sign ***
362 check_exception("The format specifier for a bool does not allow the sign option", SV("{::-}"), input);
363 check_exception("The format specifier for a bool does not allow the sign option", SV("{::+}"), input);
364 check_exception("The format specifier for a bool does not allow the sign option", SV("{:: }"), input);
365
366 check(SV("[1, 1, 0]"), SV("{::-d}"), input);
367 check(SV("[+1, +1, +0]"), SV("{::+d}"), input);
368 check(SV("[ 1, 1, 0]"), SV("{:: d}"), input);
369
370 // *** alternate form ***
371 check_exception("The format specifier for a bool does not allow the alternate form option", SV("{::#}"), input);
372
373 check(SV("[0x1, 0x1, 0x0]"), SV("{::#x}"), input);
374
375 // *** zero-padding ***
376 check_exception("The format specifier for a bool does not allow the zero-padding option", SV("{::05}"), input);
377
378 check(SV("[00001, 00001, 00000]"), SV("{::05o}"), input);
379
380 // *** precision ***
381 check_exception("The format specifier should consume the input or end with a '}'", SV("{::.}"), input);
382
383 // *** locale-specific form ***
384 check(SV("[true, true, false]"), SV("{::L}"), input);
385
386 // *** type ***
387 for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBdosxX"))
388 check_exception("The type option contains an invalid value for a bool formatting argument", fmt, input);
389
390 // ***** Both have a format-spec
391 check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^32::>7}"), input);
392 check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^{}::>7}"), input, 32);
393 check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^{}::>{}}"), input, 32, 7);
394
395 check_exception(
396 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>5}"), input);
397 check_exception(
398 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}}"), input, 32);
399}
400
401//
402// Integral
403//
404
405template <class CharT, class TestFunction, class ExceptionTest>
406void test_int(TestFunction check, ExceptionTest check_exception, auto&& input) {
407 check(SV("[1, 2, 42, -42]"), SV("{}"), input);
408 check(SV("[1, 2, 42, -42]^42"), SV("{}^42"), input);
409 check(SV("[1, 2, 42, -42]^42"), SV("{:}^42"), input);
410
411 // ***** underlying has no format-spec
412
413 // *** align-fill & width ***
414 check(SV("[1, 2, 42, -42] "), SV("{:20}"), input);
415 check(SV("[1, 2, 42, -42]*****"), SV("{:*<20}"), input);
416 check(SV("__[1, 2, 42, -42]___"), SV("{:_^20}"), input);
417 check(SV("#####[1, 2, 42, -42]"), SV("{:#>20}"), input);
418
419 check(SV("[1, 2, 42, -42] "), SV("{:{}}"), input, 20);
420 check(SV("[1, 2, 42, -42]*****"), SV("{:*<{}}"), input, 20);
421 check(SV("__[1, 2, 42, -42]___"), SV("{:_^{}}"), input, 20);
422 check(SV("#####[1, 2, 42, -42]"), SV("{:#>{}}"), input, 20);
423
424 check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
425 check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
426
427 // *** sign ***
428 check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
429 check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
430 check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
431
432 // *** alternate form ***
433 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
434
435 // *** zero-padding ***
436 check_exception("The width option should not have a leading zero", SV("{:0}"), input);
437
438 // *** precision ***
439 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
440
441 // *** locale-specific form ***
442 check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
443
444 // *** n
445 check(SV("__1, 2, 42, -42___"), SV("{:_^18n}"), input);
446
447 // *** type ***
448 check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
449 check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
450 check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
451 for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
452 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
453
454 // ***** Only underlying has a format-spec
455 check(SV("[ 1, 2, 42, -42]"), SV("{::5}"), input);
456 check(SV("[1****, 2****, 42***, -42**]"), SV("{::*<5}"), input);
457 check(SV("[__1__, __2__, _42__, _-42_]"), SV("{::_^5}"), input);
458 check(SV("[::::1, ::::2, :::42, ::-42]"), SV("{:::>5}"), input);
459
460 check(SV("[ 1, 2, 42, -42]"), SV("{::{}}"), input, 5);
461 check(SV("[1****, 2****, 42***, -42**]"), SV("{::*<{}}"), input, 5);
462 check(SV("[__1__, __2__, _42__, _-42_]"), SV("{::_^{}}"), input, 5);
463 check(SV("[::::1, ::::2, :::42, ::-42]"), SV("{:::>{}}"), input, 5);
464
465 check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
466 check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
467
468 // *** sign ***
469 check(SV("[1, 2, 42, -42]"), SV("{::-}"), input);
470 check(SV("[+1, +2, +42, -42]"), SV("{::+}"), input);
471 check(SV("[ 1, 2, 42, -42]"), SV("{:: }"), input);
472
473 // *** alternate form ***
474 check(SV("[0x1, 0x2, 0x2a, -0x2a]"), SV("{::#x}"), input);
475
476 // *** zero-padding ***
477 check(SV("[00001, 00002, 00042, -0042]"), SV("{::05}"), input);
478 check(SV("[00001, 00002, 0002a, -002a]"), SV("{::05x}"), input);
479 check(SV("[0x001, 0x002, 0x02a, -0x2a]"), SV("{::#05x}"), input);
480
481 // *** precision ***
482 check_exception("The format specifier should consume the input or end with a '}'", SV("{::.}"), input);
483
484 // *** locale-specific form ***
485 check(SV("[1, 2, 42, -42]"), SV("{::L}"), input); // does nothing in this test, but is accepted.
486
487 // *** type ***
488 for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX"))
489 check_exception("The type option contains an invalid value for an integer formatting argument", fmt, input);
490
491 // ***** Both have a format-spec
492 check(SV("^^[::::1, ::::2, :::42, ::-42]^^^"), SV("{:^^33::>5}"), input);
493 check(SV("^^[::::1, ::::2, :::42, ::-42]^^^"), SV("{:^^{}::>5}"), input, 33);
494 check(SV("^^[::::1, ::::2, :::42, ::-42]^^^"), SV("{:^^{}::>{}}"), input, 33, 5);
495
496 check_exception(
497 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>5}"), input);
498 check_exception(
499 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}}"), input, 33);
500}
501
502template <class CharT, class TestFunction, class ExceptionTest>
503void test_int(TestFunction check, ExceptionTest check_exception) {
504 test_int<CharT>(check, check_exception, std::array{1, 2, 42, -42});
505 test_int<CharT>(check, check_exception, std::list{1, 2, 42, -42});
506 test_int<CharT>(check, check_exception, std::vector{1, 2, 42, -42});
507 std::array input{1, 2, 42, -42};
508 test_int<CharT>(check, check_exception, std::span{input});
509}
510
511//
512// Floating point
513//
514
515template <class CharT, class TestFunction, class ExceptionTest>
516void test_floating_point(TestFunction check, ExceptionTest check_exception, auto&& input) {
517 check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{}"), input);
518 check(SV("[-42.5, 0, 1.25, 42.5]^42"), SV("{}^42"), input);
519 check(SV("[-42.5, 0, 1.25, 42.5]^42"), SV("{:}^42"), input);
520
521 // ***** underlying has no format-spec
522
523 // *** align-fill & width ***
524 check(SV("[-42.5, 0, 1.25, 42.5] "), SV("{:27}"), input);
525 check(SV("[-42.5, 0, 1.25, 42.5]*****"), SV("{:*<27}"), input);
526 check(SV("__[-42.5, 0, 1.25, 42.5]___"), SV("{:_^27}"), input);
527 check(SV("#####[-42.5, 0, 1.25, 42.5]"), SV("{:#>27}"), input);
528
529 check(SV("[-42.5, 0, 1.25, 42.5] "), SV("{:{}}"), input, 27);
530 check(SV("[-42.5, 0, 1.25, 42.5]*****"), SV("{:*<{}}"), input, 27);
531 check(SV("__[-42.5, 0, 1.25, 42.5]___"), SV("{:_^{}}"), input, 27);
532 check(SV("#####[-42.5, 0, 1.25, 42.5]"), SV("{:#>{}}"), input, 27);
533
534 check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
535 check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
536
537 // *** sign ***
538 check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
539 check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
540 check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
541
542 // *** alternate form ***
543 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
544
545 // *** zero-padding ***
546 check_exception("The width option should not have a leading zero", SV("{:0}"), input);
547
548 // *** precision ***
549 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
550
551 // *** locale-specific form ***
552 check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
553
554 // *** n
555 check(SV("__-42.5, 0, 1.25, 42.5___"), SV("{:_^25n}"), input);
556
557 // *** type ***
558 check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
559 check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
560 check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
561 for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
562 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
563
564 // ***** Only underlying has a format-spec
565 check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::5}"), input);
566 check(SV("[-42.5, 0****, 1.25*, 42.5*]"), SV("{::*<5}"), input);
567 check(SV("[-42.5, __0__, 1.25_, 42.5_]"), SV("{::_^5}"), input);
568 check(SV("[-42.5, ::::0, :1.25, :42.5]"), SV("{:::>5}"), input);
569
570 check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::{}}"), input, 5);
571 check(SV("[-42.5, 0****, 1.25*, 42.5*]"), SV("{::*<{}}"), input, 5);
572 check(SV("[-42.5, __0__, 1.25_, 42.5_]"), SV("{::_^{}}"), input, 5);
573 check(SV("[-42.5, ::::0, :1.25, :42.5]"), SV("{:::>{}}"), input, 5);
574
575 check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
576 check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
577
578 // *** sign ***
579 check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::-}"), input);
580 check(SV("[-42.5, +0, +1.25, +42.5]"), SV("{::+}"), input);
581 check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{:: }"), input);
582
583 // *** alternate form ***
584 check(SV("[-42.5, 0., 1.25, 42.5]"), SV("{::#}"), input);
585
586 // *** zero-padding ***
587 check(SV("[-42.5, 00000, 01.25, 042.5]"), SV("{::05}"), input);
588 check(SV("[-42.5, 0000., 01.25, 042.5]"), SV("{::#05}"), input);
589
590 // *** precision ***
591 check(SV("[-42, 0, 1.2, 42]"), SV("{::.2}"), input);
592 check(SV("[-42.500, 0.000, 1.250, 42.500]"), SV("{::.3f}"), input);
593
594 check(SV("[-42, 0, 1.2, 42]"), SV("{::.{}}"), input, 2);
595 check(SV("[-42.500, 0.000, 1.250, 42.500]"), SV("{::.{}f}"), input, 3);
596
597 check_exception("The precision option does not contain a value or an argument index", SV("{::.}"), input);
598
599 // *** locale-specific form ***
600 check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::L}"), input); // does not require locales present
601#ifndef TEST_HAS_NO_LOCALIZATION
602// TODO FMT Enable with locale testing active
603# if 0
604 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
605 check(SV("[-42,5, 0, 1,25, 42,5]"), SV("{::L}"), input);
606
607 std::locale::global(std::locale(LOCALE_en_US_UTF_8));
608 check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::L}"), input);
609
610 std::locale::global(std::locale::classic());
611# endif
612#endif // TEST_HAS_NO_LOCALIZATION
613
614 // *** type ***
615 for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("aAeEfFgG"))
616 check_exception("The type option contains an invalid value for a floating-point formatting argument", fmt, input);
617
618 // ***** Both have a format-spec
619 check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^33::>5}"), input);
620 check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^{}::>5}"), input, 33);
621 check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^{}::>{}}"), input, 33, 5);
622
623 check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^33::>5.2}"), input);
624 check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>5.2}"), input, 33);
625 check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>{}.2}"), input, 33, 5);
626 check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>{}.{}}"), input, 33, 5, 2);
627
628 check_exception(
629 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>5.2}"), input);
630 check_exception(
631 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}.2}"), input, 33);
632 check_exception(
633 "The argument index value is too large for the number of arguments supplied",
634 SV("{:^^{}::>{}.{}}"),
635 input,
636 33,
637 5);
638}
639
640template <class CharT, class TestFunction, class ExceptionTest>
641void test_floating_point(TestFunction check, ExceptionTest check_exception) {
642 test_floating_point<CharT>(check, check_exception, std::array{-42.5f, 0.0f, 1.25f, 42.5f});
643 test_floating_point<CharT>(check, check_exception, std::vector{-42.5, 0.0, 1.25, 42.5});
644
645 std::array input{-42.5l, 0.0l, 1.25l, 42.5l};
646 test_floating_point<CharT>(check, check_exception, std::span{input});
647}
648
649//
650// Pointer
651//
652
653template <class CharT, class TestFunction, class ExceptionTest>
654void test_pointer(TestFunction check, ExceptionTest check_exception, auto&& input) {
655 check(SV("[0x0]"), SV("{}"), input);
656 check(SV("[0x0]^42"), SV("{}^42"), input);
657 check(SV("[0x0]^42"), SV("{:}^42"), input);
658
659 // ***** underlying has no format-spec
660
661 // *** align-fill & width ***
662 check(SV("[0x0] "), SV("{:10}"), input);
663 check(SV("[0x0]*****"), SV("{:*<10}"), input);
664 check(SV("__[0x0]___"), SV("{:_^10}"), input);
665 check(SV("#####[0x0]"), SV("{:#>10}"), input);
666
667 check(SV("[0x0] "), SV("{:{}}"), input, 10);
668 check(SV("[0x0]*****"), SV("{:*<{}}"), input, 10);
669 check(SV("__[0x0]___"), SV("{:_^{}}"), input, 10);
670 check(SV("#####[0x0]"), SV("{:#>{}}"), input, 10);
671
672 check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
673 check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
674
675 // *** sign ***
676 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
677
678 // *** alternate form ***
679 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
680
681 // *** zero-padding ***
682 check_exception("The width option should not have a leading zero", SV("{:0}"), input);
683
684 // *** precision ***
685 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
686
687 // *** locale-specific form ***
688 check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
689
690 // *** n
691 check(SV("_0x0_"), SV("{:_^5n}"), input);
692
693 // *** type ***
694 check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
695 check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
696 check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
697 for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
698 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
699
700 // ***** Only underlying has a format-spec
701 check(SV("[ 0x0]"), SV("{::5}"), input);
702 check(SV("[0x0**]"), SV("{::*<5}"), input);
703 check(SV("[_0x0_]"), SV("{::_^5}"), input);
704 check(SV("[::0x0]"), SV("{:::>5}"), input);
705
706 check(SV("[ 0x0]"), SV("{::{}}"), input, 5);
707 check(SV("[0x0**]"), SV("{::*<{}}"), input, 5);
708 check(SV("[_0x0_]"), SV("{::_^{}}"), input, 5);
709 check(SV("[::0x0]"), SV("{:::>{}}"), input, 5);
710
711 check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
712 check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
713
714 // *** sign ***
715 check_exception("The format specifier should consume the input or end with a '}'", SV("{::-}"), input);
716
717 // *** alternate form ***
718 check_exception("The format specifier should consume the input or end with a '}'", SV("{::#}"), input);
719
720 // *** zero-padding ***
721 check(SV("[0x0000]"), SV("{::06}"), input);
722 check(SV("[0x0000]"), SV("{::06p}"), input);
723 check(SV("[0X0000]"), SV("{::06P}"), input);
724
725 // *** precision ***
726 check_exception("The format specifier should consume the input or end with a '}'", SV("{::.}"), input);
727
728 // *** locale-specific form ***
729 check_exception("The format specifier should consume the input or end with a '}'", SV("{::L}"), input);
730
731 // *** type ***
732 for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("pP"))
733 check_exception("The type option contains an invalid value for a pointer formatting argument", fmt, input);
734
735 // ***** Both have a format-spec
736 check(SV("^^[::0x0]^^^"), SV("{:^^12::>5}"), input);
737 check(SV("^^[::0x0]^^^"), SV("{:^^{}::>5}"), input, 12);
738 check(SV("^^[::0x0]^^^"), SV("{:^^{}::>{}}"), input, 12, 5);
739
740 check(SV("^^[::0x0]^^^"), SV("{:^^12::>5}"), input);
741 check(SV("^^[::0x0]^^^"), SV("{:^^{}::>5}"), input, 12);
742 check(SV("^^[::0x0]^^^"), SV("{:^^{}::>{}}"), input, 12, 5);
743
744 check_exception(
745 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>5}"), input);
746 check_exception(
747 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}}"), input, 12);
748}
749
750template <class CharT, class TestFunction, class ExceptionTest>
751void test_pointer(TestFunction check, ExceptionTest check_exception) {
752 test_pointer<CharT>(check, check_exception, std::array{nullptr});
753 test_pointer<CharT>(check, check_exception, std::array{static_cast<const void*>(0)});
754 test_pointer<CharT>(check, check_exception, std::array{static_cast<void*>(0)});
755}
756
757//
758// String
759//
760
761template <class CharT, class TestFunction, class ExceptionTest>
762void test_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
763 check(SV(R"(["Hello", "world"])"), SV("{}"), input);
764 check(SV(R"(["Hello", "world"]^42)"), SV("{}^42"), input);
765 check(SV(R"(["Hello", "world"]^42)"), SV("{:}^42"), input);
766
767 // ***** underlying has no format-spec
768
769 // *** align-fill & width ***
770 check(SV(R"(["Hello", "world"] )"), SV("{:23}"), input);
771 check(SV(R"(["Hello", "world"]*****)"), SV("{:*<23}"), input);
772 check(SV(R"(__["Hello", "world"]___)"), SV("{:_^23}"), input);
773 check(SV(R"(#####["Hello", "world"])"), SV("{:#>23}"), input);
774
775 check(SV(R"(["Hello", "world"] )"), SV("{:{}}"), input, 23);
776 check(SV(R"(["Hello", "world"]*****)"), SV("{:*<{}}"), input, 23);
777 check(SV(R"(__["Hello", "world"]___)"), SV("{:_^{}}"), input, 23);
778 check(SV(R"(#####["Hello", "world"])"), SV("{:#>{}}"), input, 23);
779
780 check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
781 check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
782
783 // *** sign ***
784 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
785
786 // *** alternate form ***
787 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
788
789 // *** zero-padding ***
790 check_exception("The width option should not have a leading zero", SV("{:0}"), input);
791
792 // *** precision ***
793 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
794
795 // *** locale-specific form ***
796 check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
797
798 // *** n
799 check(SV(R"(_"Hello", "world"_)"), SV("{:_^18n}"), input);
800
801 // *** type ***
802 check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
803 check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
804 check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
805 for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
806 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
807
808 // ***** Only underlying has a format-spec
809 check(SV(R"([Hello , world ])"), SV("{::8}"), input);
810 check(SV(R"([Hello***, world***])"), SV("{::*<8}"), input);
811 check(SV(R"([_Hello__, _world__])"), SV("{::_^8}"), input);
812 check(SV(R"([:::Hello, :::world])"), SV("{:::>8}"), input);
813
814 check(SV(R"([Hello , world ])"), SV("{::{}}"), input, 8);
815 check(SV(R"([Hello***, world***])"), SV("{::*<{}}"), input, 8);
816 check(SV(R"([_Hello__, _world__])"), SV("{::_^{}}"), input, 8);
817 check(SV(R"([:::Hello, :::world])"), SV("{:::>{}}"), input, 8);
818
819 check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
820 check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
821
822 // *** sign ***
823 check_exception("The format specifier should consume the input or end with a '}'", SV("{::-}"), input);
824
825 // *** alternate form ***
826 check_exception("The format specifier should consume the input or end with a '}'", SV("{::#}"), input);
827
828 // *** zero-padding ***
829 check_exception("The width option should not have a leading zero", SV("{::05}"), input);
830
831 // *** precision ***
832 check(SV(R"([Hel, wor])"), SV("{::.3}"), input);
833
834 check(SV(R"([Hel, wor])"), SV("{::.{}}"), input, 3);
835
836 check_exception("The precision option does not contain a value or an argument index", SV("{::.}"), input);
837
838 // *** locale-specific form ***
839 check_exception("The format specifier should consume the input or end with a '}'", SV("{::L}"), input);
840
841 // *** type ***
842 for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("s?"))
843 check_exception("The type option contains an invalid value for a string formatting argument", fmt, input);
844
845 // ***** Both have a format-spec
846 check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^25::>8}"), input);
847 check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>8}"), input, 25);
848 check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>{}}"), input, 25, 8);
849
850 check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^25::>8}"), input);
851 check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>8}"), input, 25);
852 check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>{}}"), input, 25, 8);
853
854 check_exception(
855 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>8}"), input);
856 check_exception(
857 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}}"), input, 25);
858}
859
860template <class CharT, class TestFunction, class ExceptionTest>
861void test_string(TestFunction check, ExceptionTest check_exception) {
862 test_string<CharT>(check, check_exception, std::array{CSTR("Hello"), CSTR("world")});
863 test_string<CharT>(check, check_exception, std::array{STR("Hello"), STR("world")});
864 test_string<CharT>(check, check_exception, std::array{SV("Hello"), SV("world")});
865}
866
867//
868// Handle
869//
870
871template <class CharT, class TestFunction, class ExceptionTest>
872void test_status(TestFunction check, ExceptionTest check_exception) {
873 std::array input{status::foo, status::bar, status::foobar};
874
875 check(SV("[0xaaaa, 0x5555, 0xaa55]"), SV("{}"), input);
876 check(SV("[0xaaaa, 0x5555, 0xaa55]^42"), SV("{}^42"), input);
877 check(SV("[0xaaaa, 0x5555, 0xaa55]^42"), SV("{:}^42"), input);
878
879 // ***** underlying has no format-spec
880
881 // *** align-fill & width ***
882 check(SV("[0xaaaa, 0x5555, 0xaa55] "), SV("{:29}"), input);
883 check(SV("[0xaaaa, 0x5555, 0xaa55]*****"), SV("{:*<29}"), input);
884 check(SV("__[0xaaaa, 0x5555, 0xaa55]___"), SV("{:_^29}"), input);
885 check(SV("#####[0xaaaa, 0x5555, 0xaa55]"), SV("{:#>29}"), input);
886
887 check(SV("[0xaaaa, 0x5555, 0xaa55] "), SV("{:{}}"), input, 29);
888 check(SV("[0xaaaa, 0x5555, 0xaa55]*****"), SV("{:*<{}}"), input, 29);
889 check(SV("__[0xaaaa, 0x5555, 0xaa55]___"), SV("{:_^{}}"), input, 29);
890 check(SV("#####[0xaaaa, 0x5555, 0xaa55]"), SV("{:#>{}}"), input, 29);
891
892 check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
893 check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
894
895 // *** sign ***
896 check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
897 check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
898 check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
899
900 // *** alternate form ***
901 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
902
903 // *** zero-padding ***
904 check_exception("The width option should not have a leading zero", SV("{:0}"), input);
905
906 // *** precision ***
907 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
908
909 // *** locale-specific form ***
910 check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
911
912 // *** n
913 check(SV("__0xaaaa, 0x5555, 0xaa55___"), SV("{:_^27n}"), input);
914
915 // *** type ***
916 check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
917 check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
918 check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
919 for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
920 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
921
922 // ***** Only underlying has a format-spec
923 check_exception("The type option contains an invalid value for a status formatting argument", SV("{::*<7}"), input);
924 for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("sxX"))
925 check_exception("The type option contains an invalid value for a status formatting argument", fmt, input);
926
927 check(SV("[0xaaaa, 0x5555, 0xaa55]"), SV("{::x}"), input);
928 check(SV("[0XAAAA, 0X5555, 0XAA55]"), SV("{::X}"), input);
929 check(SV("[foo, bar, foobar]"), SV("{::s}"), input);
930
931 // ***** Both have a format-spec
932 check(SV("^^[0XAAAA, 0X5555, 0XAA55]^^^"), SV("{:^^29:X}"), input);
933 check(SV("^^[0XAAAA, 0X5555, 0XAA55]^^^"), SV("{:^^{}:X}"), input, 29);
934
935 check_exception("The argument index value is too large for the number of arguments supplied", SV("{:^^{}:X}"), input);
936}
937
938//
939// Pair
940//
941
942template <class CharT, class TestFunction, class ExceptionTest>
943void test_pair_tuple(TestFunction check, ExceptionTest check_exception, auto&& input) {
944 // [format.range.formatter]/3
945 // For range_formatter<T, charT>, the format-spec in a
946 // range-underlying-spec, if any, is interpreted by formatter<T, charT>.
947 //
948 // template<class ParseContext>
949 // constexpr typename ParseContext::iterator
950 // parse(ParseContext& ctx);
951 // [format.tuple]/7
952 // ... if e.set_debug_format() is a valid expression, calls
953 // e.set_debug_format().
954 // So when there is no range-underlying-spec, there is no need to call parse
955 // thus the char element is not escaped.
956 // TODO FMT P2733 addresses this issue.
957 check(SV("[(1, 'a'), (42, '*')]"), SV("{}"), input);
958 check(SV("[(1, 'a'), (42, '*')]^42"), SV("{}^42"), input);
959 check(SV("[(1, 'a'), (42, '*')]^42"), SV("{:}^42"), input);
960
961 // ***** underlying has no format-spec
962
963 // *** align-fill & width ***
964 check(SV("[(1, 'a'), (42, '*')] "), SV("{:26}"), input);
965 check(SV("[(1, 'a'), (42, '*')]*****"), SV("{:*<26}"), input);
966 check(SV("__[(1, 'a'), (42, '*')]___"), SV("{:_^26}"), input);
967 check(SV("#####[(1, 'a'), (42, '*')]"), SV("{:#>26}"), input);
968
969 check(SV("[(1, 'a'), (42, '*')] "), SV("{:{}}"), input, 26);
970 check(SV("[(1, 'a'), (42, '*')]*****"), SV("{:*<{}}"), input, 26);
971 check(SV("__[(1, 'a'), (42, '*')]___"), SV("{:_^{}}"), input, 26);
972 check(SV("#####[(1, 'a'), (42, '*')]"), SV("{:#>{}}"), input, 26);
973
974 check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
975 check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
976
977 // *** sign ***
978 check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
979 check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
980 check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
981
982 // *** alternate form ***
983 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
984
985 // *** zero-padding ***
986 check_exception("The width option should not have a leading zero", SV("{:0}"), input);
987
988 // *** precision ***
989 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
990
991 // *** locale-specific form ***
992 check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
993
994 // *** n
995 check(SV("__(1, 'a'), (42, '*')___"), SV("{:_^24n}"), input);
996 check(SV("__(1, 'a'), (42, '*')___"), SV("{:_^24nm}"), input); // m should have no effect
997
998 // *** type ***
999 check(SV("__{(1, 'a'), (42, '*')}___"), SV("{:_^26m}"), input);
1000 check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
1001 check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
1002 for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
1003 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
1004
1005 // ***** Only underlying has a format-spec
1006 check(SV("[(1, 'a') , (42, '*') ]"), SV("{::11}"), input);
1007 check(SV("[(1, 'a')***, (42, '*')**]"), SV("{::*<11}"), input);
1008 check(SV("[_(1, 'a')__, _(42, '*')_]"), SV("{::_^11}"), input);
1009 check(SV("[###(1, 'a'), ##(42, '*')]"), SV("{::#>11}"), input);
1010
1011 check(SV("[(1, 'a') , (42, '*') ]"), SV("{::{}}"), input, 11);
1012 check(SV("[(1, 'a')***, (42, '*')**]"), SV("{::*<{}}"), input, 11);
1013 check(SV("[_(1, 'a')__, _(42, '*')_]"), SV("{::_^{}}"), input, 11);
1014 check(SV("[###(1, 'a'), ##(42, '*')]"), SV("{::#>{}}"), input, 11);
1015
1016 check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
1017 check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
1018
1019 // *** sign ***
1020 check_exception("The format specifier should consume the input or end with a '}'", SV("{::-}"), input);
1021 check_exception("The format specifier should consume the input or end with a '}'", SV("{::+}"), input);
1022 check_exception("The format specifier should consume the input or end with a '}'", SV("{:: }"), input);
1023
1024 // *** alternate form ***
1025 check_exception("The format specifier should consume the input or end with a '}'", SV("{::#}"), input);
1026
1027 // *** zero-padding ***
1028 check_exception("The width option should not have a leading zero", SV("{::05}"), input);
1029
1030 // *** precision ***
1031 check_exception("The format specifier should consume the input or end with a '}'", SV("{::.}"), input);
1032
1033 // *** locale-specific form ***
1034 check_exception("The format specifier should consume the input or end with a '}'", SV("{::L}"), input);
1035
1036 // *** type ***
1037 check(SV("[1: 'a', 42: '*']"), SV("{::m}"), input);
1038 check(SV("[1, 'a', 42, '*']"), SV("{::n}"), input);
1039 for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>(""))
1040 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
1041
1042 // ***** Both have a format-spec
1043 check(SV("^^[###(1, 'a'), ##(42, '*')]^^^"), SV("{:^^31:#>11}"), input);
1044 check(SV("^^[###(1, 'a'), ##(42, '*')]^^^"), SV("{:^^31:#>11}"), input);
1045 check(SV("^^[###(1, 'a'), ##(42, '*')]^^^"), SV("{:^^{}:#>11}"), input, 31);
1046 check(SV("^^[###(1, 'a'), ##(42, '*')]^^^"), SV("{:^^{}:#>{}}"), input, 31, 11);
1047
1048 check_exception(
1049 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}:#>5}"), input);
1050 check_exception(
1051 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}:#>{}}"), input, 31);
1052
1053 check(SV("1: 'a', 42: '*'"), SV("{:n:m}"), input);
1054 check(SV("1, 'a', 42, '*'"), SV("{:n:n}"), input);
1055 check(SV("{1: 'a', 42: '*'}"), SV("{:m:m}"), input);
1056 check(SV("{1, 'a', 42, '*'}"), SV("{:m:n}"), input);
1057}
1058
1059template <class CharT, class TestFunction, class ExceptionTest>
1060void test_pair_tuple(TestFunction check, ExceptionTest check_exception) {
1061 test_pair_tuple<CharT>(
1062 check, check_exception, std::array{std::make_pair(1, CharT('a')), std::make_pair(42, CharT('*'))});
1063 test_pair_tuple<CharT>(
1064 check, check_exception, std::array{std::make_tuple(1, CharT('a')), std::make_tuple(42, CharT('*'))});
1065}
1066
1067//
1068// Tuple 1
1069//
1070
1071template <class CharT, class TestFunction, class ExceptionTest>
1072void test_tuple_int(TestFunction check, ExceptionTest check_exception) {
1073 std::array input{std::make_tuple(args: 42), std::make_tuple(args: 99)};
1074
1075 check(SV("[(42), (99)]"), SV("{}"), input);
1076 check(SV("[(42), (99)]^42"), SV("{}^42"), input);
1077 check(SV("[(42), (99)]^42"), SV("{:}^42"), input);
1078
1079 // ***** underlying has no format-spec
1080
1081 // *** align-fill & width ***
1082 check(SV("[(42), (99)] "), SV("{:17}"), input);
1083 check(SV("[(42), (99)]*****"), SV("{:*<17}"), input);
1084 check(SV("__[(42), (99)]___"), SV("{:_^17}"), input);
1085 check(SV("#####[(42), (99)]"), SV("{:#>17}"), input);
1086
1087 check(SV("[(42), (99)] "), SV("{:{}}"), input, 17);
1088 check(SV("[(42), (99)]*****"), SV("{:*<{}}"), input, 17);
1089 check(SV("__[(42), (99)]___"), SV("{:_^{}}"), input, 17);
1090 check(SV("#####[(42), (99)]"), SV("{:#>{}}"), input, 17);
1091
1092 check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
1093 check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
1094
1095 // *** sign ***
1096 check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
1097 check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
1098 check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
1099
1100 // *** alternate form ***
1101 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
1102
1103 // *** zero-padding ***
1104 check_exception("The width option should not have a leading zero", SV("{:0}"), input);
1105
1106 // *** precision ***
1107 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
1108
1109 // *** locale-specific form ***
1110 check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
1111
1112 // *** n
1113 check(SV("__(42), (99)___"), SV("{:_^15n}"), input);
1114
1115 // *** type ***
1116 check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
1117 check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
1118 check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
1119 for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
1120 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
1121
1122 // ***** Only underlying has a format-spec
1123 check(SV("[(42) , (99) ]"), SV("{::7}"), input);
1124 check(SV("[(42)***, (99)***]"), SV("{::*<7}"), input);
1125 check(SV("[_(42)__, _(99)__]"), SV("{::_^7}"), input);
1126 check(SV("[###(42), ###(99)]"), SV("{::#>7}"), input);
1127
1128 check(SV("[(42) , (99) ]"), SV("{::{}}"), input, 7);
1129 check(SV("[(42)***, (99)***]"), SV("{::*<{}}"), input, 7);
1130 check(SV("[_(42)__, _(99)__]"), SV("{::_^{}}"), input, 7);
1131 check(SV("[###(42), ###(99)]"), SV("{::#>{}}"), input, 7);
1132
1133 check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
1134 check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
1135
1136 // *** sign ***
1137 check_exception("The format specifier should consume the input or end with a '}'", SV("{::-}"), input);
1138 check_exception("The format specifier should consume the input or end with a '}'", SV("{::+}"), input);
1139 check_exception("The format specifier should consume the input or end with a '}'", SV("{:: }"), input);
1140
1141 // *** alternate form ***
1142 check_exception("The format specifier should consume the input or end with a '}'", SV("{::#}"), input);
1143
1144 // *** zero-padding ***
1145 check_exception("The width option should not have a leading zero", SV("{::05}"), input);
1146
1147 // *** precision ***
1148 check_exception("The format specifier should consume the input or end with a '}'", SV("{::.}"), input);
1149
1150 // *** locale-specific form ***
1151 check_exception("The format specifier should consume the input or end with a '}'", SV("{::L}"), input);
1152
1153 // *** type ***
1154 check(SV("[42, 99]"), SV("{::n}"), input);
1155 for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>(""))
1156 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
1157
1158 // ***** Both have a format-spec
1159 check(SV("^^[###(42), ###(99)]^^^"), SV("{:^^23:#>7}"), input);
1160 check(SV("^^[###(42), ###(99)]^^^"), SV("{:^^23:#>7}"), input);
1161 check(SV("^^[###(42), ###(99)]^^^"), SV("{:^^{}:#>7}"), input, 23);
1162 check(SV("^^[###(42), ###(99)]^^^"), SV("{:^^{}:#>{}}"), input, 23, 7);
1163
1164 check_exception(
1165 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}:#>5}"), input);
1166 check_exception(
1167 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}:#>{}}"), input, 23);
1168}
1169
1170//
1171// Tuple 3
1172//
1173
1174template <class CharT, class TestFunction, class ExceptionTest>
1175void test_tuple_int_int_int(TestFunction check, ExceptionTest check_exception) {
1176 std::array input{std::make_tuple(args: 42, args: 99, args: 0), std::make_tuple(args: 1, args: 10, args: 100)};
1177
1178 check(SV("[(42, 99, 0), (1, 10, 100)]"), SV("{}"), input);
1179 check(SV("[(42, 99, 0), (1, 10, 100)]^42"), SV("{}^42"), input);
1180 check(SV("[(42, 99, 0), (1, 10, 100)]^42"), SV("{:}^42"), input);
1181
1182 // ***** underlying has no format-spec
1183
1184 // *** align-fill & width ***
1185 check(SV("[(42, 99, 0), (1, 10, 100)] "), SV("{:32}"), input);
1186 check(SV("[(42, 99, 0), (1, 10, 100)]*****"), SV("{:*<32}"), input);
1187 check(SV("__[(42, 99, 0), (1, 10, 100)]___"), SV("{:_^32}"), input);
1188 check(SV("#####[(42, 99, 0), (1, 10, 100)]"), SV("{:#>32}"), input);
1189
1190 check(SV("[(42, 99, 0), (1, 10, 100)] "), SV("{:{}}"), input, 32);
1191 check(SV("[(42, 99, 0), (1, 10, 100)]*****"), SV("{:*<{}}"), input, 32);
1192 check(SV("__[(42, 99, 0), (1, 10, 100)]___"), SV("{:_^{}}"), input, 32);
1193 check(SV("#####[(42, 99, 0), (1, 10, 100)]"), SV("{:#>{}}"), input, 32);
1194
1195 check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
1196 check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
1197
1198 // *** sign ***
1199 check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
1200 check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
1201 check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
1202
1203 // *** alternate form ***
1204 check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
1205
1206 // *** zero-padding ***
1207 check_exception("The width option should not have a leading zero", SV("{:0}"), input);
1208
1209 // *** precision ***
1210 check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
1211
1212 // *** locale-specific form ***
1213 check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
1214
1215 // *** n
1216 check(SV("__(42, 99, 0), (1, 10, 100)___"), SV("{:_^30n}"), input);
1217
1218 // *** type ***
1219 check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
1220 check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
1221 check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
1222 for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
1223 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
1224
1225 // ***** Only underlying has a format-spec
1226 check(SV("[(42, 99, 0) , (1, 10, 100) ]"), SV("{::14}"), input);
1227 check(SV("[(42, 99, 0)***, (1, 10, 100)**]"), SV("{::*<14}"), input);
1228 check(SV("[_(42, 99, 0)__, _(1, 10, 100)_]"), SV("{::_^14}"), input);
1229 check(SV("[###(42, 99, 0), ##(1, 10, 100)]"), SV("{::#>14}"), input);
1230
1231 check(SV("[(42, 99, 0) , (1, 10, 100) ]"), SV("{::{}}"), input, 14);
1232 check(SV("[(42, 99, 0)***, (1, 10, 100)**]"), SV("{::*<{}}"), input, 14);
1233 check(SV("[_(42, 99, 0)__, _(1, 10, 100)_]"), SV("{::_^{}}"), input, 14);
1234 check(SV("[###(42, 99, 0), ##(1, 10, 100)]"), SV("{::#>{}}"), input, 14);
1235
1236 check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
1237 check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
1238
1239 // *** sign ***
1240 check_exception("The format specifier should consume the input or end with a '}'", SV("{::-}"), input);
1241 check_exception("The format specifier should consume the input or end with a '}'", SV("{::+}"), input);
1242 check_exception("The format specifier should consume the input or end with a '}'", SV("{:: }"), input);
1243
1244 // *** alternate form ***
1245 check_exception("The format specifier should consume the input or end with a '}'", SV("{::#}"), input);
1246
1247 // *** zero-padding ***
1248 check_exception("The width option should not have a leading zero", SV("{::05}"), input);
1249
1250 // *** precision ***
1251 check_exception("The format specifier should consume the input or end with a '}'", SV("{::.}"), input);
1252
1253 // *** locale-specific form ***
1254 check_exception("The format specifier should consume the input or end with a '}'", SV("{::L}"), input);
1255
1256 // *** type ***
1257 check(SV("[42, 99, 0, 1, 10, 100]"), SV("{::n}"), input);
1258 for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("s"))
1259 check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
1260
1261 // ***** Both have a format-spec
1262 check(SV("^^[###(42, 99, 0), ##(1, 10, 100)]^^^"), SV("{:^^37:#>14}"), input);
1263 check(SV("^^[###(42, 99, 0), ##(1, 10, 100)]^^^"), SV("{:^^37:#>14}"), input);
1264 check(SV("^^[###(42, 99, 0), ##(1, 10, 100)]^^^"), SV("{:^^{}:#>14}"), input, 37);
1265 check(SV("^^[###(42, 99, 0), ##(1, 10, 100)]^^^"), SV("{:^^{}:#>{}}"), input, 37, 14);
1266
1267 check_exception(
1268 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}:#>5}"), input);
1269 check_exception(
1270 "The argument index value is too large for the number of arguments supplied", SV("{:^^{}:#>{}}"), input, 37);
1271}
1272
1273//
1274// Ranges
1275//
1276
1277template <class CharT, class TestFunction, class ExceptionTest>
1278void test_with_ranges(TestFunction check, ExceptionTest check_exception, auto&& iter) {
1279 std::ranges::subrange range{std::move(iter), std::default_sentinel};
1280 test_int<CharT>(check, check_exception, std::move(range));
1281}
1282
1283template <class CharT, class TestFunction, class ExceptionTest>
1284void test_with_ranges(TestFunction check, ExceptionTest check_exception) {
1285 std::array input{1, 2, 42, -42};
1286 test_with_ranges<CharT>(
1287 check, check_exception, std::counted_iterator{cpp20_input_iterator<int*>(input.data()), input.size()});
1288 test_with_ranges<CharT>(
1289 check, check_exception, std::counted_iterator{forward_iterator<int*>(input.data()), input.size()});
1290 test_with_ranges<CharT>(
1291 check, check_exception, std::counted_iterator{bidirectional_iterator<int*>(input.data()), input.size()});
1292 test_with_ranges<CharT>(
1293 check, check_exception, std::counted_iterator{random_access_iterator<int*>(input.data()), input.size()});
1294 test_with_ranges<CharT>(
1295 check, check_exception, std::counted_iterator{contiguous_iterator<int*>(input.data()), input.size()});
1296}
1297
1298//
1299// Adaptor
1300//
1301
1302template <class CharT>
1303class non_contiguous {
1304 // A deque iterator is random access, but not contiguous.
1305 using adaptee = std::deque<CharT>;
1306
1307public:
1308 using iterator = typename adaptee::iterator;
1309 using pointer = typename adaptee::pointer;
1310
1311 iterator begin() { return data_.begin(); }
1312 iterator end() { return data_.end(); }
1313
1314 explicit non_contiguous(adaptee&& data) : data_(std::move(data)) {}
1315
1316private:
1317 adaptee data_;
1318};
1319
1320template <class CharT>
1321class contiguous {
1322 // A vector iterator is contiguous.
1323 using adaptee = std::vector<CharT>;
1324
1325public:
1326 using iterator = typename adaptee::iterator;
1327 using pointer = typename adaptee::pointer;
1328
1329 iterator begin() { return data_.begin(); }
1330 iterator end() { return data_.end(); }
1331
1332 explicit contiguous(adaptee&& data) : data_(std::move(data)) {}
1333
1334private:
1335 adaptee data_;
1336};
1337
1338// This tests two different implementations in libc++. A basic_string_view
1339// formatter if the range is contiguous, a basic_string otherwise.
1340template <class CharT, class TestFunction, class ExceptionTest>
1341void test_adaptor(TestFunction check, ExceptionTest check_exception) {
1342 static_assert(std::format_kind<non_contiguous<CharT>> == std::range_format::sequence);
1343 static_assert(std::ranges::sized_range<non_contiguous<CharT>>);
1344 static_assert(!std::ranges::contiguous_range<non_contiguous<CharT>>);
1345 test_char_string<CharT>(
1346 check,
1347 check_exception,
1348 non_contiguous<CharT>{std::deque{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')}});
1349
1350 static_assert(std::format_kind<contiguous<CharT>> == std::range_format::sequence);
1351 static_assert(std::ranges::sized_range<contiguous<CharT>>);
1352 static_assert(std::ranges::contiguous_range<contiguous<CharT>>);
1353 test_char_string<CharT>(check,
1354 check_exception,
1355 contiguous<CharT>{std::vector{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')}});
1356}
1357
1358//
1359// Driver
1360//
1361
1362template <class CharT, class TestFunction, class ExceptionTest>
1363void format_tests(TestFunction check, ExceptionTest check_exception) {
1364 test_char<CharT>(check, check_exception);
1365#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1366 if (std::same_as<CharT, wchar_t>) // avoid testing twice
1367 test_char_to_wchar(check, check_exception);
1368#endif
1369 test_bool<CharT>(check, check_exception);
1370 test_int<CharT>(check, check_exception);
1371 test_floating_point<CharT>(check, check_exception);
1372 test_pointer<CharT>(check, check_exception);
1373 test_string<CharT>(check, check_exception);
1374
1375 test_status<CharT>(check, check_exception); // Has its own handler with its own parser
1376
1377 test_pair_tuple<CharT>(check, check_exception);
1378 test_tuple_int<CharT>(check, check_exception);
1379 test_tuple_int_int_int<CharT>(check, check_exception);
1380
1381 test_with_ranges<CharT>(check, check_exception);
1382
1383 test_adaptor<CharT>(check, check_exception);
1384}
1385
1386#endif // TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FORMATTER_FORMAT_FUNCTIONS_TESTS_H
1387

source code of libcxx/test/std/utilities/format/format.range/format.range.formatter/format.functions.tests.h