brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.7 KiB · e1a7d78 Raw
309 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, 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  check(SV("-32767"), SV("{}"), std::chrono::year{-32'767});41  check(SV("-1000"), SV("{}"), std::chrono::year{-1000});42  check(SV("-0100"), SV("{}"), std::chrono::year{-100});43  check(SV("-0010"), SV("{}"), std::chrono::year{-10});44  check(SV("-0001"), SV("{}"), std::chrono::year{-1});45  check(SV("0000"), SV("{}"), std::chrono::year{0});46  check(SV("0001"), SV("{}"), std::chrono::year{1});47  check(SV("0010"), SV("{}"), std::chrono::year{10});48  check(SV("0100"), SV("{}"), std::chrono::year{100});49  check(SV("1000"), SV("{}"), std::chrono::year{1000});50  check(SV("32727"), SV("{}"), std::chrono::year{32'727});51 52  // Invalid year53  check(SV("-32768 is not a valid year"), SV("{}"), std::chrono::year{-32'768});54  check(SV("-32768 is not a valid year"), SV("{}"), std::chrono::year{32'768});55}56 57template <class CharT>58static void test_valid_values() {59  constexpr std::basic_string_view<CharT> fmt = SV(60      "{:"61      "%%C='%C'%t"62      "%%EC='%EC'%t"63      "%%y='%y'%t"64      "%%Ey='%Ey'%t"65      "%%Oy='%Oy'%t"66      "%%Y='%Y'%t"67      "%%EY='%EY'%t"68      "%n}");69  constexpr std::basic_string_view<CharT> lfmt = SV(70      "{:L"71      "%%C='%C'%t"72      "%%EC='%EC'%t"73      "%%y='%y'%t"74      "%%Ey='%Ey'%t"75      "%%Oy='%Oy'%t"76      "%%Y='%Y'%t"77      "%%EY='%EY'%t"78      "%n}");79 80  const std::locale loc(LOCALE_ja_JP_UTF_8);81  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));82 83  // Non localized output using C-locale84  check(SV("%C='00'\t"85#if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)86           "%EC='00'\t"87#else88           "%EC='0'\t"89#endif90           "%y='00'\t"91           "%Ey='00'\t"92           "%Oy='00'\t"93           "%Y='0000'\t"94#if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)95           "%EY='0000'\t"96#elif defined(_AIX)97           "%EY=''\t"98#else99           "%EY='0'\t"100#endif101           "\n"),102        fmt,103        std::chrono::year{0});104 105  check(SV("%C='19'\t"106           "%EC='19'\t"107           "%y='70'\t"108           "%Ey='70'\t"109           "%Oy='70'\t"110           "%Y='1970'\t"111           "%EY='1970'\t"112           "\n"),113        fmt,114        std::chrono::year{1970});115 116  check(SV("%C='20'\t"117           "%EC='20'\t"118           "%y='38'\t"119           "%Ey='38'\t"120           "%Oy='38'\t"121           "%Y='2038'\t"122           "%EY='2038'\t"123           "\n"),124        fmt,125        std::chrono::year{2038});126 127  // Use the global locale (fr_FR)128  check(SV("%C='00'\t"129#if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)130           "%EC='00'\t"131#else132           "%EC='0'\t"133#endif134           "%y='00'\t"135           "%Ey='00'\t"136           "%Oy='00'\t"137           "%Y='0000'\t"138#if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)139           "%EY='0000'\t"140#elif defined(_AIX)141           "%EY=''\t"142#else143           "%EY='0'\t"144#endif145           "\n"),146        lfmt,147        std::chrono::year{0});148 149  check(SV("%C='19'\t"150           "%EC='19'\t"151           "%y='70'\t"152           "%Ey='70'\t"153           "%Oy='70'\t"154           "%Y='1970'\t"155           "%EY='1970'\t"156           "\n"),157        lfmt,158        std::chrono::year{1970});159 160  check(SV("%C='20'\t"161           "%EC='20'\t"162           "%y='38'\t"163           "%Ey='38'\t"164           "%Oy='38'\t"165           "%Y='2038'\t"166           "%EY='2038'\t"167           "\n"),168        lfmt,169        std::chrono::year{2038});170 171  // Use supplied locale (ja_JP). This locale has a different alternate.172#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)173 174  check(SV("%C='00'\t"175#  if defined(__APPLE__) || defined(_WIN32) || defined(__FreeBSD__)176           "%EC='00'\t"177#  else178           "%EC='0'\t"179#  endif180           "%y='00'\t"181           "%Ey='00'\t"182           "%Oy='00'\t"183           "%Y='0000'\t"184#  if defined(_AIX)185           "%EY=''\t"186#  else187           "%EY='0000'\t"188#  endif189           "\n"),190        lfmt,191        std::chrono::year{0});192 193  check(SV("%C='19'\t"194           "%EC='19'\t"195           "%y='70'\t"196           "%Ey='70'\t"197           "%Oy='70'\t"198           "%Y='1970'\t"199           "%EY='1970'\t"200           "\n"),201        lfmt,202        std::chrono::year{1970});203 204  check(SV("%C='20'\t"205           "%EC='20'\t"206           "%y='38'\t"207           "%Ey='38'\t"208           "%Oy='38'\t"209           "%Y='2038'\t"210           "%EY='2038'\t"211           "\n"),212        lfmt,213        std::chrono::year{2038});214 215#else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)216  check(loc,217        SV("%C='00'\t"218           "%EC='紀元前'\t"219           "%y='00'\t"220  // https://sourceware.org/bugzilla/show_bug.cgi?id=23758221#  if defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29222           "%Ey='1'\t"223#  else224           "%Ey='01'\t"225#  endif226           "%Oy='〇'\t"227           "%Y='0000'\t"228  // https://sourceware.org/bugzilla/show_bug.cgi?id=23758229#  if defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29230           "%EY='紀元前1年'\t"231#  else232           "%EY='紀元前01年'\t"233#  endif234           "\n"),235        lfmt,236        std::chrono::year{0});237 238  check(loc,239        SV("%C='19'\t"240           "%EC='昭和'\t"241           "%y='70'\t"242           "%Ey='45'\t"243           "%Oy='七十'\t"244           "%Y='1970'\t"245           "%EY='昭和45年'\t"246           "\n"),247        lfmt,248        std::chrono::year{1970});249 250  // Note this test will fail if the Reiwa era ends before 2038.251  check(loc,252        SV("%C='20'\t"253           "%EC='令和'\t"254           "%y='38'\t"255           "%Ey='20'\t"256           "%Oy='三十八'\t"257           "%Y='2038'\t"258           "%EY='令和20年'\t"259           "\n"),260        lfmt,261        std::chrono::year{2038});262#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)263 264  std::locale::global(std::locale::classic());265}266 267template <class CharT>268static void test_padding() {269  constexpr std::basic_string_view<CharT> fmt = SV("{:%%C='%C'%t%%y='%y'%t%%Y='%Y'%t%n}");270  check(SV("%C='-100'\t%y='99'\t%Y='-9999'\t\n"), fmt, std::chrono::year{-9'999});271  check(SV("%C='-10'\t%y='99'\t%Y='-0999'\t\n"), fmt, std::chrono::year{-999});272  check(SV("%C='-1'\t%y='99'\t%Y='-0099'\t\n"), fmt, std::chrono::year{-99});273  check(SV("%C='-1'\t%y='09'\t%Y='-0009'\t\n"), fmt, std::chrono::year{-9});274  check(SV("%C='00'\t%y='00'\t%Y='0000'\t\n"), fmt, std::chrono::year{0});275  check(SV("%C='00'\t%y='09'\t%Y='0009'\t\n"), fmt, std::chrono::year{9});276  check(SV("%C='00'\t%y='99'\t%Y='0099'\t\n"), fmt, std::chrono::year{99});277  check(SV("%C='09'\t%y='99'\t%Y='0999'\t\n"), fmt, std::chrono::year{999});278  check(SV("%C='99'\t%y='99'\t%Y='9999'\t\n"), fmt, std::chrono::year{9'999});279  check(SV("%C='100'\t%y='00'\t%Y='10000'\t\n"), fmt, std::chrono::year{10'000});280}281 282template <class CharT>283static void test() {284  test_no_chrono_specs<CharT>();285  test_valid_values<CharT>();286  test_padding<CharT>();287  check_invalid_types<CharT>(288      {SV("C"), SV("y"), SV("Y"), SV("EC"), SV("Ey"), SV("EY"), SV("Oy")}, std::chrono::year{1970});289 290  check_exception("The format specifier expects a '%' or a '}'", SV("{:A"), std::chrono::year{1970});291  check_exception("The chrono specifiers contain a '{'", SV("{:%%{"), std::chrono::year{1970});292  check_exception("End of input while parsing a conversion specifier", SV("{:%"), std::chrono::year{1970});293  check_exception("End of input while parsing the modifier E", SV("{:%E"), std::chrono::year{1970});294  check_exception("End of input while parsing the modifier O", SV("{:%O"), std::chrono::year{1970});295 296  // Precision not allowed297  check_exception("The format specifier expects a '%' or a '}'", SV("{:.3}"), std::chrono::year{1970});298}299 300int main(int, char**) {301  test<char>();302 303#ifndef TEST_HAS_NO_WIDE_CHARACTERS304  test<wchar_t>();305#endif306 307  return 0;308}309