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

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