xref: /freebsd-src/contrib/llvm-project/libcxx/include/__chrono/ostream.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1bdd1243dSDimitry Andric // -*- C++ -*-
2bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
3bdd1243dSDimitry Andric //
4bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7bdd1243dSDimitry Andric //
8bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
9bdd1243dSDimitry Andric 
10bdd1243dSDimitry Andric #ifndef _LIBCPP___CHRONO_OSTREAM_H
11bdd1243dSDimitry Andric #define _LIBCPP___CHRONO_OSTREAM_H
12bdd1243dSDimitry Andric 
1306c3fb27SDimitry Andric #include <__chrono/calendar.h>
14bdd1243dSDimitry Andric #include <__chrono/day.h>
15bdd1243dSDimitry Andric #include <__chrono/duration.h>
1606c3fb27SDimitry Andric #include <__chrono/file_clock.h>
1706c3fb27SDimitry Andric #include <__chrono/hh_mm_ss.h>
18*0fca6ea1SDimitry Andric #include <__chrono/local_info.h>
19bdd1243dSDimitry Andric #include <__chrono/month.h>
20bdd1243dSDimitry Andric #include <__chrono/month_weekday.h>
21bdd1243dSDimitry Andric #include <__chrono/monthday.h>
22bdd1243dSDimitry Andric #include <__chrono/statically_widen.h>
23*0fca6ea1SDimitry Andric #include <__chrono/sys_info.h>
2406c3fb27SDimitry Andric #include <__chrono/system_clock.h>
25bdd1243dSDimitry Andric #include <__chrono/weekday.h>
26bdd1243dSDimitry Andric #include <__chrono/year.h>
27bdd1243dSDimitry Andric #include <__chrono/year_month.h>
28bdd1243dSDimitry Andric #include <__chrono/year_month_day.h>
29bdd1243dSDimitry Andric #include <__chrono/year_month_weekday.h>
30*0fca6ea1SDimitry Andric #include <__chrono/zoned_time.h>
31bdd1243dSDimitry Andric #include <__concepts/same_as.h>
32bdd1243dSDimitry Andric #include <__config>
33bdd1243dSDimitry Andric #include <__format/format_functions.h>
34*0fca6ea1SDimitry Andric #include <__fwd/ostream.h>
35bdd1243dSDimitry Andric #include <ratio>
36bdd1243dSDimitry Andric 
37bdd1243dSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
38bdd1243dSDimitry Andric #  pragma GCC system_header
39bdd1243dSDimitry Andric #endif
40bdd1243dSDimitry Andric 
41bdd1243dSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
42bdd1243dSDimitry Andric 
4306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
44bdd1243dSDimitry Andric 
45bdd1243dSDimitry Andric namespace chrono {
46bdd1243dSDimitry Andric 
4706c3fb27SDimitry Andric template <class _CharT, class _Traits, class _Duration>
487a6dacacSDimitry Andric   requires(!treat_as_floating_point_v<typename _Duration::rep> && _Duration{1} < days{1})
4906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
507a6dacacSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_time<_Duration>& __tp) {
5106c3fb27SDimitry Andric   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);
5206c3fb27SDimitry Andric }
5306c3fb27SDimitry Andric 
547a6dacacSDimitry Andric template <class _CharT, class _Traits>
557a6dacacSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
567a6dacacSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_days& __dp) {
577a6dacacSDimitry Andric   return __os << year_month_day{__dp};
587a6dacacSDimitry Andric }
597a6dacacSDimitry Andric 
6006c3fb27SDimitry Andric template <class _CharT, class _Traits, class _Duration>
6106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
6206c3fb27SDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const file_time<_Duration> __tp) {
6306c3fb27SDimitry Andric   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);
6406c3fb27SDimitry Andric }
6506c3fb27SDimitry Andric 
6606c3fb27SDimitry Andric template <class _CharT, class _Traits, class _Duration>
6706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
6806c3fb27SDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const local_time<_Duration> __tp) {
6906c3fb27SDimitry Andric   return __os << sys_time<_Duration>{__tp.time_since_epoch()};
7006c3fb27SDimitry Andric }
7106c3fb27SDimitry Andric 
72bdd1243dSDimitry Andric // Depending on the type the return is a const _CharT* or a basic_string<_CharT>
73bdd1243dSDimitry Andric template <class _CharT, class _Period>
74bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI auto __units_suffix() {
75bdd1243dSDimitry Andric   // TODO FMT LWG issue the suffixes are always char and not STATICALLY-WIDEN'ed.
76bdd1243dSDimitry Andric   if constexpr (same_as<typename _Period::type, atto>)
77bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "as");
78bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, femto>)
79bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "fs");
80bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, pico>)
81bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "ps");
82bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, nano>)
83bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "ns");
84bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, micro>)
85bdd1243dSDimitry Andric #  ifndef _LIBCPP_HAS_NO_UNICODE
86bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "\u00b5s");
87bdd1243dSDimitry Andric #  else
88bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "us");
89bdd1243dSDimitry Andric #  endif
90bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, milli>)
91bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "ms");
92bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, centi>)
93bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "cs");
94bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, deci>)
95bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "ds");
96bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, ratio<1>>)
97bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "s");
98bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, deca>)
99bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "das");
100bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, hecto>)
101bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "hs");
102bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, kilo>)
103bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "ks");
104bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, mega>)
105bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ms");
106bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, giga>)
107bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "Gs");
108bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, tera>)
109bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ts");
110bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, peta>)
111bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ps");
112bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, exa>)
113bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "Es");
114bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, ratio<60>>)
115bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "min");
116bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, ratio<3600>>)
117bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "h");
118bdd1243dSDimitry Andric   else if constexpr (same_as<typename _Period::type, ratio<86400>>)
119bdd1243dSDimitry Andric     return _LIBCPP_STATICALLY_WIDEN(_CharT, "d");
120bdd1243dSDimitry Andric   else if constexpr (_Period::den == 1)
121bdd1243dSDimitry Andric     return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}]s"), _Period::num);
122bdd1243dSDimitry Andric   else
123bdd1243dSDimitry Andric     return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}/{}]s"), _Period::num, _Period::den);
124bdd1243dSDimitry Andric }
125bdd1243dSDimitry Andric 
126bdd1243dSDimitry Andric template <class _CharT, class _Traits, class _Rep, class _Period>
12706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
128bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d) {
129bdd1243dSDimitry Andric   basic_ostringstream<_CharT, _Traits> __s;
130bdd1243dSDimitry Andric   __s.flags(__os.flags());
131bdd1243dSDimitry Andric   __s.imbue(__os.getloc());
132bdd1243dSDimitry Andric   __s.precision(__os.precision());
133bdd1243dSDimitry Andric   __s << __d.count() << chrono::__units_suffix<_CharT, _Period>();
134bdd1243dSDimitry Andric   return __os << __s.str();
135bdd1243dSDimitry Andric }
136bdd1243dSDimitry Andric 
137bdd1243dSDimitry Andric template <class _CharT, class _Traits>
13806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) {
13906c3fb27SDimitry Andric   return __os << (__d.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d)
140bdd1243dSDimitry Andric                            // Note this error differs from the wording of the Standard. The
141bdd1243dSDimitry Andric                            // Standard wording doesn't work well on AIX or Windows. There
142bdd1243dSDimitry Andric                            // the formatted day seems to be either modulo 100 or completely
143bdd1243dSDimitry Andric                            // omitted. Judging by the wording this is valid.
144bdd1243dSDimitry Andric                            // TODO FMT Write a paper of file an LWG issue.
14506c3fb27SDimitry Andric                            : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"),
14606c3fb27SDimitry Andric                                          static_cast<unsigned>(__d)));
147bdd1243dSDimitry Andric }
148bdd1243dSDimitry Andric 
149bdd1243dSDimitry Andric template <class _CharT, class _Traits>
15006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
151bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) {
152bdd1243dSDimitry Andric   return __os << (__m.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%b}"), __m)
153bdd1243dSDimitry Andric                            : std::format(__os.getloc(),
154bdd1243dSDimitry Andric                                          _LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid month"),
155bdd1243dSDimitry Andric                                          static_cast<unsigned>(__m))); // TODO FMT Standard mandated locale isn't used.
156bdd1243dSDimitry Andric }
157bdd1243dSDimitry Andric 
158bdd1243dSDimitry Andric template <class _CharT, class _Traits>
15906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
160bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const year& __y) {
161bdd1243dSDimitry Andric   return __os << (__y.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y}"), __y)
162bdd1243dSDimitry Andric                            : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y} is not a valid year"), __y));
163bdd1243dSDimitry Andric }
164bdd1243dSDimitry Andric 
165bdd1243dSDimitry Andric template <class _CharT, class _Traits>
16606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
167bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) {
168bdd1243dSDimitry Andric   return __os << (__wd.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%a}"), __wd)
169bdd1243dSDimitry Andric                             : std::format(__os.getloc(), // TODO FMT Standard mandated locale isn't used.
170bdd1243dSDimitry Andric                                           _LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid weekday"),
171bdd1243dSDimitry Andric                                           static_cast<unsigned>(__wd.c_encoding())));
172bdd1243dSDimitry Andric }
173bdd1243dSDimitry Andric 
174bdd1243dSDimitry Andric template <class _CharT, class _Traits>
17506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
176bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) {
177bdd1243dSDimitry Andric   auto __i = __wdi.index();
178bdd1243dSDimitry Andric   return __os << (__i >= 1 && __i <= 5
179bdd1243dSDimitry Andric                       ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{}]"), __wdi.weekday(), __i)
180bdd1243dSDimitry Andric                       : std::format(__os.getloc(),
181bdd1243dSDimitry Andric                                     _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{} is not a valid index]"),
182bdd1243dSDimitry Andric                                     __wdi.weekday(),
183bdd1243dSDimitry Andric                                     __i));
184bdd1243dSDimitry Andric }
185bdd1243dSDimitry Andric 
186bdd1243dSDimitry Andric template <class _CharT, class _Traits>
18706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
188bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_last& __wdl) {
189bdd1243dSDimitry Andric   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[last]"), __wdl.weekday());
190bdd1243dSDimitry Andric }
191bdd1243dSDimitry Andric 
192bdd1243dSDimitry Andric template <class _CharT, class _Traits>
19306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
194bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) {
195bdd1243dSDimitry Andric   // TODO FMT The Standard allows 30th of February to be printed.
196bdd1243dSDimitry Andric   // It would be nice to show an error message instead.
197bdd1243dSDimitry Andric   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{}"), __md.month(), __md.day());
198bdd1243dSDimitry Andric }
199bdd1243dSDimitry Andric 
200bdd1243dSDimitry Andric template <class _CharT, class _Traits>
20106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
202bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day_last& __mdl) {
203bdd1243dSDimitry Andric   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/last"), __mdl.month());
204bdd1243dSDimitry Andric }
205bdd1243dSDimitry Andric 
206bdd1243dSDimitry Andric template <class _CharT, class _Traits>
20706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
208bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday& __mwd) {
209bdd1243dSDimitry Andric   return __os << std::format(
210bdd1243dSDimitry Andric              __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwd.month(), __mwd.weekday_indexed());
211bdd1243dSDimitry Andric }
212bdd1243dSDimitry Andric 
213bdd1243dSDimitry Andric template <class _CharT, class _Traits>
21406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
215bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday_last& __mwdl) {
216bdd1243dSDimitry Andric   return __os << std::format(
217bdd1243dSDimitry Andric              __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwdl.month(), __mwdl.weekday_last());
218bdd1243dSDimitry Andric }
219bdd1243dSDimitry Andric 
220bdd1243dSDimitry Andric template <class _CharT, class _Traits>
22106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
222bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) {
223bdd1243dSDimitry Andric   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ym.year(), __ym.month());
224bdd1243dSDimitry Andric }
225bdd1243dSDimitry Andric 
226bdd1243dSDimitry Andric template <class _CharT, class _Traits>
22706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
228bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day& __ymd) {
229bdd1243dSDimitry Andric   return __os << (__ymd.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F}"), __ymd)
230bdd1243dSDimitry Andric                              : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), __ymd));
231bdd1243dSDimitry Andric }
232bdd1243dSDimitry Andric 
233bdd1243dSDimitry Andric template <class _CharT, class _Traits>
23406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
235bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day_last& __ymdl) {
236bdd1243dSDimitry Andric   return __os << std::format(
237bdd1243dSDimitry Andric              __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ymdl.year(), __ymdl.month_day_last());
238bdd1243dSDimitry Andric }
239bdd1243dSDimitry Andric 
240bdd1243dSDimitry Andric template <class _CharT, class _Traits>
24106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
242bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymwd) {
243bdd1243dSDimitry Andric   return __os << std::format(
244bdd1243dSDimitry Andric              __os.getloc(),
245bdd1243dSDimitry Andric              _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),
246bdd1243dSDimitry Andric              __ymwd.year(),
247bdd1243dSDimitry Andric              __ymwd.month(),
248bdd1243dSDimitry Andric              __ymwd.weekday_indexed());
249bdd1243dSDimitry Andric }
250bdd1243dSDimitry Andric 
251bdd1243dSDimitry Andric template <class _CharT, class _Traits>
25206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
253bdd1243dSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& __ymwdl) {
254bdd1243dSDimitry Andric   return __os << std::format(
255bdd1243dSDimitry Andric              __os.getloc(),
256bdd1243dSDimitry Andric              _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),
257bdd1243dSDimitry Andric              __ymwdl.year(),
258bdd1243dSDimitry Andric              __ymwdl.month(),
259bdd1243dSDimitry Andric              __ymwdl.weekday_last());
260bdd1243dSDimitry Andric }
261bdd1243dSDimitry Andric 
26206c3fb27SDimitry Andric template <class _CharT, class _Traits, class _Duration>
26306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
26406c3fb27SDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const hh_mm_ss<_Duration> __hms) {
26506c3fb27SDimitry Andric   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%T}"), __hms);
26606c3fb27SDimitry Andric }
26706c3fb27SDimitry Andric 
268*0fca6ea1SDimitry Andric #  if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)
269*0fca6ea1SDimitry Andric 
270*0fca6ea1SDimitry Andric template <class _CharT, class _Traits>
271*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
272*0fca6ea1SDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_info& __info) {
273*0fca6ea1SDimitry Andric   // __info.abbrev is always std::basic_string<char>.
274*0fca6ea1SDimitry Andric   // Since these strings typically are short the conversion should be cheap.
275*0fca6ea1SDimitry Andric   std::basic_string<_CharT> __abbrev{__info.abbrev.begin(), __info.abbrev.end()};
276*0fca6ea1SDimitry Andric   return __os << std::format(
277*0fca6ea1SDimitry Andric              _LIBCPP_STATICALLY_WIDEN(_CharT, "[{:%F %T}, {:%F %T}) {:%T} {:%Q%q} \"{}\""),
278*0fca6ea1SDimitry Andric              __info.begin,
279*0fca6ea1SDimitry Andric              __info.end,
280*0fca6ea1SDimitry Andric              hh_mm_ss{__info.offset},
281*0fca6ea1SDimitry Andric              __info.save,
282*0fca6ea1SDimitry Andric              __abbrev);
283*0fca6ea1SDimitry Andric }
284*0fca6ea1SDimitry Andric 
285*0fca6ea1SDimitry Andric template <class _CharT, class _Traits>
286*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
287*0fca6ea1SDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const local_info& __info) {
288*0fca6ea1SDimitry Andric   auto __result = [&]() -> basic_string<_CharT> {
289*0fca6ea1SDimitry Andric     switch (__info.result) {
290*0fca6ea1SDimitry Andric     case local_info::unique:
291*0fca6ea1SDimitry Andric       return _LIBCPP_STATICALLY_WIDEN(_CharT, "unique");
292*0fca6ea1SDimitry Andric     case local_info::nonexistent:
293*0fca6ea1SDimitry Andric       return _LIBCPP_STATICALLY_WIDEN(_CharT, "non-existent");
294*0fca6ea1SDimitry Andric     case local_info::ambiguous:
295*0fca6ea1SDimitry Andric       return _LIBCPP_STATICALLY_WIDEN(_CharT, "ambiguous");
296*0fca6ea1SDimitry Andric 
297*0fca6ea1SDimitry Andric     default:
298*0fca6ea1SDimitry Andric       return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "unspecified result ({})"), __info.result);
299*0fca6ea1SDimitry Andric     };
300*0fca6ea1SDimitry Andric   };
301*0fca6ea1SDimitry Andric 
302*0fca6ea1SDimitry Andric   return __os << std::format(
303*0fca6ea1SDimitry Andric              _LIBCPP_STATICALLY_WIDEN(_CharT, "{}: {{{}, {}}}"), __result(), __info.first, __info.second);
304*0fca6ea1SDimitry Andric }
305*0fca6ea1SDimitry Andric 
306*0fca6ea1SDimitry Andric #    if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) &&                          \
307*0fca6ea1SDimitry Andric         !defined(_LIBCPP_HAS_NO_LOCALIZATION)
308*0fca6ea1SDimitry Andric template <class _CharT, class _Traits, class _Duration, class _TimeZonePtr>
309*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
310*0fca6ea1SDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const zoned_time<_Duration, _TimeZonePtr>& __tp) {
311*0fca6ea1SDimitry Andric   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T %Z}"), __tp);
312*0fca6ea1SDimitry Andric }
313*0fca6ea1SDimitry Andric #    endif
314*0fca6ea1SDimitry Andric #  endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)
315*0fca6ea1SDimitry Andric 
316bdd1243dSDimitry Andric } // namespace chrono
317bdd1243dSDimitry Andric 
31806c3fb27SDimitry Andric #endif // if _LIBCPP_STD_VER >= 20
319bdd1243dSDimitry Andric 
320bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
321bdd1243dSDimitry Andric 
322bdd1243dSDimitry Andric #endif // _LIBCPP___CHRONO_OSTREAM_H
323