xref: /openbsd-src/gnu/llvm/libcxx/include/__chrono/ostream.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
1*4bdff4beSrobert // -*- C++ -*-
2*4bdff4beSrobert //===----------------------------------------------------------------------===//
3*4bdff4beSrobert //
4*4bdff4beSrobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*4bdff4beSrobert // See https://llvm.org/LICENSE.txt for license information.
6*4bdff4beSrobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*4bdff4beSrobert //
8*4bdff4beSrobert //===----------------------------------------------------------------------===//
9*4bdff4beSrobert 
10*4bdff4beSrobert #ifndef _LIBCPP___CHRONO_OSTREAM_H
11*4bdff4beSrobert #define _LIBCPP___CHRONO_OSTREAM_H
12*4bdff4beSrobert 
13*4bdff4beSrobert #include <__chrono/day.h>
14*4bdff4beSrobert #include <__chrono/duration.h>
15*4bdff4beSrobert #include <__chrono/month.h>
16*4bdff4beSrobert #include <__chrono/month_weekday.h>
17*4bdff4beSrobert #include <__chrono/monthday.h>
18*4bdff4beSrobert #include <__chrono/statically_widen.h>
19*4bdff4beSrobert #include <__chrono/weekday.h>
20*4bdff4beSrobert #include <__chrono/year.h>
21*4bdff4beSrobert #include <__chrono/year_month.h>
22*4bdff4beSrobert #include <__chrono/year_month_day.h>
23*4bdff4beSrobert #include <__chrono/year_month_weekday.h>
24*4bdff4beSrobert #include <__concepts/same_as.h>
25*4bdff4beSrobert #include <__config>
26*4bdff4beSrobert #include <__format/format_functions.h>
27*4bdff4beSrobert #include <ostream>
28*4bdff4beSrobert #include <ratio>
29*4bdff4beSrobert 
30*4bdff4beSrobert #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
31*4bdff4beSrobert #  pragma GCC system_header
32*4bdff4beSrobert #endif
33*4bdff4beSrobert 
34*4bdff4beSrobert _LIBCPP_BEGIN_NAMESPACE_STD
35*4bdff4beSrobert 
36*4bdff4beSrobert #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
37*4bdff4beSrobert 
38*4bdff4beSrobert namespace chrono {
39*4bdff4beSrobert 
40*4bdff4beSrobert // Depending on the type the return is a const _CharT* or a basic_string<_CharT>
41*4bdff4beSrobert template <class _CharT, class _Period>
__units_suffix()42*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI auto __units_suffix() {
43*4bdff4beSrobert   // TODO FMT LWG issue the suffixes are always char and not STATICALLY-WIDEN'ed.
44*4bdff4beSrobert   if constexpr (same_as<typename _Period::type, atto>)
45*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "as");
46*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, femto>)
47*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "fs");
48*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, pico>)
49*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "ps");
50*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, nano>)
51*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "ns");
52*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, micro>)
53*4bdff4beSrobert #  ifndef _LIBCPP_HAS_NO_UNICODE
54*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "\u00b5s");
55*4bdff4beSrobert #  else
56*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "us");
57*4bdff4beSrobert #  endif
58*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, milli>)
59*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "ms");
60*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, centi>)
61*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "cs");
62*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, deci>)
63*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "ds");
64*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, ratio<1>>)
65*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "s");
66*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, deca>)
67*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "das");
68*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, hecto>)
69*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "hs");
70*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, kilo>)
71*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "ks");
72*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, mega>)
73*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ms");
74*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, giga>)
75*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "Gs");
76*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, tera>)
77*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ts");
78*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, peta>)
79*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "Ps");
80*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, exa>)
81*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "Es");
82*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, ratio<60>>)
83*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "min");
84*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, ratio<3600>>)
85*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "h");
86*4bdff4beSrobert   else if constexpr (same_as<typename _Period::type, ratio<86400>>)
87*4bdff4beSrobert     return _LIBCPP_STATICALLY_WIDEN(_CharT, "d");
88*4bdff4beSrobert   else if constexpr (_Period::den == 1)
89*4bdff4beSrobert     return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}]s"), _Period::num);
90*4bdff4beSrobert   else
91*4bdff4beSrobert     return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "[{}/{}]s"), _Period::num, _Period::den);
92*4bdff4beSrobert }
93*4bdff4beSrobert 
94*4bdff4beSrobert template <class _CharT, class _Traits, class _Rep, class _Period>
95*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
96*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d) {
97*4bdff4beSrobert   basic_ostringstream<_CharT, _Traits> __s;
98*4bdff4beSrobert   __s.flags(__os.flags());
99*4bdff4beSrobert   __s.imbue(__os.getloc());
100*4bdff4beSrobert   __s.precision(__os.precision());
101*4bdff4beSrobert   __s << __d.count() << chrono::__units_suffix<_CharT, _Period>();
102*4bdff4beSrobert   return __os << __s.str();
103*4bdff4beSrobert }
104*4bdff4beSrobert 
105*4bdff4beSrobert template <class _CharT, class _Traits>
106*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
107*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) {
108*4bdff4beSrobert   return __os
109*4bdff4beSrobert       << (__d.ok()
110*4bdff4beSrobert               ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d)
111*4bdff4beSrobert               // Note this error differs from the wording of the Standard. The
112*4bdff4beSrobert               // Standard wording doesn't work well on AIX or Windows. There
113*4bdff4beSrobert               // the formatted day seems to be either modulo 100 or completely
114*4bdff4beSrobert               // omitted. Judging by the wording this is valid.
115*4bdff4beSrobert               // TODO FMT Write a paper of file an LWG issue.
116*4bdff4beSrobert               : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"), static_cast<unsigned>(__d)));
117*4bdff4beSrobert }
118*4bdff4beSrobert 
119*4bdff4beSrobert template <class _CharT, class _Traits>
120*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
121*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) {
122*4bdff4beSrobert   return __os << (__m.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%b}"), __m)
123*4bdff4beSrobert                            : std::format(__os.getloc(),
124*4bdff4beSrobert                                          _LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid month"),
125*4bdff4beSrobert                                          static_cast<unsigned>(__m))); // TODO FMT Standard mandated locale isn't used.
126*4bdff4beSrobert }
127*4bdff4beSrobert 
128*4bdff4beSrobert template <class _CharT, class _Traits>
129*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
130*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const year& __y) {
131*4bdff4beSrobert   return __os << (__y.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y}"), __y)
132*4bdff4beSrobert                            : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y} is not a valid year"), __y));
133*4bdff4beSrobert }
134*4bdff4beSrobert 
135*4bdff4beSrobert template <class _CharT, class _Traits>
136*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
137*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) {
138*4bdff4beSrobert   return __os << (__wd.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%a}"), __wd)
139*4bdff4beSrobert                             : std::format(__os.getloc(), // TODO FMT Standard mandated locale isn't used.
140*4bdff4beSrobert                                           _LIBCPP_STATICALLY_WIDEN(_CharT, "{} is not a valid weekday"),
141*4bdff4beSrobert                                           static_cast<unsigned>(__wd.c_encoding())));
142*4bdff4beSrobert }
143*4bdff4beSrobert 
144*4bdff4beSrobert template <class _CharT, class _Traits>
145*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
146*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) {
147*4bdff4beSrobert   auto __i = __wdi.index();
148*4bdff4beSrobert   return __os << (__i >= 1 && __i <= 5
149*4bdff4beSrobert                       ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{}]"), __wdi.weekday(), __i)
150*4bdff4beSrobert                       : std::format(__os.getloc(),
151*4bdff4beSrobert                                     _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[{} is not a valid index]"),
152*4bdff4beSrobert                                     __wdi.weekday(),
153*4bdff4beSrobert                                     __i));
154*4bdff4beSrobert }
155*4bdff4beSrobert 
156*4bdff4beSrobert template <class _CharT, class _Traits>
157*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
158*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_last& __wdl) {
159*4bdff4beSrobert   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[last]"), __wdl.weekday());
160*4bdff4beSrobert }
161*4bdff4beSrobert 
162*4bdff4beSrobert template <class _CharT, class _Traits>
163*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
164*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) {
165*4bdff4beSrobert   // TODO FMT The Standard allows 30th of February to be printed.
166*4bdff4beSrobert   // It would be nice to show an error message instead.
167*4bdff4beSrobert   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{}"), __md.month(), __md.day());
168*4bdff4beSrobert }
169*4bdff4beSrobert 
170*4bdff4beSrobert template <class _CharT, class _Traits>
171*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
172*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day_last& __mdl) {
173*4bdff4beSrobert   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/last"), __mdl.month());
174*4bdff4beSrobert }
175*4bdff4beSrobert 
176*4bdff4beSrobert template <class _CharT, class _Traits>
177*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
178*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday& __mwd) {
179*4bdff4beSrobert   return __os << std::format(
180*4bdff4beSrobert              __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwd.month(), __mwd.weekday_indexed());
181*4bdff4beSrobert }
182*4bdff4beSrobert 
183*4bdff4beSrobert template <class _CharT, class _Traits>
184*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
185*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday_last& __mwdl) {
186*4bdff4beSrobert   return __os << std::format(
187*4bdff4beSrobert              __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwdl.month(), __mwdl.weekday_last());
188*4bdff4beSrobert }
189*4bdff4beSrobert 
190*4bdff4beSrobert template <class _CharT, class _Traits>
191*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
192*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) {
193*4bdff4beSrobert   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ym.year(), __ym.month());
194*4bdff4beSrobert }
195*4bdff4beSrobert 
196*4bdff4beSrobert template <class _CharT, class _Traits>
197*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
198*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day& __ymd) {
199*4bdff4beSrobert   return __os << (__ymd.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F}"), __ymd)
200*4bdff4beSrobert                              : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), __ymd));
201*4bdff4beSrobert }
202*4bdff4beSrobert 
203*4bdff4beSrobert template <class _CharT, class _Traits>
204*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
205*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day_last& __ymdl) {
206*4bdff4beSrobert   return __os << std::format(
207*4bdff4beSrobert              __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ymdl.year(), __ymdl.month_day_last());
208*4bdff4beSrobert }
209*4bdff4beSrobert 
210*4bdff4beSrobert template <class _CharT, class _Traits>
211*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
212*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymwd) {
213*4bdff4beSrobert   return __os << std::format(
214*4bdff4beSrobert              __os.getloc(),
215*4bdff4beSrobert              _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),
216*4bdff4beSrobert              __ymwd.year(),
217*4bdff4beSrobert              __ymwd.month(),
218*4bdff4beSrobert              __ymwd.weekday_indexed());
219*4bdff4beSrobert }
220*4bdff4beSrobert 
221*4bdff4beSrobert template <class _CharT, class _Traits>
222*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>&
223*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& __ymwdl) {
224*4bdff4beSrobert   return __os << std::format(
225*4bdff4beSrobert              __os.getloc(),
226*4bdff4beSrobert              _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}/{:L}"),
227*4bdff4beSrobert              __ymwdl.year(),
228*4bdff4beSrobert              __ymwdl.month(),
229*4bdff4beSrobert              __ymwdl.weekday_last());
230*4bdff4beSrobert }
231*4bdff4beSrobert 
232*4bdff4beSrobert } // namespace chrono
233*4bdff4beSrobert 
234*4bdff4beSrobert #endif //if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
235*4bdff4beSrobert 
236*4bdff4beSrobert _LIBCPP_END_NAMESPACE_STD
237*4bdff4beSrobert 
238*4bdff4beSrobert #endif // _LIBCPP___CHRONO_OSTREAM_H
239