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

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