243 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// class system_clock;22 23// template<class charT, class traits, class Duration>24// basic_ostream<charT, traits>&25// operator<<(basic_ostream<charT, traits>& os, const sys_time<Duration>& tp);26 27#include <chrono>28#include <cassert>29#include <ratio>30#include <sstream>31 32#include "make_string.h"33#include "platform_support.h" // locale name macros34#include "test_macros.h"35 36#define SV(S) MAKE_STRING_VIEW(CharT, S)37 38template <class CharT, class Duration>39static std::basic_string<CharT> stream_c_locale(std::chrono::sys_time<Duration> time_point) {40 std::basic_stringstream<CharT> sstr;41 sstr << std::fixed << time_point;42 return sstr.str();43}44 45template <class CharT, class Duration>46static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::sys_time<Duration> time_point) {47 std::basic_stringstream<CharT> sstr;48 const std::locale locale(LOCALE_fr_FR_UTF_8);49 sstr.imbue(locale);50 sstr << std::fixed << time_point;51 return sstr.str();52}53 54template <class CharT, class Duration>55static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::sys_time<Duration> time_point) {56 std::basic_stringstream<CharT> sstr;57 const std::locale locale(LOCALE_ja_JP_UTF_8);58 sstr.imbue(locale);59 sstr << std::fixed << time_point;60 return sstr.str();61}62 63template <class CharT>64static void test_c() {65 using namespace std::literals::chrono_literals;66 67 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{-946'688'523'123'456'789ns}) ==68 SV("1940-01-01 22:57:56.876543211"));69 70 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::microseconds>{-946'688'523'123'456us}) ==71 SV("1940-01-01 22:57:56.876544"));72 73 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::milliseconds>{-946'688'523'123ms}) ==74 SV("1940-01-01 22:57:56.877"));75 76 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{-1ns}) ==77 SV("1969-12-31 23:59:59.999999999"));78 79 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{0ns}) ==80 SV("1970-01-01 00:00:00.000000000"));81 82 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{1ns}) ==83 SV("1970-01-01 00:00:00.000000001"));84 85 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{946'688'523'123'456'789ns}) ==86 SV("2000-01-01 01:02:03.123456789"));87 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::microseconds>{946'688'523'123'456us}) ==88 SV("2000-01-01 01:02:03.123456"));89 90 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::milliseconds>{946'684'800'123ms}) ==91 SV("2000-01-01 00:00:00.123"));92 assert(stream_c_locale<CharT>(std::chrono::sys_seconds{1'234'567'890s}) == SV("2009-02-13 23:31:30"));93 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::minutes>{20'576'131min}) ==94 SV("2009-02-13 23:31:00"));95 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::hours>{342'935h}) == SV("2009-02-13 23:00:00"));96 97 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::duration<signed char, std::ratio<2, 1>>>{98 std::chrono::duration<signed char, std::ratio<2, 1>>{60}}) == SV("1970-01-01 00:02:00"));99 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::duration<short, std::ratio<1, 2>>>{100 std::chrono::duration<short, std::ratio<1, 2>>{3600}}) == SV("1970-01-01 00:30:00.0"));101 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::duration<int, std::ratio<1, 4>>>{102 std::chrono::duration<int, std::ratio<1, 4>>{3600}}) == SV("1970-01-01 00:15:00.00"));103 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::duration<long, std::ratio<1, 10>>>{104 std::chrono::duration<long, std::ratio<1, 10>>{36611}}) == SV("1970-01-01 01:01:01.1"));105 assert(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::duration<long long, std::ratio<1, 100>>>{106 std::chrono::duration<long long, std::ratio<1, 100>>{12'345'678'9010}}) == SV("2009-02-13 23:31:30.10"));107}108 109template <class CharT>110static void test_fr_FR() {111 using namespace std::literals::chrono_literals;112 113 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{-946'688'523'123'456'789ns}) ==114 SV("1940-01-01 22:57:56,876543211"));115 116 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::microseconds>{-946'688'523'123'456us}) ==117 SV("1940-01-01 22:57:56,876544"));118 119 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::milliseconds>{-946'688'523'123ms}) ==120 SV("1940-01-01 22:57:56,877"));121 122 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{-1ns}) ==123 SV("1969-12-31 23:59:59,999999999"));124 125 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{0ns}) ==126 SV("1970-01-01 00:00:00,000000000"));127 128 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{1ns}) ==129 SV("1970-01-01 00:00:00,000000001"));130 131 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{946'688'523'123'456'789ns}) ==132 SV("2000-01-01 01:02:03,123456789"));133 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::microseconds>{946'688'523'123'456us}) ==134 SV("2000-01-01 01:02:03,123456"));135 136 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::milliseconds>{946'684'800'123ms}) ==137 SV("2000-01-01 00:00:00,123"));138 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_seconds{1'234'567'890s}) == SV("2009-02-13 23:31:30"));139 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::minutes>{20'576'131min}) ==140 SV("2009-02-13 23:31:00"));141 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::hours>{342'935h}) == SV("2009-02-13 23:00:00"));142 143 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::duration<signed char, std::ratio<2, 1>>>{144 std::chrono::duration<signed char, std::ratio<2, 1>>{60}}) == SV("1970-01-01 00:02:00"));145 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::duration<short, std::ratio<1, 2>>>{146 std::chrono::duration<short, std::ratio<1, 2>>{3600}}) == SV("1970-01-01 00:30:00,0"));147 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::duration<int, std::ratio<1, 4>>>{148 std::chrono::duration<int, std::ratio<1, 4>>{3600}}) == SV("1970-01-01 00:15:00,00"));149 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::duration<long, std::ratio<1, 10>>>{150 std::chrono::duration<long, std::ratio<1, 10>>{36611}}) == SV("1970-01-01 01:01:01,1"));151 assert(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::duration<long long, std::ratio<1, 100>>>{152 std::chrono::duration<long long, std::ratio<1, 100>>{12'345'678'9010}}) == SV("2009-02-13 23:31:30,10"));153}154 155template <class CharT>156static void test_ja_JP() {157 using namespace std::literals::chrono_literals;158 159 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{-946'688'523'123'456'789ns}) ==160 SV("1940-01-01 22:57:56.876543211"));161 162 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::microseconds>{-946'688'523'123'456us}) ==163 SV("1940-01-01 22:57:56.876544"));164 165 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::milliseconds>{-946'688'523'123ms}) ==166 SV("1940-01-01 22:57:56.877"));167 168 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{-1ns}) ==169 SV("1969-12-31 23:59:59.999999999"));170 171 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{0ns}) ==172 SV("1970-01-01 00:00:00.000000000"));173 174 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{1ns}) ==175 SV("1970-01-01 00:00:00.000000001"));176 177 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::nanoseconds>{946'688'523'123'456'789ns}) ==178 SV("2000-01-01 01:02:03.123456789"));179 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::microseconds>{946'688'523'123'456us}) ==180 SV("2000-01-01 01:02:03.123456"));181 182 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::milliseconds>{946'684'800'123ms}) ==183 SV("2000-01-01 00:00:00.123"));184 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_seconds{1'234'567'890s}) == SV("2009-02-13 23:31:30"));185 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::minutes>{20'576'131min}) ==186 SV("2009-02-13 23:31:00"));187 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::hours>{342'935h}) == SV("2009-02-13 23:00:00"));188 189 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::duration<signed char, std::ratio<2, 1>>>{190 std::chrono::duration<signed char, std::ratio<2, 1>>{60}}) == SV("1970-01-01 00:02:00"));191 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::duration<short, std::ratio<1, 2>>>{192 std::chrono::duration<short, std::ratio<1, 2>>{3600}}) == SV("1970-01-01 00:30:00.0"));193 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::duration<int, std::ratio<1, 4>>>{194 std::chrono::duration<int, std::ratio<1, 4>>{3600}}) == SV("1970-01-01 00:15:00.00"));195 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::duration<long, std::ratio<1, 10>>>{196 std::chrono::duration<long, std::ratio<1, 10>>{36611}}) == SV("1970-01-01 01:01:01.1"));197 assert(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::duration<long long, std::ratio<1, 100>>>{198 std::chrono::duration<long long, std::ratio<1, 100>>{12'345'678'9010}}) == SV("2009-02-13 23:31:30.10"));199}200 201template <class CharT, class T>202concept is_ostreamable = requires(std::basic_ostream<CharT>& os, T const& val) {203 { os << val };204};205 206template <class CharT>207static void test() {208 // Test sys_time's constrains:209 // treat_as_floating_point_v<typename Duration::rep> is false, and Duration{1} < days{1} is true.210 static_assert(is_ostreamable<CharT, std::chrono::sys_seconds>);211 static_assert(is_ostreamable<CharT, std::chrono::sys_time<std::chrono::duration<long long>>>);212 // floating-point types213 static_assert(!is_ostreamable<CharT, std::chrono::sys_time<std::chrono::duration<float>>>);214 static_assert(!is_ostreamable<CharT, std::chrono::sys_time<std::chrono::duration<double>>>);215 static_assert(!is_ostreamable<CharT, std::chrono::sys_time<std::chrono::duration<long double>>>);216 217 static_assert(is_ostreamable<CharT, std::chrono::sys_days>);218 static_assert(is_ostreamable<CharT, std::chrono::sys_time<std::chrono::duration<int, std::ratio<86400>>>>);219 220 // duration > days{1}221 static_assert(!is_ostreamable<CharT, std::chrono::sys_time<std::chrono::duration<int, std::ratio<86401>>>>);222 static_assert(!is_ostreamable<CharT, std::chrono::sys_time<std::chrono::months>>);223 static_assert(!is_ostreamable<CharT, std::chrono::sys_time<std::chrono::years>>);224 225 // multiple of days are considered days.226 static_assert(is_ostreamable<CharT, std::chrono::sys_time<std::chrono::duration<int, std::ratio<3 * 86400>>>>);227 static_assert(is_ostreamable<CharT, std::chrono::sys_time<std::chrono::weeks>>);228 229 test_c<CharT>();230 test_fr_FR<CharT>();231 test_ja_JP<CharT>();232}233 234int main(int, char**) {235 test<char>();236 237#ifndef TEST_HAS_NO_WIDE_CHARACTERS238 test<wchar_t>();239#endif240 241 return 0;242}243