@@ -20,6 +20,72 @@ _STL_DISABLE_CLANG_WARNINGS
20
20
#undef new
21
21
22
22
_STD_BEGIN
23
+ template <class _InIt, class _Elem>
24
+ ios_base::iostate _Getint_v2(_InIt& _First, _InIt& _Last, int _Lo, int _Hi, int& _Val, int& _Digits_read,
25
+ const ctype<_Elem>& _Ctype_fac) { // get integer in range [_Lo, _Hi] from [_First, _Last)
26
+ _STL_INTERNAL_CHECK(0 <= _Hi && _Hi <= 9999);
27
+ const int _Hi_digits = (_Hi <= 9 ? 1 : _Hi <= 99 ? 2 : _Hi <= 999 ? 3 : 4);
28
+ char _Ac[_MAX_INT_DIG];
29
+ char* _Ep;
30
+ char* _Ptr = _Ac;
31
+ char _Ch;
32
+
33
+ _Digits_read = 0;
34
+
35
+ while (_First != _Last && _Digits_read < _Hi_digits && _Ctype_fac.is(ctype_base::space, *_First)) {
36
+ ++_First;
37
+ ++_Digits_read;
38
+ }
39
+
40
+ if (_First != _Last && _Digits_read < _Hi_digits) {
41
+ if ((_Ch = _Ctype_fac.narrow(*_First)) == '+') { // copy plus sign
42
+ *_Ptr++ = '+';
43
+ ++_First;
44
+ } else if (_Ch == '-') { // copy minus sign
45
+ *_Ptr++ = '-';
46
+ ++_First;
47
+ }
48
+ }
49
+
50
+ for (; _First != _Last && _Digits_read < _Hi_digits && _Ctype_fac.narrow(*_First) == '0'; ++_First) {
51
+ ++_Digits_read; // strip leading zeros
52
+ }
53
+
54
+ if (_Digits_read > 0) {
55
+ *_Ptr++ = '0'; // replace one or more with single zero
56
+ }
57
+
58
+ for (char* const _Pe = &_Ac[_MAX_INT_DIG - 1];
59
+ _First != _Last && '0' <= (_Ch = _Ctype_fac.narrow(*_First)) && _Ch <= '9' && _Digits_read < _Hi_digits;
60
+ ++_Digits_read, (void) ++_First) { // copy digits
61
+ *_Ptr = _Ch;
62
+ if (_Ptr < _Pe) {
63
+ ++_Ptr; // drop trailing digits if already too large
64
+ }
65
+ }
66
+
67
+ if (_Digits_read == 0) {
68
+ _Ptr = _Ac;
69
+ }
70
+
71
+ *_Ptr = '\0';
72
+ int _Errno = 0;
73
+ const long _Ans = _CSTD _Stolx(_Ac, &_Ep, 10, &_Errno);
74
+ ios_base::iostate _State = ios_base::goodbit;
75
+
76
+ if (_First == _Last) {
77
+ _State |= ios_base::eofbit;
78
+ }
79
+
80
+ if (_Ep == _Ac || _Errno != 0 || _Ans < _Lo || _Hi < _Ans) {
81
+ _State |= ios_base::failbit; // bad conversion
82
+ } else {
83
+ _Val = _Ans; // store valid result
84
+ }
85
+
86
+ return _State;
87
+ }
88
+
23
89
struct _CRTIMP2_PURE_IMPORT time_base : locale::facet { // base class for time_get
24
90
enum dateorder { // constants for different orders of date components
25
91
no_order,
@@ -343,17 +409,20 @@ protected:
343
409
ios_base::iostate& _State, tm* _Pt) const { // get year from [_First, _Last) into _Pt
344
410
const _Ctype& _Ctype_fac = _STD use_facet<_Ctype>(_Iosbase.getloc());
345
411
346
- int _Ans = 0;
347
- ios_base::iostate _Res = _Getint(_First, _Last, 0, 9999, _Ans, _Ctype_fac);
412
+ int _Ans = 0;
413
+ int _Digits_read;
414
+ ios_base::iostate _Res = _Getint_v2(_First, _Last, 0, 9999, _Ans, _Digits_read, _Ctype_fac);
348
415
349
416
_State |= _Res; // pass on eofbit and failbit
350
417
if (!(_Res & ios_base::failbit)) {
351
- if (_Ans < 69) {
352
- _Pt->tm_year = _Ans + 100; // [0, 68] parsed as [2000, 2068]
353
- } else if (_Ans < 100) {
354
- _Pt->tm_year = _Ans; // [69, 99] parsed as [1969, 1999]
418
+ if (_Digits_read <= 2) {
419
+ if (_Ans < 69) {
420
+ _Pt->tm_year = _Ans + 100; // [00, 68] parsed as [2000, 2068]
421
+ } else if (_Ans < 100) {
422
+ _Pt->tm_year = _Ans; // [69, 99] parsed as [1969, 1999]
423
+ }
355
424
} else {
356
- _Pt->tm_year = _Ans - 1900; // [100, 9999] parsed literally
425
+ _Pt->tm_year = _Ans - 1900; // parsed literally
357
426
}
358
427
}
359
428
@@ -485,7 +554,10 @@ protected:
485
554
break;
486
555
487
556
case 'Y':
488
- _First = get_year(_First, _Last, _Iosbase, _State, _Pt);
557
+ _State |= _Getint(_First, _Last, 0, 9999, _Ans, _Ctype_fac);
558
+ if (!(_State & ios_base::failbit)) {
559
+ _Pt->tm_year = _Ans - 1900;
560
+ }
489
561
break;
490
562
491
563
default:
@@ -529,68 +601,9 @@ protected:
529
601
private:
530
602
ios_base::iostate __CLRCALL_OR_CDECL _Getint(_InIt& _First, _InIt& _Last, int _Lo, int _Hi, int& _Val,
531
603
const _Ctype& _Ctype_fac) const { // get integer in range [_Lo, _Hi] from [_First, _Last)
532
- _STL_INTERNAL_CHECK(0 <= _Hi && _Hi <= 9999);
533
- const int _Hi_digits = (_Hi <= 9 ? 1 : _Hi <= 99 ? 2 : _Hi <= 999 ? 3 : 4);
534
- char _Ac[_MAX_INT_DIG];
535
- char* _Ep;
536
- char* _Ptr = _Ac;
537
- char _Ch;
538
-
539
- int _Digits_seen = 0;
540
-
541
- while (_First != _Last && _Digits_seen < _Hi_digits && _Ctype_fac.is(ctype_base::space, *_First)) {
542
- ++_First;
543
- ++_Digits_seen;
544
- }
545
-
546
- if (_First != _Last && _Digits_seen < _Hi_digits) {
547
- if ((_Ch = _Ctype_fac.narrow(*_First)) == '+') { // copy plus sign
548
- *_Ptr++ = '+';
549
- ++_First;
550
- } else if (_Ch == '-') { // copy minus sign
551
- *_Ptr++ = '-';
552
- ++_First;
553
- }
554
- }
555
-
556
- for (; _First != _Last && _Digits_seen < _Hi_digits && _Ctype_fac.narrow(*_First) == '0';
557
- ++_First) { // strip leading zeros
558
- ++_Digits_seen;
559
- }
560
-
561
- if (_Digits_seen > 0) {
562
- *_Ptr++ = '0'; // replace one or more with single zero
563
- }
564
-
565
- for (char* const _Pe = &_Ac[_MAX_INT_DIG - 1];
566
- _First != _Last && '0' <= (_Ch = _Ctype_fac.narrow(*_First)) && _Ch <= '9' && _Digits_seen < _Hi_digits;
567
- ++_Digits_seen, (void) ++_First) { // copy digits
568
- *_Ptr = _Ch;
569
- if (_Ptr < _Pe) {
570
- ++_Ptr; // drop trailing digits if already too large
571
- }
572
- }
573
-
574
- if (_Digits_seen == 0) {
575
- _Ptr = _Ac;
576
- }
577
-
578
- *_Ptr = '\0';
579
- int _Errno = 0;
580
- const long _Ans = _CSTD _Stolx(_Ac, &_Ep, 10, &_Errno);
581
- ios_base::iostate _State = ios_base::goodbit;
582
-
583
- if (_First == _Last) {
584
- _State |= ios_base::eofbit;
585
- }
586
-
587
- if (_Ep == _Ac || _Errno != 0 || _Ans < _Lo || _Hi < _Ans) {
588
- _State |= ios_base::failbit; // bad conversion
589
- } else {
590
- _Val = _Ans; // store valid result
591
- }
592
-
593
- return _State;
604
+ // TRANSITION, ABI
605
+ int _Digits_read;
606
+ return _Getint_v2(_First, _Last, _Lo, _Hi, _Val, _Digits_read, _Ctype_fac);
594
607
}
595
608
596
609
void __CLR_OR_THIS_CALL _Tidy() noexcept { // free all storage
0 commit comments