xref: /llvm-project/libcxx/test/std/time/time.syn/formatter.weekday_index.pass.cpp (revision 6a54dfbfe534276d644d7f9c027f0deeb748dd53)
1105fef5dSMark de Wever //===----------------------------------------------------------------------===//
2*6a54dfbfSLouis Dionne //
3105fef5dSMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4105fef5dSMark de Wever // See https://llvm.org/LICENSE.txt for license information.
5105fef5dSMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6105fef5dSMark de Wever //
7105fef5dSMark de Wever //===----------------------------------------------------------------------===//
8105fef5dSMark de Wever 
9105fef5dSMark de Wever // UNSUPPORTED: c++03, c++11, c++14, c++17
10105fef5dSMark de Wever // UNSUPPORTED: no-localization
11520c7fbbSLouis Dionne // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
12105fef5dSMark de Wever 
133d334df5SLouis Dionne // TODO FMT This test should not require std::to_chars(floating-point)
14f0fc8c48SLouis Dionne // XFAIL: availability-fp_to_chars-missing
153d334df5SLouis Dionne 
161403080aSMark de Wever // TODO FMT Investigate Windows issues.
171403080aSMark de Wever // XFAIL: msvc
181403080aSMark de Wever 
19105fef5dSMark de Wever // REQUIRES: locale.fr_FR.UTF-8
20105fef5dSMark de Wever // REQUIRES: locale.ja_JP.UTF-8
21105fef5dSMark de Wever 
22105fef5dSMark de Wever // <chrono>
23105fef5dSMark de Wever 
24105fef5dSMark de Wever // template<class charT> struct formatter<chrono::weekday_index, charT>;
25105fef5dSMark de Wever 
26105fef5dSMark de Wever #include <chrono>
27105fef5dSMark de Wever #include <format>
28105fef5dSMark de Wever 
29105fef5dSMark de Wever #include <cassert>
30105fef5dSMark de Wever #include <concepts>
31105fef5dSMark de Wever #include <locale>
32105fef5dSMark de Wever #include <iostream>
33105fef5dSMark de Wever #include <type_traits>
34105fef5dSMark de Wever 
35105fef5dSMark de Wever #include "formatter_tests.h"
36105fef5dSMark de Wever #include "make_string.h"
37105fef5dSMark de Wever #include "platform_support.h" // locale name macros
38105fef5dSMark de Wever #include "test_macros.h"
39105fef5dSMark de Wever 
40105fef5dSMark de Wever template <class CharT>
41105fef5dSMark de Wever static void test_no_chrono_specs() {
42105fef5dSMark de Wever   using namespace std::literals::chrono_literals;
43105fef5dSMark de Wever 
44105fef5dSMark de Wever   // Valid weekday valid index
45105fef5dSMark de Wever   check(SV("Sun[1]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
46105fef5dSMark de Wever 
47105fef5dSMark de Wever   // Invalid weekday valid index
48105fef5dSMark de Wever   check(SV("8 is not a valid weekday[1]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
49105fef5dSMark de Wever   check(SV("255 is not a valid weekday[1]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
50105fef5dSMark de Wever 
51105fef5dSMark de Wever   // Valid weekday invalid index
52105fef5dSMark de Wever   check(SV("Sun[0 is not a valid index]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
53105fef5dSMark de Wever   check(SV("Sun[6 is not a valid index]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 6});
54105fef5dSMark de Wever   check(SV("Sun[255 is not a valid index]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 255});
55105fef5dSMark de Wever 
56105fef5dSMark de Wever   // Invalid weekday invalid index
57105fef5dSMark de Wever   check(SV("8 is not a valid weekday[0 is not a valid index]"),
58105fef5dSMark de Wever         SV("{}"),
59105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
60105fef5dSMark de Wever   check(SV("127 is not a valid weekday[6 is not a valid index]"),
61105fef5dSMark de Wever         SV("{}"),
62105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(127), 6});
63105fef5dSMark de Wever   check(SV("255 is not a valid weekday[255 is not a valid index]"),
64105fef5dSMark de Wever         SV("{}"),
65105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(255), 255});
66105fef5dSMark de Wever }
67105fef5dSMark de Wever 
68105fef5dSMark de Wever template <class CharT>
69105fef5dSMark de Wever static void test_valid_values() {
70105fef5dSMark de Wever   constexpr std::basic_string_view<CharT> fmt =
71105fef5dSMark de Wever       SV("{:%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}");
72105fef5dSMark de Wever   constexpr std::basic_string_view<CharT> lfmt =
73105fef5dSMark de Wever       SV("{:L%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}");
74105fef5dSMark de Wever 
75105fef5dSMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
76105fef5dSMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
77105fef5dSMark de Wever 
78105fef5dSMark de Wever   // Non localized output using C-locale
79105fef5dSMark de Wever   check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"),
80105fef5dSMark de Wever         fmt,
81105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
82105fef5dSMark de Wever   check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Mon'\t%A='Monday'\n"),
83105fef5dSMark de Wever         fmt,
84105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(1), 1});
85105fef5dSMark de Wever   check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Tue'\t%A='Tuesday'\n"),
86105fef5dSMark de Wever         fmt,
87105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(2), 2});
88105fef5dSMark de Wever   check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Wed'\t%A='Wednesday'\n"),
89105fef5dSMark de Wever         fmt,
90105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(3), 3});
91105fef5dSMark de Wever   check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Thu'\t%A='Thursday'\n"),
92105fef5dSMark de Wever         fmt,
93105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(4), 4});
94105fef5dSMark de Wever   check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Fri'\t%A='Friday'\n"),
95105fef5dSMark de Wever         fmt,
96105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(5), 5});
97105fef5dSMark de Wever   check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sat'\t%A='Saturday'\n"),
98105fef5dSMark de Wever         fmt,
99105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(6), 6});
100105fef5dSMark de Wever   check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"),
101105fef5dSMark de Wever         fmt,
102105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(7), 7});
103105fef5dSMark de Wever 
104105fef5dSMark de Wever   // Use the global locale (fr_FR)
105105fef5dSMark de Wever #if defined(__APPLE__)
106105fef5dSMark de Wever   check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"),
107105fef5dSMark de Wever         lfmt,
108105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
109105fef5dSMark de Wever   check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Lun'\t%A='Lundi'\n"),
110105fef5dSMark de Wever         lfmt,
111105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(1), 1});
112105fef5dSMark de Wever   check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Mar'\t%A='Mardi'\n"),
113105fef5dSMark de Wever         lfmt,
114105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(2), 2});
115105fef5dSMark de Wever   check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Mer'\t%A='Mercredi'\n"),
116105fef5dSMark de Wever         lfmt,
117105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(3), 3});
118105fef5dSMark de Wever   check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Jeu'\t%A='Jeudi'\n"),
119105fef5dSMark de Wever         lfmt,
120105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(4), 4});
121105fef5dSMark de Wever   check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Ven'\t%A='Vendredi'\n"),
122105fef5dSMark de Wever         lfmt,
123105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(5), 5});
124105fef5dSMark de Wever   check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sam'\t%A='Samedi'\n"),
125105fef5dSMark de Wever         lfmt,
126105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(6), 6});
127105fef5dSMark de Wever   check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"),
128105fef5dSMark de Wever         lfmt,
129105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(7), 7});
130105fef5dSMark de Wever #else  // defined(__APPLE__)
131105fef5dSMark de Wever   check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"),
132105fef5dSMark de Wever         lfmt,
133105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
134105fef5dSMark de Wever   check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='lun.'\t%A='lundi'\n"),
135105fef5dSMark de Wever         lfmt,
136105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(1), 1});
137105fef5dSMark de Wever   check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='mar.'\t%A='mardi'\n"),
138105fef5dSMark de Wever         lfmt,
139105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(2), 2});
140105fef5dSMark de Wever   check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='mer.'\t%A='mercredi'\n"),
141105fef5dSMark de Wever         lfmt,
142105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(3), 3});
143105fef5dSMark de Wever   check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='jeu.'\t%A='jeudi'\n"),
144105fef5dSMark de Wever         lfmt,
145105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(4), 4});
146105fef5dSMark de Wever   check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='ven.'\t%A='vendredi'\n"),
147105fef5dSMark de Wever         lfmt,
148105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(5), 5});
149105fef5dSMark de Wever   check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='sam.'\t%A='samedi'\n"),
150105fef5dSMark de Wever         lfmt,
151105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(6), 6});
152105fef5dSMark de Wever   check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"),
153105fef5dSMark de Wever         lfmt,
154105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(7), 7});
155105fef5dSMark de Wever #endif // defined(__APPLE__)
156105fef5dSMark de Wever 
157105fef5dSMark de Wever   // Use supplied locale (ja_JP).
158105fef5dSMark de Wever   // This locale has a different alternate, but not on all platforms
1598f01029bSMark de Wever #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
160105fef5dSMark de Wever   check(loc,
161105fef5dSMark de Wever         SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"),
162105fef5dSMark de Wever         lfmt,
163105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
164105fef5dSMark de Wever   check(loc,
165105fef5dSMark de Wever         SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='月'\t%A='月曜日'\n"),
166105fef5dSMark de Wever         lfmt,
167105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(1), 1});
168105fef5dSMark de Wever   check(loc,
169105fef5dSMark de Wever         SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='火'\t%A='火曜日'\n"),
170105fef5dSMark de Wever         lfmt,
171105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(2), 2});
172105fef5dSMark de Wever   check(loc,
173105fef5dSMark de Wever         SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='水'\t%A='水曜日'\n"),
174105fef5dSMark de Wever         lfmt,
175105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(3), 3});
176105fef5dSMark de Wever   check(loc,
177105fef5dSMark de Wever         SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='木'\t%A='木曜日'\n"),
178105fef5dSMark de Wever         lfmt,
179105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(4), 4});
180105fef5dSMark de Wever   check(loc,
181105fef5dSMark de Wever         SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='金'\t%A='金曜日'\n"),
182105fef5dSMark de Wever         lfmt,
183105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(5), 5});
184105fef5dSMark de Wever   check(loc,
185105fef5dSMark de Wever         SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='土'\t%A='土曜日'\n"),
186105fef5dSMark de Wever         lfmt,
187105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(6), 6});
188105fef5dSMark de Wever   check(loc,
189105fef5dSMark de Wever         SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"),
190105fef5dSMark de Wever         lfmt,
191105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(7), 7});
1928f01029bSMark de Wever #else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
193105fef5dSMark de Wever   check(loc,
194105fef5dSMark de Wever         SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"),
195105fef5dSMark de Wever         lfmt,
196105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
197105fef5dSMark de Wever   check(loc,
198105fef5dSMark de Wever         SV("%u='1'\t%Ou='一'\t%w='1'\t%Ow='一'\t%a='月'\t%A='月曜日'\n"),
199105fef5dSMark de Wever         lfmt,
200105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(1), 1});
201105fef5dSMark de Wever   check(loc,
202105fef5dSMark de Wever         SV("%u='2'\t%Ou='二'\t%w='2'\t%Ow='二'\t%a='火'\t%A='火曜日'\n"),
203105fef5dSMark de Wever         lfmt,
204105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(2), 2});
205105fef5dSMark de Wever   check(loc,
206105fef5dSMark de Wever         SV("%u='3'\t%Ou='三'\t%w='3'\t%Ow='三'\t%a='水'\t%A='水曜日'\n"),
207105fef5dSMark de Wever         lfmt,
208105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(3), 3});
209105fef5dSMark de Wever   check(loc,
210105fef5dSMark de Wever         SV("%u='4'\t%Ou='四'\t%w='4'\t%Ow='四'\t%a='木'\t%A='木曜日'\n"),
211105fef5dSMark de Wever         lfmt,
212105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(4), 4});
213105fef5dSMark de Wever   check(loc,
214105fef5dSMark de Wever         SV("%u='5'\t%Ou='五'\t%w='5'\t%Ow='五'\t%a='金'\t%A='金曜日'\n"),
215105fef5dSMark de Wever         lfmt,
216105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(5), 5});
217105fef5dSMark de Wever   check(loc,
218105fef5dSMark de Wever         SV("%u='6'\t%Ou='六'\t%w='6'\t%Ow='六'\t%a='土'\t%A='土曜日'\n"),
219105fef5dSMark de Wever         lfmt,
220105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(6), 6});
221105fef5dSMark de Wever   check(loc,
222105fef5dSMark de Wever         SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"),
223105fef5dSMark de Wever         lfmt,
224105fef5dSMark de Wever         std::chrono::weekday_indexed{std::chrono::weekday(7), 7});
2258f01029bSMark de Wever #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
226105fef5dSMark de Wever 
227105fef5dSMark de Wever   std::locale::global(std::locale::classic());
228105fef5dSMark de Wever }
229105fef5dSMark de Wever 
230105fef5dSMark de Wever template <class CharT>
231105fef5dSMark de Wever static void test_invalid_values() {
232105fef5dSMark de Wever   // Test that %a and %A throw an exception.
233402eb2efSMark de Wever   check_exception("Formatting a weekday name needs a valid weekday",
234105fef5dSMark de Wever                   SV("{:%a}"),
235105fef5dSMark de Wever                   std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
236402eb2efSMark de Wever   check_exception("Formatting a weekday name needs a valid weekday",
237105fef5dSMark de Wever                   SV("{:%a}"),
238105fef5dSMark de Wever                   std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
239402eb2efSMark de Wever   check_exception("Formatting a weekday name needs a valid weekday",
240105fef5dSMark de Wever                   SV("{:%A}"),
241105fef5dSMark de Wever                   std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
242402eb2efSMark de Wever   check_exception("Formatting a weekday name needs a valid weekday",
243105fef5dSMark de Wever                   SV("{:%A}"),
244105fef5dSMark de Wever                   std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
245105fef5dSMark de Wever 
246105fef5dSMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
247105fef5dSMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
248105fef5dSMark de Wever 
249105fef5dSMark de Wever   { // Invalid weekday, can't test %a and %A
250105fef5dSMark de Wever     constexpr std::basic_string_view<CharT> fmt  = SV("{:%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");
251105fef5dSMark de Wever     constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");
2528f01029bSMark de Wever #if defined(__APPLE__) || defined(__FreeBSD__)
253105fef5dSMark de Wever     // Non localized output using C-locale
254105fef5dSMark de Wever     check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
255105fef5dSMark de Wever     check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
256105fef5dSMark de Wever     check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
257105fef5dSMark de Wever           fmt,
258105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
259105fef5dSMark de Wever     check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
260105fef5dSMark de Wever           fmt,
261105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
262105fef5dSMark de Wever 
263105fef5dSMark de Wever     // Use the global locale (fr_FR)
264105fef5dSMark de Wever     check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
265105fef5dSMark de Wever     check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
266105fef5dSMark de Wever     check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
267105fef5dSMark de Wever           lfmt,
268105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
269105fef5dSMark de Wever     check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
270105fef5dSMark de Wever           lfmt,
271105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
272105fef5dSMark de Wever 
273105fef5dSMark de Wever     // Use supplied locale (ja_JP). This locale has a different alternate.
274105fef5dSMark de Wever     check(
275105fef5dSMark de Wever         loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
276105fef5dSMark de Wever     check(
277105fef5dSMark de Wever         loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
278105fef5dSMark de Wever     check(loc,
279105fef5dSMark de Wever           SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
280105fef5dSMark de Wever           lfmt,
281105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
282105fef5dSMark de Wever     check(loc,
283105fef5dSMark de Wever           SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),
284105fef5dSMark de Wever           lfmt,
285105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
2868f01029bSMark de Wever #elif defined(_WIN32) //  defined(__APPLE__) || defined(__FreeBSD__)
2871403080aSMark de Wever     // Non localized output using C-locale
2881403080aSMark de Wever     check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
2891403080aSMark de Wever     check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
2901403080aSMark de Wever     check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
2911403080aSMark de Wever     check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
2921403080aSMark de Wever 
2931403080aSMark de Wever     // Use the global locale (fr_FR)
2941403080aSMark de Wever     check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
2951403080aSMark de Wever     check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
2961403080aSMark de Wever     check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
2971403080aSMark de Wever     check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
2981403080aSMark de Wever 
2991403080aSMark de Wever     // Use supplied locale (ja_JP). This locale has a different alternate.
3001403080aSMark de Wever     check(loc, SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
3011403080aSMark de Wever     check(loc, SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
3021403080aSMark de Wever     check(loc, SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
3031403080aSMark de Wever     check(loc, SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
3048f01029bSMark de Wever #elif defined(_AIX)   //  defined(__APPLE__) || defined(__FreeBSD__)
305105fef5dSMark de Wever     // Non localized output using C-locale
306105fef5dSMark de Wever     check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
307105fef5dSMark de Wever     check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
308105fef5dSMark de Wever     check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
309105fef5dSMark de Wever     check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
310105fef5dSMark de Wever 
311105fef5dSMark de Wever     // Use the global locale (fr_FR)
312105fef5dSMark de Wever     check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
313105fef5dSMark de Wever     check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
314105fef5dSMark de Wever     check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
315105fef5dSMark de Wever     check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
316105fef5dSMark de Wever 
317105fef5dSMark de Wever     // Use supplied locale (ja_JP). This locale has a different alternate.
318105fef5dSMark de Wever     check(
319105fef5dSMark de Wever         loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
320105fef5dSMark de Wever     check(
321105fef5dSMark de Wever         loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
322105fef5dSMark de Wever     check(loc,
323105fef5dSMark de Wever           SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"),
324105fef5dSMark de Wever           lfmt,
325105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
326105fef5dSMark de Wever     check(loc,
327105fef5dSMark de Wever           SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"),
328105fef5dSMark de Wever           lfmt,
329105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
3308f01029bSMark de Wever #else                 // defined(__APPLE__) || defined(__FreeBSD__)
331105fef5dSMark de Wever     // Non localized output using C-locale
332105fef5dSMark de Wever     check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
333105fef5dSMark de Wever     check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
334105fef5dSMark de Wever     check(
335105fef5dSMark de Wever         SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
336105fef5dSMark de Wever     check(
337105fef5dSMark de Wever         SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
338105fef5dSMark de Wever 
339105fef5dSMark de Wever     // Use the global locale (fr_FR)
340105fef5dSMark de Wever     check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
341105fef5dSMark de Wever     check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
342105fef5dSMark de Wever     check(
343105fef5dSMark de Wever         SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
344105fef5dSMark de Wever     check(
345105fef5dSMark de Wever         SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
346105fef5dSMark de Wever 
347105fef5dSMark de Wever     // Use supplied locale (ja_JP). This locale has a different alternate.
348105fef5dSMark de Wever     check(loc,
349105fef5dSMark de Wever           SV("%u='1'\t%Ou='一'\t%w='8'\t%Ow='八'\n"),
350105fef5dSMark de Wever           lfmt,
351105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(8), 0});
352105fef5dSMark de Wever     check(loc,
353105fef5dSMark de Wever           SV("%u='1'\t%Ou='一'\t%w='8'\t%Ow='八'\n"),
354105fef5dSMark de Wever           lfmt,
355105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(8), 1});
356105fef5dSMark de Wever     check(loc,
357105fef5dSMark de Wever           SV("%u='3'\t%Ou='三'\t%w='255'\t%Ow='255'\n"),
358105fef5dSMark de Wever           lfmt,
359105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(255), 0});
360105fef5dSMark de Wever     check(loc,
361105fef5dSMark de Wever           SV("%u='3'\t%Ou='三'\t%w='255'\t%Ow='255'\n"),
362105fef5dSMark de Wever           lfmt,
363105fef5dSMark de Wever           std::chrono::weekday_indexed{std::chrono::weekday(255), 1});
3648f01029bSMark de Wever #endif                // defined(__APPLE__) || defined(__FreeBSD__)
365105fef5dSMark de Wever   }
366105fef5dSMark de Wever 
367105fef5dSMark de Wever   { // Valid weekday, tests %a and %A
368105fef5dSMark de Wever     constexpr std::basic_string_view<CharT> fmt  = SV("{:%%a='%a'%t%%A='%A'%n}");
369105fef5dSMark de Wever     constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%a='%a'%t%%A='%A'%n}");
370105fef5dSMark de Wever 
371105fef5dSMark de Wever     // Non localized output using C-locale
372105fef5dSMark de Wever     check(SV("%a='Sun'\t%A='Sunday'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
373105fef5dSMark de Wever     check(SV("%a='Sun'\t%A='Sunday'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6});
374105fef5dSMark de Wever 
375105fef5dSMark de Wever     // Use the global locale (fr_FR)
376105fef5dSMark de Wever #if defined(__APPLE__)
377105fef5dSMark de Wever     check(SV("%a='Dim'\t%A='Dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
378105fef5dSMark de Wever     check(SV("%a='Dim'\t%A='Dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6});
379105fef5dSMark de Wever #else  // defined(__APPLE__)
380105fef5dSMark de Wever     check(SV("%a='dim.'\t%A='dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
381105fef5dSMark de Wever     check(SV("%a='dim.'\t%A='dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6});
382105fef5dSMark de Wever #endif // defined(__APPLE__)
383105fef5dSMark de Wever 
384105fef5dSMark de Wever     // Use supplied locale (ja_JP)
385105fef5dSMark de Wever     check(loc, SV("%a='日'\t%A='日曜日'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0});
386105fef5dSMark de Wever     check(loc, SV("%a='日'\t%A='日曜日'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6});
387105fef5dSMark de Wever   }
388105fef5dSMark de Wever 
389105fef5dSMark de Wever   std::locale::global(std::locale::classic());
390105fef5dSMark de Wever }
391105fef5dSMark de Wever 
392105fef5dSMark de Wever template <class CharT>
393105fef5dSMark de Wever static void test() {
394105fef5dSMark de Wever   test_no_chrono_specs<CharT>();
395105fef5dSMark de Wever   test_valid_values<CharT>();
396105fef5dSMark de Wever   test_invalid_values<CharT>();
397105fef5dSMark de Wever   check_invalid_types<CharT>({SV("a"), SV("A"), SV("t"), SV("u"), SV("w"), SV("Ou"), SV("Ow")},
398105fef5dSMark de Wever                              std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
399105fef5dSMark de Wever 
400402eb2efSMark de Wever   check_exception("The format specifier expects a '%' or a '}'",
401105fef5dSMark de Wever                   SV("{:A"),
402105fef5dSMark de Wever                   std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
403105fef5dSMark de Wever   check_exception(
404402eb2efSMark de Wever       "The chrono specifiers contain a '{'", SV("{:%%{"), std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
405402eb2efSMark de Wever   check_exception("End of input while parsing a conversion specifier",
406105fef5dSMark de Wever                   SV("{:%"),
407105fef5dSMark de Wever                   std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
408105fef5dSMark de Wever   check_exception("End of input while parsing the modifier E",
409105fef5dSMark de Wever                   SV("{:%E"),
410105fef5dSMark de Wever                   std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
411105fef5dSMark de Wever   check_exception("End of input while parsing the modifier O",
412105fef5dSMark de Wever                   SV("{:%O"),
413105fef5dSMark de Wever                   std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
414105fef5dSMark de Wever 
415105fef5dSMark de Wever   // Precision not allowed
416402eb2efSMark de Wever   check_exception("The format specifier expects a '%' or a '}'",
417105fef5dSMark de Wever                   SV("{:.3}"),
418105fef5dSMark de Wever                   std::chrono::weekday_indexed{std::chrono::weekday(0), 1});
419105fef5dSMark de Wever }
420105fef5dSMark de Wever 
421105fef5dSMark de Wever int main(int, char**) {
422105fef5dSMark de Wever   test<char>();
423105fef5dSMark de Wever 
424105fef5dSMark de Wever #ifndef TEST_HAS_NO_WIDE_CHARACTERS
425105fef5dSMark de Wever   test<wchar_t>();
426105fef5dSMark de Wever #endif
427105fef5dSMark de Wever 
428105fef5dSMark de Wever   return 0;
429105fef5dSMark de Wever }
430