Revert "[libc] Use best-fit binary trie to make malloc logarithmic" (#117065)
[llvm-project.git] / libcxx / test / std / time / time.syn / formatter.year.pass.cpp
blobe1a7d788f9db11c46668a377dac96c396caec8af
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, 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 check(SV("-32767"), SV("{}"), std::chrono::year{-32'767});
41 check(SV("-1000"), SV("{}"), std::chrono::year{-1000});
42 check(SV("-0100"), SV("{}"), std::chrono::year{-100});
43 check(SV("-0010"), SV("{}"), std::chrono::year{-10});
44 check(SV("-0001"), SV("{}"), std::chrono::year{-1});
45 check(SV("0000"), SV("{}"), std::chrono::year{0});
46 check(SV("0001"), SV("{}"), std::chrono::year{1});
47 check(SV("0010"), SV("{}"), std::chrono::year{10});
48 check(SV("0100"), SV("{}"), std::chrono::year{100});
49 check(SV("1000"), SV("{}"), std::chrono::year{1000});
50 check(SV("32727"), SV("{}"), std::chrono::year{32'727});
52 // Invalid year
53 check(SV("-32768 is not a valid year"), SV("{}"), std::chrono::year{-32'768});
54 check(SV("-32768 is not a valid year"), SV("{}"), std::chrono::year{32'768});
57 template <class CharT>
58 static void test_valid_values() {
59 constexpr std::basic_string_view<CharT> fmt = SV(
60 "{:"
61 "%%C='%C'%t"
62 "%%EC='%EC'%t"
63 "%%y='%y'%t"
64 "%%Ey='%Ey'%t"
65 "%%Oy='%Oy'%t"
66 "%%Y='%Y'%t"
67 "%%EY='%EY'%t"
68 "%n}");
69 constexpr std::basic_string_view<CharT> lfmt = SV(
70 "{:L"
71 "%%C='%C'%t"
72 "%%EC='%EC'%t"
73 "%%y='%y'%t"
74 "%%Ey='%Ey'%t"
75 "%%Oy='%Oy'%t"
76 "%%Y='%Y'%t"
77 "%%EY='%EY'%t"
78 "%n}");
80 const std::locale loc(LOCALE_ja_JP_UTF_8);
81 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
83 // Non localized output using C-locale
84 check(SV("%C='00'\t"
85 #if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)
86 "%EC='00'\t"
87 #else
88 "%EC='0'\t"
89 #endif
90 "%y='00'\t"
91 "%Ey='00'\t"
92 "%Oy='00'\t"
93 "%Y='0000'\t"
94 #if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)
95 "%EY='0000'\t"
96 #elif defined(_AIX)
97 "%EY=''\t"
98 #else
99 "%EY='0'\t"
100 #endif
101 "\n"),
102 fmt,
103 std::chrono::year{0});
105 check(SV("%C='19'\t"
106 "%EC='19'\t"
107 "%y='70'\t"
108 "%Ey='70'\t"
109 "%Oy='70'\t"
110 "%Y='1970'\t"
111 "%EY='1970'\t"
112 "\n"),
113 fmt,
114 std::chrono::year{1970});
116 check(SV("%C='20'\t"
117 "%EC='20'\t"
118 "%y='38'\t"
119 "%Ey='38'\t"
120 "%Oy='38'\t"
121 "%Y='2038'\t"
122 "%EY='2038'\t"
123 "\n"),
124 fmt,
125 std::chrono::year{2038});
127 // Use the global locale (fr_FR)
128 check(SV("%C='00'\t"
129 #if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)
130 "%EC='00'\t"
131 #else
132 "%EC='0'\t"
133 #endif
134 "%y='00'\t"
135 "%Ey='00'\t"
136 "%Oy='00'\t"
137 "%Y='0000'\t"
138 #if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)
139 "%EY='0000'\t"
140 #elif defined(_AIX)
141 "%EY=''\t"
142 #else
143 "%EY='0'\t"
144 #endif
145 "\n"),
146 lfmt,
147 std::chrono::year{0});
149 check(SV("%C='19'\t"
150 "%EC='19'\t"
151 "%y='70'\t"
152 "%Ey='70'\t"
153 "%Oy='70'\t"
154 "%Y='1970'\t"
155 "%EY='1970'\t"
156 "\n"),
157 lfmt,
158 std::chrono::year{1970});
160 check(SV("%C='20'\t"
161 "%EC='20'\t"
162 "%y='38'\t"
163 "%Ey='38'\t"
164 "%Oy='38'\t"
165 "%Y='2038'\t"
166 "%EY='2038'\t"
167 "\n"),
168 lfmt,
169 std::chrono::year{2038});
171 // Use supplied locale (ja_JP). This locale has a different alternate.
172 #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
174 check(SV("%C='00'\t"
175 # if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)
176 "%EC='00'\t"
177 # else
178 "%EC='0'\t"
179 # endif
180 "%y='00'\t"
181 "%Ey='00'\t"
182 "%Oy='00'\t"
183 "%Y='0000'\t"
184 # if defined(_AIX)
185 "%EY=''\t"
186 # else
187 "%EY='0000'\t"
188 # endif
189 "\n"),
190 lfmt,
191 std::chrono::year{0});
193 check(SV("%C='19'\t"
194 "%EC='19'\t"
195 "%y='70'\t"
196 "%Ey='70'\t"
197 "%Oy='70'\t"
198 "%Y='1970'\t"
199 "%EY='1970'\t"
200 "\n"),
201 lfmt,
202 std::chrono::year{1970});
204 check(SV("%C='20'\t"
205 "%EC='20'\t"
206 "%y='38'\t"
207 "%Ey='38'\t"
208 "%Oy='38'\t"
209 "%Y='2038'\t"
210 "%EY='2038'\t"
211 "\n"),
212 lfmt,
213 std::chrono::year{2038});
215 #else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
216 check(loc,
217 SV("%C='00'\t"
218 "%EC='紀元前'\t"
219 "%y='00'\t"
220 // https://sourceware.org/bugzilla/show_bug.cgi?id=23758
221 # if defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29
222 "%Ey='1'\t"
223 # else
224 "%Ey='01'\t"
225 # endif
226 "%Oy='〇'\t"
227 "%Y='0000'\t"
228 // https://sourceware.org/bugzilla/show_bug.cgi?id=23758
229 # if defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29
230 "%EY='紀元前1年'\t"
231 # else
232 "%EY='紀元前01年'\t"
233 # endif
234 "\n"),
235 lfmt,
236 std::chrono::year{0});
238 check(loc,
239 SV("%C='19'\t"
240 "%EC='昭和'\t"
241 "%y='70'\t"
242 "%Ey='45'\t"
243 "%Oy='七十'\t"
244 "%Y='1970'\t"
245 "%EY='昭和45年'\t"
246 "\n"),
247 lfmt,
248 std::chrono::year{1970});
250 // Note this test will fail if the Reiwa era ends before 2038.
251 check(loc,
252 SV("%C='20'\t"
253 "%EC='令和'\t"
254 "%y='38'\t"
255 "%Ey='20'\t"
256 "%Oy='三十八'\t"
257 "%Y='2038'\t"
258 "%EY='令和20年'\t"
259 "\n"),
260 lfmt,
261 std::chrono::year{2038});
262 #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
264 std::locale::global(std::locale::classic());
267 template <class CharT>
268 static void test_padding() {
269 constexpr std::basic_string_view<CharT> fmt = SV("{:%%C='%C'%t%%y='%y'%t%%Y='%Y'%t%n}");
270 check(SV("%C='-100'\t%y='99'\t%Y='-9999'\t\n"), fmt, std::chrono::year{-9'999});
271 check(SV("%C='-10'\t%y='99'\t%Y='-0999'\t\n"), fmt, std::chrono::year{-999});
272 check(SV("%C='-1'\t%y='99'\t%Y='-0099'\t\n"), fmt, std::chrono::year{-99});
273 check(SV("%C='-1'\t%y='09'\t%Y='-0009'\t\n"), fmt, std::chrono::year{-9});
274 check(SV("%C='00'\t%y='00'\t%Y='0000'\t\n"), fmt, std::chrono::year{0});
275 check(SV("%C='00'\t%y='09'\t%Y='0009'\t\n"), fmt, std::chrono::year{9});
276 check(SV("%C='00'\t%y='99'\t%Y='0099'\t\n"), fmt, std::chrono::year{99});
277 check(SV("%C='09'\t%y='99'\t%Y='0999'\t\n"), fmt, std::chrono::year{999});
278 check(SV("%C='99'\t%y='99'\t%Y='9999'\t\n"), fmt, std::chrono::year{9'999});
279 check(SV("%C='100'\t%y='00'\t%Y='10000'\t\n"), fmt, std::chrono::year{10'000});
282 template <class CharT>
283 static void test() {
284 test_no_chrono_specs<CharT>();
285 test_valid_values<CharT>();
286 test_padding<CharT>();
287 check_invalid_types<CharT>(
288 {SV("C"), SV("y"), SV("Y"), SV("EC"), SV("Ey"), SV("EY"), SV("Oy")}, std::chrono::year{1970});
290 check_exception("The format specifier expects a '%' or a '}'", SV("{:A"), std::chrono::year{1970});
291 check_exception("The chrono specifiers contain a '{'", SV("{:%%{"), std::chrono::year{1970});
292 check_exception("End of input while parsing a conversion specifier", SV("{:%"), std::chrono::year{1970});
293 check_exception("End of input while parsing the modifier E", SV("{:%E"), std::chrono::year{1970});
294 check_exception("End of input while parsing the modifier O", SV("{:%O"), std::chrono::year{1970});
296 // Precision not allowed
297 check_exception("The format specifier expects a '%' or a '}'", SV("{:.3}"), std::chrono::year{1970});
300 int main(int, char**) {
301 test<char>();
303 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
304 test<wchar_t>();
305 #endif
307 return 0;