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_CONTAINERS_CONTAINER_ADAPTORS_CONTAINER_ADAPTORS_FORMAT_FORMAT_FUNCTIONS_TESTS_H
10 #define TEST_STD_CONTAINERS_CONTAINER_ADAPTORS_CONTAINER_ADAPTORS_FORMAT_FORMAT_FUNCTIONS_TESTS_H
11 
12 #include <algorithm>
13 #include <array>
14 #include <charconv>
15 #include <concepts>
16 #include <format>
17 #include <list>
18 #include <queue>
19 #include <stack>
20 
21 #include "format.functions.common.h"
22 #include "make_string.h"
23 #include "platform_support.h" // locale name macros
24 #include "test_macros.h"
25 
26 //
27 // Char
28 //
29 
30 template <class CharT, class TestFunction, class ExceptionTest>
31 void test_char_default(TestFunction check, ExceptionTest check_exception, auto&& input) {
32   // Note when no range-underlying-spec is present the char is escaped,
33   check(SV("['H', 'e', 'l', 'l', 'o']"), SV("{}"), input);
34   check(SV("['H', 'e', 'l', 'l', 'o']^42"), SV("{}^42"), input);
35   check(SV("['H', 'e', 'l', 'l', 'o']^42"), SV("{:}^42"), input);
36 
37   // when one is present there is no escaping,
38   check(SV("[H, e, l, l, o]"), SV("{::}"), input);
39   check(SV("[H, e, l, l, o]"), SV("{::<}"), input);
40   // unless forced by the type specifier.
41   check(SV("['H', 'e', 'l', 'l', 'o']"), SV("{::?}"), input);
42   check(SV("['H', 'e', 'l', 'l', 'o']"), SV("{::<?}"), input);
43 
44   // ***** underlying has no format-spec
45 
46   // *** align-fill & width ***
47   check(SV("['H', 'e', 'l', 'l', 'o']     "), SV("{:30}"), input);
48   check(SV("['H', 'e', 'l', 'l', 'o']*****"), SV("{:*<30}"), input);
49   check(SV("__['H', 'e', 'l', 'l', 'o']___"), SV("{:_^30}"), input);
50   check(SV("#####['H', 'e', 'l', 'l', 'o']"), SV("{:#>30}"), input);
51 
52   check(SV("['H', 'e', 'l', 'l', 'o']     "), SV("{:{}}"), input, 30);
53   check(SV("['H', 'e', 'l', 'l', 'o']*****"), SV("{:*<{}}"), input, 30);
54   check(SV("__['H', 'e', 'l', 'l', 'o']___"), SV("{:_^{}}"), input, 30);
55   check(SV("#####['H', 'e', 'l', 'l', 'o']"), SV("{:#>{}}"), input, 30);
56 
57   check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
58   check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
59 
60   // *** sign ***
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   check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
64 
65   // *** alternate form ***
66   check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
67 
68   // *** zero-padding ***
69   check_exception("The width option should not have a leading zero", SV("{:0}"), input);
70 
71   // *** precision ***
72   check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
73 
74   // *** locale-specific form ***
75   check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
76 
77   // *** n
78   check(SV("__'H', 'e', 'l', 'l', 'o'___"), SV("{:_^28n}"), input);
79 
80   // *** type ***
81   check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
82   for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
83     check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
84 
85   // ***** Only underlying has a format-spec
86   check(SV("[H   , e   , l   , l   , o   ]"), SV("{::4}"), input);
87   check(SV("[H***, e***, l***, l***, o***]"), SV("{::*<4}"), input);
88   check(SV("[_H__, _e__, _l__, _l__, _o__]"), SV("{::_^4}"), input);
89   check(SV("[:::H, :::e, :::l, :::l, :::o]"), SV("{:::>4}"), input);
90 
91   check(SV("[H   , e   , l   , l   , o   ]"), SV("{::{}}"), input, 4);
92   check(SV("[H***, e***, l***, l***, o***]"), SV("{::*<{}}"), input, 4);
93   check(SV("[_H__, _e__, _l__, _l__, _o__]"), SV("{::_^{}}"), input, 4);
94   check(SV("[:::H, :::e, :::l, :::l, :::o]"), SV("{:::>{}}"), input, 4);
95 
96   check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
97   check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
98 
99   // *** sign ***
100   check_exception("The format specifier for a character does not allow the sign option", SV("{::-}"), input);
101   check_exception("The format specifier for a character does not allow the sign option", SV("{::+}"), input);
102   check_exception("The format specifier for a character does not allow the sign option", SV("{:: }"), input);
103 
104   check(SV("[72, 101, 108, 108, 111]"), SV("{::-d}"), input);
105   check(SV("[+72, +101, +108, +108, +111]"), SV("{::+d}"), input);
106   check(SV("[ 72,  101,  108,  108,  111]"), SV("{:: d}"), input);
107 
108   // *** alternate form ***
109   check_exception("The format specifier for a character does not allow the alternate form option", SV("{::#}"), input);
110 
111   check(SV("[0x48, 0x65, 0x6c, 0x6c, 0x6f]"), SV("{::#x}"), input);
112 
113   // *** zero-padding ***
114   check_exception("The format specifier for a character does not allow the zero-padding option", SV("{::05}"), input);
115 
116   check(SV("[00110, 00145, 00154, 00154, 00157]"), SV("{::05o}"), input);
117 
118   // *** precision ***
119   check_exception("The format specifier should consume the input or end with a '}'", SV("{::.}"), input);
120 
121   // *** locale-specific form ***
122   check(SV("[H, e, l, l, o]"), SV("{::L}"), input);
123 
124   // *** type ***
125   for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX?"))
126     check_exception("The type option contains an invalid value for a character formatting argument", fmt, input);
127 
128   // ***** Both have a format specifier
129   check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^25::>2}"), input);
130   check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^{}::>2}"), input, 25);
131   check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^{}::>{}}"), input, 25, 2);
132 
133   check_exception(
134       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>2}"), input);
135   check_exception(
136       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}}"), input, 25);
137 }
138 
139 template <class CharT, class TestFunction, class ExceptionTest>
140 void test_char_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
141   check(SV("Hello"), SV("{:s}"), input);
142 
143   // ***** underlying has no format-spec
144 
145   // *** align-fill & width ***
146   check(SV("Hello   "), SV("{:8s}"), input);
147   check(SV("Hello***"), SV("{:*<8s}"), input);
148   check(SV("_Hello__"), SV("{:_^8s}"), input);
149   check(SV("###Hello"), SV("{:#>8s}"), input);
150 
151   check(SV("Hello   "), SV("{:{}s}"), input, 8);
152   check(SV("Hello***"), SV("{:*<{}s}"), input, 8);
153   check(SV("_Hello__"), SV("{:_^{}s}"), input, 8);
154   check(SV("###Hello"), SV("{:#>{}s}"), input, 8);
155 
156   check_exception("The format string contains an invalid escape sequence", SV("{:}<s}"), input);
157   check_exception("The fill option contains an invalid value", SV("{:{<s}"), input);
158 
159   // *** sign ***
160   check_exception("The format specifier should consume the input or end with a '}'", SV("{:-s}"), input);
161   check_exception("The format specifier should consume the input or end with a '}'", SV("{:+s}"), input);
162   check_exception("The format specifier should consume the input or end with a '}'", SV("{: s}"), input);
163 
164   // *** alternate form ***
165   check_exception("The format specifier should consume the input or end with a '}'", SV("{:#s}"), input);
166 
167   // *** zero-padding ***
168   check_exception("The width option should not have a leading zero", SV("{:0s}"), input);
169 
170   // *** precision ***
171   check_exception("The format specifier should consume the input or end with a '}'", SV("{:.s}"), input);
172 
173   // *** locale-specific form ***
174   check_exception("The format specifier should consume the input or end with a '}'", SV("{:Ls}"), input);
175 
176   // *** n
177   check_exception("The n option and type s can't be used together", SV("{:ns}"), input);
178 
179   // *** type ***
180   check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
181   check_exception("The type option contains an invalid value for a character formatting argument", SV("{::<s}"), input);
182 
183   // ***** Only underlying has a format-spec
184   check_exception("Type s and an underlying format specification can't be used together", SV("{:s:}"), input);
185   for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX?"))
186     check_exception("The type option contains an invalid value for a character formatting argument", fmt, input);
187 
188   // ***** Both have a format-spec
189   check_exception("Type s and an underlying format specification can't be used together", SV("{:5s:5}"), input);
190 }
191 
192 template <class CharT, class TestFunction, class ExceptionTest>
193 void test_char_escaped_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
194   check(SV(R"("Hello")"), SV("{:?s}"), input);
195 
196   // ***** underlying has no format-spec
197 
198   // *** align-fill & width ***
199   check(SV(R"("Hello"   )"), SV("{:10?s}"), input);
200   check(SV(R"("Hello"***)"), SV("{:*<10?s}"), input);
201   check(SV(R"(_"Hello"__)"), SV("{:_^10?s}"), input);
202   check(SV(R"(###"Hello")"), SV("{:#>10?s}"), input);
203 
204   check(SV(R"("Hello"   )"), SV("{:{}?s}"), input, 10);
205   check(SV(R"("Hello"***)"), SV("{:*<{}?s}"), input, 10);
206   check(SV(R"(_"Hello"__)"), SV("{:_^{}?s}"), input, 10);
207   check(SV(R"(###"Hello")"), SV("{:#>{}?s}"), input, 10);
208 
209   check_exception("The format string contains an invalid escape sequence", SV("{:}<?s}"), input);
210   check_exception("The fill option contains an invalid value", SV("{:{<?s}"), input);
211   check_exception("The format specifier should consume the input or end with a '}'", SV("{::<?s}"), input);
212 
213   // *** sign ***
214   check_exception("The format specifier should consume the input or end with a '}'", SV("{:-?s}"), input);
215   check_exception("The format specifier should consume the input or end with a '}'", SV("{:+?s}"), input);
216   check_exception("The format specifier should consume the input or end with a '}'", SV("{: ?s}"), input);
217 
218   // *** alternate form ***
219   check_exception("The format specifier should consume the input or end with a '}'", SV("{:#?s}"), input);
220 
221   // *** zero-padding ***
222   check_exception("The width option should not have a leading zero", SV("{:0?s}"), input);
223 
224   // *** precision ***
225   check_exception("The format specifier should consume the input or end with a '}'", SV("{:.?s}"), input);
226 
227   // *** locale-specific form ***
228   check_exception("The format specifier should consume the input or end with a '}'", SV("{:L?s}"), input);
229 
230   // *** n
231   check_exception("The n option and type ?s can't be used together", SV("{:n?s}"), input);
232 
233   // *** type ***
234   check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
235 
236   // ***** Only underlying has a format-spec
237   check_exception("Type ?s and an underlying format specification can't be used together", SV("{:?s:}"), input);
238 
239   // ***** Both have a format-spec
240   check_exception("Type ?s and an underlying format specification can't be used together", SV("{:5?s:5}"), input);
241 }
242 
243 template <class CharT, class TestFunction, class ExceptionTest>
244 void test_char(TestFunction check, ExceptionTest check_exception) {
245   // These values are in numeric order when using ASCII, which is used by the priority_queue.
246   std::array input{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')};
247   test_char_default<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
248   test_char_default<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
249   test_char_default<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
250 
251   test_char_string<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
252   test_char_string<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
253   test_char_string<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
254 
255   test_char_escaped_string<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
256   test_char_escaped_string<CharT>(
257       check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
258   test_char_escaped_string<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
259 
260   // LWG3881 fixes formatting container adaptors backed by a std::string.
261   test_char_default<CharT>(check, check_exception, std::queue{std::basic_string<CharT>{input.begin(), input.end()}});
262   test_char_default<CharT>(
263       check,
264       check_exception,
265       std::priority_queue{std::greater{}, std::basic_string<CharT>{input.begin(), input.end()}});
266   test_char_default<CharT>(check, check_exception, std::stack{std::basic_string<CharT>{input.begin(), input.end()}});
267 }
268 
269 //
270 // char -> wchar_t
271 //
272 
273 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
274 template <class TestFunction, class ExceptionTest>
275 void test_char_to_wchar(TestFunction check, ExceptionTest check_exception) {
276   std::array input{'H', 'e', 'l', 'l', 'o'};
277   test_char_default<wchar_t>(check, check_exception, std::queue{input.begin(), input.end()});
278   test_char_default<wchar_t>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
279   test_char_default<wchar_t>(check, check_exception, std::stack{input.begin(), input.end()});
280 
281   // The types s and ?s may only be used when using range_formatter<T, charT>
282   // where the types T and charT are the same. This means this can't be used for
283   // range_formatter<wchar_t, char> even when formatter<wchar_t, char> has a
284   // debug-enabled specialization.
285 
286   using CharT = wchar_t;
287   check_exception(
288       "Type s requires character type as formatting argument", SV("{:s}"), std::queue{input.begin(), input.end()});
289   check_exception("Type s requires character type as formatting argument",
290                   SV("{:s}"),
291                   std::priority_queue{input.begin(), input.end()});
292   check_exception(
293       "Type s requires character type as formatting argument", SV("{:s}"), std::stack{input.begin(), input.end()});
294   check_exception(
295       "Type ?s requires character type as formatting argument", SV("{:?s}"), std::queue{input.begin(), input.end()});
296   check_exception("Type ?s requires character type as formatting argument",
297                   SV("{:?s}"),
298                   std::priority_queue{input.begin(), input.end()});
299   check_exception(
300       "Type ?s requires character type as formatting argument", SV("{:?s}"), std::stack{input.begin(), input.end()});
301 }
302 #endif // TEST_HAS_NO_WIDE_CHARACTERS
303 
304 //
305 // Bool
306 //
307 
308 template <class CharT, class TestFunction, class ExceptionTest>
309 void test_bool(TestFunction check, ExceptionTest check_exception, auto&& input) {
310   check(SV("[true, true, false]"), SV("{}"), input);
311   check(SV("[true, true, false]^42"), SV("{}^42"), input);
312   check(SV("[true, true, false]^42"), SV("{:}^42"), input);
313 
314   // ***** underlying has no format-spec
315 
316   // *** align-fill & width ***
317   check(SV("[true, true, false]     "), SV("{:24}"), input);
318   check(SV("[true, true, false]*****"), SV("{:*<24}"), input);
319   check(SV("__[true, true, false]___"), SV("{:_^24}"), input);
320   check(SV("#####[true, true, false]"), SV("{:#>24}"), input);
321 
322   check(SV("[true, true, false]     "), SV("{:{}}"), input, 24);
323   check(SV("[true, true, false]*****"), SV("{:*<{}}"), input, 24);
324   check(SV("__[true, true, false]___"), SV("{:_^{}}"), input, 24);
325   check(SV("#####[true, true, false]"), SV("{:#>{}}"), input, 24);
326 
327   check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
328   check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
329 
330   // *** sign ***
331   check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
332   check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
333   check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
334 
335   // *** alternate form ***
336   check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
337 
338   // *** zero-padding ***
339   check_exception("The width option should not have a leading zero", SV("{:0}"), input);
340 
341   // *** precision ***
342   check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
343 
344   // *** locale-specific form ***
345   check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
346 
347   // *** n
348   check(SV("__true, true, false___"), SV("{:_^22n}"), input);
349 
350   // *** type ***
351   check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
352   check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
353   check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
354   for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
355     check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
356 
357   // ***** Only underlying has a format-spec
358   check(SV("[true   , true   , false  ]"), SV("{::7}"), input);
359   check(SV("[true***, true***, false**]"), SV("{::*<7}"), input);
360   check(SV("[_true__, _true__, _false_]"), SV("{::_^7}"), input);
361   check(SV("[:::true, :::true, ::false]"), SV("{:::>7}"), input);
362 
363   check(SV("[true   , true   , false  ]"), SV("{::{}}"), input, 7);
364   check(SV("[true***, true***, false**]"), SV("{::*<{}}"), input, 7);
365   check(SV("[_true__, _true__, _false_]"), SV("{::_^{}}"), input, 7);
366   check(SV("[:::true, :::true, ::false]"), SV("{:::>{}}"), input, 7);
367 
368   check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
369   check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
370 
371   // *** sign ***
372   check_exception("The format specifier for a bool does not allow the sign option", SV("{::-}"), input);
373   check_exception("The format specifier for a bool does not allow the sign option", SV("{::+}"), input);
374   check_exception("The format specifier for a bool does not allow the sign option", SV("{:: }"), input);
375 
376   check(SV("[1, 1, 0]"), SV("{::-d}"), input);
377   check(SV("[+1, +1, +0]"), SV("{::+d}"), input);
378   check(SV("[ 1,  1,  0]"), SV("{:: d}"), input);
379 
380   // *** alternate form ***
381   check_exception("The format specifier for a bool does not allow the alternate form option", SV("{::#}"), input);
382 
383   check(SV("[0x1, 0x1, 0x0]"), SV("{::#x}"), input);
384 
385   // *** zero-padding ***
386   check_exception("The format specifier for a bool does not allow the zero-padding option", SV("{::05}"), input);
387 
388   check(SV("[00001, 00001, 00000]"), SV("{::05o}"), input);
389 
390   // *** precision ***
391   check_exception("The format specifier should consume the input or end with a '}'", SV("{::.}"), input);
392 
393   // *** locale-specific form ***
394   check(SV("[true, true, false]"), SV("{::L}"), input);
395 
396   // *** type ***
397   for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBdosxX"))
398     check_exception("The type option contains an invalid value for a bool formatting argument", fmt, input);
399 
400   // ***** Both have a format-spec
401   check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^32::>7}"), input);
402   check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^{}::>7}"), input, 32);
403   check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^{}::>{}}"), input, 32, 7);
404 
405   check_exception(
406       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>5}"), input);
407   check_exception(
408       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}}"), input, 32);
409 }
410 
411 template <class CharT, class TestFunction, class ExceptionTest>
412 void test_bool(TestFunction check, ExceptionTest check_exception) {
413   std::array input{true, true, false};
414   test_bool<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
415   test_bool<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end()});
416   test_bool<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
417 }
418 
419 //
420 // Integral
421 //
422 
423 template <class CharT, class TestFunction, class ExceptionTest>
424 void test_int(TestFunction check, ExceptionTest check_exception, auto&& input) {
425   check(SV("[-42, 1, 2, 42]"), SV("{}"), input);
426   check(SV("[-42, 1, 2, 42]^42"), SV("{}^42"), input);
427   check(SV("[-42, 1, 2, 42]^42"), SV("{:}^42"), input);
428 
429   // ***** underlying has no format-spec
430 
431   // *** align-fill & width ***
432   check(SV("[-42, 1, 2, 42]     "), SV("{:20}"), input);
433   check(SV("[-42, 1, 2, 42]*****"), SV("{:*<20}"), input);
434   check(SV("__[-42, 1, 2, 42]___"), SV("{:_^20}"), input);
435   check(SV("#####[-42, 1, 2, 42]"), SV("{:#>20}"), input);
436 
437   check(SV("[-42, 1, 2, 42]     "), SV("{:{}}"), input, 20);
438   check(SV("[-42, 1, 2, 42]*****"), SV("{:*<{}}"), input, 20);
439   check(SV("__[-42, 1, 2, 42]___"), SV("{:_^{}}"), input, 20);
440   check(SV("#####[-42, 1, 2, 42]"), SV("{:#>{}}"), input, 20);
441 
442   check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
443   check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
444 
445   // *** sign ***
446   check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
447   check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
448   check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
449 
450   // *** alternate form ***
451   check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
452 
453   // *** zero-padding ***
454   check_exception("The width option should not have a leading zero", SV("{:0}"), input);
455 
456   // *** precision ***
457   check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
458 
459   // *** locale-specific form ***
460   check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
461 
462   // *** n
463   check(SV("__-42, 1, 2, 42___"), SV("{:_^18n}"), input);
464 
465   // *** type ***
466   check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
467   check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
468   check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
469   for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
470     check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
471 
472   // ***** Only underlying has a format-spec
473   check(SV("[  -42,     1,     2,    42]"), SV("{::5}"), input);
474   check(SV("[-42**, 1****, 2****, 42***]"), SV("{::*<5}"), input);
475   check(SV("[_-42_, __1__, __2__, _42__]"), SV("{::_^5}"), input);
476   check(SV("[::-42, ::::1, ::::2, :::42]"), SV("{:::>5}"), input);
477 
478   check(SV("[  -42,     1,     2,    42]"), SV("{::{}}"), input, 5);
479   check(SV("[-42**, 1****, 2****, 42***]"), SV("{::*<{}}"), input, 5);
480   check(SV("[_-42_, __1__, __2__, _42__]"), SV("{::_^{}}"), input, 5);
481   check(SV("[::-42, ::::1, ::::2, :::42]"), SV("{:::>{}}"), input, 5);
482 
483   check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
484   check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
485 
486   // *** sign ***
487   check(SV("[-42, 1, 2, 42]"), SV("{::-}"), input);
488   check(SV("[-42, +1, +2, +42]"), SV("{::+}"), input);
489   check(SV("[-42,  1,  2,  42]"), SV("{:: }"), input);
490 
491   // *** alternate form ***
492   check(SV("[-0x2a, 0x1, 0x2, 0x2a]"), SV("{::#x}"), input);
493 
494   // *** zero-padding ***
495   check(SV("[-0042, 00001, 00002, 00042]"), SV("{::05}"), input);
496   check(SV("[-002a, 00001, 00002, 0002a]"), SV("{::05x}"), input);
497   check(SV("[-0x2a, 0x001, 0x002, 0x02a]"), SV("{::#05x}"), input);
498 
499   // *** precision ***
500   check_exception("The format specifier should consume the input or end with a '}'", SV("{::.}"), input);
501 
502   // *** locale-specific form ***
503   check(SV("[-42, 1, 2, 42]"), SV("{::L}"), input); // does nothing in this test, but is accepted.
504 
505   // *** type ***
506   for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX"))
507     check_exception("The type option contains an invalid value for an integer formatting argument", fmt, input);
508 
509   // ***** Both have a format-spec
510   check(SV("^^[::-42, ::::1, ::::2, :::42]^^^"), SV("{:^^33::>5}"), input);
511   check(SV("^^[::-42, ::::1, ::::2, :::42]^^^"), SV("{:^^{}::>5}"), input, 33);
512   check(SV("^^[::-42, ::::1, ::::2, :::42]^^^"), SV("{:^^{}::>{}}"), input, 33, 5);
513 
514   check_exception(
515       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>5}"), input);
516   check_exception(
517       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}}"), input, 33);
518 }
519 
520 template <class CharT, class TestFunction, class ExceptionTest>
521 void test_int(TestFunction check, ExceptionTest check_exception) {
522   std::array input{-42, 1, 2, 42};
523   test_int<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
524   test_int<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
525   test_int<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
526 }
527 
528 //
529 // Floating point
530 //
531 
532 template <class CharT, class TestFunction, class ExceptionTest>
533 void test_floating_point(TestFunction check, ExceptionTest check_exception, auto&& input) {
534   check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{}"), input);
535   check(SV("[-42.5, 0, 1.25, 42.5]^42"), SV("{}^42"), input);
536   check(SV("[-42.5, 0, 1.25, 42.5]^42"), SV("{:}^42"), input);
537 
538   // ***** underlying has no format-spec
539 
540   // *** align-fill & width ***
541   check(SV("[-42.5, 0, 1.25, 42.5]     "), SV("{:27}"), input);
542   check(SV("[-42.5, 0, 1.25, 42.5]*****"), SV("{:*<27}"), input);
543   check(SV("__[-42.5, 0, 1.25, 42.5]___"), SV("{:_^27}"), input);
544   check(SV("#####[-42.5, 0, 1.25, 42.5]"), SV("{:#>27}"), input);
545 
546   check(SV("[-42.5, 0, 1.25, 42.5]     "), SV("{:{}}"), input, 27);
547   check(SV("[-42.5, 0, 1.25, 42.5]*****"), SV("{:*<{}}"), input, 27);
548   check(SV("__[-42.5, 0, 1.25, 42.5]___"), SV("{:_^{}}"), input, 27);
549   check(SV("#####[-42.5, 0, 1.25, 42.5]"), SV("{:#>{}}"), input, 27);
550 
551   check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
552   check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
553 
554   // *** sign ***
555   check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
556   check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
557   check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
558 
559   // *** alternate form ***
560   check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
561 
562   // *** zero-padding ***
563   check_exception("The width option should not have a leading zero", SV("{:0}"), input);
564 
565   // *** precision ***
566   check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
567 
568   // *** locale-specific form ***
569   check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
570 
571   // *** n
572   check(SV("__-42.5, 0, 1.25, 42.5___"), SV("{:_^25n}"), input);
573 
574   // *** type ***
575   check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
576   check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
577   check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
578   for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
579     check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
580 
581   // ***** Only underlying has a format-spec
582   check(SV("[-42.5,     0,  1.25,  42.5]"), SV("{::5}"), input);
583   check(SV("[-42.5, 0****, 1.25*, 42.5*]"), SV("{::*<5}"), input);
584   check(SV("[-42.5, __0__, 1.25_, 42.5_]"), SV("{::_^5}"), input);
585   check(SV("[-42.5, ::::0, :1.25, :42.5]"), SV("{:::>5}"), input);
586 
587   check(SV("[-42.5,     0,  1.25,  42.5]"), SV("{::{}}"), input, 5);
588   check(SV("[-42.5, 0****, 1.25*, 42.5*]"), SV("{::*<{}}"), input, 5);
589   check(SV("[-42.5, __0__, 1.25_, 42.5_]"), SV("{::_^{}}"), input, 5);
590   check(SV("[-42.5, ::::0, :1.25, :42.5]"), SV("{:::>{}}"), input, 5);
591 
592   check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
593   check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
594 
595   // *** sign ***
596   check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::-}"), input);
597   check(SV("[-42.5, +0, +1.25, +42.5]"), SV("{::+}"), input);
598   check(SV("[-42.5,  0,  1.25,  42.5]"), SV("{:: }"), input);
599 
600   // *** alternate form ***
601   check(SV("[-42.5, 0., 1.25, 42.5]"), SV("{::#}"), input);
602 
603   // *** zero-padding ***
604   check(SV("[-42.5, 00000, 01.25, 042.5]"), SV("{::05}"), input);
605   check(SV("[-42.5, 0000., 01.25, 042.5]"), SV("{::#05}"), input);
606 
607   // *** precision ***
608   check(SV("[-42, 0, 1.2, 42]"), SV("{::.2}"), input);
609   check(SV("[-42.500, 0.000, 1.250, 42.500]"), SV("{::.3f}"), input);
610 
611   check(SV("[-42, 0, 1.2, 42]"), SV("{::.{}}"), input, 2);
612   check(SV("[-42.500, 0.000, 1.250, 42.500]"), SV("{::.{}f}"), input, 3);
613 
614   check_exception("The precision option does not contain a value or an argument index", SV("{::.}"), input);
615 
616   // *** locale-specific form ***
617   check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::L}"), input); // does not require locales present
618 #ifndef TEST_HAS_NO_LOCALIZATION
619 // TODO FMT Enable with locale testing active
620 #  if 0
621   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
622   check(SV("[-42,5, 0, 1,25, 42,5]"), SV("{::L}"), input);
623 
624   std::locale::global(std::locale(LOCALE_en_US_UTF_8));
625   check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::L}"), input);
626 
627   std::locale::global(std::locale::classic());
628 #  endif
629 #endif // TEST_HAS_NO_LOCALIZATION
630 
631   // *** type ***
632   for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("aAeEfFgG"))
633     check_exception("The type option contains an invalid value for a floating-point formatting argument", fmt, input);
634 
635   // ***** Both have a format-spec
636   check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^33::>5}"), input);
637   check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^{}::>5}"), input, 33);
638   check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^{}::>{}}"), input, 33, 5);
639 
640   check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^33::>5.2}"), input);
641   check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>5.2}"), input, 33);
642   check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>{}.2}"), input, 33, 5);
643   check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>{}.{}}"), input, 33, 5, 2);
644 
645   check_exception(
646       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>5.2}"), input);
647   check_exception(
648       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}.2}"), input, 33);
649   check_exception(
650       "The argument index value is too large for the number of arguments supplied",
651       SV("{:^^{}::>{}.{}}"),
652       input,
653       33,
654       5);
655 }
656 
657 template <class CharT, class TestFunction, class ExceptionTest>
658 void test_floating_point(TestFunction check, ExceptionTest check_exception) {
659   std::array input{-42.5l, 0.0l, 1.25l, 42.5l};
660   test_floating_point<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
661   test_floating_point<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
662   test_floating_point<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
663 }
664 
665 //
666 // Pointer
667 //
668 
669 template <class CharT, class TestFunction, class ExceptionTest>
670 void test_pointer(TestFunction check, ExceptionTest check_exception, auto&& input) {
671   check(SV("[0x0]"), SV("{}"), input);
672   check(SV("[0x0]^42"), SV("{}^42"), input);
673   check(SV("[0x0]^42"), SV("{:}^42"), input);
674 
675   // ***** underlying has no format-spec
676 
677   // *** align-fill & width ***
678   check(SV("[0x0]     "), SV("{:10}"), input);
679   check(SV("[0x0]*****"), SV("{:*<10}"), input);
680   check(SV("__[0x0]___"), SV("{:_^10}"), input);
681   check(SV("#####[0x0]"), SV("{:#>10}"), input);
682 
683   check(SV("[0x0]     "), SV("{:{}}"), input, 10);
684   check(SV("[0x0]*****"), SV("{:*<{}}"), input, 10);
685   check(SV("__[0x0]___"), SV("{:_^{}}"), input, 10);
686   check(SV("#####[0x0]"), SV("{:#>{}}"), input, 10);
687 
688   check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
689   check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
690 
691   // *** sign ***
692   check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
693 
694   // *** alternate form ***
695   check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
696 
697   // *** zero-padding ***
698   check_exception("The width option should not have a leading zero", SV("{:0}"), input);
699 
700   // *** precision ***
701   check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
702 
703   // *** locale-specific form ***
704   check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
705 
706   // *** n
707   check(SV("_0x0_"), SV("{:_^5n}"), input);
708 
709   // *** type ***
710   check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
711   check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
712   check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
713   for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
714     check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
715 
716   // ***** Only underlying has a format-spec
717   check(SV("[  0x0]"), SV("{::5}"), input);
718   check(SV("[0x0**]"), SV("{::*<5}"), input);
719   check(SV("[_0x0_]"), SV("{::_^5}"), input);
720   check(SV("[::0x0]"), SV("{:::>5}"), input);
721 
722   check(SV("[  0x0]"), SV("{::{}}"), input, 5);
723   check(SV("[0x0**]"), SV("{::*<{}}"), input, 5);
724   check(SV("[_0x0_]"), SV("{::_^{}}"), input, 5);
725   check(SV("[::0x0]"), SV("{:::>{}}"), input, 5);
726 
727   check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
728   check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
729 
730   // *** sign ***
731   check_exception("The format specifier should consume the input or end with a '}'", SV("{::-}"), input);
732 
733   // *** alternate form ***
734   check_exception("The format specifier should consume the input or end with a '}'", SV("{::#}"), input);
735 
736   // *** zero-padding ***
737   check(SV("[0x0000]"), SV("{::06}"), input);
738   check(SV("[0x0000]"), SV("{::06p}"), input);
739   check(SV("[0X0000]"), SV("{::06P}"), input);
740 
741   // *** precision ***
742   check_exception("The format specifier should consume the input or end with a '}'", SV("{::.}"), input);
743 
744   // *** locale-specific form ***
745   check_exception("The format specifier should consume the input or end with a '}'", SV("{::L}"), input);
746 
747   // *** type ***
748   for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("pP"))
749     check_exception("The type option contains an invalid value for a pointer formatting argument", fmt, input);
750 
751   // ***** Both have a format-spec
752   check(SV("^^[::0x0]^^^"), SV("{:^^12::>5}"), input);
753   check(SV("^^[::0x0]^^^"), SV("{:^^{}::>5}"), input, 12);
754   check(SV("^^[::0x0]^^^"), SV("{:^^{}::>{}}"), input, 12, 5);
755 
756   check(SV("^^[::0x0]^^^"), SV("{:^^12::>5}"), input);
757   check(SV("^^[::0x0]^^^"), SV("{:^^{}::>5}"), input, 12);
758   check(SV("^^[::0x0]^^^"), SV("{:^^{}::>{}}"), input, 12, 5);
759 
760   check_exception(
761       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>5}"), input);
762   check_exception(
763       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}}"), input, 12);
764 }
765 
766 template <class CharT, class TestFunction, class ExceptionTest>
767 void test_pointer(TestFunction check, ExceptionTest check_exception) {
768   std::array input{static_cast<void*>(0)};
769   test_pointer<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
770   test_pointer<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end()});
771   test_pointer<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
772 }
773 
774 //
775 // String
776 //
777 
778 template <class CharT, class TestFunction, class ExceptionTest>
779 void test_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
780   check(SV(R"(["Hello", "world"])"), SV("{}"), input);
781   check(SV(R"(["Hello", "world"]^42)"), SV("{}^42"), input);
782   check(SV(R"(["Hello", "world"]^42)"), SV("{:}^42"), input);
783 
784   // ***** underlying has no format-spec
785 
786   // *** align-fill & width ***
787   check(SV(R"(["Hello", "world"]     )"), SV("{:23}"), input);
788   check(SV(R"(["Hello", "world"]*****)"), SV("{:*<23}"), input);
789   check(SV(R"(__["Hello", "world"]___)"), SV("{:_^23}"), input);
790   check(SV(R"(#####["Hello", "world"])"), SV("{:#>23}"), input);
791 
792   check(SV(R"(["Hello", "world"]     )"), SV("{:{}}"), input, 23);
793   check(SV(R"(["Hello", "world"]*****)"), SV("{:*<{}}"), input, 23);
794   check(SV(R"(__["Hello", "world"]___)"), SV("{:_^{}}"), input, 23);
795   check(SV(R"(#####["Hello", "world"])"), SV("{:#>{}}"), input, 23);
796 
797   check_exception("The format string contains an invalid escape sequence", SV("{:}<}"), input);
798   check_exception("The fill option contains an invalid value", SV("{:{<}"), input);
799 
800   // *** sign ***
801   check_exception("The format specifier should consume the input or end with a '}'", SV("{:-}"), input);
802 
803   // *** alternate form ***
804   check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
805 
806   // *** zero-padding ***
807   check_exception("The width option should not have a leading zero", SV("{:0}"), input);
808 
809   // *** precision ***
810   check_exception("The format specifier should consume the input or end with a '}'", SV("{:.}"), input);
811 
812   // *** locale-specific form ***
813   check_exception("The format specifier should consume the input or end with a '}'", SV("{:L}"), input);
814 
815   // *** n
816   check(SV(R"(_"Hello", "world"_)"), SV("{:_^18n}"), input);
817 
818   // *** type ***
819   check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
820   check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
821   check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
822   for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
823     check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
824 
825   // ***** Only underlying has a format-spec
826   check(SV(R"([Hello   , world   ])"), SV("{::8}"), input);
827   check(SV(R"([Hello***, world***])"), SV("{::*<8}"), input);
828   check(SV(R"([_Hello__, _world__])"), SV("{::_^8}"), input);
829   check(SV(R"([:::Hello, :::world])"), SV("{:::>8}"), input);
830 
831   check(SV(R"([Hello   , world   ])"), SV("{::{}}"), input, 8);
832   check(SV(R"([Hello***, world***])"), SV("{::*<{}}"), input, 8);
833   check(SV(R"([_Hello__, _world__])"), SV("{::_^{}}"), input, 8);
834   check(SV(R"([:::Hello, :::world])"), SV("{:::>{}}"), input, 8);
835 
836   check_exception("The format string contains an invalid escape sequence", SV("{::}<}"), input);
837   check_exception("The fill option contains an invalid value", SV("{::{<}"), input);
838 
839   // *** sign ***
840   check_exception("The format specifier should consume the input or end with a '}'", SV("{::-}"), input);
841 
842   // *** alternate form ***
843   check_exception("The format specifier should consume the input or end with a '}'", SV("{::#}"), input);
844 
845   // *** zero-padding ***
846   check_exception("The width option should not have a leading zero", SV("{::05}"), input);
847 
848   // *** precision ***
849   check(SV(R"([Hel, wor])"), SV("{::.3}"), input);
850 
851   check(SV(R"([Hel, wor])"), SV("{::.{}}"), input, 3);
852 
853   check_exception("The precision option does not contain a value or an argument index", SV("{::.}"), input);
854 
855   // *** locale-specific form ***
856   check_exception("The format specifier should consume the input or end with a '}'", SV("{::L}"), input);
857 
858   // *** type ***
859   for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("s?"))
860     check_exception("The type option contains an invalid value for a string formatting argument", fmt, input);
861 
862   // ***** Both have a format-spec
863   check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^25::>8}"), input);
864   check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>8}"), input, 25);
865   check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>{}}"), input, 25, 8);
866 
867   check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^25::>8}"), input);
868   check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>8}"), input, 25);
869   check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>{}}"), input, 25, 8);
870 
871   check_exception(
872       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>8}"), input);
873   check_exception(
874       "The argument index value is too large for the number of arguments supplied", SV("{:^^{}::>{}}"), input, 25);
875 }
876 
877 template <class CharT, class TestFunction, class ExceptionTest>
878 void test_string(TestFunction check, ExceptionTest check_exception) {
879   std::array input{STR("Hello"), STR("world")};
880   test_string<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
881   test_string<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
882   test_string<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
883 }
884 
885 //
886 // Handle
887 //
888 
889 template <class CharT, class TestFunction, class ExceptionTest>
890 void test_status(TestFunction check, ExceptionTest check_exception, auto&& input) {
891   check(SV("[0xaaaa, 0x5555, 0xaa55]"), SV("{}"), input);
892   check(SV("[0xaaaa, 0x5555, 0xaa55]^42"), SV("{}^42"), input);
893   check(SV("[0xaaaa, 0x5555, 0xaa55]^42"), SV("{:}^42"), input);
894 
895   // ***** underlying has no format-spec
896 
897   // *** align-fill & width ***
898   check(SV("[0xaaaa, 0x5555, 0xaa55]     "), SV("{:29}"), input);
899   check(SV("[0xaaaa, 0x5555, 0xaa55]*****"), SV("{:*<29}"), input);
900   check(SV("__[0xaaaa, 0x5555, 0xaa55]___"), SV("{:_^29}"), input);
901   check(SV("#####[0xaaaa, 0x5555, 0xaa55]"), SV("{:#>29}"), input);
902 
903   check(SV("[0xaaaa, 0x5555, 0xaa55]     "), SV("{:{}}"), input, 29);
904   check(SV("[0xaaaa, 0x5555, 0xaa55]*****"), SV("{:*<{}}"), input, 29);
905   check(SV("__[0xaaaa, 0x5555, 0xaa55]___"), SV("{:_^{}}"), input, 29);
906   check(SV("#####[0xaaaa, 0x5555, 0xaa55]"), SV("{:#>{}}"), input, 29);
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   check_exception("The format specifier should consume the input or end with a '}'", SV("{:+}"), input);
914   check_exception("The format specifier should consume the input or end with a '}'", SV("{: }"), input);
915 
916   // *** alternate form ***
917   check_exception("The format specifier should consume the input or end with a '}'", SV("{:#}"), input);
918 
919   // *** zero-padding ***
920   check_exception("The width option should not have a leading zero", SV("{:0}"), 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   // *** n
929   check(SV("__0xaaaa, 0x5555, 0xaa55___"), SV("{:_^27n}"), input);
930 
931   // *** type ***
932   check_exception("Type m requires a pair or a tuple with two elements", SV("{:m}"), input);
933   check_exception("Type s requires character type as formatting argument", SV("{:s}"), input);
934   check_exception("Type ?s requires character type as formatting argument", SV("{:?s}"), input);
935   for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
936     check_exception("The format specifier should consume the input or end with a '}'", fmt, input);
937 
938   // ***** Only underlying has a format-spec
939   check_exception("The type option contains an invalid value for a status formatting argument", SV("{::*<7}"), input);
940   for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("sxX"))
941     check_exception("The type option contains an invalid value for a status formatting argument", fmt, input);
942 
943   check(SV("[0xaaaa, 0x5555, 0xaa55]"), SV("{::x}"), input);
944   check(SV("[0XAAAA, 0X5555, 0XAA55]"), SV("{::X}"), input);
945   check(SV("[foo, bar, foobar]"), SV("{::s}"), input);
946 
947   // ***** Both have a format-spec
948   check(SV("^^[0XAAAA, 0X5555, 0XAA55]^^^"), SV("{:^^29:X}"), input);
949   check(SV("^^[0XAAAA, 0X5555, 0XAA55]^^^"), SV("{:^^{}:X}"), input, 29);
950 
951   check_exception("The argument index value is too large for the number of arguments supplied", SV("{:^^{}:X}"), input);
952 }
953 
954 template <class CharT, class TestFunction, class ExceptionTest>
955 void test_status(TestFunction check, ExceptionTest check_exception) {
956   std::array input{status::foo, status::bar, status::foobar};
957   test_status<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
958   test_status<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::less{}});
959   test_status<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
960 }
961 
962 //
963 // Driver
964 //
965 
966 template <class CharT, class TestFunction, class ExceptionTest>
967 void format_tests(TestFunction check, ExceptionTest check_exception) {
968   test_char<CharT>(check, check_exception);
969 #if _LIBCPP_HAS_WIDE_CHARACTERS
970   if (std::same_as<CharT, wchar_t>) // avoid testing twice
971     test_char_to_wchar(check, check_exception);
972 #endif
973   test_bool<CharT>(check, check_exception);
974   test_int<CharT>(check, check_exception);
975   test_floating_point<CharT>(check, check_exception);
976   test_pointer<CharT>(check, check_exception);
977   test_string<CharT>(check, check_exception);
978 
979   test_status<CharT>(check, check_exception); // Has its own handler with its own parser
980 }
981 
982 #endif // TEST_STD_CONTAINERS_CONTAINER_ADAPTORS_CONTAINER_ADAPTORS_FORMAT_FORMAT_FUNCTIONS_TESTS_H
983