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 // template<class charT> struct formatter<chrono::year_month_weekday_last, charT>; 22 23 #include <chrono> 24 #include <format> 25 26 #include <cassert> 27 #include <concepts> 28 #include <locale> 29 #include <iostream> 30 #include <type_traits> 31 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" 37 38 template <class CharT> 39 static void test_no_chrono_specs() { 40 // Valid 41 check(SV("1970/Jan/Mon[last]"), 42 SV("{}"), 43 std::chrono::year_month_weekday_last{ 44 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 45 check(SV("*1970/Jan/Mon[last]*"), 46 SV("{:*^20}"), 47 std::chrono::year_month_weekday_last{ 48 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 49 check(SV("*1970/Jan/Mon[last]"), 50 SV("{:*>19}"), 51 std::chrono::year_month_weekday_last{ 52 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 53 54 // Invalid 55 check(SV("1970/Jan/8 is not a valid weekday[last]"), 56 SV("{}"), 57 std::chrono::year_month_weekday_last{ 58 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}); 59 check(SV("1970/0 is not a valid month/Mon[last]"), 60 SV("{}"), 61 std::chrono::year_month_weekday_last{ 62 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 63 check(SV("-32768 is not a valid year/Jan/Mon[last]"), 64 SV("{}"), 65 std::chrono::year_month_weekday_last{ 66 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 67 } 68 69 template <class CharT> 70 static void test_invalid_values() { 71 // *** Invalid weekday *** 72 73 // Weekday name conversion 74 check_exception( 75 "Formatting a weekday name needs a valid weekday", 76 SV("{:%a}"), 77 std::chrono::year_month_weekday_last{ 78 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}); 79 check_exception( 80 "Formatting a weekday name needs a valid weekday", 81 SV("{:%A}"), 82 std::chrono::year_month_weekday_last{ 83 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}); 84 85 // Weekday conversion 86 check_exception( 87 "Formatting a weekday needs a valid weekday", 88 SV("{:%u}"), 89 std::chrono::year_month_weekday_last{ 90 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}); 91 check_exception( 92 "Formatting a weekday needs a valid weekday", 93 SV("{:%w}"), 94 std::chrono::year_month_weekday_last{ 95 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}); 96 check_exception( 97 "Formatting a weekday needs a valid weekday", 98 SV("{:%Ou}"), 99 std::chrono::year_month_weekday_last{ 100 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}); 101 check_exception( 102 "Formatting a weekday needs a valid weekday", 103 SV("{:%Ow}"), 104 std::chrono::year_month_weekday_last{ 105 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}); 106 107 // Day of year field 108 check_exception( 109 "Formatting a day of year needs a valid date", 110 SV("{:%j}"), 111 std::chrono::year_month_weekday_last{ 112 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}); 113 114 // Month name conversion 115 check(SV("Jan"), 116 SV("{:%b}"), 117 std::chrono::year_month_weekday_last{ 118 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}); 119 check(SV("Jan"), 120 SV("{:%h}"), 121 std::chrono::year_month_weekday_last{ 122 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}); 123 check(SV("January"), 124 SV("{:%B}"), 125 std::chrono::year_month_weekday_last{ 126 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}}); 127 128 // *** Invalid month *** 129 130 // Weekday name conversion 131 check(SV("Mon"), 132 SV("{:%a}"), 133 std::chrono::year_month_weekday_last{ 134 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 135 check(SV("Monday"), 136 SV("{:%A}"), 137 std::chrono::year_month_weekday_last{ 138 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 139 // Weekday conversion 140 check(SV("1"), 141 SV("{:%u}"), 142 std::chrono::year_month_weekday_last{ 143 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 144 check(SV("1"), 145 SV("{:%w}"), 146 std::chrono::year_month_weekday_last{ 147 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 148 check(SV("1"), 149 SV("{:%Ou}"), 150 std::chrono::year_month_weekday_last{ 151 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 152 check(SV("1"), 153 SV("{:%Ow}"), 154 std::chrono::year_month_weekday_last{ 155 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 156 157 // Day of year field 158 check_exception( 159 "Formatting a day of year needs a valid date", 160 SV("{:%j}"), 161 std::chrono::year_month_weekday_last{ 162 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 163 164 // Month name conversion 165 check_exception( 166 "Formatting a month name from an invalid month number", 167 SV("{:%b}"), 168 std::chrono::year_month_weekday_last{ 169 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 170 check_exception( 171 "Formatting a month name from an invalid month number", 172 SV("{:%h}"), 173 std::chrono::year_month_weekday_last{ 174 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 175 check_exception( 176 "Formatting a month name from an invalid month number", 177 SV("{:%B}"), 178 std::chrono::year_month_weekday_last{ 179 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 180 181 // *** Invalid year *** 182 183 // Weekday name conversion 184 check(SV("Mon"), 185 SV("{:%a}"), 186 std::chrono::year_month_weekday_last{ 187 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 188 check(SV("Monday"), 189 SV("{:%A}"), 190 std::chrono::year_month_weekday_last{ 191 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 192 193 // Weekday conversion 194 check(SV("1"), 195 SV("{:%u}"), 196 std::chrono::year_month_weekday_last{ 197 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 198 check(SV("1"), 199 SV("{:%w}"), 200 std::chrono::year_month_weekday_last{ 201 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 202 check(SV("1"), 203 SV("{:%Ou}"), 204 std::chrono::year_month_weekday_last{ 205 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 206 check(SV("1"), 207 SV("{:%Ow}"), 208 std::chrono::year_month_weekday_last{ 209 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 210 211 // Day of year field 212 check_exception( 213 "Formatting a day of year needs a valid date", 214 SV("{:%j}"), 215 std::chrono::year_month_weekday_last{ 216 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 217 218 // Month name conversion 219 check(SV("Jan"), 220 SV("{:%b}"), 221 std::chrono::year_month_weekday_last{ 222 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 223 check(SV("Jan"), 224 SV("{:%h}"), 225 std::chrono::year_month_weekday_last{ 226 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 227 check(SV("January"), 228 SV("{:%B}"), 229 std::chrono::year_month_weekday_last{ 230 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}}); 231 } 232 233 template <class CharT> 234 static void test() { 235 test_no_chrono_specs<CharT>(); 236 test_invalid_values<CharT>(); 237 } 238 239 int main(int, char**) { 240 test<char>(); 241 242 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 243 test<wchar_t>(); 244 #endif 245 246 return 0; 247 } 248