diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index afd242b32aa..dedee8c1b0a 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -628,7 +628,7 @@ GLIBCXX_3.4 { _ZNSt8time_get*; _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE1*; _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE8*; - _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE21*; + _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE21*PK[cw]; # std::time_get_byname _ZNSt15time_get_bynameI[cw]*EEEC[12]EPKc[jmy]; @@ -1887,7 +1887,9 @@ GLIBCXX_3.4.21 { _ZNKSt7__cxx119money_putI*; _ZNKSt7__cxx1110moneypunctI*; _ZNKSt7__cxx118numpunctI*; - _ZNKSt7__cxx118time_getI*; + _ZNKSt7__cxx118time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[13-9]*; + _ZNKSt7__cxx118time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE21*PK[cw]; + _ZNKSt7__cxx118time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE24*; _ZSt9has_facetINSt7__cxx117collate*; _ZSt9has_facetINSt7__cxx118messages*; @@ -2427,6 +2429,12 @@ GLIBCXX_3.4.30 { # Only defined #if ! __GXX_TYPEINFO_EQUALITY_INLINE _ZNKSt9type_info7__equalERKS_; + # std::time_get + _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE21*__time_get_state; + _ZNKSt7__cxx118time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE21*__time_get_state; + + _ZNSt16__time_get_state17_M_finalize_stateEP2tm; + } GLIBCXX_3.4.29; # Symbols in the support library (libsupc++) have their own tag. diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.h b/libstdc++-v3/include/bits/locale_facets_nonio.h index 8f2aa863302..71a82af5ee3 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.h +++ b/libstdc++-v3/include/bits/locale_facets_nonio.h @@ -355,6 +355,30 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION + struct __time_get_state + { + // Finalize state. + void + _M_finalize_state(tm* __tm); + + unsigned int _M_have_I : 1; + unsigned int _M_have_wday : 1; + unsigned int _M_have_yday : 1; + unsigned int _M_have_mon : 1; + unsigned int _M_have_mday : 1; + unsigned int _M_have_uweek : 1; + unsigned int _M_have_wweek : 1; + unsigned int _M_have_century : 1; + unsigned int _M_is_pm : 1; + unsigned int _M_want_century : 1; + unsigned int _M_want_xday : 1; + unsigned int _M_pad1 : 5; + unsigned int _M_week_no : 6; + unsigned int _M_pad2 : 10; + int _M_century; + int _M_pad3; + }; + _GLIBCXX_BEGIN_NAMESPACE_CXX11 /** @@ -756,6 +780,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm, const _CharT* __format) const; + + // Extract on a component-by-component basis, via __format argument, with + // state. + iter_type + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format, + __time_get_state &__state) const; }; template diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc index d199bcc5ea9..64737823374 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc +++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc @@ -691,7 +691,8 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 time_get<_CharT, _InIter>:: _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm, - const _CharT* __format) const + const _CharT* __format, + __time_get_state &__state) const { const locale& __loc = __io._M_getloc(); const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); @@ -722,7 +723,10 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 __beg = _M_extract_name(__beg, __end, __mem, __days, 14, __io, __tmperr); if (!__tmperr) - __tm->tm_wday = __mem % 7; + { + __tm->tm_wday = __mem % 7; + __state._M_have_wday = 1; + } break; case 'h': case 'b': @@ -734,14 +738,31 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 __beg = _M_extract_name(__beg, __end, __mem, __months, 24, __io, __tmperr); if (!__tmperr) - __tm->tm_mon = __mem % 12; + { + __tm->tm_mon = __mem % 12; + __state._M_have_mon = 1; + __state._M_want_xday = 1; + } break; case 'c': // Default time and date representation. const char_type* __dt[2]; __tp._M_date_time_formats(__dt); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __dt[0]); + __tm, __dt[0], __state); + if (!__tmperr) + __state._M_want_xday = 1; + break; + case 'C': + // Century. + __beg = _M_extract_num(__beg, __end, __mem, 0, 99, 2, + __io, __tmperr); + if (!__tmperr) + { + __state._M_century = __mem; + __state._M_have_century = 1; + __state._M_want_xday = 1; + } break; case 'd': case 'e': @@ -751,35 +772,60 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 __beg = _M_extract_num(__beg, __end, __mem, 1, 31, 2, __io, __tmperr); if (!__tmperr) - __tm->tm_mday = __mem; + { + __tm->tm_mday = __mem; + __state._M_have_mday = 1; + __state._M_want_xday = 1; + } break; case 'D': // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] __cs = "%m/%d/%y"; __ctype.widen(__cs, __cs + 9, __wcs); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __wcs); + __tm, __wcs, __state); + if (!__tmperr) + __state._M_want_xday = 1; break; case 'H': // Hour [00, 23]. [tm_hour] __beg = _M_extract_num(__beg, __end, __mem, 0, 23, 2, __io, __tmperr); if (!__tmperr) - __tm->tm_hour = __mem; + { + __tm->tm_hour = __mem; + __state._M_have_I = 0; + } break; case 'I': // Hour [01, 12]. [tm_hour] __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, __io, __tmperr); if (!__tmperr) - __tm->tm_hour = __mem % 12; + { + __tm->tm_hour = __mem % 12; + __state._M_have_I = 1; + } + break; + case 'j': + // Day number of year. + __beg = _M_extract_num(__beg, __end, __mem, 1, 366, 3, + __io, __tmperr); + if (!__tmperr) + { + __tm->tm_yday = __mem - 1; + __state._M_have_yday = 1; + } break; case 'm': // Month [01, 12]. [tm_mon] __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, __io, __tmperr); if (!__tmperr) - __tm->tm_mon = __mem - 1; + { + __tm->tm_mon = __mem - 1; + __state._M_have_mon = 1; + } break; case 'M': // Minute [00, 59]. [tm_min] @@ -802,23 +848,22 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 break; __beg = _M_extract_name(__beg, __end, __mem, __ampm, 2, __io, __tmperr); - // FIXME: This only works if %I comes before %p. if (!__tmperr && __mem) - __tm->tm_hour += 12; + __state._M_is_pm = 1; break; case 'r': // Locale's 12-hour clock time format (in C %I:%M:%S %p). const char_type* __ampm_format; __tp._M_am_pm_format(&__ampm_format); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __ampm_format); + __tm, __ampm_format, __state); break; case 'R': // Equivalent to (%H:%M). __cs = "%H:%M"; __ctype.widen(__cs, __cs + 6, __wcs); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __wcs); + __tm, __wcs, __state); break; case 'S': // Seconds. [tm_sec] @@ -830,41 +875,105 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 #endif __io, __tmperr); if (!__tmperr) - __tm->tm_sec = __mem; + __tm->tm_sec = __mem; break; case 'T': // Equivalent to (%H:%M:%S). __cs = "%H:%M:%S"; __ctype.widen(__cs, __cs + 9, __wcs); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __wcs); + __tm, __wcs, __state); + break; + case 'U': + // Week number of the year (Sunday as first day of week). + __beg = _M_extract_num(__beg, __end, __mem, 0, 53, 2, + __io, __tmperr); + if (!__tmperr) + { + __state._M_week_no = __mem; + __state._M_have_uweek = 1; + } + break; + case 'w': + // Weekday [tm_wday] + __beg = _M_extract_num(__beg, __end, __mem, 0, 6, 1, + __io, __tmperr); + if (!__tmperr) + { + __tm->tm_wday = __mem; + __state._M_have_wday = 1; + } + break; + case 'W': + // Week number of the year (Monday as first day of week). + __beg = _M_extract_num(__beg, __end, __mem, 0, 53, 2, + __io, __tmperr); + if (!__tmperr) + { + __state._M_week_no = __mem; + __state._M_have_wweek = 1; + } break; case 'x': // Locale's date. const char_type* __dates[2]; __tp._M_date_formats(__dates); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __dates[0]); + __tm, __dates[0], __state); break; case 'X': // Locale's time. const char_type* __times[2]; __tp._M_time_formats(__times); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __times[0]); + __tm, __times[0], __state); break; case 'y': - case 'C': // C99 - // Two digit year. + // The last 2 digits of year. + __beg = _M_extract_num(__beg, __end, __mem, 0, 99, 2, + __io, __tmperr); + if (!__tmperr) + { + __state._M_want_century = 1; + __state._M_want_xday = 1; + // As an extension, if the 2 digits are followed by + // 1-2 further digits, treat it like %Y. + __c = 0; + if (__beg != __end) + __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + { + ++__beg; + __mem = __mem * 10 + (__c - '0'); + if (__beg != __end) + { + __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + { + ++__beg; + __mem = __mem * 10 + (__c - '0'); + } + } + __mem -= 1900; + __state._M_want_century = 0; + } + // Otherwise, as per POSIX 2008, 00-68 is 2000-2068, + // while 69-99 is 1969-1999. + else if (__mem < 69) + __mem += 100; + __tm->tm_year = __mem; + } + break; case 'Y': - // Year [1900). - // NB: We parse either two digits, implicitly years since - // 1900, or 4 digits, full year. In both cases we can - // reconstruct [tm_year]. See also libstdc++/26701. + // Year. __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, __io, __tmperr); if (!__tmperr) - __tm->tm_year = __mem < 0 ? __mem + 100 : __mem - 1900; + { + __tm->tm_year = __mem - 1900; + __state._M_want_century = 0; + __state._M_want_xday = 1; + } break; case 'Z': // Timezone info. @@ -925,6 +1034,18 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 return __beg; } + template + _InIter + time_get<_CharT, _InIter>:: + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format) const + { + __time_get_state __state = __time_get_state(); + return _M_extract_via_format(__beg, __end, __io, __err, __tm, + __format, __state); + } + template _InIter time_get<_CharT, _InIter>:: @@ -949,13 +1070,7 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 else break; } - // Special encoding for do_get_year, 'y', and 'Y' above. - if (__len == 4 && __i == 2) - __member = __value - 100; - else if (__len == 4 && __i == 4) - __member = __value; - else if (__len == 2 && __i && __i <= 2 - && __value >= __min && __value <= __max) + if (__i && __value >= __min && __value <= __max) __member = __value; else __err |= ios_base::failbit; @@ -1212,8 +1327,10 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); const char_type* __times[2]; __tp._M_time_formats(__times); + __time_get_state __state = __time_get_state(); __beg = _M_extract_via_format(__beg, __end, __io, __err, - __tm, __times[0]); + __tm, __times[0], __state); + __state._M_finalize_state(__tm); if (__beg == __end) __err |= ios_base::eofbit; return __beg; @@ -1229,8 +1346,10 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); const char_type* __dates[2]; __tp._M_date_formats(__dates); + __time_get_state __state = __time_get_state(); __beg = _M_extract_via_format(__beg, __end, __io, __err, - __tm, __dates[0]); + __tm, __dates[0], __state); + __state._M_finalize_state(__tm); if (__beg == __end) __err |= ios_base::eofbit; return __beg; @@ -1296,11 +1415,38 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 { int __tmpyear; ios_base::iostate __tmperr = ios_base::goodbit; + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); - __beg = _M_extract_num(__beg, __end, __tmpyear, 0, 9999, 4, + __beg = _M_extract_num(__beg, __end, __tmpyear, 0, 99, 2, __io, __tmperr); if (!__tmperr) - __tm->tm_year = __tmpyear < 0 ? __tmpyear + 100 : __tmpyear - 1900; + { + char __c = 0; + if (__beg != __end) + __c = __ctype.narrow(*__beg, '*'); + // For 1-2 digit year, assume 69-99 is 1969-1999, 0-68 is 2000-2068. + // For 3-4 digit year, use it as year. + // __tm->tm_year needs year - 1900 though. + if (__c >= '0' && __c <= '9') + { + ++__beg; + __tmpyear = __tmpyear * 10 + (__c - '0'); + if (__beg != __end) + { + __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + { + ++__beg; + __tmpyear = __tmpyear * 10 + (__c - '0'); + } + } + __tmpyear -= 1900; + } + else if (__tmpyear < 69) + __tmpyear += 100; + __tm->tm_year = __tmpyear; + } else __err |= ios_base::failbit; @@ -1321,6 +1467,21 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 const locale& __loc = __io._M_getloc(); ctype<_CharT> const& __ctype = use_facet >(__loc); __err = ios_base::goodbit; + bool __use_state = false; +#if __GNUC__ >= 5 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpmf-conversions" + // Nasty hack. The C++ standard mandates that get invokes the do_get + // virtual method, but unfortunately at least without an ABI change + // for the facets we can't keep state across the different do_get + // calls. So e.g. if __fmt is "%p %I:%M:%S", we can't handle it + // properly, because we first handle the %p am/pm specifier and only + // later the 12-hour format specifier. + if ((void*)(this->*(&time_get::do_get)) == (void*)(&time_get::do_get)) + __use_state = true; +#pragma GCC diagnostic pop +#endif + __time_get_state __state = __time_get_state(); while (__fmt != __fmtend && __err == ios_base::goodbit) { @@ -1331,6 +1492,7 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 } else if (__ctype.narrow(*__fmt, 0) == '%') { + const char_type* __fmt_start = __fmt; char __format; char __mod = 0; if (++__fmt == __fmtend) @@ -1351,8 +1513,26 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 __err = ios_base::failbit; break; } - __s = this->do_get(__s, __end, __io, __err, __tm, __format, - __mod); + if (__use_state) + { + char_type __new_fmt[4]; + __new_fmt[0] = __fmt_start[0]; + __new_fmt[1] = __fmt_start[1]; + if (__mod) + { + __new_fmt[2] = __fmt_start[2]; + __new_fmt[3] = char_type(); + } + else + __new_fmt[2] = char_type(); + __s = _M_extract_via_format(__s, __end, __io, __err, __tm, + __new_fmt, __state); + if (__s == __end) + __err |= ios_base::eofbit; + } + else + __s = this->do_get(__s, __end, __io, __err, __tm, __format, + __mod); ++__fmt; } else if (__ctype.is(ctype_base::space, *__fmt)) @@ -1379,6 +1559,8 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 break; } } + if (__use_state) + __state._M_finalize_state(__tm); return __s; } @@ -1408,7 +1590,10 @@ _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 __fmt[3] = char_type(); } - __beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __fmt); + __time_get_state __state = __time_get_state(); + __beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __fmt, + __state); + __state._M_finalize_state(__tm); if (__beg == __end) __err |= ios_base::eofbit; return __beg; diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc index 9fcfaf99217..1293a37e642 100644 --- a/libstdc++-v3/src/c++98/locale_facets.cc +++ b/libstdc++-v3/src/c++98/locale_facets.cc @@ -134,5 +134,115 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __grouping_tmp.size()); } + namespace + { + bool + is_leap(int year) + { + return (year % 100 != 0 || year % 400 == 0) && year % 4 == 0; + } + + const unsigned short int mon_yday[2][13] = + { + // Normal years. + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + // Leap years. + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } + }; + + int + day_of_the_week (int year, int mon, int mday) + { + // We know that January 1st 1970 was a Thursday (= 4). Compute the + // difference between this date and the one in arguments and so + // determine the weekday. + int corr_year = 1900 + year - (mon < 2); + int wday = (-473 + + (365 * (year - 70)) + + (corr_year / 4) + - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) + + (((corr_year / 4) / 25) / 4) + + mon_yday[0][mon] + + mday - 1); + return ((wday % 7) + 7) % 7; + } + + // Compute the day of the year. + int + day_of_the_year (tm *tm) + { + return (mon_yday[is_leap (1900 + tm->tm_year)][tm->tm_mon] + + (tm->tm_mday - 1)); + } + } + + // Finalize time_get state. + void + __time_get_state:: + _M_finalize_state(tm* tm) + { + if (_M_have_I && _M_is_pm) + tm->tm_hour += 12; + if (_M_have_century) + { + if (_M_want_century) + tm->tm_year = tm->tm_year % 100; + else + tm->tm_year = 0; + tm->tm_year += (_M_century - 19) * 100; + } + if (_M_want_xday && !_M_have_wday) + { + if (!(_M_have_mon && _M_have_mday) && _M_have_yday) + { + // We don't have tm_mon and/or tm_mday, compute them. + int t_mon = 0; + while (mon_yday[is_leap(1900 + tm->tm_year)][t_mon] + <= tm->tm_yday) + ++t_mon; + if (!_M_have_mon) + tm->tm_mon = t_mon - 1; + if (!_M_have_mday) + tm->tm_mday + = (tm->tm_yday + - mon_yday[is_leap(1900 + tm->tm_year)][t_mon - 1] + 1); + _M_have_mon = 1; + _M_have_mday = 1; + } + // Don't crash in day_of_the_week if tm_mon is uninitialized. + if (_M_have_mon || (unsigned) tm->tm_mon <= 11) + tm->tm_wday + = day_of_the_week (tm->tm_year, tm->tm_mon, tm->tm_mday); + } + if (_M_want_xday + && !_M_have_yday + && (_M_have_mon || (unsigned) tm->tm_mon <= 11)) + tm->tm_yday = day_of_the_year (tm); + if ((_M_have_uweek || _M_have_wweek) && _M_have_wday) + { + int w_offset = _M_have_uweek ? 0 : 1; + int wday = day_of_the_week (tm->tm_year, 0, 1); + + if (!_M_have_yday) + tm->tm_yday = ((7 - (wday - w_offset)) % 7 + + (_M_week_no - 1) * 7 + + (tm->tm_wday - w_offset + 7) % 7); + + if (!_M_have_mday || !_M_have_mon) + { + int t_mon = 0; + while (mon_yday[is_leap(1900 + tm->tm_year)][t_mon] + <= tm->tm_yday) + ++t_mon; + if (!_M_have_mon) + tm->tm_mon = t_mon - 1; + if (!_M_have_mday) + tm->tm_mday + = (tm->tm_yday + - mon_yday[is_leap(1900 + tm->tm_year)][t_mon - 1] + 1); + } + } + } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/char/4.cc b/libstdc++-v3/testsuite/22_locale/time_get/get/char/4.cc new file mode 100644 index 00000000000..d0619f9de1f --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/time_get/get/char/4.cc @@ -0,0 +1,243 @@ +// { dg-do run { target c++11 } } + +// Copyright (C) 2021-2022 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include +#include +#include + +void +test01() +{ + using namespace std; + + locale loc_c = locale::classic(); + + istringstream iss; + iss.imbue(loc_c); + const time_get& tget = use_facet>(iss.getloc()); + typedef istreambuf_iterator iter; + const iter end; + + tm time; + ios_base::iostate err = ios_base::badbit; + + iss.str("PM01:38:12"); + string format = "%p%I:%M:%S"; + time = tm(); + auto ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_hour == 13 ); + VERIFY( time.tm_min == 38 ); + VERIFY( time.tm_sec == 12 ); + + iss.str("05 37"); + format = "%C %y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 537 - 1900 ); + + iss.str("68"); + format = "%y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2068 - 1900 ); + + iss.str("69"); + format = "%y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 1969 - 1900 ); + + iss.str("03-Feb-2003"); + format = "%d-%b-%Y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2003 - 1900 ); + VERIFY( time.tm_mon == 1 ); + VERIFY( time.tm_mday == 3 ); + VERIFY( time.tm_wday == 1 ); + VERIFY( time.tm_yday == 33 ); + + iss.str("16-Dec-2020"); + format = "%d-%b-%Y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2020 - 1900 ); + VERIFY( time.tm_mon == 11 ); + VERIFY( time.tm_mday == 16 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 350 ); + + iss.str("16-Dec-2021"); + format = "%d-%b-%Y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2021 - 1900 ); + VERIFY( time.tm_mon == 11 ); + VERIFY( time.tm_mday == 16 ); + VERIFY( time.tm_wday == 4 ); + VERIFY( time.tm_yday == 349 ); + + iss.str("253 2020"); + format = "%j %Y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2020 - 1900 ); + VERIFY( time.tm_mon == 8 ); + VERIFY( time.tm_mday == 9 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 252 ); + + iss.str("233 2021"); + format = "%j %Y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2021 - 1900 ); + VERIFY( time.tm_mon == 7 ); + VERIFY( time.tm_mday == 21 ); + VERIFY( time.tm_wday == 6 ); + VERIFY( time.tm_yday == 232 ); + + iss.str("2020 23 3"); + format = "%Y %U %w"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2020 - 1900 ); + VERIFY( time.tm_mon == 5 ); + VERIFY( time.tm_mday == 10 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 161 ); + + iss.str("2020 23 3"); + format = "%Y %W %w"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2020 - 1900 ); + VERIFY( time.tm_mon == 5 ); + VERIFY( time.tm_mday == 10 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 161 ); + + iss.str("2021 43 Fri"); + format = "%Y %W %a"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2021 - 1900 ); + VERIFY( time.tm_mon == 9 ); + VERIFY( time.tm_mday == 29 ); + VERIFY( time.tm_wday == 5 ); + VERIFY( time.tm_yday == 301 ); + + iss.str("2024 23 3"); + format = "%Y %U %w"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2024 - 1900 ); + VERIFY( time.tm_mon == 5 ); + VERIFY( time.tm_mday == 12 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 163 ); + + iss.str("2024 23 3"); + format = "%Y %W %w"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2024 - 1900 ); + VERIFY( time.tm_mon == 5 ); + VERIFY( time.tm_mday == 5 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 156 ); + + // As an extension, parse also 4 digit years. + iss.str("0068"); + format = "%y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 68 - 1900 ); + + iss.str("0069"); + format = "%y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 69 - 1900 ); + + iss.str("1492"); + format = "%y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 1492 - 1900 ); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/4.cc b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/4.cc new file mode 100644 index 00000000000..0518842692f --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/time_get/get/wchar_t/4.cc @@ -0,0 +1,243 @@ +// { dg-do run { target c++11 } } + +// Copyright (C) 2021-2022 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include +#include +#include + +void +test01() +{ + using namespace std; + + locale loc_c = locale::classic(); + + wistringstream iss; + iss.imbue(loc_c); + const time_get& tget = use_facet>(iss.getloc()); + typedef istreambuf_iterator iter; + const iter end; + + tm time; + ios_base::iostate err = ios_base::badbit; + + iss.str(L"PM01:38:12"); + wstring format = L"%p%I:%M:%S"; + time = tm(); + auto ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_hour == 13 ); + VERIFY( time.tm_min == 38 ); + VERIFY( time.tm_sec == 12 ); + + iss.str(L"05 37"); + format = L"%C %y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 537 - 1900 ); + + iss.str(L"68"); + format = L"%y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2068 - 1900 ); + + iss.str(L"69"); + format = L"%y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 1969 - 1900 ); + + iss.str(L"03-Feb-2003"); + format = L"%d-%b-%Y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2003 - 1900 ); + VERIFY( time.tm_mon == 1 ); + VERIFY( time.tm_mday == 3 ); + VERIFY( time.tm_wday == 1 ); + VERIFY( time.tm_yday == 33 ); + + iss.str(L"16-Dec-2020"); + format = L"%d-%b-%Y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2020 - 1900 ); + VERIFY( time.tm_mon == 11 ); + VERIFY( time.tm_mday == 16 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 350 ); + + iss.str(L"16-Dec-2021"); + format = L"%d-%b-%Y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2021 - 1900 ); + VERIFY( time.tm_mon == 11 ); + VERIFY( time.tm_mday == 16 ); + VERIFY( time.tm_wday == 4 ); + VERIFY( time.tm_yday == 349 ); + + iss.str(L"253 2020"); + format = L"%j %Y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2020 - 1900 ); + VERIFY( time.tm_mon == 8 ); + VERIFY( time.tm_mday == 9 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 252 ); + + iss.str(L"233 2021"); + format = L"%j %Y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2021 - 1900 ); + VERIFY( time.tm_mon == 7 ); + VERIFY( time.tm_mday == 21 ); + VERIFY( time.tm_wday == 6 ); + VERIFY( time.tm_yday == 232 ); + + iss.str(L"2020 23 3"); + format = L"%Y %U %w"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2020 - 1900 ); + VERIFY( time.tm_mon == 5 ); + VERIFY( time.tm_mday == 10 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 161 ); + + iss.str(L"2020 23 3"); + format = L"%Y %W %w"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2020 - 1900 ); + VERIFY( time.tm_mon == 5 ); + VERIFY( time.tm_mday == 10 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 161 ); + + iss.str(L"2021 43 Fri"); + format = L"%Y %W %a"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2021 - 1900 ); + VERIFY( time.tm_mon == 9 ); + VERIFY( time.tm_mday == 29 ); + VERIFY( time.tm_wday == 5 ); + VERIFY( time.tm_yday == 301 ); + + iss.str(L"2024 23 3"); + format = L"%Y %U %w"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2024 - 1900 ); + VERIFY( time.tm_mon == 5 ); + VERIFY( time.tm_mday == 12 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 163 ); + + iss.str(L"2024 23 3"); + format = L"%Y %W %w"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 2024 - 1900 ); + VERIFY( time.tm_mon == 5 ); + VERIFY( time.tm_mday == 5 ); + VERIFY( time.tm_wday == 3 ); + VERIFY( time.tm_yday == 156 ); + + // As an extension, parse also 4 digit years. + iss.str(L"0068"); + format = L"%y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 68 - 1900 ); + + iss.str(L"0069"); + format = L"%y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 69 - 1900 ); + + iss.str(L"1492"); + format = L"%y"; + time = tm(); + ret = tget.get(iter(iss), end, iss, err, &time, + format.data(), format.data()+format.size()); + VERIFY( err == ios_base::eofbit ); + VERIFY( ret == end ); + VERIFY( time.tm_year == 1492 - 1900 ); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_year/char/1.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_year/char/1.cc index c9d9896a6c0..e6f53de4a55 100644 --- a/libstdc++-v3/testsuite/22_locale/time_get/get_year/char/1.cc +++ b/libstdc++-v3/testsuite/22_locale/time_get/get_year/char/1.cc @@ -76,8 +76,8 @@ void test01() errorstate = good; iterator_type ret03 = tim_get.get_year(is_it03, end, iss, errorstate, &time03); - VERIFY( time03.tm_year == 3 ); - VERIFY( errorstate == ios_base::failbit ); + VERIFY( time03.tm_year == 197 - 1900 ); + VERIFY( errorstate == good ); VERIFY( *ret03 == 'd' ); iss.str("71d71"); diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_year/char/5.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_year/char/5.cc index d518d96c45f..c4544479828 100644 --- a/libstdc++-v3/testsuite/22_locale/time_get/get_year/char/5.cc +++ b/libstdc++-v3/testsuite/22_locale/time_get/get_year/char/5.cc @@ -49,12 +49,13 @@ void test01() const string str0 = "1"; tg.get_year(str0.begin(), str0.end(), iss, err, &tm0); - VERIFY( err == (failbit | eofbit) ); - VERIFY( tm0.tm_year == 0 ); + VERIFY( err == eofbit ); + VERIFY( tm0.tm_year == 2001 - 1900 ); const string str1 = "1997 "; + err = goodbit; iter_type end1 = tg.get_year(str1.begin(), str1.end(), iss, err, &tm1); - VERIFY( err == (failbit | eofbit) ); + VERIFY( err == goodbit ); VERIFY( tm1.tm_year == time_sanity.tm_year ); VERIFY( *end1 == ' ' ); } diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_year/char/6.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_year/char/6.cc new file mode 100644 index 00000000000..e50afa6aa73 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/time_get/get_year/char/6.cc @@ -0,0 +1,79 @@ +// Copyright (C) 2001-2022 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 22.2.5.1.1 time_get members + +#include +#include +#include + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator iterator_type; + + locale loc_c = locale::classic(); + + iterator_type end; + + istringstream iss; + iss.imbue(loc_c); + const time_get& tim_get = use_facet >(iss.getloc()); + ios_base::iostate errorstate = ios_base::goodbit; + + iss.str("69"); + iterator_type is_it01(iss); + tm time01; + tim_get.get_year(is_it01, end, iss, errorstate, &time01); + VERIFY( time01.tm_year == 1969 - 1900 ); + VERIFY( errorstate == ios_base::eofbit ); + + iss.str("68 "); + iterator_type is_it02(iss); + tm time02; + errorstate = ios_base::goodbit; + iterator_type ret02 = tim_get.get_year(is_it02, end, iss, errorstate, + &time02); + VERIFY( time02.tm_year == 2068 - 1900 ); + VERIFY( errorstate == ios_base::goodbit ); + VERIFY( *ret02 == ' ' ); + + iss.str("0069"); + iterator_type is_it03(iss); + tm time03; + errorstate = ios_base::goodbit; + iterator_type ret03 = tim_get.get_year(is_it03, end, iss, errorstate, + &time03); + VERIFY( time03.tm_year == 69 - 1900 ); + VERIFY( errorstate == ios_base::eofbit ); + + iss.str("0068"); + iterator_type is_it04(iss); + tm time04; + errorstate = ios_base::goodbit; + iterator_type ret04 = tim_get.get_year(is_it04, end, iss, errorstate, + &time04); + VERIFY( time04.tm_year == 68 - 1900 ); + VERIFY( errorstate == ios_base::eofbit ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_year/wchar_t/1.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_year/wchar_t/1.cc index e17712098f4..ba95fb91520 100644 --- a/libstdc++-v3/testsuite/22_locale/time_get/get_year/wchar_t/1.cc +++ b/libstdc++-v3/testsuite/22_locale/time_get/get_year/wchar_t/1.cc @@ -76,8 +76,8 @@ void test01() errorstate = good; iterator_type ret03 = tim_get.get_year(is_it03, end, iss, errorstate, &time03); - VERIFY( time03.tm_year == 3 ); - VERIFY( errorstate == ios_base::failbit ); + VERIFY( time03.tm_year == 197 - 1900 ); + VERIFY( errorstate == good ); VERIFY( *ret03 == L'd' ); iss.str(L"71d71"); diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_year/wchar_t/5.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_year/wchar_t/5.cc index 8ce1bdaac12..c1ee71015aa 100644 --- a/libstdc++-v3/testsuite/22_locale/time_get/get_year/wchar_t/5.cc +++ b/libstdc++-v3/testsuite/22_locale/time_get/get_year/wchar_t/5.cc @@ -49,12 +49,13 @@ void test01() const wstring str0 = L"1"; tg.get_year(str0.begin(), str0.end(), iss, err, &tm0); - VERIFY( err == (failbit | eofbit) ); - VERIFY( tm0.tm_year == 0 ); + VERIFY( err == eofbit ); + VERIFY( tm0.tm_year == 2001 - 1900 ); const wstring str1 = L"1997 "; + err = goodbit; iter_type end1 = tg.get_year(str1.begin(), str1.end(), iss, err, &tm1); - VERIFY( err == (failbit | eofbit) ); + VERIFY( err == goodbit ); VERIFY( tm1.tm_year == time_sanity.tm_year ); VERIFY( *end1 == L' ' ); } diff --git a/libstdc++-v3/testsuite/22_locale/time_get/get_year/wchar_t/6.cc b/libstdc++-v3/testsuite/22_locale/time_get/get_year/wchar_t/6.cc new file mode 100644 index 00000000000..f6e32b7f781 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/time_get/get_year/wchar_t/6.cc @@ -0,0 +1,79 @@ +// Copyright (C) 2001-2022 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 22.2.5.1.1 time_get members + +#include +#include +#include + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator iterator_type; + + locale loc_c = locale::classic(); + + iterator_type end; + + wistringstream iss; + iss.imbue(loc_c); + const time_get& tim_get = use_facet >(iss.getloc()); + ios_base::iostate errorstate = ios_base::goodbit; + + iss.str(L"69"); + iterator_type is_it01(iss); + tm time01; + tim_get.get_year(is_it01, end, iss, errorstate, &time01); + VERIFY( time01.tm_year == 1969 - 1900 ); + VERIFY( errorstate == ios_base::eofbit ); + + iss.str(L"68 "); + iterator_type is_it02(iss); + tm time02; + errorstate = ios_base::goodbit; + iterator_type ret02 = tim_get.get_year(is_it02, end, iss, errorstate, + &time02); + VERIFY( time02.tm_year == 2068 - 1900 ); + VERIFY( errorstate == ios_base::goodbit ); + VERIFY( *ret02 == L' ' ); + + iss.str(L"0069"); + iterator_type is_it03(iss); + tm time03; + errorstate = ios_base::goodbit; + iterator_type ret03 = tim_get.get_year(is_it03, end, iss, errorstate, + &time03); + VERIFY( time03.tm_year == 69 - 1900 ); + VERIFY( errorstate == ios_base::eofbit ); + + iss.str(L"0068"); + iterator_type is_it04(iss); + tm time04; + errorstate = ios_base::goodbit; + iterator_type ret04 = tim_get.get_year(is_it04, end, iss, errorstate, + &time04); + VERIFY( time04.tm_year == 68 - 1900 ); + VERIFY( errorstate == ios_base::eofbit ); +} + +int main() +{ + test01(); + return 0; +}