brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.3 KiB · bbd9c07 Raw
554 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// XFAIL: availability-fp_to_chars-missing14 15// REQUIRES: locale.fr_FR.UTF-816// REQUIRES: locale.ja_JP.UTF-817 18// <chrono>19 20// template<class Rep, class Period, class charT>21//   struct formatter<chrono::hh_mm_ss<duration<Rep, Period>>, charT>;22 23#include <chrono>24#include <format>25 26#include <cassert>27#include <concepts>28#include <locale>29#include <iostream>30#include <ratio>31#include <type_traits>32 33#include "formatter_tests.h"34#include "make_string.h"35#include "platform_support.h" // locale name macros36#include "string_literal.h"37#include "test_macros.h"38 39template <class CharT>40static void test_no_chrono_specs() {41  using namespace std::literals::chrono_literals;42 43  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));44 45  // Non localized output46  check(SV("00:00:00.000"), SV("{}"), std::chrono::hh_mm_ss{0ms});47  check(SV("*00:00:00.000*"), SV("{:*^14}"), std::chrono::hh_mm_ss{0ms});48  check(SV("*00:00:00.000"), SV("{:*>13}"), std::chrono::hh_mm_ss{0ms});49 50  std::locale::global(std::locale::classic());51}52 53template <class CharT>54static void test_valid_values() {55  using namespace std::literals::chrono_literals;56 57  constexpr std::basic_string_view<CharT> fmt = SV(58      "{:"59      "%%H='%H'%t"60      "%%OH='%OH'%t"61      "%%I='%I'%t"62      "%%OI='%OI'%t"63      "%%M='%M'%t"64      "%%OM='%OM'%t"65      "%%S='%S'%t"66      "%%OS='%OS'%t"67      "%%p='%p'%t"68      "%%R='%R'%t"69      "%%T='%T'%t"70      "%%r='%r'%t"71      "%%X='%X'%t"72      "%%EX='%EX'%t"73      "%n}");74  constexpr std::basic_string_view<CharT> lfmt = SV(75      "{:L"76      "%%H='%H'%t"77      "%%OH='%OH'%t"78      "%%I='%I'%t"79      "%%OI='%OI'%t"80      "%%M='%M'%t"81      "%%OM='%OM'%t"82      "%%S='%S'%t"83      "%%OS='%OS'%t"84      "%%p='%p'%t"85      "%%R='%R'%t"86      "%%T='%T'%t"87      "%%r='%r'%t"88      "%%X='%X'%t"89      "%%EX='%EX'%t"90      "%n}");91 92  const std::locale loc(LOCALE_ja_JP_UTF_8);93  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));94 95  // Non localized output using C-locale96  check(SV("%H='00'\t"97           "%OH='00'\t"98           "%I='12'\t"99           "%OI='12'\t"100           "%M='00'\t"101           "%OM='00'\t"102           "%S='00'\t"103           "%OS='00'\t"104           "%p='AM'\t"105           "%R='00:00'\t"106           "%T='00:00:00'\t"107           "%r='12:00:00 AM'\t"108           "%X='00:00:00'\t"109           "%EX='00:00:00'\t"110           "\n"),111        fmt,112        std::chrono::hh_mm_ss(0s));113 114  check(SV("%H='23'\t"115           "%OH='23'\t"116           "%I='11'\t"117           "%OI='11'\t"118           "%M='31'\t"119           "%OM='31'\t"120           "%S='30.123'\t"121           "%OS='30.123'\t"122           "%p='PM'\t"123           "%R='23:31'\t"124           "%T='23:31:30.123'\t"125           "%r='11:31:30 PM'\t"126           "%X='23:31:30'\t"127           "%EX='23:31:30'\t"128           "\n"),129        fmt,130        std::chrono::hh_mm_ss(23h + 31min + 30s + 123ms));131 132  check(SV("-%H='03'\t"133           "%OH='03'\t"134           "%I='03'\t"135           "%OI='03'\t"136           "%M='02'\t"137           "%OM='02'\t"138           "%S='01.123456789012'\t"139           "%OS='01.123456789012'\t"140           "%p='AM'\t"141           "%R='03:02'\t"142           "%T='03:02:01.123456789012'\t"143           "%r='03:02:01 AM'\t"144           "%X='03:02:01'\t"145           "%EX='03:02:01'\t"146           "\n"),147        fmt,148        std::chrono::hh_mm_ss(-(3h + 2min + 1s + std::chrono::duration<std::int64_t, std::pico>(123456789012))));149 150  // The number of fractional seconds is 0 according to the Standard151  // TODO FMT Determine what to do.152  check(SV("%H='01'\t"153           "%OH='01'\t"154           "%I='01'\t"155           "%OI='01'\t"156           "%M='01'\t"157           "%OM='01'\t"158           "%S='01'\t"159           "%OS='01'\t"160           "%p='AM'\t"161           "%R='01:01'\t"162           "%T='01:01:01'\t"163           "%r='01:01:01 AM'\t"164           "%X='01:01:01'\t"165           "%EX='01:01:01'\t"166           "\n"),167        fmt,168        std::chrono::hh_mm_ss(std::chrono::duration<double>(3661.123456)));169 170  // Use the global locale (fr_FR)171  check(SV("%H='00'\t"172           "%OH='00'\t"173           "%I='12'\t"174           "%OI='12'\t"175           "%M='00'\t"176           "%OM='00'\t"177           "%S='00'\t"178           "%OS='00'\t"179#if defined(_AIX)180           "%p='AM'\t"181#else182           "%p=''\t"183#endif184           "%R='00:00'\t"185           "%T='00:00:00'\t"186#ifdef _WIN32187           "%r='00:00:00'\t"188#elif defined(_AIX)189           "%r='12:00:00 AM'\t"190#elif defined(__APPLE__) || defined(__FreeBSD__)191           "%r=''\t"192#else193           "%r='12:00:00 '\t"194#endif195           "%X='00:00:00'\t"196           "%EX='00:00:00'\t"197           "\n"),198        lfmt,199        std::chrono::hh_mm_ss(0s));200 201  check(SV("%H='23'\t"202           "%OH='23'\t"203           "%I='11'\t"204           "%OI='11'\t"205           "%M='31'\t"206           "%OM='31'\t"207           "%S='30,123'\t"208           "%OS='30,123'\t"209#if defined(_AIX)210           "%p='PM'\t"211#else212           "%p=''\t"213#endif214           "%R='23:31'\t"215           "%T='23:31:30,123'\t"216#ifdef _WIN32217           "%r='23:31:30'\t"218#elif defined(_AIX)219           "%r='11:31:30 PM'\t"220#elif defined(__APPLE__) || defined(__FreeBSD__)221           "%r=''\t"222#else223           "%r='11:31:30 '\t"224#endif225           "%X='23:31:30'\t"226           "%EX='23:31:30'\t"227           "\n"),228        lfmt,229        std::chrono::hh_mm_ss(23h + 31min + 30s + 123ms));230 231  check(SV("-%H='03'\t"232           "%OH='03'\t"233           "%I='03'\t"234           "%OI='03'\t"235           "%M='02'\t"236           "%OM='02'\t"237           "%S='01,123456789012'\t"238           "%OS='01,123456789012'\t"239#if defined(_AIX)240           "%p='AM'\t"241#else242           "%p=''\t"243#endif244           "%R='03:02'\t"245           "%T='03:02:01,123456789012'\t"246#ifdef _WIN32247           "%r='03:02:01'\t"248#elif defined(_AIX)249           "%r='03:02:01 AM'\t"250#elif defined(__APPLE__) || defined(__FreeBSD__)251           "%r=''\t"252#else253           "%r='03:02:01 '\t"254#endif255           "%X='03:02:01'\t"256           "%EX='03:02:01'\t"257           "\n"),258        lfmt,259        std::chrono::hh_mm_ss(-(3h + 2min + 1s + std::chrono::duration<std::int64_t, std::pico>(123456789012))));260 261  check(SV("%H='01'\t"262           "%OH='01'\t"263           "%I='01'\t"264           "%OI='01'\t"265           "%M='01'\t"266           "%OM='01'\t"267           "%S='01'\t"268           "%OS='01'\t"269#if defined(_AIX)270           "%p='AM'\t"271#else272           "%p=''\t"273#endif274           "%R='01:01'\t"275           "%T='01:01:01'\t"276#ifdef _WIN32277           "%r='01:01:01'\t"278#elif defined(_AIX)279           "%r='01:01:01 AM'\t"280#elif defined(__APPLE__) || defined(__FreeBSD__)281           "%r=''\t"282#else283           "%r='01:01:01 '\t"284#endif285           "%X='01:01:01'\t"286           "%EX='01:01:01'\t"287           "\n"),288        lfmt,289        std::chrono::hh_mm_ss(std::chrono::duration<double>(3661.123456)));290 291  // Use supplied locale (ja_JP). This locale has a different alternate.292#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)293  check(loc,294        SV("%H='00'\t"295           "%OH='00'\t"296           "%I='12'\t"297           "%OI='12'\t"298           "%M='00'\t"299           "%OM='00'\t"300           "%S='00'\t"301           "%OS='00'\t"302           "%p='午前'\t"303           "%R='00:00'\t"304           "%T='00:00:00'\t"305#  if defined(__APPLE__) || defined(__FreeBSD__)306           "%r='12:00:00 午前'\t"307           "%X='00時00分00秒'\t"308           "%EX='00時00分00秒'\t"309#  elif defined(_WIN32)310           "%r='0:00:00'\t"311           "%X='0:00:00'\t"312           "%EX='0:00:00'\t"313#  else314           "%r='午前12:00:00'\t"315           "%X='00:00:00'\t"316           "%EX='00:00:00'\t"317#  endif318           "\n"),319        lfmt,320        std::chrono::hh_mm_ss(0s));321 322  check(loc,323        SV("%H='23'\t"324           "%OH='23'\t"325           "%I='11'\t"326           "%OI='11'\t"327           "%M='31'\t"328           "%OM='31'\t"329           "%S='30.123'\t"330           "%OS='30.123'\t"331           "%p='午後'\t"332           "%R='23:31'\t"333           "%T='23:31:30.123'\t"334#  if defined(__APPLE__) || defined(__FreeBSD__)335           "%r='11:31:30 午後'\t"336           "%X='23時31分30秒'\t"337           "%EX='23時31分30秒'\t"338#  elif defined(_WIN32)339           "%r='23:31:30'\t"340           "%X='23:31:30'\t"341           "%EX='23:31:30'\t"342#  else343           "%r='午後11:31:30'\t"344           "%X='23:31:30'\t"345           "%EX='23:31:30'\t"346#  endif347           "\n"),348        lfmt,349        std::chrono::hh_mm_ss(23h + 31min + 30s + 123ms));350 351  check(loc,352        SV("-%H='03'\t"353           "%OH='03'\t"354           "%I='03'\t"355           "%OI='03'\t"356           "%M='02'\t"357           "%OM='02'\t"358           "%S='01.123456789012'\t"359           "%OS='01.123456789012'\t"360           "%p='午前'\t"361           "%R='03:02'\t"362           "%T='03:02:01.123456789012'\t"363#  if defined(__APPLE__) || defined(__FreeBSD__)364           "%r='03:02:01 午前'\t"365           "%X='03時02分01秒'\t"366           "%EX='03時02分01秒'\t"367#  elif defined(_WIN32)368           "%r='3:02:01'\t"369           "%X='3:02:01'\t"370           "%EX='3:02:01'\t"371#  else372           "%r='午前03:02:01'\t"373           "%X='03:02:01'\t"374           "%EX='03:02:01'\t"375#  endif376           "\n"),377        lfmt,378        std::chrono::hh_mm_ss(-(3h + 2min + 1s + std::chrono::duration<std::int64_t, std::pico>(123456789012))));379 380  check(loc,381        SV("%H='01'\t"382           "%OH='01'\t"383           "%I='01'\t"384           "%OI='01'\t"385           "%M='01'\t"386           "%OM='01'\t"387           "%S='01'\t"388           "%OS='01'\t"389           "%p='午前'\t"390           "%R='01:01'\t"391           "%T='01:01:01'\t"392#  if defined(__APPLE__) || defined(__FreeBSD__)393           "%r='01:01:01 午前'\t"394           "%X='01時01分01秒'\t"395           "%EX='01時01分01秒'\t"396#  elif defined(_WIN32)397           "%r='1:01:01'\t"398           "%X='1:01:01'\t"399           "%EX='1:01:01'\t"400#  else401           "%r='午前01:01:01'\t"402           "%X='01:01:01'\t"403           "%EX='01:01:01'\t"404#  endif405           "\n"),406        lfmt,407        std::chrono::hh_mm_ss(std::chrono::duration<double>(3661.123456)));408#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)409  check(loc,410        SV("%H='00'\t"411           "%OH='〇'\t"412           "%I='12'\t"413           "%OI='十二'\t"414           "%M='00'\t"415           "%OM='〇'\t"416           "%S='00'\t"417           "%OS='〇'\t"418           "%p='午前'\t"419           "%R='00:00'\t"420           "%T='00:00:00'\t"421           "%r='午前12時00分00秒'\t"422           "%X='00時00分00秒'\t"423           "%EX='00時00分00秒'\t"424           "\n"),425        lfmt,426        std::chrono::hh_mm_ss(0s));427 428  // TODO FMT What should fractions be in alternate display mode?429  check(loc,430        SV("%H='23'\t"431           "%OH='二十三'\t"432           "%I='11'\t"433           "%OI='十一'\t"434           "%M='31'\t"435           "%OM='三十一'\t"436           "%S='30.123'\t"437           "%OS='三十.123'\t"438           "%p='午後'\t"439           "%R='23:31'\t"440           "%T='23:31:30.123'\t"441           "%r='午後11時31分30秒'\t"442           "%X='23時31分30秒'\t"443           "%EX='23時31分30秒'\t"444           "\n"),445        lfmt,446        std::chrono::hh_mm_ss(23h + 31min + 30s + 123ms));447 448  check(loc,449        SV("-%H='03'\t"450           "%OH='三'\t"451           "%I='03'\t"452           "%OI='三'\t"453           "%M='02'\t"454           "%OM='二'\t"455           "%S='01.123456789012'\t"456           "%OS='一.123456789012'\t"457           "%p='午前'\t"458           "%R='03:02'\t"459           "%T='03:02:01.123456789012'\t"460           "%r='午前03時02分01秒'\t"461           "%X='03時02分01秒'\t"462           "%EX='03時02分01秒'\t"463           "\n"),464        lfmt,465        std::chrono::hh_mm_ss(-(3h + 2min + 1s + std::chrono::duration<std::int64_t, std::pico>(123456789012))));466 467  check(loc,468        SV("%H='01'\t"469           "%OH='一'\t"470           "%I='01'\t"471           "%OI='一'\t"472           "%M='01'\t"473           "%OM='一'\t"474           "%S='01'\t"475           "%OS='一'\t"476           "%p='午前'\t"477           "%R='01:01'\t"478           "%T='01:01:01'\t"479           "%r='午前01時01分01秒'\t"480           "%X='01時01分01秒'\t"481           "%EX='01時01分01秒'\t"482           "\n"),483        lfmt,484        std::chrono::hh_mm_ss(std::chrono::duration<double>(3661.123456)));485#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)486 487  std::locale::global(std::locale::classic());488}489 490template <class CharT>491static void test_invalid_values() {492  using namespace std::literals::chrono_literals;493 494  // This looks odd, however the 24 hours is not valid for a 24 hour clock.495  // TODO FMT discuss what the "proper" behaviour is.496  check_exception("Formatting a hour needs a valid value", SV("{:%H"), std::chrono::hh_mm_ss{24h});497  check_exception("Formatting a hour needs a valid value", SV("{:%OH"), std::chrono::hh_mm_ss{24h});498  check_exception("Formatting a hour needs a valid value", SV("{:%I"), std::chrono::hh_mm_ss{24h});499  check_exception("Formatting a hour needs a valid value", SV("{:%OI"), std::chrono::hh_mm_ss{24h});500  check(SV("00"), SV("{:%M}"), std::chrono::hh_mm_ss{24h});501  check(SV("00"), SV("{:%OM}"), std::chrono::hh_mm_ss{24h});502  check(SV("00"), SV("{:%S}"), std::chrono::hh_mm_ss{24h});503  check(SV("00"), SV("{:%OS}"), std::chrono::hh_mm_ss{24h});504  check_exception("Formatting a hour needs a valid value", SV("{:%p"), std::chrono::hh_mm_ss{24h});505  check_exception("Formatting a hour needs a valid value", SV("{:%R"), std::chrono::hh_mm_ss{24h});506  check_exception("Formatting a hour needs a valid value", SV("{:%T"), std::chrono::hh_mm_ss{24h});507  check_exception("Formatting a hour needs a valid value", SV("{:%r"), std::chrono::hh_mm_ss{24h});508  check_exception("Formatting a hour needs a valid value", SV("{:%X"), std::chrono::hh_mm_ss{24h});509  check_exception("Formatting a hour needs a valid value", SV("{:%EX"), std::chrono::hh_mm_ss{24h});510}511 512template <class CharT>513static void test() {514  using namespace std::literals::chrono_literals;515 516  test_no_chrono_specs<CharT>();517  test_valid_values<CharT>();518  test_invalid_values<CharT>();519  check_invalid_types<CharT>(520      {SV("H"),521       SV("I"),522       SV("M"),523       SV("S"),524       SV("p"),525       SV("r"),526       SV("R"),527       SV("T"),528       SV("X"),529       SV("OH"),530       SV("OI"),531       SV("OM"),532       SV("OS"),533       SV("EX")},534      std::chrono::hh_mm_ss{0ms});535 536  check_exception("The format specifier expects a '%' or a '}'", SV("{:A"), std::chrono::hh_mm_ss{0ms});537  check_exception("The chrono specifiers contain a '{'", SV("{:%%{"), std::chrono::hh_mm_ss{0ms});538  check_exception("End of input while parsing a conversion specifier", SV("{:%"), std::chrono::hh_mm_ss{0ms});539  check_exception("End of input while parsing the modifier E", SV("{:%E"), std::chrono::hh_mm_ss{0ms});540  check_exception("End of input while parsing the modifier O", SV("{:%O"), std::chrono::hh_mm_ss{0ms});541 542  check_exception("The format specifier expects a '%' or a '}'", SV("{:.3}"), std::chrono::hh_mm_ss{0ms});543}544 545int main(int, char**) {546  test<char>();547 548#ifndef TEST_HAS_NO_WIDE_CHARACTERS549  test<wchar_t>();550#endif551 552  return 0;553}554