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_month, 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() {
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}});
46 check(SV("1970/0 is not a valid month"),
48 std::chrono::year_month
{std::chrono::year
{1970}, std::chrono::month
{0}});
49 check(SV("*1970/0 is not a valid month*"),
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",
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",
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(
82 constexpr std::basic_string_view
<CharT
> lfmt
= SV(
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"
112 std::chrono::year_month
{std::chrono::year
{1970}, std::chrono::January
});
114 check(SV("%b='May'\t"
126 std::chrono::year_month
{std::chrono::year
{2004}, std::chrono::May
});
128 // Use the global locale (fr_FR)
130 #if defined(__APPLE__)
137 #if defined(__APPLE__)
150 std::chrono::year_month
{std::chrono::year
{1970}, std::chrono::January
});
152 check(SV("%b='mai'\t"
164 std::chrono::year_month
{std::chrono::year
{2004}, std::chrono::May
});
166 // Use supplied locale (ja_JP)
171 #elif defined(_AIX) // defined(_WIN32)
173 #elif defined(__APPLE__) // defined(_WIN32)
175 #else // defined(_WIN32)
177 #endif // defined(_WIN32)
182 #elif defined(_AIX) // defined(_WIN32)
184 #elif defined(__APPLE__) // defined(_WIN32)
186 #else // defined(_WIN32)
188 #endif // defined(_WIN32)
191 #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
196 #else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
201 #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
204 std::chrono::year_month
{std::chrono::year
{1970}, std::chrono::January
});
211 #elif defined(_AIX) // defined(_WIN32)
213 #elif defined(__APPLE__) // defined(_WIN32)
215 #else // defined(_WIN32)
217 #endif // defined(_WIN32)
222 #elif defined(_AIX) // defined(_WIN32)
224 #elif defined(__APPLE__) // defined(_WIN32)
226 #else // defined(_WIN32)
228 #endif // defined(_WIN32)
231 #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
236 #else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
241 #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
244 std::chrono::year_month
{std::chrono::year
{2004}, std::chrono::May
});
246 std::locale::global(std::locale::classic());
249 template <class CharT
>
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 '}'",
261 std::chrono::year_month
{std::chrono::year
{1970}, std::chrono::January
});
262 check_exception("The chrono specifiers contain a '{'",
264 std::chrono::year_month
{std::chrono::year
{1970}, std::chrono::January
});
265 check_exception("End of input while parsing a conversion specifier",
267 std::chrono::year_month
{std::chrono::year
{1970}, std::chrono::January
});
268 check_exception("End of input while parsing the modifier E",
270 std::chrono::year_month
{std::chrono::year
{1970}, std::chrono::January
});
271 check_exception("End of input while parsing the modifier 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 '}'",
278 std::chrono::year_month
{std::chrono::year
{1970}, std::chrono::January
});
281 int main(int, char**) {
284 #ifndef TEST_HAS_NO_WIDE_CHARACTERS