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 // TODO FMT Investigate Windows issues. 17 // XFAIL: msvc 18 19 // REQUIRES: locale.fr_FR.UTF-8 20 // REQUIRES: locale.ja_JP.UTF-8 21 22 // <chrono> 23 24 // template<class charT> struct formatter<chrono::weekday_index, charT>; 25 26 #include <chrono> 27 #include <format> 28 29 #include <cassert> 30 #include <concepts> 31 #include <locale> 32 #include <iostream> 33 #include <type_traits> 34 35 #include "formatter_tests.h" 36 #include "make_string.h" 37 #include "platform_support.h" // locale name macros 38 #include "test_macros.h" 39 40 template <class CharT> 41 static void test_no_chrono_specs() { 42 using namespace std::literals::chrono_literals; 43 44 // Valid weekday valid index 45 check(SV("Sun[1]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 1}); 46 47 // Invalid weekday valid index 48 check(SV("8 is not a valid weekday[1]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 49 check(SV("255 is not a valid weekday[1]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 50 51 // Valid weekday invalid index 52 check(SV("Sun[0 is not a valid index]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 0}); 53 check(SV("Sun[6 is not a valid index]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 6}); 54 check(SV("Sun[255 is not a valid index]"), SV("{}"), std::chrono::weekday_indexed{std::chrono::weekday(0), 255}); 55 56 // Invalid weekday invalid index 57 check(SV("8 is not a valid weekday[0 is not a valid index]"), 58 SV("{}"), 59 std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 60 check(SV("127 is not a valid weekday[6 is not a valid index]"), 61 SV("{}"), 62 std::chrono::weekday_indexed{std::chrono::weekday(127), 6}); 63 check(SV("255 is not a valid weekday[255 is not a valid index]"), 64 SV("{}"), 65 std::chrono::weekday_indexed{std::chrono::weekday(255), 255}); 66 } 67 68 template <class CharT> 69 static void test_valid_values() { 70 constexpr std::basic_string_view<CharT> fmt = 71 SV("{:%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}"); 72 constexpr std::basic_string_view<CharT> lfmt = 73 SV("{:L%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}"); 74 75 const std::locale loc(LOCALE_ja_JP_UTF_8); 76 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8)); 77 78 // Non localized output using C-locale 79 check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"), 80 fmt, 81 std::chrono::weekday_indexed{std::chrono::weekday(0), 0}); 82 check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Mon'\t%A='Monday'\n"), 83 fmt, 84 std::chrono::weekday_indexed{std::chrono::weekday(1), 1}); 85 check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Tue'\t%A='Tuesday'\n"), 86 fmt, 87 std::chrono::weekday_indexed{std::chrono::weekday(2), 2}); 88 check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Wed'\t%A='Wednesday'\n"), 89 fmt, 90 std::chrono::weekday_indexed{std::chrono::weekday(3), 3}); 91 check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Thu'\t%A='Thursday'\n"), 92 fmt, 93 std::chrono::weekday_indexed{std::chrono::weekday(4), 4}); 94 check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Fri'\t%A='Friday'\n"), 95 fmt, 96 std::chrono::weekday_indexed{std::chrono::weekday(5), 5}); 97 check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sat'\t%A='Saturday'\n"), 98 fmt, 99 std::chrono::weekday_indexed{std::chrono::weekday(6), 6}); 100 check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"), 101 fmt, 102 std::chrono::weekday_indexed{std::chrono::weekday(7), 7}); 103 104 // Use the global locale (fr_FR) 105 #if defined(__APPLE__) 106 check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"), 107 lfmt, 108 std::chrono::weekday_indexed{std::chrono::weekday(0), 0}); 109 check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Lun'\t%A='Lundi'\n"), 110 lfmt, 111 std::chrono::weekday_indexed{std::chrono::weekday(1), 1}); 112 check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Mar'\t%A='Mardi'\n"), 113 lfmt, 114 std::chrono::weekday_indexed{std::chrono::weekday(2), 2}); 115 check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Mer'\t%A='Mercredi'\n"), 116 lfmt, 117 std::chrono::weekday_indexed{std::chrono::weekday(3), 3}); 118 check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Jeu'\t%A='Jeudi'\n"), 119 lfmt, 120 std::chrono::weekday_indexed{std::chrono::weekday(4), 4}); 121 check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Ven'\t%A='Vendredi'\n"), 122 lfmt, 123 std::chrono::weekday_indexed{std::chrono::weekday(5), 5}); 124 check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sam'\t%A='Samedi'\n"), 125 lfmt, 126 std::chrono::weekday_indexed{std::chrono::weekday(6), 6}); 127 check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"), 128 lfmt, 129 std::chrono::weekday_indexed{std::chrono::weekday(7), 7}); 130 #else // defined(__APPLE__) 131 check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"), 132 lfmt, 133 std::chrono::weekday_indexed{std::chrono::weekday(0), 0}); 134 check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='lun.'\t%A='lundi'\n"), 135 lfmt, 136 std::chrono::weekday_indexed{std::chrono::weekday(1), 1}); 137 check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='mar.'\t%A='mardi'\n"), 138 lfmt, 139 std::chrono::weekday_indexed{std::chrono::weekday(2), 2}); 140 check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='mer.'\t%A='mercredi'\n"), 141 lfmt, 142 std::chrono::weekday_indexed{std::chrono::weekday(3), 3}); 143 check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='jeu.'\t%A='jeudi'\n"), 144 lfmt, 145 std::chrono::weekday_indexed{std::chrono::weekday(4), 4}); 146 check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='ven.'\t%A='vendredi'\n"), 147 lfmt, 148 std::chrono::weekday_indexed{std::chrono::weekday(5), 5}); 149 check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='sam.'\t%A='samedi'\n"), 150 lfmt, 151 std::chrono::weekday_indexed{std::chrono::weekday(6), 6}); 152 check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"), 153 lfmt, 154 std::chrono::weekday_indexed{std::chrono::weekday(7), 7}); 155 #endif // defined(__APPLE__) 156 157 // Use supplied locale (ja_JP). 158 // This locale has a different alternate, but not on all platforms 159 #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__) 160 check(loc, 161 SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"), 162 lfmt, 163 std::chrono::weekday_indexed{std::chrono::weekday(0), 0}); 164 check(loc, 165 SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='月'\t%A='月曜日'\n"), 166 lfmt, 167 std::chrono::weekday_indexed{std::chrono::weekday(1), 1}); 168 check(loc, 169 SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='火'\t%A='火曜日'\n"), 170 lfmt, 171 std::chrono::weekday_indexed{std::chrono::weekday(2), 2}); 172 check(loc, 173 SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='水'\t%A='水曜日'\n"), 174 lfmt, 175 std::chrono::weekday_indexed{std::chrono::weekday(3), 3}); 176 check(loc, 177 SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='木'\t%A='木曜日'\n"), 178 lfmt, 179 std::chrono::weekday_indexed{std::chrono::weekday(4), 4}); 180 check(loc, 181 SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='金'\t%A='金曜日'\n"), 182 lfmt, 183 std::chrono::weekday_indexed{std::chrono::weekday(5), 5}); 184 check(loc, 185 SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='土'\t%A='土曜日'\n"), 186 lfmt, 187 std::chrono::weekday_indexed{std::chrono::weekday(6), 6}); 188 check(loc, 189 SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"), 190 lfmt, 191 std::chrono::weekday_indexed{std::chrono::weekday(7), 7}); 192 #else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__) 193 check(loc, 194 SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"), 195 lfmt, 196 std::chrono::weekday_indexed{std::chrono::weekday(0), 0}); 197 check(loc, 198 SV("%u='1'\t%Ou='一'\t%w='1'\t%Ow='一'\t%a='月'\t%A='月曜日'\n"), 199 lfmt, 200 std::chrono::weekday_indexed{std::chrono::weekday(1), 1}); 201 check(loc, 202 SV("%u='2'\t%Ou='二'\t%w='2'\t%Ow='二'\t%a='火'\t%A='火曜日'\n"), 203 lfmt, 204 std::chrono::weekday_indexed{std::chrono::weekday(2), 2}); 205 check(loc, 206 SV("%u='3'\t%Ou='三'\t%w='3'\t%Ow='三'\t%a='水'\t%A='水曜日'\n"), 207 lfmt, 208 std::chrono::weekday_indexed{std::chrono::weekday(3), 3}); 209 check(loc, 210 SV("%u='4'\t%Ou='四'\t%w='4'\t%Ow='四'\t%a='木'\t%A='木曜日'\n"), 211 lfmt, 212 std::chrono::weekday_indexed{std::chrono::weekday(4), 4}); 213 check(loc, 214 SV("%u='5'\t%Ou='五'\t%w='5'\t%Ow='五'\t%a='金'\t%A='金曜日'\n"), 215 lfmt, 216 std::chrono::weekday_indexed{std::chrono::weekday(5), 5}); 217 check(loc, 218 SV("%u='6'\t%Ou='六'\t%w='6'\t%Ow='六'\t%a='土'\t%A='土曜日'\n"), 219 lfmt, 220 std::chrono::weekday_indexed{std::chrono::weekday(6), 6}); 221 check(loc, 222 SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"), 223 lfmt, 224 std::chrono::weekday_indexed{std::chrono::weekday(7), 7}); 225 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__) 226 227 std::locale::global(std::locale::classic()); 228 } 229 230 template <class CharT> 231 static void test_invalid_values() { 232 // Test that %a and %A throw an exception. 233 check_exception("Formatting a weekday name needs a valid weekday", 234 SV("{:%a}"), 235 std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 236 check_exception("Formatting a weekday name needs a valid weekday", 237 SV("{:%a}"), 238 std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 239 check_exception("Formatting a weekday name needs a valid weekday", 240 SV("{:%A}"), 241 std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 242 check_exception("Formatting a weekday name needs a valid weekday", 243 SV("{:%A}"), 244 std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 245 246 const std::locale loc(LOCALE_ja_JP_UTF_8); 247 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8)); 248 249 { // Invalid weekday, can't test %a and %A 250 constexpr std::basic_string_view<CharT> fmt = SV("{:%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}"); 251 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}"); 252 #if defined(__APPLE__) || defined(__FreeBSD__) 253 // Non localized output using C-locale 254 check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 255 check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 256 check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"), 257 fmt, 258 std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 259 check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"), 260 fmt, 261 std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 262 263 // Use the global locale (fr_FR) 264 check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 265 check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 266 check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"), 267 lfmt, 268 std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 269 check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"), 270 lfmt, 271 std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 272 273 // Use supplied locale (ja_JP). This locale has a different alternate. 274 check( 275 loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 276 check( 277 loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 278 check(loc, 279 SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"), 280 lfmt, 281 std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 282 check(loc, 283 SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"), 284 lfmt, 285 std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 286 #elif defined(_WIN32) // defined(__APPLE__) || defined(__FreeBSD__) 287 // Non localized output using C-locale 288 check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 289 check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 290 check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 291 check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 292 293 // Use the global locale (fr_FR) 294 check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 295 check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 296 check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 297 check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 298 299 // Use supplied locale (ja_JP). This locale has a different alternate. 300 check(loc, SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 301 check(loc, SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 302 check(loc, SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 303 check(loc, SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 304 #elif defined(_AIX) // defined(__APPLE__) || defined(__FreeBSD__) 305 // Non localized output using C-locale 306 check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 307 check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 308 check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 309 check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 310 311 // Use the global locale (fr_FR) 312 check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 313 check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 314 check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 315 check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 316 317 // Use supplied locale (ja_JP). This locale has a different alternate. 318 check( 319 loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 320 check( 321 loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 322 check(loc, 323 SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), 324 lfmt, 325 std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 326 check(loc, 327 SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), 328 lfmt, 329 std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 330 #else // defined(__APPLE__) || defined(__FreeBSD__) 331 // Non localized output using C-locale 332 check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 333 check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 334 check( 335 SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 336 check( 337 SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 338 339 // Use the global locale (fr_FR) 340 check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 341 check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 342 check( 343 SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 344 check( 345 SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 346 347 // Use supplied locale (ja_JP). This locale has a different alternate. 348 check(loc, 349 SV("%u='1'\t%Ou='一'\t%w='8'\t%Ow='八'\n"), 350 lfmt, 351 std::chrono::weekday_indexed{std::chrono::weekday(8), 0}); 352 check(loc, 353 SV("%u='1'\t%Ou='一'\t%w='8'\t%Ow='八'\n"), 354 lfmt, 355 std::chrono::weekday_indexed{std::chrono::weekday(8), 1}); 356 check(loc, 357 SV("%u='3'\t%Ou='三'\t%w='255'\t%Ow='255'\n"), 358 lfmt, 359 std::chrono::weekday_indexed{std::chrono::weekday(255), 0}); 360 check(loc, 361 SV("%u='3'\t%Ou='三'\t%w='255'\t%Ow='255'\n"), 362 lfmt, 363 std::chrono::weekday_indexed{std::chrono::weekday(255), 1}); 364 #endif // defined(__APPLE__) || defined(__FreeBSD__) 365 } 366 367 { // Valid weekday, tests %a and %A 368 constexpr std::basic_string_view<CharT> fmt = SV("{:%%a='%a'%t%%A='%A'%n}"); 369 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%a='%a'%t%%A='%A'%n}"); 370 371 // Non localized output using C-locale 372 check(SV("%a='Sun'\t%A='Sunday'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0}); 373 check(SV("%a='Sun'\t%A='Sunday'\n"), fmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6}); 374 375 // Use the global locale (fr_FR) 376 #if defined(__APPLE__) 377 check(SV("%a='Dim'\t%A='Dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0}); 378 check(SV("%a='Dim'\t%A='Dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6}); 379 #else // defined(__APPLE__) 380 check(SV("%a='dim.'\t%A='dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0}); 381 check(SV("%a='dim.'\t%A='dimanche'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6}); 382 #endif // defined(__APPLE__) 383 384 // Use supplied locale (ja_JP) 385 check(loc, SV("%a='日'\t%A='日曜日'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 0}); 386 check(loc, SV("%a='日'\t%A='日曜日'\n"), lfmt, std::chrono::weekday_indexed{std::chrono::weekday(0), 6}); 387 } 388 389 std::locale::global(std::locale::classic()); 390 } 391 392 template <class CharT> 393 static void test() { 394 test_no_chrono_specs<CharT>(); 395 test_valid_values<CharT>(); 396 test_invalid_values<CharT>(); 397 check_invalid_types<CharT>({SV("a"), SV("A"), SV("t"), SV("u"), SV("w"), SV("Ou"), SV("Ow")}, 398 std::chrono::weekday_indexed{std::chrono::weekday(0), 1}); 399 400 check_exception("The format specifier expects a '%' or a '}'", 401 SV("{:A"), 402 std::chrono::weekday_indexed{std::chrono::weekday(0), 1}); 403 check_exception( 404 "The chrono specifiers contain a '{'", SV("{:%%{"), std::chrono::weekday_indexed{std::chrono::weekday(0), 1}); 405 check_exception("End of input while parsing a conversion specifier", 406 SV("{:%"), 407 std::chrono::weekday_indexed{std::chrono::weekday(0), 1}); 408 check_exception("End of input while parsing the modifier E", 409 SV("{:%E"), 410 std::chrono::weekday_indexed{std::chrono::weekday(0), 1}); 411 check_exception("End of input while parsing the modifier O", 412 SV("{:%O"), 413 std::chrono::weekday_indexed{std::chrono::weekday(0), 1}); 414 415 // Precision not allowed 416 check_exception("The format specifier expects a '%' or a '}'", 417 SV("{:.3}"), 418 std::chrono::weekday_indexed{std::chrono::weekday(0), 1}); 419 } 420 421 int main(int, char**) { 422 test<char>(); 423 424 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 425 test<wchar_t>(); 426 #endif 427 428 return 0; 429 } 430