brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.4 KiB · c8f68aa Raw
325 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// TODO FMT Investigate Windows issues.17// XFAIL: msvc18 19// REQUIRES: locale.fr_FR.UTF-820// REQUIRES: locale.ja_JP.UTF-821 22// <chrono>23 24// template<class charT> struct formatter<chrono::weekday_last, 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 macros38#include "test_macros.h"39 40template <class CharT>41static void test_no_chrono_specs() {42  using namespace std::literals::chrono_literals;43 44  // Valid day45  check(SV("Sun[last]"), SV("{}"), std::chrono::weekday_last{std::chrono::weekday(0)});46 47  // Invalid day48  check(SV("8 is not a valid weekday[last]"), SV("{}"), std::chrono::weekday_last{std::chrono::weekday(8)});49}50 51template <class CharT>52static void test_valid_values() {53  constexpr std::basic_string_view<CharT> fmt =54      SV("{:%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}");55  constexpr std::basic_string_view<CharT> lfmt =56      SV("{:L%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%t%%a='%a'%t%%A='%A'%n}");57 58  const std::locale loc(LOCALE_ja_JP_UTF_8);59  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));60 61  // Non localized output using C-locale62  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"),63        fmt,64        std::chrono::weekday_last{std::chrono::weekday(0)});65  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Mon'\t%A='Monday'\n"),66        fmt,67        std::chrono::weekday_last{std::chrono::weekday(1)});68  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Tue'\t%A='Tuesday'\n"),69        fmt,70        std::chrono::weekday_last{std::chrono::weekday(2)});71  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Wed'\t%A='Wednesday'\n"),72        fmt,73        std::chrono::weekday_last{std::chrono::weekday(3)});74  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Thu'\t%A='Thursday'\n"),75        fmt,76        std::chrono::weekday_last{std::chrono::weekday(4)});77  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Fri'\t%A='Friday'\n"),78        fmt,79        std::chrono::weekday_last{std::chrono::weekday(5)});80  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sat'\t%A='Saturday'\n"),81        fmt,82        std::chrono::weekday_last{std::chrono::weekday(6)});83  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Sun'\t%A='Sunday'\n"),84        fmt,85        std::chrono::weekday_last{std::chrono::weekday(7)});86 87  // Use the global locale (fr_FR)88#if defined(__APPLE__)89  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"),90        lfmt,91        std::chrono::weekday_last{std::chrono::weekday(0)});92  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='Lun'\t%A='Lundi'\n"),93        lfmt,94        std::chrono::weekday_last{std::chrono::weekday(1)});95  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='Mar'\t%A='Mardi'\n"),96        lfmt,97        std::chrono::weekday_last{std::chrono::weekday(2)});98  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='Mer'\t%A='Mercredi'\n"),99        lfmt,100        std::chrono::weekday_last{std::chrono::weekday(3)});101  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='Jeu'\t%A='Jeudi'\n"),102        lfmt,103        std::chrono::weekday_last{std::chrono::weekday(4)});104  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='Ven'\t%A='Vendredi'\n"),105        lfmt,106        std::chrono::weekday_last{std::chrono::weekday(5)});107  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='Sam'\t%A='Samedi'\n"),108        lfmt,109        std::chrono::weekday_last{std::chrono::weekday(6)});110  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='Dim'\t%A='Dimanche'\n"),111        lfmt,112        std::chrono::weekday_last{std::chrono::weekday(7)});113#else  // defined(__APPLE__)114  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"),115        lfmt,116        std::chrono::weekday_last{std::chrono::weekday(0)});117  check(SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='lun.'\t%A='lundi'\n"),118        lfmt,119        std::chrono::weekday_last{std::chrono::weekday(1)});120  check(SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='mar.'\t%A='mardi'\n"),121        lfmt,122        std::chrono::weekday_last{std::chrono::weekday(2)});123  check(SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='mer.'\t%A='mercredi'\n"),124        lfmt,125        std::chrono::weekday_last{std::chrono::weekday(3)});126  check(SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='jeu.'\t%A='jeudi'\n"),127        lfmt,128        std::chrono::weekday_last{std::chrono::weekday(4)});129  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='ven.'\t%A='vendredi'\n"),130        lfmt,131        std::chrono::weekday_last{std::chrono::weekday(5)});132  check(SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='sam.'\t%A='samedi'\n"),133        lfmt,134        std::chrono::weekday_last{std::chrono::weekday(6)});135  check(SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='dim.'\t%A='dimanche'\n"),136        lfmt,137        std::chrono::weekday_last{std::chrono::weekday(7)});138#endif // defined(__APPLE__)139 140  // Use supplied locale (ja_JP).141  // This locale has a different alternate, but not on all platforms142#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)143  check(loc,144        SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"),145        lfmt,146        std::chrono::weekday_last{std::chrono::weekday(0)});147  check(loc,148        SV("%u='1'\t%Ou='1'\t%w='1'\t%Ow='1'\t%a='月'\t%A='月曜日'\n"),149        lfmt,150        std::chrono::weekday_last{std::chrono::weekday(1)});151  check(loc,152        SV("%u='2'\t%Ou='2'\t%w='2'\t%Ow='2'\t%a='火'\t%A='火曜日'\n"),153        lfmt,154        std::chrono::weekday_last{std::chrono::weekday(2)});155  check(loc,156        SV("%u='3'\t%Ou='3'\t%w='3'\t%Ow='3'\t%a='水'\t%A='水曜日'\n"),157        lfmt,158        std::chrono::weekday_last{std::chrono::weekday(3)});159  check(loc,160        SV("%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\t%a='木'\t%A='木曜日'\n"),161        lfmt,162        std::chrono::weekday_last{std::chrono::weekday(4)});163  check(loc,164        SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\t%a='金'\t%A='金曜日'\n"),165        lfmt,166        std::chrono::weekday_last{std::chrono::weekday(5)});167  check(loc,168        SV("%u='6'\t%Ou='6'\t%w='6'\t%Ow='6'\t%a='土'\t%A='土曜日'\n"),169        lfmt,170        std::chrono::weekday_last{std::chrono::weekday(6)});171  check(loc,172        SV("%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\t%a='日'\t%A='日曜日'\n"),173        lfmt,174        std::chrono::weekday_last{std::chrono::weekday(7)});175#else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)176  check(loc,177        SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"),178        lfmt,179        std::chrono::weekday_last{std::chrono::weekday(0)});180  check(loc,181        SV("%u='1'\t%Ou='一'\t%w='1'\t%Ow='一'\t%a='月'\t%A='月曜日'\n"),182        lfmt,183        std::chrono::weekday_last{std::chrono::weekday(1)});184  check(loc,185        SV("%u='2'\t%Ou='二'\t%w='2'\t%Ow='二'\t%a='火'\t%A='火曜日'\n"),186        lfmt,187        std::chrono::weekday_last{std::chrono::weekday(2)});188  check(loc,189        SV("%u='3'\t%Ou='三'\t%w='3'\t%Ow='三'\t%a='水'\t%A='水曜日'\n"),190        lfmt,191        std::chrono::weekday_last{std::chrono::weekday(3)});192  check(loc,193        SV("%u='4'\t%Ou='四'\t%w='4'\t%Ow='四'\t%a='木'\t%A='木曜日'\n"),194        lfmt,195        std::chrono::weekday_last{std::chrono::weekday(4)});196  check(loc,197        SV("%u='5'\t%Ou='五'\t%w='5'\t%Ow='五'\t%a='金'\t%A='金曜日'\n"),198        lfmt,199        std::chrono::weekday_last{std::chrono::weekday(5)});200  check(loc,201        SV("%u='6'\t%Ou='六'\t%w='6'\t%Ow='六'\t%a='土'\t%A='土曜日'\n"),202        lfmt,203        std::chrono::weekday_last{std::chrono::weekday(6)});204  check(loc,205        SV("%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\t%a='日'\t%A='日曜日'\n"),206        lfmt,207        std::chrono::weekday_last{std::chrono::weekday(7)});208#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)209 210  std::locale::global(std::locale::classic());211}212 213template <class CharT>214static void test_invalid_values() {215  // Test that %a and %A throw an exception.216  check_exception("Formatting a weekday name needs a valid weekday",217                  SV("{:%a}"),218                  std::chrono::weekday_last{std::chrono::weekday(8)});219  check_exception("Formatting a weekday name needs a valid weekday",220                  SV("{:%a}"),221                  std::chrono::weekday_last{std::chrono::weekday(255)});222  check_exception("Formatting a weekday name needs a valid weekday",223                  SV("{:%A}"),224                  std::chrono::weekday_last{std::chrono::weekday(8)});225  check_exception("Formatting a weekday name needs a valid weekday",226                  SV("{:%A}"),227                  std::chrono::weekday_last{std::chrono::weekday(255)});228 229  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");230  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");231 232  const std::locale loc(LOCALE_ja_JP_UTF_8);233  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));234 235#if defined(__APPLE__) || defined(__FreeBSD__)236  // Non localized output using C-locale237  check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(8)});238  check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(255)});239 240  // Use the global locale (fr_FR)241  check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});242  check(SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});243 244  // Use supplied locale (ja_JP). This locale has a different alternate.245  check(loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});246  check(loc,247        SV("%u='255'\t%Ou='255'\t%w='255'\t%Ow='255'\n"),248        lfmt,249        std::chrono::weekday_last{std::chrono::weekday(255)});250#elif defined(_WIN32) // defined(__APPLE__) || defined(__FreeBSD__)251  // Non localized output using C-locale252  check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(8)});253  check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(255)});254 255  // Use the global locale (fr_FR)256  check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});257  check(SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});258 259  // Use supplied locale (ja_JP). This locale has a different alternate.260  check(loc, SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});261  check(loc, SV("%u=''\t%Ou=''\t%w=''\t%Ow=''\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});262#elif defined(_AIX)   // defined(__APPLE__) || defined(__FreeBSD__)263  // Non localized output using C-locale264  check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(8)});265  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(255)});266 267  // Use the global locale (fr_FR)268  check(SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});269  check(SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});270 271  // Use supplied locale (ja_JP). This locale has a different alternate.272  check(loc, SV("%u='8'\t%Ou='8'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});273  check(loc, SV("%u='5'\t%Ou='5'\t%w='5'\t%Ow='5'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});274#else                 //  defined(__APPLE__) || defined(__FreeBSD__)275  // Non localized output using C-locale276  check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(8)});277  check(SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), fmt, std::chrono::weekday_last{std::chrono::weekday(255)});278 279  // Use the global locale (fr_FR)280  check(SV("%u='1'\t%Ou='1'\t%w='8'\t%Ow='8'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});281  check(SV("%u='3'\t%Ou='3'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});282 283  // Use supplied locale (ja_JP). This locale has a different alternate.284  check(loc, SV("%u='1'\t%Ou='一'\t%w='8'\t%Ow='八'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(8)});285  check(loc, SV("%u='3'\t%Ou='三'\t%w='255'\t%Ow='255'\n"), lfmt, std::chrono::weekday_last{std::chrono::weekday(255)});286#endif                // defined(__APPLE__) || defined(__FreeBSD__)287 288  std::locale::global(std::locale::classic());289}290 291template <class CharT>292static void test() {293  test_no_chrono_specs<CharT>();294  test_valid_values<CharT>();295  test_invalid_values<CharT>();296  check_invalid_types<CharT>({SV("a"), SV("A"), SV("t"), SV("u"), SV("w"), SV("Ou"), SV("Ow")},297                             std::chrono::weekday_last{std::chrono::weekday(0)});298 299  check_exception(300      "The format specifier expects a '%' or a '}'", SV("{:A"), std::chrono::weekday_last{std::chrono::weekday(0)});301  check_exception(302      "The chrono specifiers contain a '{'", SV("{:%%{"), std::chrono::weekday_last{std::chrono::weekday(0)});303  check_exception("End of input while parsing a conversion specifier",304                  SV("{:%"),305                  std::chrono::weekday_last{std::chrono::weekday(0)});306  check_exception(307      "End of input while parsing the modifier E", SV("{:%E"), std::chrono::weekday_last{std::chrono::weekday(0)});308  check_exception(309      "End of input while parsing the modifier O", SV("{:%O"), std::chrono::weekday_last{std::chrono::weekday(0)});310 311  // Precision not allowed312  check_exception(313      "The format specifier expects a '%' or a '}'", SV("{:.3}"), std::chrono::weekday_last{std::chrono::weekday(0)});314}315 316int main(int, char**) {317  test<char>();318 319#ifndef TEST_HAS_NO_WIDE_CHARACTERS320  test<wchar_t>();321#endif322 323  return 0;324}325