1 //===----------------------------------------------------------------------===//
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
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
21 // template<class charT> struct formatter<chrono::year, charT>;
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});
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(
69 constexpr std::basic_string_view
<CharT
> lfmt
= SV(
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
85 #if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)
94 #if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)
103 std::chrono::year
{0});
114 std::chrono::year
{1970});
125 std::chrono::year
{2038});
127 // Use the global locale (fr_FR)
129 #if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)
138 #if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)
147 std::chrono::year
{0});
158 std::chrono::year
{1970});
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__)
175 # if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)
191 std::chrono::year
{0});
202 std::chrono::year
{1970});
213 std::chrono::year
{2038});
215 #else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
220 // https://sourceware.org/bugzilla/show_bug.cgi?id=23758
221 # if defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29
228 // https://sourceware.org/bugzilla/show_bug.cgi?id=23758
229 # if defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29
236 std::chrono::year
{0});
248 std::chrono::year
{1970});
250 // Note this test will fail if the Reiwa era ends before 2038.
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
>
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**) {
303 #ifndef TEST_HAS_NO_WIDE_CHARACTERS