Path: blob/main/contrib/llvm-project/libcxx/include/__chrono/ostream.h
35262 views
// -*- C++ -*-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//===----------------------------------------------------------------------===//89#ifndef _LIBCPP___CHRONO_OSTREAM_H10#define _LIBCPP___CHRONO_OSTREAM_H1112#include <__chrono/calendar.h>13#include <__chrono/day.h>14#include <__chrono/duration.h>15#include <__chrono/file_clock.h>16#include <__chrono/hh_mm_ss.h>17#include <__chrono/local_info.h>18#include <__chrono/month.h>19#include <__chrono/month_weekday.h>20#include <__chrono/monthday.h>21#include <__chrono/statically_widen.h>22#include <__chrono/sys_info.h>23#include <__chrono/system_clock.h>24#include <__chrono/weekday.h>25#include <__chrono/year.h>26#include <__chrono/year_month.h>27#include <__chrono/year_month_day.h>28#include <__chrono/year_month_weekday.h>29#include <__chrono/zoned_time.h>30#include <__concepts/same_as.h>31#include <__config>32#include <__format/format_functions.h>33#include <__fwd/ostream.h>34#include <ratio>3536#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)37# pragma GCC system_header38#endif3940_LIBCPP_BEGIN_NAMESPACE_STD4142#if _LIBCPP_STD_VER >= 204344namespace chrono {4546template <class _CharT, class _Traits, class _Duration>47requires(!treat_as_floating_point_v<typename _Duration::rep> && _Duration{1} < days{1})48_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&49operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_time<_Duration>& __tp) {50return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);51}5253template <class _CharT, class _Traits>54_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&55operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_days& __dp) {56return __os << year_month_day{__dp};57}5859template <class _CharT, class _Traits, class _Duration>60_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&61operator<<(basic_ostream<_CharT, _Traits>& __os, const file_time<_Duration> __tp) {62return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);63}6465template <class _CharT, class _Traits, class _Duration>66_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&67operator<<(basic_ostream<_CharT, _Traits>& __os, const local_time<_Duration> __tp) {68return __os << sys_time<_Duration>{__tp.time_since_epoch()};69}7071// Depending on the type the return is a const _CharT* or a basic_string<_CharT>72template <class _CharT, class _Period>73_LIBCPP_HIDE_FROM_ABI auto __units_suffix() {74// TODO FMT LWG issue the suffixes are always char and not STATICALLY-WIDEN'ed.75if constexpr (same_as<typename _Period::type, atto>)76return _LIBCPP_STATICALLY_WIDEN(_CharT, "as");77else if constexpr (same_as<typename _Period::type, femto>)78return _LIBCPP_STATICALLY_WIDEN(_CharT, "fs");79else if constexpr (same_as<typename _Period::type, pico>)80return _LIBCPP_STATICALLY_WIDEN(_CharT, "ps");81else if constexpr (same_as<typename _Period::type, nano>)82return _LIBCPP_STATICALLY_WIDEN(_CharT, "ns");83else if constexpr (same_as<typename _Period::type, micro>)84# ifndef _LIBCPP_HAS_NO_UNICODE85return _LIBCPP_STATICALLY_WIDEN(_CharT, "\u00b5s");86# else87return _LIBCPP_STATICALLY_WIDEN(_CharT, "us");88# endif89else if constexpr (same_as<typename _Period::type, milli>)90return _LIBCPP_STATICALLY_WIDEN(_CharT, "ms");91else if constexpr (same_as<typename _Period::type, centi>)92return _LIBCPP_STATICALLY_WIDEN(_CharT, "cs");93else if constexpr (same_as<typename _Period::type, deci>)94return _LIBCPP_STATICALLY_WIDEN(_CharT, "ds");95else if constexpr (same_as<typename _Period::type, ratio<1>>)96return _LIBCPP_STATICALLY_WIDEN(_CharT, "s");97else if constexpr (same_as<typename _Period::type, deca>)98return _LIBCPP_STATICALLY_WIDEN(_CharT, "das");99else if constexpr (same_as<typename _Period::type, hecto>)100return _LIBCPP_STATICALLY_WIDEN(_CharT, "hs");101else if constexpr (same_as<typename _Period::type, kilo>)102return _LIBCPP_STATICALLY_WIDEN(_CharT, "ks");103else if constexpr (same_as<typename _Period::type, mega>)104return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ms");105else if constexpr (same_as<typename _Period::type, giga>)106return _LIBCPP_STATICALLY_WIDEN(_CharT, "Gs");107else if constexpr (same_as<typename _Period::type, tera>)108return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ts");109else if constexpr (same_as<typename _Period::type, peta>)110return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ps");111else if constexpr (same_as<typename _Period::type, exa>)112return _LIBCPP_STATICALLY_WIDEN(_CharT, "Es");113else if constexpr (same_as<typename _Period::type, ratio<60>>)114return _LIBCPP_STATICALLY_WIDEN(_CharT, "min");115else if constexpr (same_as<typename _Period::type, ratio<3600>>)116return _LIBCPP_STATICALLY_WIDEN(_CharT, "h");117else if constexpr (same_as<typename _Period::type, ratio<86400>>)118return _LIBCPP_STATICALLY_WIDEN(_CharT, "d");119else if constexpr (_Period::den == 1)120return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}]s"), _Period::num);121else122return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}/{}]s"), _Period::num, _Period::den);123}124125template <class _CharT, class _Traits, class _Rep, class _Period>126_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&127operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d) {128basic_ostringstream<_CharT, _Traits> __s;129__s.flags(__os.flags());130__s.imbue(__os.getloc());131__s.precision(__os.precision());132__s << __d.count() << chrono::__units_suffix<_CharT, _Period>();133return __os << __s.str();134}135136template <class _CharT, class _Traits>137_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) {138return __os << (__d.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d)139// Note this error differs from the wording of the Standard. The140// Standard wording doesn't work well on AIX or Windows. There141// the formatted day seems to be either modulo 100 or completely142// omitted. Judging by the wording this is valid.143// TODO FMT Write a paper of file an LWG issue.144: std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"),145static_cast<unsigned>(__d)));146}147148template <class _CharT, class _Traits>149_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&150operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) {151return __os << (__m.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%b}"), __m)152: std::format(__os.getloc(),153_LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid month"),154static_cast<unsigned>(__m))); // TODO FMT Standard mandated locale isn't used.155}156157template <class _CharT, class _Traits>158_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&159operator<<(basic_ostream<_CharT, _Traits>& __os, const year& __y) {160return __os << (__y.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y}"), __y)161: std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y} is not a valid year"), __y));162}163164template <class _CharT, class _Traits>165_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&166operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) {167return __os << (__wd.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%a}"), __wd)168: std::format(__os.getloc(), // TODO FMT Standard mandated locale isn't used.169_LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid weekday"),170static_cast<unsigned>(__wd.c_encoding())));171}172173template <class _CharT, class _Traits>174_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&175operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) {176auto __i = __wdi.index();177return __os << (__i >= 1 && __i <= 5178? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{}]"), __wdi.weekday(), __i)179: std::format(__os.getloc(),180_LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{} is not a valid index]"),181__wdi.weekday(),182__i));183}184185template <class _CharT, class _Traits>186_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&187operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_last& __wdl) {188return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[last]"), __wdl.weekday());189}190191template <class _CharT, class _Traits>192_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&193operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) {194// TODO FMT The Standard allows 30th of February to be printed.195// It would be nice to show an error message instead.196return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{}"), __md.month(), __md.day());197}198199template <class _CharT, class _Traits>200_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&201operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day_last& __mdl) {202return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/last"), __mdl.month());203}204205template <class _CharT, class _Traits>206_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&207operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday& __mwd) {208return __os << std::format(209__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwd.month(), __mwd.weekday_indexed());210}211212template <class _CharT, class _Traits>213_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&214operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday_last& __mwdl) {215return __os << std::format(216__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwdl.month(), __mwdl.weekday_last());217}218219template <class _CharT, class _Traits>220_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&221operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) {222return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ym.year(), __ym.month());223}224225template <class _CharT, class _Traits>226_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&227operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day& __ymd) {228return __os << (__ymd.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F}"), __ymd)229: std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), __ymd));230}231232template <class _CharT, class _Traits>233_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&234operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day_last& __ymdl) {235return __os << std::format(236__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ymdl.year(), __ymdl.month_day_last());237}238239template <class _CharT, class _Traits>240_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&241operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymwd) {242return __os << std::format(243__os.getloc(),244_LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),245__ymwd.year(),246__ymwd.month(),247__ymwd.weekday_indexed());248}249250template <class _CharT, class _Traits>251_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&252operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& __ymwdl) {253return __os << std::format(254__os.getloc(),255_LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),256__ymwdl.year(),257__ymwdl.month(),258__ymwdl.weekday_last());259}260261template <class _CharT, class _Traits, class _Duration>262_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&263operator<<(basic_ostream<_CharT, _Traits>& __os, const hh_mm_ss<_Duration> __hms) {264return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%T}"), __hms);265}266267# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)268269template <class _CharT, class _Traits>270_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&271operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_info& __info) {272// __info.abbrev is always std::basic_string<char>.273// Since these strings typically are short the conversion should be cheap.274std::basic_string<_CharT> __abbrev{__info.abbrev.begin(), __info.abbrev.end()};275return __os << std::format(276_LIBCPP_STATICALLY_WIDEN(_CharT, "[{:%F %T}, {:%F %T}) {:%T} {:%Q%q} \"{}\""),277__info.begin,278__info.end,279hh_mm_ss{__info.offset},280__info.save,281__abbrev);282}283284template <class _CharT, class _Traits>285_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&286operator<<(basic_ostream<_CharT, _Traits>& __os, const local_info& __info) {287auto __result = [&]() -> basic_string<_CharT> {288switch (__info.result) {289case local_info::unique:290return _LIBCPP_STATICALLY_WIDEN(_CharT, "unique");291case local_info::nonexistent:292return _LIBCPP_STATICALLY_WIDEN(_CharT, "non-existent");293case local_info::ambiguous:294return _LIBCPP_STATICALLY_WIDEN(_CharT, "ambiguous");295296default:297return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "unspecified result ({})"), __info.result);298};299};300301return __os << std::format(302_LIBCPP_STATICALLY_WIDEN(_CharT, "{}: {{{}, {}}}"), __result(), __info.first, __info.second);303}304305# if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \306!defined(_LIBCPP_HAS_NO_LOCALIZATION)307template <class _CharT, class _Traits, class _Duration, class _TimeZonePtr>308_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&309operator<<(basic_ostream<_CharT, _Traits>& __os, const zoned_time<_Duration, _TimeZonePtr>& __tp) {310return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T %Z}"), __tp);311}312# endif313# endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)314315} // namespace chrono316317#endif // if _LIBCPP_STD_VER >= 20318319_LIBCPP_END_NAMESPACE_STD320321#endif // _LIBCPP___CHRONO_OSTREAM_H322323324