246 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// ADDITIONAL_COMPILE_FLAGS: -DFR_THOU_SEP=%{LOCALE_CONV_FR_FR_UTF_8_THOUSANDS_SEP}20// ADDITIONAL_COMPILE_FLAGS: -DFR_DEC_POINT=%{LOCALE_CONV_FR_FR_UTF_8_DECIMAL_POINT}21 22// <chrono>23 24// template<class Rep, class Period = ratio<1>> class duration;25 26// template<class charT, class traits, class Rep, class Period>27// basic_ostream<charT, traits>&28// operator<<(basic_ostream<charT, traits>& os,29// const duration<Rep, Period>& d);30 31#include <chrono>32 33#include <cassert>34#include <concepts>35#include <ratio>36#include <sstream>37 38#include "make_string.h"39#include "locale_helpers.h"40#include "platform_support.h" // locale name macros41#include "test_macros.h"42 43#define SV(S) MAKE_STRING_VIEW(CharT, S)44 45template <class CharT, class Rep, class Period>46static std::basic_string<CharT> stream_c_locale(std::chrono::duration<Rep, Period> duration) {47 std::basic_stringstream<CharT> sstr;48 sstr.precision(4);49 sstr << std::fixed << duration;50 return sstr.str();51}52 53template <class CharT, class Rep, class Period>54static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::duration<Rep, Period> duration) {55 std::basic_stringstream<CharT> sstr;56 const std::locale locale(LOCALE_fr_FR_UTF_8);57 sstr.imbue(locale);58 sstr.precision(4);59 sstr << std::fixed << duration;60 return sstr.str();61}62 63template <class CharT, class Rep, class Period>64static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::duration<Rep, Period> duration) {65 std::basic_stringstream<CharT> sstr;66 const std::locale locale(LOCALE_ja_JP_UTF_8);67 sstr.imbue(locale);68 sstr.precision(4);69 sstr << std::fixed << duration;70 return sstr.str();71}72 73template <class CharT>74static void test_values() {75 using namespace std::literals::chrono_literals;76 77 assert(stream_c_locale<CharT>(-1'000'000s) == SV("-1000000s"));78 assert(stream_c_locale<CharT>(1'000'000s) == SV("1000000s"));79 assert(stream_c_locale<CharT>(-1'000.123456s) == SV("-1000.1235s"));80 assert(stream_c_locale<CharT>(1'000.123456s) == SV("1000.1235s"));81 82 if constexpr (std::same_as<CharT, char>) {83 assert(stream_fr_FR_locale<CharT>(-1'000'000s) == SV("-1 000 000s"));84 assert(stream_fr_FR_locale<CharT>(1'000'000s) == SV("1 000 000s"));85 assert(stream_fr_FR_locale<CharT>(-1'000.123456s) == SV("-1 000,1235s"));86 assert(stream_fr_FR_locale<CharT>(1'000.123456s) == SV("1 000,1235s"));87 } else {88#ifndef TEST_HAS_NO_WIDE_CHARACTERS89 assert(stream_fr_FR_locale<CharT>(-1'000'000s) == L"-1" FR_THOU_SEP "000" FR_THOU_SEP "000s");90 assert(stream_fr_FR_locale<CharT>(1'000'000s) == L"1" FR_THOU_SEP "000" FR_THOU_SEP "000s");91 assert(stream_fr_FR_locale<CharT>(-1'000.123456s) == L"-1" FR_THOU_SEP "000" FR_DEC_POINT "1235s");92 assert(stream_fr_FR_locale<CharT>(1'000.123456s) == L"1" FR_THOU_SEP "000" FR_DEC_POINT "1235s");93#endif94 }95 96 assert(stream_ja_JP_locale<CharT>(-1'000'000s) == SV("-1,000,000s"));97 assert(stream_ja_JP_locale<CharT>(1'000'000s) == SV("1,000,000s"));98 assert(stream_ja_JP_locale<CharT>(-1'000.123456s) == SV("-1,000.1235s"));99 assert(stream_ja_JP_locale<CharT>(1'000.123456s) == SV("1,000.1235s"));100}101 102template <class CharT>103static void test_units() {104 using namespace std::literals::chrono_literals;105 106 // C locale107 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::atto>(0)) == SV("0as"));108 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::femto>(0)) == SV("0fs"));109 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::pico>(0)) == SV("0ps"));110 assert(stream_c_locale<CharT>(0ns) == SV("0ns"));111#ifndef TEST_HAS_NO_UNICODE112 assert(stream_c_locale<CharT>(0us) == SV("0\u00b5s"));113#else114 assert(stream_c_locale<CharT>(0us) == SV("0us"));115#endif116 assert(stream_c_locale<CharT>(0ms) == SV("0ms"));117 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::centi>(0)) == SV("0cs"));118 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::deci>(0)) == SV("0ds"));119 120 assert(stream_c_locale<CharT>(0s) == SV("0s"));121 122 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::deca>(0)) == SV("0das"));123 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::hecto>(0)) == SV("0hs"));124 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::kilo>(0)) == SV("0ks"));125 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::mega>(0)) == SV("0Ms"));126 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::giga>(0)) == SV("0Gs"));127 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::tera>(0)) == SV("0Ts"));128 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::peta>(0)) == SV("0Ps"));129 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::exa>(0)) == SV("0Es"));130 131 assert(stream_c_locale<CharT>(0min) == SV("0min"));132 assert(stream_c_locale<CharT>(0h) == SV("0h"));133 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::ratio<86400>>(0)) == SV("0d"));134 135 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::ratio<42>>(0)) == SV("0[42]s"));136 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::ratio<33, 3>>(0)) == SV("0[11]s"));137 assert(stream_c_locale<CharT>(std::chrono::duration<int, std::ratio<11, 9>>(0)) == SV("0[11/9]s"));138 139 // fr_FR locale140 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::atto>(0)) == SV("0as"));141 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::femto>(0)) == SV("0fs"));142 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::pico>(0)) == SV("0ps"));143 assert(stream_fr_FR_locale<CharT>(0ns) == SV("0ns"));144#ifndef TEST_HAS_NO_UNICODE145 assert(stream_fr_FR_locale<CharT>(0us) == SV("0\u00b5s"));146#else147 assert(stream_fr_FR_locale<CharT>(0us) == SV("0us"));148#endif149 assert(stream_fr_FR_locale<CharT>(0ms) == SV("0ms"));150 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::centi>(0)) == SV("0cs"));151 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::deci>(0)) == SV("0ds"));152 153 assert(stream_fr_FR_locale<CharT>(0s) == SV("0s"));154 155 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::deca>(0)) == SV("0das"));156 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::hecto>(0)) == SV("0hs"));157 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::kilo>(0)) == SV("0ks"));158 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::mega>(0)) == SV("0Ms"));159 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::giga>(0)) == SV("0Gs"));160 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::tera>(0)) == SV("0Ts"));161 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::peta>(0)) == SV("0Ps"));162 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::exa>(0)) == SV("0Es"));163 164 assert(stream_fr_FR_locale<CharT>(0min) == SV("0min"));165 assert(stream_fr_FR_locale<CharT>(0h) == SV("0h"));166 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::ratio<86400>>(0)) == SV("0d"));167 168 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::ratio<42>>(0)) == SV("0[42]s"));169 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::ratio<33, 3>>(0)) == SV("0[11]s"));170 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<int, std::ratio<11, 9>>(0)) == SV("0[11/9]s"));171 172 // ja_JP locale173 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::atto>(0)) == SV("0as"));174 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::femto>(0)) == SV("0fs"));175 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::pico>(0)) == SV("0ps"));176 assert(stream_ja_JP_locale<CharT>(0ns) == SV("0ns"));177#ifndef TEST_HAS_NO_UNICODE178 assert(stream_ja_JP_locale<CharT>(0us) == SV("0\u00b5s"));179#else180 assert(stream_ja_JP_locale<CharT>(0us) == SV("0us"));181#endif182 assert(stream_ja_JP_locale<CharT>(0ms) == SV("0ms"));183 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::centi>(0)) == SV("0cs"));184 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::deci>(0)) == SV("0ds"));185 186 assert(stream_ja_JP_locale<CharT>(0s) == SV("0s"));187 188 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::deca>(0)) == SV("0das"));189 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::hecto>(0)) == SV("0hs"));190 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::kilo>(0)) == SV("0ks"));191 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::mega>(0)) == SV("0Ms"));192 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::giga>(0)) == SV("0Gs"));193 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::tera>(0)) == SV("0Ts"));194 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::peta>(0)) == SV("0Ps"));195 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::exa>(0)) == SV("0Es"));196 197 assert(stream_ja_JP_locale<CharT>(0min) == SV("0min"));198 assert(stream_ja_JP_locale<CharT>(0h) == SV("0h"));199 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::ratio<86400>>(0)) == SV("0d"));200 201 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::ratio<42>>(0)) == SV("0[42]s"));202 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::ratio<33, 3>>(0)) == SV("0[11]s"));203 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<int, std::ratio<11, 9>>(0)) == SV("0[11/9]s"));204}205 206template <class CharT>207static void test_unsigned_types() {208 // Reported in https://llvm.org/PR96820209 using namespace std::literals::chrono_literals;210 211 // C locale212 assert(stream_c_locale<CharT>(std::chrono::duration<unsigned short, std::atto>(0)) == SV("0as"));213 assert(stream_c_locale<CharT>(std::chrono::duration<unsigned, std::femto>(0)) == SV("0fs"));214 assert(stream_c_locale<CharT>(std::chrono::duration<unsigned long, std::pico>(0)) == SV("0ps"));215 assert(stream_c_locale<CharT>(std::chrono::duration<unsigned long long, std::nano>(0)) == SV("0ns"));216 217 // fr_FR locale218 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<unsigned short, std::atto>(0)) == SV("0as"));219 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<unsigned, std::femto>(0)) == SV("0fs"));220 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<unsigned long, std::pico>(0)) == SV("0ps"));221 assert(stream_fr_FR_locale<CharT>(std::chrono::duration<unsigned long long, std::nano>(0)) == SV("0ns"));222 223 // ja_JP locale224 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<unsigned short, std::atto>(0)) == SV("0as"));225 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<unsigned, std::femto>(0)) == SV("0fs"));226 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<unsigned long, std::pico>(0)) == SV("0ps"));227 assert(stream_ja_JP_locale<CharT>(std::chrono::duration<unsigned long long, std::nano>(0)) == SV("0ns"));228}229 230template <class CharT>231static void test() {232 test_values<CharT>();233 test_units<CharT>();234 test_unsigned_types<CharT>();235}236 237int main(int, char**) {238 test<char>();239 240#ifndef TEST_HAS_NO_WIDE_CHARACTERS241 test<wchar_t>();242#endif243 244 return 0;245}246