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_CONTAINERS_SEQUENCES_VECTOR_BOOL_VECTOR_BOOL_FMT_FORMAT_FUNCTIONS_TESTS_H |
9 | #define TEST_STD_CONTAINERS_SEQUENCES_VECTOR_BOOL_VECTOR_BOOL_FMT_FORMAT_FUNCTIONS_TESTS_H |
10 | |
11 | #include <vector> |
12 | |
13 | #include "format.functions.common.h" |
14 | #include "test_macros.h" |
15 | |
16 | template <class CharT, class TestFunction, class ExceptionTest> |
17 | void format_test_vector_bool(TestFunction check, ExceptionTest check_exception, auto&& input) { |
18 | check(SV("[true, true, false]" ), SV("{}" ), input); |
19 | check(SV("[true, true, false]^42" ), SV("{}^42" ), input); |
20 | check(SV("[true, true, false]^42" ), SV("{:}^42" ), input); |
21 | |
22 | // ***** underlying has no format-spec |
23 | |
24 | // *** align-fill & width *** |
25 | check(SV("[true, true, false] " ), SV("{:24}" ), input); |
26 | check(SV("[true, true, false]*****" ), SV("{:*<24}" ), input); |
27 | check(SV("__[true, true, false]___" ), SV("{:_^24}" ), input); |
28 | check(SV("#####[true, true, false]" ), SV("{:#>24}" ), input); |
29 | |
30 | check(SV("[true, true, false] " ), SV("{:{}}" ), input, 24); |
31 | check(SV("[true, true, false]*****" ), SV("{:*<{}}" ), input, 24); |
32 | check(SV("__[true, true, false]___" ), SV("{:_^{}}" ), input, 24); |
33 | check(SV("#####[true, true, false]" ), SV("{:#>{}}" ), input, 24); |
34 | |
35 | check_exception("The format string contains an invalid escape sequence" , SV("{:}<}" ), input); |
36 | check_exception("The fill option contains an invalid value" , SV("{:{<}" ), input); |
37 | |
38 | // *** sign *** |
39 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{:-}" ), input); |
40 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{:+}" ), input); |
41 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{: }" ), input); |
42 | |
43 | // *** alternate form *** |
44 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{:#}" ), input); |
45 | |
46 | // *** zero-padding *** |
47 | check_exception("The width option should not have a leading zero" , SV("{:0}" ), input); |
48 | |
49 | // *** precision *** |
50 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{:.}" ), input); |
51 | |
52 | // *** locale-specific form *** |
53 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{:L}" ), input); |
54 | |
55 | // *** n |
56 | check(SV("__true, true, false___" ), SV("{:_^22n}" ), input); |
57 | |
58 | // *** type *** |
59 | check_exception("Type m requires a pair or a tuple with two elements" , SV("{:m}" ), input); |
60 | check_exception("Type s requires character type as formatting argument" , SV("{:s}" ), input); |
61 | check_exception("Type ?s requires character type as formatting argument" , SV("{:?s}" ), input); |
62 | |
63 | for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s" )) |
64 | check_exception("The format specifier should consume the input or end with a '}'" , fmt, input); |
65 | |
66 | // ***** Only underlying has a format-spec |
67 | check(SV("[true , true , false ]" ), SV("{::7}" ), input); |
68 | check(SV("[true***, true***, false**]" ), SV("{::*<7}" ), input); |
69 | check(SV("[_true__, _true__, _false_]" ), SV("{::_^7}" ), input); |
70 | check(SV("[:::true, :::true, ::false]" ), SV("{:::>7}" ), input); |
71 | |
72 | check(SV("[true , true , false ]" ), SV("{::{}}" ), input, 7); |
73 | check(SV("[true***, true***, false**]" ), SV("{::*<{}}" ), input, 7); |
74 | check(SV("[_true__, _true__, _false_]" ), SV("{::_^{}}" ), input, 7); |
75 | check(SV("[:::true, :::true, ::false]" ), SV("{:::>{}}" ), input, 7); |
76 | |
77 | check_exception("The format string contains an invalid escape sequence" , SV("{::}<}" ), input); |
78 | check_exception("The fill option contains an invalid value" , SV("{::{<}" ), input); |
79 | |
80 | // *** sign *** |
81 | check_exception("The format specifier for a bool does not allow the sign option" , SV("{::-}" ), input); |
82 | check_exception("The format specifier for a bool does not allow the sign option" , SV("{::+}" ), input); |
83 | check_exception("The format specifier for a bool does not allow the sign option" , SV("{:: }" ), input); |
84 | |
85 | check(SV("[1, 1, 0]" ), SV("{::-d}" ), input); |
86 | check(SV("[+1, +1, +0]" ), SV("{::+d}" ), input); |
87 | check(SV("[ 1, 1, 0]" ), SV("{:: d}" ), input); |
88 | |
89 | // *** alternate form *** |
90 | check_exception("The format specifier for a bool does not allow the alternate form option" , SV("{::#}" ), input); |
91 | |
92 | check(SV("[0x1, 0x1, 0x0]" ), SV("{::#x}" ), input); |
93 | |
94 | // *** zero-padding *** |
95 | check_exception("The format specifier for a bool does not allow the zero-padding option" , SV("{::05}" ), input); |
96 | |
97 | check(SV("[00001, 00001, 00000]" ), SV("{::05o}" ), input); |
98 | |
99 | // *** precision *** |
100 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{::.}" ), input); |
101 | |
102 | // *** type *** |
103 | for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBdosxX" )) |
104 | check_exception("The type option contains an invalid value for a bool formatting argument" , fmt, input); |
105 | |
106 | // ***** Both have a format-spec |
107 | check(SV("^^[:::true, :::true, ::false]^^^" ), SV("{:^^32::>7}" ), input); |
108 | check(SV("^^[:::true, :::true, ::false]^^^" ), SV("{:^^{}::>7}" ), input, 32); |
109 | check(SV("^^[:::true, :::true, ::false]^^^" ), SV("{:^^{}::>{}}" ), input, 32, 7); |
110 | |
111 | check_exception( |
112 | "The argument index value is too large for the number of arguments supplied" , SV("{:^^{}::>5}" ), input); |
113 | check_exception( |
114 | "The argument index value is too large for the number of arguments supplied" , SV("{:^^{}::>{}}" ), input, 32); |
115 | } |
116 | |
117 | template <class CharT, class TestFunction, class ExceptionTest> |
118 | void format_tests(TestFunction check, ExceptionTest check_exception) { |
119 | format_test_vector_bool<CharT>(check, check_exception, std::vector{true, true, false}); |
120 | |
121 | // The const_reference shall be a bool. |
122 | // However libc++ uses a __bit_const_reference<vector> when |
123 | // _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL is defined. |
124 | const std::vector input{true, true, false}; |
125 | format_test_vector_bool<CharT>(check, check_exception, input); |
126 | } |
127 | |
128 | #endif // TEST_STD_CONTAINERS_SEQUENCES_VECTOR_BOOL_VECTOR_BOOL_FMT_FORMAT_FUNCTIONS_TESTS_H |
129 | |