[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / libcxx / test / std / time / time.syn / formatter.year_month.pass.cpp
blob96b654d828b48bf3a1a249d7b9b53402249623dd
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 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 // UNSUPPORTED: no-localization
11 // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
13 // TODO FMT This test should not require std::to_chars(floating-point)
14 // XFAIL: availability-fp_to_chars-missing
16 // REQUIRES: locale.fr_FR.UTF-8
17 // REQUIRES: locale.ja_JP.UTF-8
19 // <chrono>
21 // template<class charT> struct formatter<chrono::year_month, charT>;
23 #include <chrono>
24 #include <format>
26 #include <cassert>
27 #include <concepts>
28 #include <locale>
29 #include <iostream>
30 #include <type_traits>
32 #include "formatter_tests.h"
33 #include "make_string.h"
34 #include "platform_support.h" // locale name macros
35 #include "string_literal.h"
36 #include "test_macros.h"
38 template <class CharT>
39 static void test_no_chrono_specs() {
40 // Valid month
41 check(SV("1970/Jan"), SV("{}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
42 check(SV("*1970/Jan*"), SV("{:*^10}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
43 check(SV("*1970/Jan"), SV("{:*>9}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
45 // Invalid month_day
46 check(SV("1970/0 is not a valid month"),
47 SV("{}"),
48 std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
49 check(SV("*1970/0 is not a valid month*"),
50 SV("{:*^29}"),
51 std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
54 template <class CharT>
55 static void test_invalid_values() {
56 // Test that %b and %B throw an exception.
57 check_exception("Formatting a month name from an invalid month number",
58 SV("{:%b}"),
59 std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
61 check_exception("Formatting a month name from an invalid month number",
62 SV("{:%B}"),
63 std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
66 template <class CharT>
67 static void test_valid_values() {
68 constexpr std::basic_string_view<CharT> fmt = SV(
69 "{:"
70 "%%b='%b'%t"
71 "%%B='%B'%t"
72 "%%C='%C'%t"
73 "%%h='%h'%t"
74 "%%y='%y'%t"
75 "%%Y='%Y'%t"
76 "%%EC='%EC'%t"
77 "%%Ey='%Ey'%t"
78 "%%EY='%EY'%t"
79 "%%Oy='%Oy'%t"
80 "%n}");
82 constexpr std::basic_string_view<CharT> lfmt = SV(
83 "{:L"
84 "%%b='%b'%t"
85 "%%B='%B'%t"
86 "%%C='%C'%t"
87 "%%h='%h'%t"
88 "%%y='%y'%t"
89 "%%Y='%Y'%t"
90 "%%EC='%EC'%t"
91 "%%Ey='%Ey'%t"
92 "%%EY='%EY'%t"
93 "%%Oy='%Oy'%t"
94 "%n}");
96 const std::locale loc(LOCALE_ja_JP_UTF_8);
97 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
99 // Non localized output using C-locale
100 check(SV("%b='Jan'\t"
101 "%B='January'\t"
102 "%C='19'\t"
103 "%h='Jan'\t"
104 "%y='70'\t"
105 "%Y='1970'\t"
106 "%EC='19'\t"
107 "%Ey='70'\t"
108 "%EY='1970'\t"
109 "%Oy='70'\t"
110 "\n"),
111 fmt,
112 std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
114 check(SV("%b='May'\t"
115 "%B='May'\t"
116 "%C='20'\t"
117 "%h='May'\t"
118 "%y='04'\t"
119 "%Y='2004'\t"
120 "%EC='20'\t"
121 "%Ey='04'\t"
122 "%EY='2004'\t"
123 "%Oy='04'\t"
124 "\n"),
125 fmt,
126 std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
128 // Use the global locale (fr_FR)
129 check(SV(
130 #if defined(__APPLE__)
131 "%b='jan'\t"
132 #else
133 "%b='janv.'\t"
134 #endif
135 "%B='janvier'\t"
136 "%C='19'\t"
137 #if defined(__APPLE__)
138 "%h='jan'\t"
139 #else
140 "%h='janv.'\t"
141 #endif
142 "%y='70'\t"
143 "%Y='1970'\t"
144 "%EC='19'\t"
145 "%Ey='70'\t"
146 "%EY='1970'\t"
147 "%Oy='70'\t"
148 "\n"),
149 lfmt,
150 std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
152 check(SV("%b='mai'\t"
153 "%B='mai'\t"
154 "%C='20'\t"
155 "%h='mai'\t"
156 "%y='04'\t"
157 "%Y='2004'\t"
158 "%EC='20'\t"
159 "%Ey='04'\t"
160 "%EY='2004'\t"
161 "%Oy='04'\t"
162 "\n"),
163 lfmt,
164 std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
166 // Use supplied locale (ja_JP)
167 check(loc,
169 #if defined(_WIN32)
170 "%b='1'\t"
171 #elif defined(_AIX) // defined(_WIN32)
172 "%b='1月'\t"
173 #elif defined(__APPLE__) // defined(_WIN32)
174 "%b=' 1'\t"
175 #else // defined(_WIN32)
176 "%b=' 1月'\t"
177 #endif // defined(_WIN32)
178 "%B='1月'\t"
179 "%C='19'\t"
180 #if defined(_WIN32)
181 "%h='1'\t"
182 #elif defined(_AIX) // defined(_WIN32)
183 "%h='1月'\t"
184 #elif defined(__APPLE__) // defined(_WIN32)
185 "%h=' 1'\t"
186 #else // defined(_WIN32)
187 "%h=' 1月'\t"
188 #endif // defined(_WIN32)
189 "%y='70'\t"
190 "%Y='1970'\t"
191 #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
192 "%EC='19'\t"
193 "%Ey='70'\t"
194 "%EY='1970'\t"
195 "%Oy='70'\t"
196 #else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
197 "%EC='昭和'\t"
198 "%Ey='45'\t"
199 "%EY='昭和45年'\t"
200 "%Oy='七十'\t"
201 #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
202 "\n"),
203 lfmt,
204 std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
206 check(loc,
209 #if defined(_WIN32)
210 "%b='5'\t"
211 #elif defined(_AIX) // defined(_WIN32)
212 "%b='5月'\t"
213 #elif defined(__APPLE__) // defined(_WIN32)
214 "%b=' 5'\t"
215 #else // defined(_WIN32)
216 "%b=' 5月'\t"
217 #endif // defined(_WIN32)
218 "%B='5月'\t"
219 "%C='20'\t"
220 #if defined(_WIN32)
221 "%h='5'\t"
222 #elif defined(_AIX) // defined(_WIN32)
223 "%h='5月'\t"
224 #elif defined(__APPLE__) // defined(_WIN32)
225 "%h=' 5'\t"
226 #else // defined(_WIN32)
227 "%h=' 5月'\t"
228 #endif // defined(_WIN32)
229 "%y='04'\t"
230 "%Y='2004'\t"
231 #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
232 "%EC='20'\t"
233 "%Ey='04'\t"
234 "%EY='2004'\t"
235 "%Oy='04'\t"
236 #else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
237 "%EC='平成'\t"
238 "%Ey='16'\t"
239 "%EY='平成16年'\t"
240 "%Oy='四'\t"
241 #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
242 "\n"),
243 lfmt,
244 std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
246 std::locale::global(std::locale::classic());
249 template <class CharT>
250 static void test() {
251 test_no_chrono_specs<CharT>();
252 test_invalid_values<CharT>();
253 test_valid_values<CharT>();
255 check_invalid_types<CharT>(
256 {SV("b"), SV("B"), SV("C"), SV("EC"), SV("Ey"), SV("EY"), SV("h"), SV("m"), SV("Om"), SV("Oy"), SV("y"), SV("Y")},
257 std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
259 check_exception("The format specifier expects a '%' or a '}'",
260 SV("{:A"),
261 std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
262 check_exception("The chrono specifiers contain a '{'",
263 SV("{:%%{"),
264 std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
265 check_exception("End of input while parsing a conversion specifier",
266 SV("{:%"),
267 std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
268 check_exception("End of input while parsing the modifier E",
269 SV("{:%E"),
270 std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
271 check_exception("End of input while parsing the modifier O",
272 SV("{:%O"),
273 std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
275 // Precision not allowed
276 check_exception("The format specifier expects a '%' or a '}'",
277 SV("{:.3}"),
278 std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
281 int main(int, char**) {
282 test<char>();
284 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
285 test<wchar_t>();
286 #endif
288 return 0;