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 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 // UNSUPPORTED: no-localization
11 // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
12 
13 // TODO FMT This test should not require std::to_chars(floating-point)
14 // XFAIL: availability-fp_to_chars-missing
15 
16 // REQUIRES: locale.fr_FR.UTF-8
17 // REQUIRES: locale.ja_JP.UTF-8
18 
19 // <chrono>
20 
21 // class year_month_weekday_last;
22 
23 // template<class charT, class traits>
24 //   basic_ostream<charT, traits>&
25 //     operator<<(basic_ostream<charT, traits>& os, const year_month_weekday_last& ymwdl);
26 
27 #include <chrono>
28 #include <cassert>
29 #include <sstream>
30 
31 #include "make_string.h"
32 #include "platform_support.h" // locale name macros
33 #include "test_macros.h"
34 #include "assert_macros.h"
35 #include "concat_macros.h"
36 
37 #define SV(S) MAKE_STRING_VIEW(CharT, S)
38 
39 #define TEST_EQUAL(OUT, EXPECTED)                                                                                      \
40   TEST_REQUIRE(OUT == EXPECTED,                                                                                        \
41                TEST_WRITE_CONCATENATED(                                                                                \
42                    "\nExpression      ", #OUT, "\nExpected output ", EXPECTED, "\nActual output   ", OUT, '\n'));
43 
44 template <class CharT>
stream_c_locale(std::chrono::year_month_weekday_last ymwdl)45 static std::basic_string<CharT> stream_c_locale(std::chrono::year_month_weekday_last ymwdl) {
46   std::basic_stringstream<CharT> sstr;
47   sstr << ymwdl;
48   return sstr.str();
49 }
50 
51 template <class CharT>
stream_fr_FR_locale(std::chrono::year_month_weekday_last ymwdl)52 static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::year_month_weekday_last ymwdl) {
53   std::basic_stringstream<CharT> sstr;
54   const std::locale locale(LOCALE_fr_FR_UTF_8);
55   sstr.imbue(locale);
56   sstr << ymwdl;
57   return sstr.str();
58 }
59 
60 template <class CharT>
stream_ja_JP_locale(std::chrono::year_month_weekday_last ymwdl)61 static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::year_month_weekday_last ymwdl) {
62   std::basic_stringstream<CharT> sstr;
63   const std::locale locale(LOCALE_ja_JP_UTF_8);
64   sstr.imbue(locale);
65   sstr << ymwdl;
66   return sstr.str();
67 }
68 
69 template <class CharT>
test()70 static void test() {
71   TEST_EQUAL(
72       stream_c_locale<CharT>(std::chrono::year_month_weekday_last{
73           std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
74       SV("-32768 is not a valid year/Jan/Sun[last]"));
75   TEST_EQUAL(
76       stream_c_locale<CharT>(std::chrono::year_month_weekday_last{
77           std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
78       SV("-32767/0 is not a valid month/Sun[last]"));
79   TEST_EQUAL(
80       stream_c_locale<CharT>(std::chrono::year_month_weekday_last{
81           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}),
82       SV("-32767/Jan/8 is not a valid weekday[last]"));
83   TEST_EQUAL(
84       stream_c_locale<CharT>(std::chrono::year_month_weekday_last{
85           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
86       SV("-32767/Jan/Sun[last]"));
87 
88   TEST_EQUAL(stream_c_locale<CharT>(std::chrono::year_month_weekday_last{
89                  std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
90              SV("1970/Jan/Sun[last]"));
91 
92 #if defined(__APPLE__)
93   TEST_EQUAL(
94       stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
95           std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
96       SV("-32768 is not a valid year/jan/Dim[last]"));
97   TEST_EQUAL(
98       stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
99           std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
100       SV("-32767/0 is not a valid month/Dim[last]"));
101   TEST_EQUAL(
102       stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
103           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}),
104       SV("-32767/jan/8 is not a valid weekday[last]"));
105   TEST_EQUAL(
106       stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
107           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
108       SV("-32767/jan/Dim[last]"));
109 
110   TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
111                  std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
112              SV("1970/jan/Dim[last]"));
113 #else  //  defined(__APPLE__)
114   TEST_EQUAL(
115       stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
116           std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
117       SV("-32768 is not a valid year/janv./dim.[last]"));
118   TEST_EQUAL(
119       stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
120           std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
121       SV("-32767/0 is not a valid month/dim.[last]"));
122   TEST_EQUAL(
123       stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
124           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}),
125       SV("-32767/janv./8 is not a valid weekday[last]"));
126   TEST_EQUAL(
127       stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
128           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
129       SV("-32767/janv./dim.[last]"));
130 
131   TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::year_month_weekday_last{
132                  std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
133              SV("1970/janv./dim.[last]"));
134 #endif //  defined(__APPLE__)
135 
136 #if defined(__APPLE__)
137   TEST_EQUAL(
138       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
139           std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
140       SV("-32768 is not a valid year/ 1/日[last]"));
141   TEST_EQUAL(
142       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
143           std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
144       SV("-32767/0 is not a valid month/日[last]"));
145   TEST_EQUAL(
146       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
147           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}),
148       SV("-32767/ 1/8 is not a valid weekday[last]"));
149   TEST_EQUAL(
150       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
151           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
152       SV("-32767/ 1/日[last]"));
153 
154   TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
155                  std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
156              SV("1970/ 1/日[last]"));
157 #elif defined(_WIN32) // defined(__APPLE__)
158   TEST_EQUAL(
159       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
160           std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
161       SV("-32768 is not a valid year/1/日[last]"));
162   TEST_EQUAL(
163       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
164           std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
165       SV("-32767/0 is not a valid month/日[last]"));
166   TEST_EQUAL(
167       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
168           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}),
169       SV("-32767/1/8 is not a valid weekday[last]"));
170   TEST_EQUAL(
171       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
172           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
173       SV("-32767/1/日[last]"));
174 
175   TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
176                  std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
177              SV("1970/1/日[last]"));
178 #elif defined(_AIX)   // defined(__APPLE__)
179   TEST_EQUAL(
180       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
181           std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
182       SV("-32768 is not a valid year/1月/日[last]"));
183   TEST_EQUAL(
184       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
185           std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
186       SV("-32767/0 is not a valid month/日[last]"));
187   TEST_EQUAL(
188       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
189           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}),
190       SV("-32767/1月/8 is not a valid weekday[last]"));
191 
192   TEST_EQUAL(
193       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
194           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
195       SV("-32767/1月/日[last]"));
196 
197   TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
198                  std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
199              SV("1970/1月/日[last]"));
200 #else                 // defined(__APPLE__)
201   TEST_EQUAL(
202       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
203           std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
204       SV("-32768 is not a valid year/ 1月/日[last]"));
205   TEST_EQUAL(
206       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
207           std::chrono::year{-32'767}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
208       SV("-32767/0 is not a valid month/日[last]"));
209   TEST_EQUAL(
210       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
211           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}),
212       SV("-32767/ 1月/8 is not a valid weekday[last]"));
213   TEST_EQUAL(
214       stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
215           std::chrono::year{-32'767}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
216       SV("-32767/ 1月/日[last]"));
217 
218   TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::year_month_weekday_last{
219                  std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{0}}}),
220              SV("1970/ 1月/日[last]"));
221 #endif                // defined(__APPLE__)
222 }
223 
main(int,char **)224 int main(int, char**) {
225   test<char>();
226 
227 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
228   test<wchar_t>();
229 #endif
230 
231   return 0;
232 }
233