brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.8 KiB · 96b654d Raw
290 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710// UNSUPPORTED: no-localization11// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME12 13// TODO FMT This test should not require std::to_chars(floating-point)14// XFAIL: availability-fp_to_chars-missing15 16// REQUIRES: locale.fr_FR.UTF-817// REQUIRES: locale.ja_JP.UTF-818 19// <chrono>20 21// template<class charT> struct formatter<chrono::year_month, 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 macros35#include "string_literal.h"36#include "test_macros.h"37 38template <class CharT>39static void test_no_chrono_specs() {40  // Valid month41  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}});44 45  // Invalid month_day46  check(SV("1970/0 is not a valid month"),47        SV("{}"),48        std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});49  check(SV("*1970/0 is not a valid month*"),50        SV("{:*^29}"),51        std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});52}53 54template <class CharT>55static 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",58                  SV("{:%b}"),59                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});60 61  check_exception("Formatting a month name from an invalid month number",62                  SV("{:%B}"),63                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});64}65 66template <class CharT>67static void test_valid_values() {68  constexpr std::basic_string_view<CharT> fmt = SV(69      "{:"70      "%%b='%b'%t"71      "%%B='%B'%t"72      "%%C='%C'%t"73      "%%h='%h'%t"74      "%%y='%y'%t"75      "%%Y='%Y'%t"76      "%%EC='%EC'%t"77      "%%Ey='%Ey'%t"78      "%%EY='%EY'%t"79      "%%Oy='%Oy'%t"80      "%n}");81 82  constexpr std::basic_string_view<CharT> lfmt = SV(83      "{:L"84      "%%b='%b'%t"85      "%%B='%B'%t"86      "%%C='%C'%t"87      "%%h='%h'%t"88      "%%y='%y'%t"89      "%%Y='%Y'%t"90      "%%EC='%EC'%t"91      "%%Ey='%Ey'%t"92      "%%EY='%EY'%t"93      "%%Oy='%Oy'%t"94      "%n}");95 96  const std::locale loc(LOCALE_ja_JP_UTF_8);97  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));98 99  // Non localized output using C-locale100  check(SV("%b='Jan'\t"101           "%B='January'\t"102           "%C='19'\t"103           "%h='Jan'\t"104           "%y='70'\t"105           "%Y='1970'\t"106           "%EC='19'\t"107           "%Ey='70'\t"108           "%EY='1970'\t"109           "%Oy='70'\t"110           "\n"),111        fmt,112        std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});113 114  check(SV("%b='May'\t"115           "%B='May'\t"116           "%C='20'\t"117           "%h='May'\t"118           "%y='04'\t"119           "%Y='2004'\t"120           "%EC='20'\t"121           "%Ey='04'\t"122           "%EY='2004'\t"123           "%Oy='04'\t"124           "\n"),125        fmt,126        std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});127 128  // Use the global locale (fr_FR)129  check(SV(130#if defined(__APPLE__)131            "%b='jan'\t"132#else133            "%b='janv.'\t"134#endif135            "%B='janvier'\t"136            "%C='19'\t"137#if defined(__APPLE__)138            "%h='jan'\t"139#else140            "%h='janv.'\t"141#endif142            "%y='70'\t"143            "%Y='1970'\t"144            "%EC='19'\t"145            "%Ey='70'\t"146            "%EY='1970'\t"147            "%Oy='70'\t"148            "\n"),149        lfmt,150        std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});151 152  check(SV("%b='mai'\t"153           "%B='mai'\t"154           "%C='20'\t"155           "%h='mai'\t"156           "%y='04'\t"157           "%Y='2004'\t"158           "%EC='20'\t"159           "%Ey='04'\t"160           "%EY='2004'\t"161           "%Oy='04'\t"162           "\n"),163        lfmt,164        std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});165 166  // Use supplied locale (ja_JP)167  check(loc,168        SV(169#if defined(_WIN32)170            "%b='1'\t"171#elif defined(_AIX)      // defined(_WIN32)172            "%b='1月'\t"173#elif defined(__APPLE__) // defined(_WIN32)174            "%b=' 1'\t"175#else                    // defined(_WIN32)176            "%b=' 1月'\t"177#endif                   // defined(_WIN32)178            "%B='1月'\t"179            "%C='19'\t"180#if defined(_WIN32)181            "%h='1'\t"182#elif defined(_AIX)      // defined(_WIN32)183            "%h='1月'\t"184#elif defined(__APPLE__) // defined(_WIN32)185            "%h=' 1'\t"186#else                    // defined(_WIN32)187            "%h=' 1月'\t"188#endif                   // defined(_WIN32)189            "%y='70'\t"190            "%Y='1970'\t"191#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)192            "%EC='19'\t"193            "%Ey='70'\t"194            "%EY='1970'\t"195            "%Oy='70'\t"196#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)197            "%EC='昭和'\t"198            "%Ey='45'\t"199            "%EY='昭和45年'\t"200            "%Oy='七十'\t"201#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)202            "\n"),203        lfmt,204        std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});205 206  check(loc,207        SV(208 209#if defined(_WIN32)210            "%b='5'\t"211#elif defined(_AIX)      // defined(_WIN32)212            "%b='5月'\t"213#elif defined(__APPLE__) // defined(_WIN32)214            "%b=' 5'\t"215#else                    // defined(_WIN32)216            "%b=' 5月'\t"217#endif                   // defined(_WIN32)218            "%B='5月'\t"219            "%C='20'\t"220#if defined(_WIN32)221            "%h='5'\t"222#elif defined(_AIX)      // defined(_WIN32)223            "%h='5月'\t"224#elif defined(__APPLE__) // defined(_WIN32)225            "%h=' 5'\t"226#else                    // defined(_WIN32)227            "%h=' 5月'\t"228#endif                   // defined(_WIN32)229            "%y='04'\t"230            "%Y='2004'\t"231#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)232            "%EC='20'\t"233            "%Ey='04'\t"234            "%EY='2004'\t"235            "%Oy='04'\t"236#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)237            "%EC='平成'\t"238            "%Ey='16'\t"239            "%EY='平成16年'\t"240            "%Oy='四'\t"241#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)242            "\n"),243        lfmt,244        std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});245 246  std::locale::global(std::locale::classic());247}248 249template <class CharT>250static void test() {251  test_no_chrono_specs<CharT>();252  test_invalid_values<CharT>();253  test_valid_values<CharT>();254 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});258 259  check_exception("The format specifier expects a '%' or a '}'",260                  SV("{:A"),261                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});262  check_exception("The chrono specifiers contain a '{'",263                  SV("{:%%{"),264                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});265  check_exception("End of input while parsing a conversion specifier",266                  SV("{:%"),267                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});268  check_exception("End of input while parsing the modifier E",269                  SV("{:%E"),270                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});271  check_exception("End of input while parsing the modifier O",272                  SV("{:%O"),273                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});274 275  // Precision not allowed276  check_exception("The format specifier expects a '%' or a '}'",277                  SV("{:.3}"),278                  std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});279}280 281int main(int, char**) {282  test<char>();283 284#ifndef TEST_HAS_NO_WIDE_CHARACTERS285  test<wchar_t>();286#endif287 288  return 0;289}290