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

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