File indexing completed on 2026-05-03 08:13:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CHRONO_OSTREAM_H
0011 #define _LIBCPP___CHRONO_OSTREAM_H
0012
0013 #include <__config>
0014
0015 #if _LIBCPP_HAS_LOCALIZATION
0016
0017 # include <__chrono/calendar.h>
0018 # include <__chrono/day.h>
0019 # include <__chrono/duration.h>
0020 # include <__chrono/file_clock.h>
0021 # include <__chrono/hh_mm_ss.h>
0022 # include <__chrono/local_info.h>
0023 # include <__chrono/month.h>
0024 # include <__chrono/month_weekday.h>
0025 # include <__chrono/monthday.h>
0026 # include <__chrono/statically_widen.h>
0027 # include <__chrono/sys_info.h>
0028 # include <__chrono/system_clock.h>
0029 # include <__chrono/utc_clock.h>
0030 # include <__chrono/weekday.h>
0031 # include <__chrono/year.h>
0032 # include <__chrono/year_month.h>
0033 # include <__chrono/year_month_day.h>
0034 # include <__chrono/year_month_weekday.h>
0035 # include <__chrono/zoned_time.h>
0036 # include <__concepts/same_as.h>
0037 # include <__format/format_functions.h>
0038 # include <__fwd/ostream.h>
0039 # include <ratio>
0040 # include <sstream>
0041
0042 # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0043 # pragma GCC system_header
0044 # endif
0045
0046 _LIBCPP_BEGIN_NAMESPACE_STD
0047
0048 # if _LIBCPP_STD_VER >= 20
0049
0050 namespace chrono {
0051
0052 template <class _CharT, class _Traits, class _Duration>
0053 requires(!treat_as_floating_point_v<typename _Duration::rep> && _Duration{1} < days{1})
0054 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0055 operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_time<_Duration>& __tp) {
0056 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);
0057 }
0058
0059 template <class _CharT, class _Traits>
0060 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0061 operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_days& __dp) {
0062 return __os << year_month_day{__dp};
0063 }
0064
0065 # if _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
0066 # if _LIBCPP_HAS_EXPERIMENTAL_TZDB
0067
0068 template <class _CharT, class _Traits, class _Duration>
0069 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0070 operator<<(basic_ostream<_CharT, _Traits>& __os, const utc_time<_Duration>& __tp) {
0071 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);
0072 }
0073
0074 # endif
0075 # endif
0076
0077 template <class _CharT, class _Traits, class _Duration>
0078 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0079 operator<<(basic_ostream<_CharT, _Traits>& __os, const file_time<_Duration> __tp) {
0080 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);
0081 }
0082
0083 template <class _CharT, class _Traits, class _Duration>
0084 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0085 operator<<(basic_ostream<_CharT, _Traits>& __os, const local_time<_Duration> __tp) {
0086 return __os << sys_time<_Duration>{__tp.time_since_epoch()};
0087 }
0088
0089
0090 template <class _CharT, class _Period>
0091 _LIBCPP_HIDE_FROM_ABI auto __units_suffix() {
0092
0093 if constexpr (same_as<typename _Period::type, atto>)
0094 return _LIBCPP_STATICALLY_WIDEN(_CharT, "as");
0095 else if constexpr (same_as<typename _Period::type, femto>)
0096 return _LIBCPP_STATICALLY_WIDEN(_CharT, "fs");
0097 else if constexpr (same_as<typename _Period::type, pico>)
0098 return _LIBCPP_STATICALLY_WIDEN(_CharT, "ps");
0099 else if constexpr (same_as<typename _Period::type, nano>)
0100 return _LIBCPP_STATICALLY_WIDEN(_CharT, "ns");
0101 else if constexpr (same_as<typename _Period::type, micro>)
0102 # if _LIBCPP_HAS_UNICODE
0103 return _LIBCPP_STATICALLY_WIDEN(_CharT, "\u00b5s");
0104 # else
0105 return _LIBCPP_STATICALLY_WIDEN(_CharT, "us");
0106 # endif
0107 else if constexpr (same_as<typename _Period::type, milli>)
0108 return _LIBCPP_STATICALLY_WIDEN(_CharT, "ms");
0109 else if constexpr (same_as<typename _Period::type, centi>)
0110 return _LIBCPP_STATICALLY_WIDEN(_CharT, "cs");
0111 else if constexpr (same_as<typename _Period::type, deci>)
0112 return _LIBCPP_STATICALLY_WIDEN(_CharT, "ds");
0113 else if constexpr (same_as<typename _Period::type, ratio<1>>)
0114 return _LIBCPP_STATICALLY_WIDEN(_CharT, "s");
0115 else if constexpr (same_as<typename _Period::type, deca>)
0116 return _LIBCPP_STATICALLY_WIDEN(_CharT, "das");
0117 else if constexpr (same_as<typename _Period::type, hecto>)
0118 return _LIBCPP_STATICALLY_WIDEN(_CharT, "hs");
0119 else if constexpr (same_as<typename _Period::type, kilo>)
0120 return _LIBCPP_STATICALLY_WIDEN(_CharT, "ks");
0121 else if constexpr (same_as<typename _Period::type, mega>)
0122 return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ms");
0123 else if constexpr (same_as<typename _Period::type, giga>)
0124 return _LIBCPP_STATICALLY_WIDEN(_CharT, "Gs");
0125 else if constexpr (same_as<typename _Period::type, tera>)
0126 return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ts");
0127 else if constexpr (same_as<typename _Period::type, peta>)
0128 return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ps");
0129 else if constexpr (same_as<typename _Period::type, exa>)
0130 return _LIBCPP_STATICALLY_WIDEN(_CharT, "Es");
0131 else if constexpr (same_as<typename _Period::type, ratio<60>>)
0132 return _LIBCPP_STATICALLY_WIDEN(_CharT, "min");
0133 else if constexpr (same_as<typename _Period::type, ratio<3600>>)
0134 return _LIBCPP_STATICALLY_WIDEN(_CharT, "h");
0135 else if constexpr (same_as<typename _Period::type, ratio<86400>>)
0136 return _LIBCPP_STATICALLY_WIDEN(_CharT, "d");
0137 else if constexpr (_Period::den == 1)
0138 return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}]s"), _Period::num);
0139 else
0140 return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}/{}]s"), _Period::num, _Period::den);
0141 }
0142
0143 template <class _CharT, class _Traits, class _Rep, class _Period>
0144 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0145 operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d) {
0146 basic_ostringstream<_CharT, _Traits> __s;
0147 __s.flags(__os.flags());
0148 __s.imbue(__os.getloc());
0149 __s.precision(__os.precision());
0150 __s << __d.count() << chrono::__units_suffix<_CharT, _Period>();
0151 return __os << __s.str();
0152 }
0153
0154 template <class _CharT, class _Traits>
0155 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) {
0156 return __os << (__d.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d)
0157
0158
0159
0160
0161
0162 : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"),
0163 static_cast<unsigned>(__d)));
0164 }
0165
0166 template <class _CharT, class _Traits>
0167 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0168 operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) {
0169 return __os << (__m.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%b}"), __m)
0170 : std::format(__os.getloc(),
0171 _LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid month"),
0172 static_cast<unsigned>(__m)));
0173 }
0174
0175 template <class _CharT, class _Traits>
0176 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0177 operator<<(basic_ostream<_CharT, _Traits>& __os, const year& __y) {
0178 return __os << (__y.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y}"), __y)
0179 : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y} is not a valid year"), __y));
0180 }
0181
0182 template <class _CharT, class _Traits>
0183 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0184 operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) {
0185 return __os << (__wd.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%a}"), __wd)
0186 : std::format(__os.getloc(),
0187 _LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid weekday"),
0188 static_cast<unsigned>(__wd.c_encoding())));
0189 }
0190
0191 template <class _CharT, class _Traits>
0192 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0193 operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) {
0194 auto __i = __wdi.index();
0195 return __os << (__i >= 1 && __i <= 5
0196 ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{}]"), __wdi.weekday(), __i)
0197 : std::format(__os.getloc(),
0198 _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{} is not a valid index]"),
0199 __wdi.weekday(),
0200 __i));
0201 }
0202
0203 template <class _CharT, class _Traits>
0204 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0205 operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_last& __wdl) {
0206 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[last]"), __wdl.weekday());
0207 }
0208
0209 template <class _CharT, class _Traits>
0210 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0211 operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) {
0212
0213
0214 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{}"), __md.month(), __md.day());
0215 }
0216
0217 template <class _CharT, class _Traits>
0218 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0219 operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day_last& __mdl) {
0220 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/last"), __mdl.month());
0221 }
0222
0223 template <class _CharT, class _Traits>
0224 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0225 operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday& __mwd) {
0226 return __os << std::format(
0227 __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwd.month(), __mwd.weekday_indexed());
0228 }
0229
0230 template <class _CharT, class _Traits>
0231 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0232 operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday_last& __mwdl) {
0233 return __os << std::format(
0234 __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwdl.month(), __mwdl.weekday_last());
0235 }
0236
0237 template <class _CharT, class _Traits>
0238 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0239 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) {
0240 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ym.year(), __ym.month());
0241 }
0242
0243 template <class _CharT, class _Traits>
0244 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0245 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day& __ymd) {
0246 return __os << (__ymd.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F}"), __ymd)
0247 : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), __ymd));
0248 }
0249
0250 template <class _CharT, class _Traits>
0251 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0252 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day_last& __ymdl) {
0253 return __os << std::format(
0254 __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ymdl.year(), __ymdl.month_day_last());
0255 }
0256
0257 template <class _CharT, class _Traits>
0258 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0259 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymwd) {
0260 return __os << std::format(
0261 __os.getloc(),
0262 _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),
0263 __ymwd.year(),
0264 __ymwd.month(),
0265 __ymwd.weekday_indexed());
0266 }
0267
0268 template <class _CharT, class _Traits>
0269 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0270 operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& __ymwdl) {
0271 return __os << std::format(
0272 __os.getloc(),
0273 _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),
0274 __ymwdl.year(),
0275 __ymwdl.month(),
0276 __ymwdl.weekday_last());
0277 }
0278
0279 template <class _CharT, class _Traits, class _Duration>
0280 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0281 operator<<(basic_ostream<_CharT, _Traits>& __os, const hh_mm_ss<_Duration> __hms) {
0282 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%T}"), __hms);
0283 }
0284
0285 # if _LIBCPP_HAS_EXPERIMENTAL_TZDB
0286
0287 template <class _CharT, class _Traits>
0288 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0289 operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_info& __info) {
0290
0291
0292 std::basic_string<_CharT> __abbrev{__info.abbrev.begin(), __info.abbrev.end()};
0293 return __os << std::format(
0294 _LIBCPP_STATICALLY_WIDEN(_CharT, "[{:%F %T}, {:%F %T}) {:%T} {:%Q%q} \"{}\""),
0295 __info.begin,
0296 __info.end,
0297 hh_mm_ss{__info.offset},
0298 __info.save,
0299 __abbrev);
0300 }
0301
0302 template <class _CharT, class _Traits>
0303 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0304 operator<<(basic_ostream<_CharT, _Traits>& __os, const local_info& __info) {
0305 auto __result = [&]() -> basic_string<_CharT> {
0306 switch (__info.result) {
0307 case local_info::unique:
0308 return _LIBCPP_STATICALLY_WIDEN(_CharT, "unique");
0309 case local_info::nonexistent:
0310 return _LIBCPP_STATICALLY_WIDEN(_CharT, "non-existent");
0311 case local_info::ambiguous:
0312 return _LIBCPP_STATICALLY_WIDEN(_CharT, "ambiguous");
0313
0314 default:
0315 return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "unspecified result ({})"), __info.result);
0316 };
0317 };
0318
0319 return __os << std::format(
0320 _LIBCPP_STATICALLY_WIDEN(_CharT, "{}: {{{}, {}}}"), __result(), __info.first, __info.second);
0321 }
0322
0323 # if _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
0324 template <class _CharT, class _Traits, class _Duration, class _TimeZonePtr>
0325 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0326 operator<<(basic_ostream<_CharT, _Traits>& __os, const zoned_time<_Duration, _TimeZonePtr>& __tp) {
0327 return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T %Z}"), __tp);
0328 }
0329 # endif
0330 # endif
0331
0332 }
0333
0334 # endif
0335
0336 _LIBCPP_END_NAMESPACE_STD
0337
0338 #endif
0339
0340 #endif