brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.9 KiB · 78698e9 Raw
763 lines · 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//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___LOCALE_DIR_TIME_H10#define _LIBCPP___LOCALE_DIR_TIME_H11 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_LOCALIZATION19 20#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)21#    pragma GCC system_header22#  endif23 24_LIBCPP_BEGIN_NAMESPACE_STD25 26template <class _CharT, class _InputIterator>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 >= 130  if (__b == __e) {31    __err |= ios_base::eofbit | ios_base::failbit;32    return 0;33  }34  // get first digit35  _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 digit43    __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 53class _LIBCPP_EXPORTED_FROM_ABI time_base {54public:55  enum dateorder { no_order, dmy, mdy, ymd, ydm };56};57 58template <class _CharT>59class __time_get_c_storage {60protected: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 71  _LIBCPP_HIDE_FROM_ABI ~__time_get_c_storage() {}72};73 74template <>75_LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__weeks() const;76template <>77_LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__months() const;78template <>79_LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__am_pm() const;80template <>81_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__c() const;82template <>83_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__r() const;84template <>85_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__x() const;86template <>87_LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__X() const;88 89#  if _LIBCPP_HAS_WIDE_CHARACTERS90template <>91_LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__weeks() const;92template <>93_LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__months() const;94template <>95_LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__am_pm() const;96template <>97_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__c() const;98template <>99_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__r() const;100template <>101_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__x() const;102template <>103_LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__X() const;104#  endif105 106template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >107class time_get : public locale::facet, public time_base, private __time_get_c_storage<_CharT> {108public: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 114  _LIBCPP_HIDE_FROM_ABI explicit time_get(size_t __refs = 0) : locale::facet(__refs) {}115 116  _LIBCPP_HIDE_FROM_ABI dateorder date_order() const { return this->do_date_order(); }117 118  _LIBCPP_HIDE_FROM_ABI iter_type119  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_type124  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_type129  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_type134  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_type139  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_type144  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_type150  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 160protected:161  _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get() override {}162 163  virtual dateorder do_date_order() const;164  virtual iter_type165  do_get_time(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;166  virtual iter_type167  do_get_date(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;168  virtual iter_type169  do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;170  virtual iter_type171  do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const;172  virtual iter_type173  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 177private: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  void187  __get_month(int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;188  void189  __get_year(int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;190  void191  __get_year4(int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;192  void193  __get_hour(int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;194  void195  __get_12_hour(int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;196  void197  __get_am_pm(int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;198  void199  __get_minute(int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;200  void201  __get_second(int& __s, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const;202  void203  __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 208template <class _CharT, class _InputIterator>209locale::id time_get<_CharT, _InputIterator>::id;210 211// time_get primitives212 213template <class _CharT, class _InputIterator>214void 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 spec217  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 223template <class _CharT, class _InputIterator>224void 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 spec227  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 233template <class _CharT, class _InputIterator>234void 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  else240    __err |= ios_base::failbit;241}242 243template <class _CharT, class _InputIterator>244void 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  else250    __err |= ios_base::failbit;251}252 253template <class _CharT, class _InputIterator>254void 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 266template <class _CharT, class _InputIterator>267void 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 274template <class _CharT, class _InputIterator>275void 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  else281    __err |= ios_base::failbit;282}283 284template <class _CharT, class _InputIterator>285void 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  else291    __err |= ios_base::failbit;292}293 294template <class _CharT, class _InputIterator>295void 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  else301    __err |= ios_base::failbit;302}303 304template <class _CharT, class _InputIterator>305void 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  else311    __err |= ios_base::failbit;312}313 314template <class _CharT, class _InputIterator>315void 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  else321    __err |= ios_base::failbit;322}323 324template <class _CharT, class _InputIterator>325void 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  else331    __err |= ios_base::failbit;332}333 334template <class _CharT, class _InputIterator>335void 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 343template <class _CharT, class _InputIterator>344void 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 358template <class _CharT, class _InputIterator>359void 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 primitives372 373template <class _CharT, class _InputIterator>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    } else415      __err = ios_base::failbit;416  }417  if (__b == __e)418    __err |= ios_base::eofbit;419  return __b;420}421 422template <class _CharT, class _InputIterator>423typename time_get<_CharT, _InputIterator>::dateorder time_get<_CharT, _InputIterator>::do_date_order() const {424  return mdy;425}426 427template <class _CharT, class _InputIterator>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 434template <class _CharT, class _InputIterator>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 441template <class _CharT, class _InputIterator>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 449template <class _CharT, class _InputIterator>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 457template <class _CharT, class _InputIterator>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 465template <class _CharT, class _InputIterator>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 557extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>;558#  if _LIBCPP_HAS_WIDE_CHARACTERS559extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>;560#  endif561 562class _LIBCPP_EXPORTED_FROM_ABI __time_get {563protected:564  __locale::__locale_t __loc_;565 566  __time_get(const char* __nm);567  __time_get(const string& __nm);568  ~__time_get();569};570 571template <class _CharT>572class __time_get_storage : public __time_get {573protected: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 587  _LIBCPP_HIDE_FROM_ABI ~__time_get_storage() {}588 589  time_base::dateorder __do_date_order() const;590 591private: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    void __time_get_storage<_CharT>::init(const ctype<_CharT>&);                                                       \605    template <>                                                                                                        \606    __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&);         \607    extern template _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order()       \608        const;                                                                                                         \609    extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*);             \610    extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&);611 612_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char)613#  if _LIBCPP_HAS_WIDE_CHARACTERS614_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t)615#  endif616#  undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION617 618template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >619class time_get_byname : public time_get<_CharT, _InputIterator>, private __time_get_storage<_CharT> {620public:621  typedef time_base::dateorder dateorder;622  typedef _InputIterator iter_type;623  typedef _CharT char_type;624  typedef basic_string<char_type> string_type;625 626  _LIBCPP_HIDE_FROM_ABI explicit time_get_byname(const char* __nm, size_t __refs = 0)627      : time_get<_CharT, _InputIterator>(__refs), __time_get_storage<_CharT>(__nm) {}628  _LIBCPP_HIDE_FROM_ABI explicit time_get_byname(const string& __nm, size_t __refs = 0)629      : time_get<_CharT, _InputIterator>(__refs), __time_get_storage<_CharT>(__nm) {}630 631protected:632  _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get_byname() override {}633 634  _LIBCPP_HIDE_FROM_ABI_VIRTUAL dateorder do_date_order() const override { return this->__do_date_order(); }635 636private:637  _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __weeks() const override { return this->__weeks_; }638  _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __months() const override { return this->__months_; }639  _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __am_pm() const override { return this->__am_pm_; }640  _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __c() const override { return this->__c_; }641  _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __r() const override { return this->__r_; }642  _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __x() const override { return this->__x_; }643  _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __X() const override { return this->__X_; }644};645 646extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>;647#  if _LIBCPP_HAS_WIDE_CHARACTERS648extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>;649#  endif650 651class _LIBCPP_EXPORTED_FROM_ABI __time_put {652  __locale::__locale_t __loc_;653 654protected:655  _LIBCPP_HIDE_FROM_ABI __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}656  __time_put(const char* __nm);657  __time_put(const string& __nm);658  ~__time_put();659  void __do_put(char* __nb, char*& __ne, const tm* __tm, char __fmt, char __mod) const;660#  if _LIBCPP_HAS_WIDE_CHARACTERS661  void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, char __fmt, char __mod) const;662#  endif663};664 665template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >666class time_put : public locale::facet, private __time_put {667public:668  typedef _CharT char_type;669  typedef _OutputIterator iter_type;670 671  _LIBCPP_HIDE_FROM_ABI explicit time_put(size_t __refs = 0) : locale::facet(__refs) {}672 673  iter_type674  put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, const char_type* __pb, const char_type* __pe)675      const;676 677  _LIBCPP_HIDE_FROM_ABI iter_type678  put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, char __fmt, char __mod = 0) const {679    return do_put(__s, __iob, __fl, __tm, __fmt, __mod);680  }681 682  static locale::id id;683 684protected:685  _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put() override {}686  virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const;687 688  _LIBCPP_HIDE_FROM_ABI explicit time_put(const char* __nm, size_t __refs) : locale::facet(__refs), __time_put(__nm) {}689  _LIBCPP_HIDE_FROM_ABI explicit time_put(const string& __nm, size_t __refs)690      : locale::facet(__refs), __time_put(__nm) {}691};692 693template <class _CharT, class _OutputIterator>694locale::id time_put<_CharT, _OutputIterator>::id;695 696template <class _CharT, class _OutputIterator>697_OutputIterator time_put<_CharT, _OutputIterator>::put(698    iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, const char_type* __pb, const char_type* __pe)699    const {700  const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc());701  for (; __pb != __pe; ++__pb) {702    if (__ct.narrow(*__pb, 0) == '%') {703      if (++__pb == __pe) {704        *__s++ = __pb[-1];705        break;706      }707      char __mod = 0;708      char __fmt = __ct.narrow(*__pb, 0);709      if (__fmt == 'E' || __fmt == 'O') {710        if (++__pb == __pe) {711          *__s++ = __pb[-2];712          *__s++ = __pb[-1];713          break;714        }715        __mod = __fmt;716        __fmt = __ct.narrow(*__pb, 0);717      }718      __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);719    } else720      *__s++ = *__pb;721  }722  return __s;723}724 725template <class _CharT, class _OutputIterator>726_OutputIterator time_put<_CharT, _OutputIterator>::do_put(727    iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const {728  char_type __nar[100];729  char_type* __nb = __nar;730  char_type* __ne = __nb + 100;731  __do_put(__nb, __ne, __tm, __fmt, __mod);732  return std::copy(__nb, __ne, __s);733}734 735extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>;736#  if _LIBCPP_HAS_WIDE_CHARACTERS737extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>;738#  endif739 740template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >741class time_put_byname : public time_put<_CharT, _OutputIterator> {742public:743  _LIBCPP_HIDE_FROM_ABI explicit time_put_byname(const char* __nm, size_t __refs = 0)744      : time_put<_CharT, _OutputIterator>(__nm, __refs) {}745 746  _LIBCPP_HIDE_FROM_ABI explicit time_put_byname(const string& __nm, size_t __refs = 0)747      : time_put<_CharT, _OutputIterator>(__nm, __refs) {}748 749protected:750  _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put_byname() override {}751};752 753extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>;754#  if _LIBCPP_HAS_WIDE_CHARACTERS755extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>;756#  endif757 758_LIBCPP_END_NAMESPACE_STD759 760#endif // _LIBCPP_HAS_LOCALIZATION761 762#endif // _LIBCPP___LOCALE_DIR_TIME_H763