xref: /freebsd/contrib/llvm-project/libcxx/include/__locale_dir/time.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef _LIBCPP___LOCALE_DIR_TIME_H
10 #define _LIBCPP___LOCALE_DIR_TIME_H
11 
12 #include <__algorithm/copy.h>
13 #include <__config>
14 #include <__locale_dir/get_c_locale.h>
15 #include <__locale_dir/scan_keyword.h>
16 #include <ios>
17 
18 #if _LIBCPP_HAS_LOCALIZATION
19 
20 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21 #    pragma GCC system_header
22 #  endif
23 
24 _LIBCPP_BEGIN_NAMESPACE_STD
25 
26 template <class _CharT, class _InputIterator>
__get_up_to_n_digits(_InputIterator & __b,_InputIterator __e,ios_base::iostate & __err,const ctype<_CharT> & __ct,int __n)27 _LIBCPP_HIDE_FROM_ABI int __get_up_to_n_digits(
28     _InputIterator& __b, _InputIterator __e, ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n) {
29   // Precondition:  __n >= 1
30   if (__b == __e) {
31     __err |= ios_base::eofbit | ios_base::failbit;
32     return 0;
33   }
34   // get first digit
35   _CharT __c = *__b;
36   if (!__ct.is(ctype_base::digit, __c)) {
37     __err |= ios_base::failbit;
38     return 0;
39   }
40   int __r = __ct.narrow(__c, 0) - '0';
41   for (++__b, (void)--__n; __b != __e && __n > 0; ++__b, (void)--__n) {
42     // get next digit
43     __c = *__b;
44     if (!__ct.is(ctype_base::digit, __c))
45       return __r;
46     __r = __r * 10 + __ct.narrow(__c, 0) - '0';
47   }
48   if (__b == __e)
49     __err |= ios_base::eofbit;
50   return __r;
51 }
52 
53 class _LIBCPP_EXPORTED_FROM_ABI time_base {
54 public:
55   enum dateorder { no_order, dmy, mdy, ymd, ydm };
56 };
57 
58 template <class _CharT>
59 class __time_get_c_storage {
60 protected:
61   typedef basic_string<_CharT> string_type;
62 
63   virtual const string_type* __weeks() const;
64   virtual const string_type* __months() const;
65   virtual const string_type* __am_pm() const;
66   virtual const string_type& __c() const;
67   virtual const string_type& __r() const;
68   virtual const string_type& __x() const;
69   virtual const string_type& __X() const;
70 
~__time_get_c_storage()71   _LIBCPP_HIDE_FROM_ABI ~__time_get_c_storage() {}
72 };
73 
74 template <>
75 _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__weeks() const;
76 template <>
77 _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__months() const;
78 template <>
79 _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__am_pm() const;
80 template <>
81 _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__c() const;
82 template <>
83 _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__r() const;
84 template <>
85 _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__x() const;
86 template <>
87 _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__X() const;
88 
89 #  if _LIBCPP_HAS_WIDE_CHARACTERS
90 template <>
91 _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__weeks() const;
92 template <>
93 _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__months() const;
94 template <>
95 _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__am_pm() const;
96 template <>
97 _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__c() const;
98 template <>
99 _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__r() const;
100 template <>
101 _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__x() const;
102 template <>
103 _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__X() const;
104 #  endif
105 
106 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
107 class time_get : public locale::facet, public time_base, private __time_get_c_storage<_CharT> {
108 public:
109   typedef _CharT char_type;
110   typedef _InputIterator iter_type;
111   typedef time_base::dateorder dateorder;
112   typedef basic_string<char_type> string_type;
113 
facet(__refs)114   _LIBCPP_HIDE_FROM_ABI explicit time_get(size_t __refs = 0) : locale::facet(__refs) {}
115 
date_order()116   _LIBCPP_HIDE_FROM_ABI dateorder date_order() const { return this->do_date_order(); }
117 
118   _LIBCPP_HIDE_FROM_ABI iter_type
get_time(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm)119   get_time(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
120     return do_get_time(__b, __e, __iob, __err, __tm);
121   }
122 
123   _LIBCPP_HIDE_FROM_ABI iter_type
get_date(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm)124   get_date(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
125     return do_get_date(__b, __e, __iob, __err, __tm);
126   }
127 
128   _LIBCPP_HIDE_FROM_ABI iter_type
get_weekday(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm)129   get_weekday(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
130     return do_get_weekday(__b, __e, __iob, __err, __tm);
131   }
132 
133   _LIBCPP_HIDE_FROM_ABI iter_type
get_monthname(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm)134   get_monthname(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
135     return do_get_monthname(__b, __e, __iob, __err, __tm);
136   }
137 
138   _LIBCPP_HIDE_FROM_ABI iter_type
get_year(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm)139   get_year(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
140     return do_get_year(__b, __e, __iob, __err, __tm);
141   }
142 
143   _LIBCPP_HIDE_FROM_ABI iter_type
144   get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char __mod = 0)
145       const {
146     return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
147   }
148 
149   iter_type
150   get(iter_type __b,
151       iter_type __e,
152       ios_base& __iob,
153       ios_base::iostate& __err,
154       tm* __tm,
155       const char_type* __fmtb,
156       const char_type* __fmte) const;
157 
158   static locale::id id;
159 
160 protected:
~time_get()161   _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get() override {}
162 
163   virtual dateorder do_date_order() const;
164   virtual iter_type
165   do_get_time(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;
166   virtual iter_type
167   do_get_date(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;
168   virtual iter_type
169   do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;
170   virtual iter_type
171   do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;
172   virtual iter_type
173   do_get_year(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;
174   virtual iter_type do_get(
175       iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char __mod) const;
176 
177 private:
178   void __get_white_space(iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
179   void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
180 
181   void __get_weekdayname(
182       int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
183   void __get_monthname(
184       int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
185   void __get_day(int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
186   void
187   __get_month(int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
188   void
189   __get_year(int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
190   void
191   __get_year4(int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
192   void
193   __get_hour(int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
194   void
195   __get_12_hour(int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
196   void
197   __get_am_pm(int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
198   void
199   __get_minute(int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
200   void
201   __get_second(int& __s, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
202   void
203   __get_weekday(int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
204   void __get_day_year_num(
205       int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;
206 };
207 
208 template <class _CharT, class _InputIterator>
209 locale::id time_get<_CharT, _InputIterator>::id;
210 
211 // time_get primitives
212 
213 template <class _CharT, class _InputIterator>
__get_weekdayname(int & __w,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)214 void time_get<_CharT, _InputIterator>::__get_weekdayname(
215     int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
216   // Note:  ignoring case comes from the POSIX strptime spec
217   const string_type* __wk = this->__weeks();
218   ptrdiff_t __i           = std::__scan_keyword(__b, __e, __wk, __wk + 14, __ct, __err, false) - __wk;
219   if (__i < 14)
220     __w = __i % 7;
221 }
222 
223 template <class _CharT, class _InputIterator>
__get_monthname(int & __m,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)224 void time_get<_CharT, _InputIterator>::__get_monthname(
225     int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
226   // Note:  ignoring case comes from the POSIX strptime spec
227   const string_type* __month = this->__months();
228   ptrdiff_t __i              = std::__scan_keyword(__b, __e, __month, __month + 24, __ct, __err, false) - __month;
229   if (__i < 24)
230     __m = __i % 12;
231 }
232 
233 template <class _CharT, class _InputIterator>
__get_day(int & __d,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)234 void time_get<_CharT, _InputIterator>::__get_day(
235     int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
236   int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
237   if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
238     __d = __t;
239   else
240     __err |= ios_base::failbit;
241 }
242 
243 template <class _CharT, class _InputIterator>
__get_month(int & __m,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)244 void time_get<_CharT, _InputIterator>::__get_month(
245     int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
246   int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
247   if (!(__err & ios_base::failbit) && 0 <= __t && __t <= 11)
248     __m = __t;
249   else
250     __err |= ios_base::failbit;
251 }
252 
253 template <class _CharT, class _InputIterator>
__get_year(int & __y,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)254 void time_get<_CharT, _InputIterator>::__get_year(
255     int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
256   int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 4);
257   if (!(__err & ios_base::failbit)) {
258     if (__t < 69)
259       __t += 2000;
260     else if (69 <= __t && __t <= 99)
261       __t += 1900;
262     __y = __t - 1900;
263   }
264 }
265 
266 template <class _CharT, class _InputIterator>
__get_year4(int & __y,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)267 void time_get<_CharT, _InputIterator>::__get_year4(
268     int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
269   int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 4);
270   if (!(__err & ios_base::failbit))
271     __y = __t - 1900;
272 }
273 
274 template <class _CharT, class _InputIterator>
__get_hour(int & __h,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)275 void time_get<_CharT, _InputIterator>::__get_hour(
276     int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
277   int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
278   if (!(__err & ios_base::failbit) && __t <= 23)
279     __h = __t;
280   else
281     __err |= ios_base::failbit;
282 }
283 
284 template <class _CharT, class _InputIterator>
__get_12_hour(int & __h,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)285 void time_get<_CharT, _InputIterator>::__get_12_hour(
286     int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
287   int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
288   if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
289     __h = __t;
290   else
291     __err |= ios_base::failbit;
292 }
293 
294 template <class _CharT, class _InputIterator>
__get_minute(int & __m,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)295 void time_get<_CharT, _InputIterator>::__get_minute(
296     int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
297   int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
298   if (!(__err & ios_base::failbit) && __t <= 59)
299     __m = __t;
300   else
301     __err |= ios_base::failbit;
302 }
303 
304 template <class _CharT, class _InputIterator>
__get_second(int & __s,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)305 void time_get<_CharT, _InputIterator>::__get_second(
306     int& __s, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
307   int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2);
308   if (!(__err & ios_base::failbit) && __t <= 60)
309     __s = __t;
310   else
311     __err |= ios_base::failbit;
312 }
313 
314 template <class _CharT, class _InputIterator>
__get_weekday(int & __w,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)315 void time_get<_CharT, _InputIterator>::__get_weekday(
316     int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
317   int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 1);
318   if (!(__err & ios_base::failbit) && __t <= 6)
319     __w = __t;
320   else
321     __err |= ios_base::failbit;
322 }
323 
324 template <class _CharT, class _InputIterator>
__get_day_year_num(int & __d,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)325 void time_get<_CharT, _InputIterator>::__get_day_year_num(
326     int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
327   int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 3);
328   if (!(__err & ios_base::failbit) && __t <= 365)
329     __d = __t;
330   else
331     __err |= ios_base::failbit;
332 }
333 
334 template <class _CharT, class _InputIterator>
__get_white_space(iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)335 void time_get<_CharT, _InputIterator>::__get_white_space(
336     iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
337   for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
338     ;
339   if (__b == __e)
340     __err |= ios_base::eofbit;
341 }
342 
343 template <class _CharT, class _InputIterator>
__get_am_pm(int & __h,iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)344 void time_get<_CharT, _InputIterator>::__get_am_pm(
345     int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
346   const string_type* __ap = this->__am_pm();
347   if (__ap[0].size() + __ap[1].size() == 0) {
348     __err |= ios_base::failbit;
349     return;
350   }
351   ptrdiff_t __i = std::__scan_keyword(__b, __e, __ap, __ap + 2, __ct, __err, false) - __ap;
352   if (__i == 0 && __h == 12)
353     __h = 0;
354   else if (__i == 1 && __h < 12)
355     __h += 12;
356 }
357 
358 template <class _CharT, class _InputIterator>
__get_percent(iter_type & __b,iter_type __e,ios_base::iostate & __err,const ctype<char_type> & __ct)359 void time_get<_CharT, _InputIterator>::__get_percent(
360     iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const {
361   if (__b == __e) {
362     __err |= ios_base::eofbit | ios_base::failbit;
363     return;
364   }
365   if (__ct.narrow(*__b, 0) != '%')
366     __err |= ios_base::failbit;
367   else if (++__b == __e)
368     __err |= ios_base::eofbit;
369 }
370 
371 // time_get end primitives
372 
373 template <class _CharT, class _InputIterator>
get(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm,const char_type * __fmtb,const char_type * __fmte)374 _InputIterator time_get<_CharT, _InputIterator>::get(
375     iter_type __b,
376     iter_type __e,
377     ios_base& __iob,
378     ios_base::iostate& __err,
379     tm* __tm,
380     const char_type* __fmtb,
381     const char_type* __fmte) const {
382   const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
383   __err                        = ios_base::goodbit;
384   while (__fmtb != __fmte && __err == ios_base::goodbit) {
385     if (__b == __e) {
386       __err = ios_base::failbit;
387       break;
388     }
389     if (__ct.narrow(*__fmtb, 0) == '%') {
390       if (++__fmtb == __fmte) {
391         __err = ios_base::failbit;
392         break;
393       }
394       char __cmd = __ct.narrow(*__fmtb, 0);
395       char __opt = '\0';
396       if (__cmd == 'E' || __cmd == '0') {
397         if (++__fmtb == __fmte) {
398           __err = ios_base::failbit;
399           break;
400         }
401         __opt = __cmd;
402         __cmd = __ct.narrow(*__fmtb, 0);
403       }
404       __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
405       ++__fmtb;
406     } else if (__ct.is(ctype_base::space, *__fmtb)) {
407       for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
408         ;
409       for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
410         ;
411     } else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb)) {
412       ++__b;
413       ++__fmtb;
414     } else
415       __err = ios_base::failbit;
416   }
417   if (__b == __e)
418     __err |= ios_base::eofbit;
419   return __b;
420 }
421 
422 template <class _CharT, class _InputIterator>
do_date_order()423 typename time_get<_CharT, _InputIterator>::dateorder time_get<_CharT, _InputIterator>::do_date_order() const {
424   return mdy;
425 }
426 
427 template <class _CharT, class _InputIterator>
do_get_time(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm)428 _InputIterator time_get<_CharT, _InputIterator>::do_get_time(
429     iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
430   const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
431   return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt) / sizeof(__fmt[0]));
432 }
433 
434 template <class _CharT, class _InputIterator>
do_get_date(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm)435 _InputIterator time_get<_CharT, _InputIterator>::do_get_date(
436     iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
437   const string_type& __fmt = this->__x();
438   return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
439 }
440 
441 template <class _CharT, class _InputIterator>
do_get_weekday(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm)442 _InputIterator time_get<_CharT, _InputIterator>::do_get_weekday(
443     iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
444   const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
445   __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
446   return __b;
447 }
448 
449 template <class _CharT, class _InputIterator>
do_get_monthname(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm)450 _InputIterator time_get<_CharT, _InputIterator>::do_get_monthname(
451     iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
452   const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
453   __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
454   return __b;
455 }
456 
457 template <class _CharT, class _InputIterator>
do_get_year(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm)458 _InputIterator time_get<_CharT, _InputIterator>::do_get_year(
459     iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const {
460   const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
461   __get_year(__tm->tm_year, __b, __e, __err, __ct);
462   return __b;
463 }
464 
465 template <class _CharT, class _InputIterator>
do_get(iter_type __b,iter_type __e,ios_base & __iob,ios_base::iostate & __err,tm * __tm,char __fmt,char)466 _InputIterator time_get<_CharT, _InputIterator>::do_get(
467     iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char) const {
468   __err                        = ios_base::goodbit;
469   const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
470   switch (__fmt) {
471   case 'a':
472   case 'A':
473     __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
474     break;
475   case 'b':
476   case 'B':
477   case 'h':
478     __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
479     break;
480   case 'c': {
481     const string_type& __fm = this->__c();
482     __b                     = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
483   } break;
484   case 'd':
485   case 'e':
486     __get_day(__tm->tm_mday, __b, __e, __err, __ct);
487     break;
488   case 'D': {
489     const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
490     __b                    = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0]));
491   } break;
492   case 'F': {
493     const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
494     __b                    = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0]));
495   } break;
496   case 'H':
497     __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
498     break;
499   case 'I':
500     __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
501     break;
502   case 'j':
503     __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
504     break;
505   case 'm':
506     __get_month(__tm->tm_mon, __b, __e, __err, __ct);
507     break;
508   case 'M':
509     __get_minute(__tm->tm_min, __b, __e, __err, __ct);
510     break;
511   case 'n':
512   case 't':
513     __get_white_space(__b, __e, __err, __ct);
514     break;
515   case 'p':
516     __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
517     break;
518   case 'r': {
519     const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
520     __b                    = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0]));
521   } break;
522   case 'R': {
523     const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
524     __b                    = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0]));
525   } break;
526   case 'S':
527     __get_second(__tm->tm_sec, __b, __e, __err, __ct);
528     break;
529   case 'T': {
530     const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
531     __b                    = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0]));
532   } break;
533   case 'w':
534     __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
535     break;
536   case 'x':
537     return do_get_date(__b, __e, __iob, __err, __tm);
538   case 'X': {
539     const string_type& __fm = this->__X();
540     __b                     = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
541   } break;
542   case 'y':
543     __get_year(__tm->tm_year, __b, __e, __err, __ct);
544     break;
545   case 'Y':
546     __get_year4(__tm->tm_year, __b, __e, __err, __ct);
547     break;
548   case '%':
549     __get_percent(__b, __e, __err, __ct);
550     break;
551   default:
552     __err |= ios_base::failbit;
553   }
554   return __b;
555 }
556 
557 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>;
558 #  if _LIBCPP_HAS_WIDE_CHARACTERS
559 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>;
560 #  endif
561 
562 class _LIBCPP_EXPORTED_FROM_ABI __time_get {
563 protected:
564   __locale::__locale_t __loc_;
565 
566   __time_get(const char* __nm);
567   __time_get(const string& __nm);
568   ~__time_get();
569 };
570 
571 template <class _CharT>
572 class __time_get_storage : public __time_get {
573 protected:
574   typedef basic_string<_CharT> string_type;
575 
576   string_type __weeks_[14];
577   string_type __months_[24];
578   string_type __am_pm_[2];
579   string_type __c_;
580   string_type __r_;
581   string_type __x_;
582   string_type __X_;
583 
584   explicit __time_get_storage(const char* __nm);
585   explicit __time_get_storage(const string& __nm);
586 
~__time_get_storage()587   _LIBCPP_HIDE_FROM_ABI ~__time_get_storage() {}
588 
589   time_base::dateorder __do_date_order() const;
590 
591 private:
592   void init(const ctype<_CharT>&);
593   string_type __analyze(char __fmt, const ctype<_CharT>&);
594 };
595 
596 #  define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT)                                                      \
597     template <>                                                                                                        \
598     _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const;                \
599     template <>                                                                                                        \
600     _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*);                             \
601     template <>                                                                                                        \
602     _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&);                           \
603     template <>                                                                                                        \
604     _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&);                             \
605     template <>                                                                                                        \
606     _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(           \
607         char, const ctype<_CharT>&);                                                                                   \
608     extern template _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order()       \
609         const;                                                                                                         \
610     extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*);             \
611     extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&);           \
612     extern template _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&);             \
613     extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type                                  \
614     __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&);
615 
616 _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)
617 #  if _LIBCPP_HAS_WIDE_CHARACTERS
_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t)618 _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t)
619 #  endif
620 #  undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION
621 
622 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
623 class time_get_byname : public time_get<_CharT, _InputIterator>, private __time_get_storage<_CharT> {
624 public:
625   typedef time_base::dateorder dateorder;
626   typedef _InputIterator iter_type;
627   typedef _CharT char_type;
628   typedef basic_string<char_type> string_type;
629 
630   _LIBCPP_HIDE_FROM_ABI explicit time_get_byname(const char* __nm, size_t __refs = 0)
631       : time_get<_CharT, _InputIterator>(__refs), __time_get_storage<_CharT>(__nm) {}
632   _LIBCPP_HIDE_FROM_ABI explicit time_get_byname(const string& __nm, size_t __refs = 0)
633       : time_get<_CharT, _InputIterator>(__refs), __time_get_storage<_CharT>(__nm) {}
634 
635 protected:
636   _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get_byname() override {}
637 
638   _LIBCPP_HIDE_FROM_ABI_VIRTUAL dateorder do_date_order() const override { return this->__do_date_order(); }
639 
640 private:
641   _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __weeks() const override { return this->__weeks_; }
642   _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __months() const override { return this->__months_; }
643   _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __am_pm() const override { return this->__am_pm_; }
644   _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __c() const override { return this->__c_; }
645   _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __r() const override { return this->__r_; }
646   _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __x() const override { return this->__x_; }
647   _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __X() const override { return this->__X_; }
648 };
649 
650 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>;
651 #  if _LIBCPP_HAS_WIDE_CHARACTERS
652 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>;
653 #  endif
654 
655 class _LIBCPP_EXPORTED_FROM_ABI __time_put {
656   __locale::__locale_t __loc_;
657 
658 protected:
__time_put()659   _LIBCPP_HIDE_FROM_ABI __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
660   __time_put(const char* __nm);
661   __time_put(const string& __nm);
662   ~__time_put();
663   void __do_put(char* __nb, char*& __ne, const tm* __tm, char __fmt, char __mod) const;
664 #  if _LIBCPP_HAS_WIDE_CHARACTERS
665   void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, char __fmt, char __mod) const;
666 #  endif
667 };
668 
669 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
670 class time_put : public locale::facet, private __time_put {
671 public:
672   typedef _CharT char_type;
673   typedef _OutputIterator iter_type;
674 
facet(__refs)675   _LIBCPP_HIDE_FROM_ABI explicit time_put(size_t __refs = 0) : locale::facet(__refs) {}
676 
677   iter_type
678   put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, const char_type* __pb, const char_type* __pe)
679       const;
680 
681   _LIBCPP_HIDE_FROM_ABI iter_type
682   put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, char __fmt, char __mod = 0) const {
683     return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
684   }
685 
686   static locale::id id;
687 
688 protected:
~time_put()689   _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put() override {}
690   virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const;
691 
time_put(const char * __nm,size_t __refs)692   _LIBCPP_HIDE_FROM_ABI explicit time_put(const char* __nm, size_t __refs) : locale::facet(__refs), __time_put(__nm) {}
time_put(const string & __nm,size_t __refs)693   _LIBCPP_HIDE_FROM_ABI explicit time_put(const string& __nm, size_t __refs)
694       : locale::facet(__refs), __time_put(__nm) {}
695 };
696 
697 template <class _CharT, class _OutputIterator>
698 locale::id time_put<_CharT, _OutputIterator>::id;
699 
700 template <class _CharT, class _OutputIterator>
put(iter_type __s,ios_base & __iob,char_type __fl,const tm * __tm,const char_type * __pb,const char_type * __pe)701 _OutputIterator time_put<_CharT, _OutputIterator>::put(
702     iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, const char_type* __pb, const char_type* __pe)
703     const {
704   const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());
705   for (; __pb != __pe; ++__pb) {
706     if (__ct.narrow(*__pb, 0) == '%') {
707       if (++__pb == __pe) {
708         *__s++ = __pb[-1];
709         break;
710       }
711       char __mod = 0;
712       char __fmt = __ct.narrow(*__pb, 0);
713       if (__fmt == 'E' || __fmt == 'O') {
714         if (++__pb == __pe) {
715           *__s++ = __pb[-2];
716           *__s++ = __pb[-1];
717           break;
718         }
719         __mod = __fmt;
720         __fmt = __ct.narrow(*__pb, 0);
721       }
722       __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
723     } else
724       *__s++ = *__pb;
725   }
726   return __s;
727 }
728 
729 template <class _CharT, class _OutputIterator>
do_put(iter_type __s,ios_base &,char_type,const tm * __tm,char __fmt,char __mod)730 _OutputIterator time_put<_CharT, _OutputIterator>::do_put(
731     iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const {
732   char_type __nar[100];
733   char_type* __nb = __nar;
734   char_type* __ne = __nb + 100;
735   __do_put(__nb, __ne, __tm, __fmt, __mod);
736   return std::copy(__nb, __ne, __s);
737 }
738 
739 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>;
740 #  if _LIBCPP_HAS_WIDE_CHARACTERS
741 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>;
742 #  endif
743 
744 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
745 class time_put_byname : public time_put<_CharT, _OutputIterator> {
746 public:
747   _LIBCPP_HIDE_FROM_ABI explicit time_put_byname(const char* __nm, size_t __refs = 0)
748       : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
749 
750   _LIBCPP_HIDE_FROM_ABI explicit time_put_byname(const string& __nm, size_t __refs = 0)
751       : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
752 
753 protected:
~time_put_byname()754   _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put_byname() override {}
755 };
756 
757 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>;
758 #  if _LIBCPP_HAS_WIDE_CHARACTERS
759 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>;
760 #  endif
761 
762 _LIBCPP_END_NAMESPACE_STD
763 
764 #endif // _LIBCPP_HAS_LOCALIZATION
765 
766 #endif // _LIBCPP___LOCALE_DIR_TIME_H
767