| //===----------------------------------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef _LIBCPP___LOCALE_DIR_TIME_H |
| #define _LIBCPP___LOCALE_DIR_TIME_H |
| |
| #include <__algorithm/copy.h> |
| #include <__config> |
| #include <__locale_dir/get_c_locale.h> |
| #include <__locale_dir/scan_keyword.h> |
| #include <ios> |
| |
| #if _LIBCPP_HAS_LOCALIZATION |
| |
| # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| # pragma GCC system_header |
| # endif |
| |
| _LIBCPP_BEGIN_NAMESPACE_STD |
| |
| template <class _CharT, class _InputIterator> |
| _LIBCPP_HIDE_FROM_ABI int __get_up_to_n_digits( |
| _InputIterator& __b, _InputIterator __e, ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n) { |
| // Precondition: __n >= 1 |
| if (__b == __e) { |
| __err |= ios_base::eofbit | ios_base::failbit; |
| return 0; |
| } |
| // get first digit |
| _CharT __c = *__b; |
| if (!__ct.is(ctype_base::digit, __c)) { |
| __err |= ios_base::failbit; |
| return 0; |
| } |
| int __r = __ct.narrow(__c, 0) - '0'; |
| for (++__b, (void)--__n; __b != __e && __n > 0; ++__b, (void)--__n) { |
| // get next digit |
| __c = *__b; |
| if (!__ct.is(ctype_base::digit, __c)) |
| return __r; |
| __r = __r * 10 + __ct.narrow(__c, 0) - '0'; |
| } |
| if (__b == __e) |
| __err |= ios_base::eofbit; |
| return __r; |
| } |
| |
| class _LIBCPP_EXPORTED_FROM_ABI time_base { |
| public: |
| enum dateorder { no_order, dmy, mdy, ymd, ydm }; |
| }; |
| |
| template <class _CharT> |
| class __time_get_c_storage { |
| protected: |
| typedef basic_string<_CharT> string_type; |
| |
| virtual const string_type* __weeks() const; |
| virtual const string_type* __months() const; |
| virtual const string_type* __am_pm() const; |
| virtual const string_type& __c() const; |
| virtual const string_type& __r() const; |
| virtual const string_type& __x() const; |
| virtual const string_type& __X() const; |
| |
| _LIBCPP_HIDE_FROM_ABI ~__time_get_c_storage() {} |
| }; |
| |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__weeks() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__months() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__am_pm() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__c() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__r() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__x() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__X() const; |
| |
| # if _LIBCPP_HAS_WIDE_CHARACTERS |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__weeks() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__months() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__am_pm() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__c() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__r() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__x() const; |
| template <> |
| _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__X() const; |
| # endif |
| |
| template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > |
| class time_get : public locale::facet, public time_base, private __time_get_c_storage<_CharT> { |
| public: |
| typedef _CharT char_type; |
| typedef _InputIterator iter_type; |
| typedef time_base::dateorder dateorder; |
| typedef basic_string<char_type> string_type; |
| |
| _LIBCPP_HIDE_FROM_ABI explicit time_get(size_t __refs = 0) : locale::facet(__refs) {} |
| |
| _LIBCPP_HIDE_FROM_ABI dateorder date_order() const { return this->do_date_order(); } |
| |
| _LIBCPP_HIDE_FROM_ABI iter_type |
| get_time(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { |
| return do_get_time(__b, __e, __iob, __err, __tm); |
| } |
| |
| _LIBCPP_HIDE_FROM_ABI iter_type |
| get_date(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { |
| return do_get_date(__b, __e, __iob, __err, __tm); |
| } |
| |
| _LIBCPP_HIDE_FROM_ABI iter_type |
| get_weekday(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { |
| return do_get_weekday(__b, __e, __iob, __err, __tm); |
| } |
| |
| _LIBCPP_HIDE_FROM_ABI iter_type |
| get_monthname(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { |
| return do_get_monthname(__b, __e, __iob, __err, __tm); |
| } |
| |
| _LIBCPP_HIDE_FROM_ABI iter_type |
| get_year(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { |
| return do_get_year(__b, __e, __iob, __err, __tm); |
| } |
| |
| _LIBCPP_HIDE_FROM_ABI iter_type |
| get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char __mod = 0) |
| const { |
| return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod); |
| } |
| |
| iter_type |
| get(iter_type __b, |
| iter_type __e, |
| ios_base& __iob, |
| ios_base::iostate& __err, |
| tm* __tm, |
| const char_type* __fmtb, |
| const char_type* __fmte) const; |
| |
| static locale::id id; |
| |
| protected: |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get() override {} |
| |
| virtual dateorder do_date_order() const; |
| virtual iter_type |
| do_get_time(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const; |
| virtual iter_type |
| do_get_date(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const; |
| virtual iter_type |
| do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const; |
| virtual iter_type |
| do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const; |
| virtual iter_type |
| do_get_year(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const; |
| virtual iter_type do_get( |
| iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char __mod) const; |
| |
| private: |
| void __get_white_space(iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| |
| void __get_weekdayname( |
| int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void __get_monthname( |
| int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void __get_day(int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void |
| __get_month(int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void |
| __get_year(int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void |
| __get_year4(int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void |
| __get_hour(int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void |
| __get_12_hour(int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void |
| __get_am_pm(int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void |
| __get_minute(int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void |
| __get_second(int& __s, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void |
| __get_weekday(int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| void __get_day_year_num( |
| int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const; |
| }; |
| |
| template <class _CharT, class _InputIterator> |
| locale::id time_get<_CharT, _InputIterator>::id; |
| |
| // time_get primitives |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_weekdayname( |
| int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| // Note: ignoring case comes from the POSIX strptime spec |
| const string_type* __wk = this->__weeks(); |
| ptrdiff_t __i = std::__scan_keyword(__b, __e, __wk, __wk + 14, __ct, __err, false) - __wk; |
| if (__i < 14) |
| __w = __i % 7; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_monthname( |
| int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| // Note: ignoring case comes from the POSIX strptime spec |
| const string_type* __month = this->__months(); |
| ptrdiff_t __i = std::__scan_keyword(__b, __e, __month, __month + 24, __ct, __err, false) - __month; |
| if (__i < 24) |
| __m = __i % 12; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_day( |
| int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2); |
| if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31) |
| __d = __t; |
| else |
| __err |= ios_base::failbit; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_month( |
| int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1; |
| if (!(__err & ios_base::failbit) && 0 <= __t && __t <= 11) |
| __m = __t; |
| else |
| __err |= ios_base::failbit; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_year( |
| int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 4); |
| if (!(__err & ios_base::failbit)) { |
| if (__t < 69) |
| __t += 2000; |
| else if (69 <= __t && __t <= 99) |
| __t += 1900; |
| __y = __t - 1900; |
| } |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_year4( |
| int& __y, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 4); |
| if (!(__err & ios_base::failbit)) |
| __y = __t - 1900; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_hour( |
| int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2); |
| if (!(__err & ios_base::failbit) && __t <= 23) |
| __h = __t; |
| else |
| __err |= ios_base::failbit; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_12_hour( |
| int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2); |
| if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12) |
| __h = __t; |
| else |
| __err |= ios_base::failbit; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_minute( |
| int& __m, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2); |
| if (!(__err & ios_base::failbit) && __t <= 59) |
| __m = __t; |
| else |
| __err |= ios_base::failbit; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_second( |
| int& __s, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 2); |
| if (!(__err & ios_base::failbit) && __t <= 60) |
| __s = __t; |
| else |
| __err |= ios_base::failbit; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_weekday( |
| int& __w, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 1); |
| if (!(__err & ios_base::failbit) && __t <= 6) |
| __w = __t; |
| else |
| __err |= ios_base::failbit; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_day_year_num( |
| int& __d, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| int __t = std::__get_up_to_n_digits(__b, __e, __err, __ct, 3); |
| if (!(__err & ios_base::failbit) && __t <= 365) |
| __d = __t; |
| else |
| __err |= ios_base::failbit; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_white_space( |
| iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) |
| ; |
| if (__b == __e) |
| __err |= ios_base::eofbit; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_am_pm( |
| int& __h, iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| const string_type* __ap = this->__am_pm(); |
| if (__ap[0].size() + __ap[1].size() == 0) { |
| __err |= ios_base::failbit; |
| return; |
| } |
| ptrdiff_t __i = std::__scan_keyword(__b, __e, __ap, __ap + 2, __ct, __err, false) - __ap; |
| if (__i == 0 && __h == 12) |
| __h = 0; |
| else if (__i == 1 && __h < 12) |
| __h += 12; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| void time_get<_CharT, _InputIterator>::__get_percent( |
| iter_type& __b, iter_type __e, ios_base::iostate& __err, const ctype<char_type>& __ct) const { |
| if (__b == __e) { |
| __err |= ios_base::eofbit | ios_base::failbit; |
| return; |
| } |
| if (__ct.narrow(*__b, 0) != '%') |
| __err |= ios_base::failbit; |
| else if (++__b == __e) |
| __err |= ios_base::eofbit; |
| } |
| |
| // time_get end primitives |
| |
| template <class _CharT, class _InputIterator> |
| _InputIterator time_get<_CharT, _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) const { |
| const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); |
| __err = ios_base::goodbit; |
| while (__fmtb != __fmte && __err == ios_base::goodbit) { |
| if (__b == __e) { |
| __err = ios_base::failbit; |
| break; |
| } |
| if (__ct.narrow(*__fmtb, 0) == '%') { |
| if (++__fmtb == __fmte) { |
| __err = ios_base::failbit; |
| break; |
| } |
| char __cmd = __ct.narrow(*__fmtb, 0); |
| char __opt = '\0'; |
| if (__cmd == 'E' || __cmd == '0') { |
| if (++__fmtb == __fmte) { |
| __err = ios_base::failbit; |
| break; |
| } |
| __opt = __cmd; |
| __cmd = __ct.narrow(*__fmtb, 0); |
| } |
| __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt); |
| ++__fmtb; |
| } else if (__ct.is(ctype_base::space, *__fmtb)) { |
| for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb) |
| ; |
| for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) |
| ; |
| } else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb)) { |
| ++__b; |
| ++__fmtb; |
| } else |
| __err = ios_base::failbit; |
| } |
| if (__b == __e) |
| __err |= ios_base::eofbit; |
| return __b; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| typename time_get<_CharT, _InputIterator>::dateorder time_get<_CharT, _InputIterator>::do_date_order() const { |
| return mdy; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| _InputIterator time_get<_CharT, _InputIterator>::do_get_time( |
| iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { |
| const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; |
| return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt) / sizeof(__fmt[0])); |
| } |
| |
| template <class _CharT, class _InputIterator> |
| _InputIterator time_get<_CharT, _InputIterator>::do_get_date( |
| iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { |
| const string_type& __fmt = this->__x(); |
| return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size()); |
| } |
| |
| template <class _CharT, class _InputIterator> |
| _InputIterator time_get<_CharT, _InputIterator>::do_get_weekday( |
| iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { |
| const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); |
| __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); |
| return __b; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| _InputIterator time_get<_CharT, _InputIterator>::do_get_monthname( |
| iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { |
| const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); |
| __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); |
| return __b; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| _InputIterator time_get<_CharT, _InputIterator>::do_get_year( |
| iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm) const { |
| const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); |
| __get_year(__tm->tm_year, __b, __e, __err, __ct); |
| return __b; |
| } |
| |
| template <class _CharT, class _InputIterator> |
| _InputIterator time_get<_CharT, _InputIterator>::do_get( |
| iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, tm* __tm, char __fmt, char) const { |
| __err = ios_base::goodbit; |
| const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); |
| switch (__fmt) { |
| case 'a': |
| case 'A': |
| __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); |
| break; |
| case 'b': |
| case 'B': |
| case 'h': |
| __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); |
| break; |
| case 'c': { |
| const string_type& __fm = this->__c(); |
| __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); |
| } break; |
| case 'd': |
| case 'e': |
| __get_day(__tm->tm_mday, __b, __e, __err, __ct); |
| break; |
| case 'D': { |
| const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; |
| __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0])); |
| } break; |
| case 'F': { |
| const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; |
| __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0])); |
| } break; |
| case 'H': |
| __get_hour(__tm->tm_hour, __b, __e, __err, __ct); |
| break; |
| case 'I': |
| __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct); |
| break; |
| case 'j': |
| __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct); |
| break; |
| case 'm': |
| __get_month(__tm->tm_mon, __b, __e, __err, __ct); |
| break; |
| case 'M': |
| __get_minute(__tm->tm_min, __b, __e, __err, __ct); |
| break; |
| case 'n': |
| case 't': |
| __get_white_space(__b, __e, __err, __ct); |
| break; |
| case 'p': |
| __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct); |
| break; |
| case 'r': { |
| const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; |
| __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0])); |
| } break; |
| case 'R': { |
| const char_type __fm[] = {'%', 'H', ':', '%', 'M'}; |
| __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0])); |
| } break; |
| case 'S': |
| __get_second(__tm->tm_sec, __b, __e, __err, __ct); |
| break; |
| case 'T': { |
| const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; |
| __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm) / sizeof(__fm[0])); |
| } break; |
| case 'w': |
| __get_weekday(__tm->tm_wday, __b, __e, __err, __ct); |
| break; |
| case 'x': |
| return do_get_date(__b, __e, __iob, __err, __tm); |
| case 'X': { |
| const string_type& __fm = this->__X(); |
| __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); |
| } break; |
| case 'y': |
| __get_year(__tm->tm_year, __b, __e, __err, __ct); |
| break; |
| case 'Y': |
| __get_year4(__tm->tm_year, __b, __e, __err, __ct); |
| break; |
| case '%': |
| __get_percent(__b, __e, __err, __ct); |
| break; |
| default: |
| __err |= ios_base::failbit; |
| } |
| return __b; |
| } |
| |
| extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>; |
| # if _LIBCPP_HAS_WIDE_CHARACTERS |
| extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>; |
| # endif |
| |
| class _LIBCPP_EXPORTED_FROM_ABI __time_get { |
| protected: |
| __locale::__locale_t __loc_; |
| |
| __time_get(const char* __nm); |
| __time_get(const string& __nm); |
| ~__time_get(); |
| }; |
| |
| template <class _CharT> |
| class __time_get_storage : public __time_get { |
| protected: |
| typedef basic_string<_CharT> string_type; |
| |
| string_type __weeks_[14]; |
| string_type __months_[24]; |
| string_type __am_pm_[2]; |
| string_type __c_; |
| string_type __r_; |
| string_type __x_; |
| string_type __X_; |
| |
| explicit __time_get_storage(const char* __nm); |
| explicit __time_get_storage(const string& __nm); |
| |
| _LIBCPP_HIDE_FROM_ABI ~__time_get_storage() {} |
| |
| time_base::dateorder __do_date_order() const; |
| |
| private: |
| void init(const ctype<_CharT>&); |
| string_type __analyze(char __fmt, const ctype<_CharT>&); |
| }; |
| |
| # define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \ |
| template <> \ |
| _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ |
| template <> \ |
| _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \ |
| template <> \ |
| _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \ |
| template <> \ |
| _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ |
| template <> \ |
| _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze( \ |
| char, const ctype<_CharT>&); \ |
| extern template _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() \ |
| const; \ |
| extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \ |
| extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \ |
| extern template _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ |
| extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type \ |
| __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); |
| |
| _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char) |
| # if _LIBCPP_HAS_WIDE_CHARACTERS |
| _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t) |
| # endif |
| # undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION |
| |
| template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > |
| class time_get_byname : public time_get<_CharT, _InputIterator>, private __time_get_storage<_CharT> { |
| public: |
| typedef time_base::dateorder dateorder; |
| typedef _InputIterator iter_type; |
| typedef _CharT char_type; |
| typedef basic_string<char_type> string_type; |
| |
| _LIBCPP_HIDE_FROM_ABI explicit time_get_byname(const char* __nm, size_t __refs = 0) |
| : time_get<_CharT, _InputIterator>(__refs), __time_get_storage<_CharT>(__nm) {} |
| _LIBCPP_HIDE_FROM_ABI explicit time_get_byname(const string& __nm, size_t __refs = 0) |
| : time_get<_CharT, _InputIterator>(__refs), __time_get_storage<_CharT>(__nm) {} |
| |
| protected: |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_get_byname() override {} |
| |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL dateorder do_date_order() const override { return this->__do_date_order(); } |
| |
| private: |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __weeks() const override { return this->__weeks_; } |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __months() const override { return this->__months_; } |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type* __am_pm() const override { return this->__am_pm_; } |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __c() const override { return this->__c_; } |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __r() const override { return this->__r_; } |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __x() const override { return this->__x_; } |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL const string_type& __X() const override { return this->__X_; } |
| }; |
| |
| extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>; |
| # if _LIBCPP_HAS_WIDE_CHARACTERS |
| extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>; |
| # endif |
| |
| class _LIBCPP_EXPORTED_FROM_ABI __time_put { |
| __locale::__locale_t __loc_; |
| |
| protected: |
| _LIBCPP_HIDE_FROM_ABI __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} |
| __time_put(const char* __nm); |
| __time_put(const string& __nm); |
| ~__time_put(); |
| void __do_put(char* __nb, char*& __ne, const tm* __tm, char __fmt, char __mod) const; |
| # if _LIBCPP_HAS_WIDE_CHARACTERS |
| void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, char __fmt, char __mod) const; |
| # endif |
| }; |
| |
| template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > |
| class time_put : public locale::facet, private __time_put { |
| public: |
| typedef _CharT char_type; |
| typedef _OutputIterator iter_type; |
| |
| _LIBCPP_HIDE_FROM_ABI explicit time_put(size_t __refs = 0) : locale::facet(__refs) {} |
| |
| iter_type |
| put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, const char_type* __pb, const char_type* __pe) |
| const; |
| |
| _LIBCPP_HIDE_FROM_ABI iter_type |
| put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, char __fmt, char __mod = 0) const { |
| return do_put(__s, __iob, __fl, __tm, __fmt, __mod); |
| } |
| |
| static locale::id id; |
| |
| protected: |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put() override {} |
| virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const; |
| |
| _LIBCPP_HIDE_FROM_ABI explicit time_put(const char* __nm, size_t __refs) : locale::facet(__refs), __time_put(__nm) {} |
| _LIBCPP_HIDE_FROM_ABI explicit time_put(const string& __nm, size_t __refs) |
| : locale::facet(__refs), __time_put(__nm) {} |
| }; |
| |
| template <class _CharT, class _OutputIterator> |
| locale::id time_put<_CharT, _OutputIterator>::id; |
| |
| template <class _CharT, class _OutputIterator> |
| _OutputIterator time_put<_CharT, _OutputIterator>::put( |
| iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, const char_type* __pb, const char_type* __pe) |
| const { |
| const ctype<char_type>& __ct = std::use_facet<ctype<char_type> >(__iob.getloc()); |
| for (; __pb != __pe; ++__pb) { |
| if (__ct.narrow(*__pb, 0) == '%') { |
| if (++__pb == __pe) { |
| *__s++ = __pb[-1]; |
| break; |
| } |
| char __mod = 0; |
| char __fmt = __ct.narrow(*__pb, 0); |
| if (__fmt == 'E' || __fmt == 'O') { |
| if (++__pb == __pe) { |
| *__s++ = __pb[-2]; |
| *__s++ = __pb[-1]; |
| break; |
| } |
| __mod = __fmt; |
| __fmt = __ct.narrow(*__pb, 0); |
| } |
| __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod); |
| } else |
| *__s++ = *__pb; |
| } |
| return __s; |
| } |
| |
| template <class _CharT, class _OutputIterator> |
| _OutputIterator time_put<_CharT, _OutputIterator>::do_put( |
| iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const { |
| char_type __nar[100]; |
| char_type* __nb = __nar; |
| char_type* __ne = __nb + 100; |
| __do_put(__nb, __ne, __tm, __fmt, __mod); |
| return std::copy(__nb, __ne, __s); |
| } |
| |
| extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>; |
| # if _LIBCPP_HAS_WIDE_CHARACTERS |
| extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>; |
| # endif |
| |
| template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > |
| class time_put_byname : public time_put<_CharT, _OutputIterator> { |
| public: |
| _LIBCPP_HIDE_FROM_ABI explicit time_put_byname(const char* __nm, size_t __refs = 0) |
| : time_put<_CharT, _OutputIterator>(__nm, __refs) {} |
| |
| _LIBCPP_HIDE_FROM_ABI explicit time_put_byname(const string& __nm, size_t __refs = 0) |
| : time_put<_CharT, _OutputIterator>(__nm, __refs) {} |
| |
| protected: |
| _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~time_put_byname() override {} |
| }; |
| |
| extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>; |
| # if _LIBCPP_HAS_WIDE_CHARACTERS |
| extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>; |
| # endif |
| |
| _LIBCPP_END_NAMESPACE_STD |
| |
| #endif // _LIBCPP_HAS_LOCALIZATION |
| |
| #endif // _LIBCPP___LOCALE_DIR_TIME_H |