Skip to content

Commit f392449

Browse files
Various cleanups: <chrono> (#4119)
1 parent b34b4ad commit f392449

7 files changed

Lines changed: 126 additions & 127 deletions

File tree

stl/inc/__msvc_tzdb.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ class _Crt_allocator {
151151
void deallocate(_Ty* const _Ptr, size_t) noexcept {
152152
__std_free_crt(_Ptr);
153153
}
154+
155+
template <class _Other>
156+
_NODISCARD bool operator==(const _Crt_allocator<_Other>&) const noexcept {
157+
return true;
158+
}
154159
};
155160

156161
_STD_END

stl/inc/chrono

Lines changed: 87 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,7 +1712,7 @@ namespace chrono {
17121712

17131713
template <class _Duration>
17141714
[[noreturn]] void _Throw_nonexistent_local_time(const local_time<_Duration>& _Tp, const local_info& _Info) {
1715-
_THROW((nonexistent_local_time{_Tp, _Info}));
1715+
_THROW(nonexistent_local_time{_Tp, _Info});
17161716
}
17171717

17181718
_EXPORT_STD class ambiguous_local_time : public runtime_error {
@@ -1735,16 +1735,39 @@ namespace chrono {
17351735

17361736
template <class _Duration>
17371737
[[noreturn]] void _Throw_ambiguous_local_time(const local_time<_Duration>& _Tp, const local_info& _Info) {
1738-
_THROW((ambiguous_local_time{_Tp, _Info}));
1738+
_THROW(ambiguous_local_time{_Tp, _Info});
17391739
}
17401740

17411741
// [time.zone.timezone]
17421742

1743+
template <auto& _Get_tzdb_info, class... _Types>
1744+
_NODISCARD auto _Make_unique_tzdb_info(_Types&&... _Args) {
1745+
const auto _Raw_ptr = _Get_tzdb_info(_STD forward<_Types>(_Args)...);
1746+
1747+
using _Tzdb_info = remove_pointer_t<decltype(_Raw_ptr)>;
1748+
1749+
unique_ptr<_Tzdb_info, _Tzdb_deleter<_Tzdb_info>> _Info{_Raw_ptr};
1750+
1751+
if (_Info == nullptr) {
1752+
_Xbad_alloc();
1753+
} else if (_Info->_Err == __std_tzdb_error::_Win_error) {
1754+
_XGetLastError();
1755+
} else if (_Info->_Err == __std_tzdb_error::_Icu_error) {
1756+
_Xruntime_error("Internal error loading IANA database information");
1757+
}
1758+
1759+
return _Info;
1760+
}
1761+
17431762
_EXPORT_STD enum class choose { earliest, latest };
17441763

1764+
struct _Secret_time_zone_construct_tag {
1765+
explicit _Secret_time_zone_construct_tag() = default;
1766+
};
1767+
17451768
_EXPORT_STD class time_zone {
17461769
public:
1747-
explicit time_zone(string_view _Name_) : _Name(_Name_) {}
1770+
explicit time_zone(_Secret_time_zone_construct_tag, string_view _Name_) : _Name(_Name_) {}
17481771

17491772
time_zone(time_zone&&) = default;
17501773
time_zone& operator=(time_zone&&) = default;
@@ -1811,16 +1834,8 @@ namespace chrono {
18111834

18121835
const auto _Tz_len = _Name.length();
18131836

1814-
const unique_ptr<__std_tzdb_sys_info, _Tzdb_deleter<__std_tzdb_sys_info>> _Info{
1815-
__std_tzdb_get_sys_info(_Tz_arg.c_str(), _Tz_len, _Internal_dur.count())};
1816-
1817-
if (_Info == nullptr) {
1818-
_Xbad_alloc();
1819-
} else if (_Info->_Err == __std_tzdb_error::_Win_error) {
1820-
_XGetLastError();
1821-
} else if (_Info->_Err == __std_tzdb_error::_Icu_error) {
1822-
_Xruntime_error("Internal error loading IANA database information");
1823-
}
1837+
const auto _Info =
1838+
_Make_unique_tzdb_info<__std_tzdb_get_sys_info>(_Tz_arg.c_str(), _Tz_len, _Internal_dur.count());
18241839

18251840
constexpr auto _Min_internal =
18261841
_CHRONO duration_cast<_Internal_duration>(_Min_seconds.time_since_epoch()).count();
@@ -2012,9 +2027,14 @@ namespace chrono {
20122027

20132028
// [time.zone.link]
20142029

2030+
struct _Secret_time_zone_link_construct_tag {
2031+
explicit _Secret_time_zone_link_construct_tag() = default;
2032+
};
2033+
20152034
_EXPORT_STD class time_zone_link {
20162035
public:
2017-
explicit time_zone_link(string_view _Name_, string_view _Target_) : _Name(_Name_), _Target(_Target_) {}
2036+
explicit time_zone_link(_Secret_time_zone_link_construct_tag, string_view _Name_, string_view _Target_)
2037+
: _Name(_Name_), _Target(_Target_) {}
20182038

20192039
time_zone_link(time_zone_link&&) = default;
20202040
time_zone_link& operator=(time_zone_link&&) = default;
@@ -2046,17 +2066,9 @@ namespace chrono {
20462066
// [time.zone.db]
20472067

20482068
_NODISCARD inline string _Tzdb_generate_current_zone() {
2049-
unique_ptr<__std_tzdb_current_zone_info, _Tzdb_deleter<__std_tzdb_current_zone_info>> _Info{
2050-
__std_tzdb_get_current_zone()};
2051-
if (_Info == nullptr) {
2052-
_Xbad_alloc();
2053-
} else if (_Info->_Err == __std_tzdb_error::_Win_error) {
2054-
_XGetLastError();
2055-
} else if (_Info->_Err == __std_tzdb_error::_Icu_error) {
2056-
_Xruntime_error("Internal error loading IANA database information");
2057-
}
2069+
auto _Info = _Make_unique_tzdb_info<__std_tzdb_get_current_zone>();
20582070

2059-
return {_Info->_Tz_name};
2071+
return _Info->_Tz_name;
20602072
}
20612073

20622074
template <class _Ty>
@@ -2094,26 +2106,18 @@ namespace chrono {
20942106
}
20952107
};
20962108

2097-
_NODISCARD inline tuple<string, decltype(tzdb::zones), decltype(tzdb::links)> _Tzdb_generate_time_zones() {
2098-
unique_ptr<__std_tzdb_time_zones_info, _Tzdb_deleter<__std_tzdb_time_zones_info>> _Info{
2099-
__std_tzdb_get_time_zones()};
2100-
if (_Info == nullptr) {
2101-
_Xbad_alloc();
2102-
} else if (_Info->_Err == __std_tzdb_error::_Win_error) {
2103-
_XGetLastError();
2104-
} else if (_Info->_Err == __std_tzdb_error::_Icu_error) {
2105-
_Xruntime_error("Internal error loading IANA database information");
2106-
}
2109+
_NODISCARD inline tuple<string, vector<time_zone>, vector<time_zone_link>> _Tzdb_generate_time_zones() {
2110+
auto _Info = _Make_unique_tzdb_info<__std_tzdb_get_time_zones>();
21072111

2108-
decltype(tzdb::zones) _Time_zones;
2109-
decltype(tzdb::links) _Time_zone_links;
2112+
vector<time_zone> _Time_zones;
2113+
vector<time_zone_link> _Time_zone_links;
21102114
for (size_t _Idx = 0; _Idx < _Info->_Num_time_zones; ++_Idx) {
21112115
const string_view _Name{_Info->_Names[_Idx]};
21122116
if (_Info->_Links[_Idx] == nullptr) {
2113-
_Time_zones.emplace_back(_Name);
2117+
_Time_zones.emplace_back(_Secret_time_zone_construct_tag{}, _Name);
21142118
} else {
21152119
const string_view _Target{_Info->_Links[_Idx]};
2116-
_Time_zone_links.emplace_back(_Name, _Target);
2120+
_Time_zone_links.emplace_back(_Secret_time_zone_link_construct_tag{}, _Name, _Target);
21172121
}
21182122
}
21192123

@@ -2259,13 +2263,13 @@ namespace chrono {
22592263
vector<time_zone> _Zones;
22602264
_Zones.reserve(_Tzdb.zones.size());
22612265
for (const auto& _Tz : _Tzdb.zones) {
2262-
_Zones.emplace_back(_Tz.name());
2266+
_Zones.emplace_back(_Secret_time_zone_construct_tag{}, _Tz.name());
22632267
}
22642268

22652269
vector<time_zone_link> _Links;
22662270
_Links.reserve(_Tzdb.links.size());
22672271
for (const auto& _Link : _Tzdb.links) {
2268-
_Links.emplace_back(_Link.name(), _Link.target());
2272+
_Links.emplace_back(_Secret_time_zone_link_construct_tag{}, _Link.name(), _Link.target());
22692273
}
22702274

22712275
auto _Version = _Tzdb_update_version(_Tzdb.version, _Leap_sec.size());
@@ -3166,12 +3170,12 @@ namespace chrono {
31663170
}
31673171
}
31683172

3169-
if (!_Val.has_value()) {
3170-
_Val = _New;
3171-
return true;
3172-
} else {
3173-
return _STD exchange(_Val, _New) == _New;
3173+
if (_Val.has_value()) {
3174+
return _STD exchange(*_Val, _New) == _New;
31743175
}
3176+
3177+
_Val = _New;
3178+
return true;
31753179
}
31763180

31773181
_NODISCARD static pair<int, int> _Decompose_year(const int _Year) {
@@ -3581,7 +3585,6 @@ namespace chrono {
35813585

35823586
template <class _DurationType>
35833587
_NODISCARD bool _Make_time_point(_DurationType& _Dur, _Leap_second_rep _Leap) {
3584-
35853588
const bool _Consistent{_Calculate_hour24() && _Calculate_year_fields() && _Calculate_ymd()};
35863589
if (!_Consistent || !_Apply_duration_fields<_Parse_tp_or_duration::_Time_point>(_Dur)) {
35873590
return false;
@@ -3609,7 +3612,7 @@ namespace chrono {
36093612
return false;
36103613
} else {
36113614
// It's possible that the parsed time doesn't exist because (a) _Seconds == 60 and there *isn't* a
3612-
// leap second insertion or (b) _Seconds >= 59 and there *is* a leap second subtraction.
3615+
// leap second insertion or (b) _Seconds >= 59 and there *is* a leap second deletion.
36133616
const auto& _Tzdb{_CHRONO get_tzdb()};
36143617

36153618
const bool _Possible_insertion{_Second == 60};
@@ -3725,15 +3728,14 @@ namespace chrono {
37253728
}
37263729
}
37273730

3728-
template <class _InIt>
3729-
_NODISCARD _InIt _Parse_time_field(_InIt _First, ios_base& _Iosbase, ios_base::iostate& _State,
3730-
const char _Flag, const char _Modifier, const unsigned int _Width,
3731-
const unsigned int _Subsecond_precision) {
3732-
using _CharT = _InIt::value_type;
3731+
template <class _CharT, class _Traits>
3732+
_NODISCARD istreambuf_iterator<_CharT, _Traits> _Parse_time_field(istreambuf_iterator<_CharT, _Traits> _First,
3733+
ios_base& _Iosbase, ios_base::iostate& _State, const char _Flag, const char _Modifier,
3734+
const unsigned int _Width, const unsigned int _Subsecond_precision) {
37333735

37343736
const auto& _Ctype_fac = _STD use_facet<ctype<_CharT>>(_Iosbase.getloc());
37353737
const auto& _Time_fac = _STD use_facet<time_get<_CharT>>(_Iosbase.getloc());
3736-
constexpr _InIt _Last{};
3738+
constexpr istreambuf_iterator<_CharT, _Traits> _Last{};
37373739

37383740
int _Val{0};
37393741
switch (_Flag) {
@@ -4051,19 +4053,19 @@ namespace chrono {
40514053
return _First;
40524054
}
40534055

4054-
template <class _InIt>
4055-
_NODISCARD _InIt _Parse_time_field_restricted(_InIt _First, ios_base& _Iosbase, ios_base::iostate& _State,
4056+
template <class _CharT, class _Traits>
4057+
_NODISCARD istreambuf_iterator<_CharT, _Traits> _Parse_time_field_restricted(
4058+
istreambuf_iterator<_CharT, _Traits> _First, ios_base& _Iosbase, ios_base::iostate& _State,
40564059
const char* _Fmt, const unsigned int _Subsecond_precision = 0) {
4057-
using _Ctype = ctype<typename _InIt::value_type>;
40584060
// Parses a restricted format string. It generally doesn't handle anything parsed outside of
40594061
// _Parse_time_field:
40604062
// (a) any whitespace (' ', %n, %t)
40614063
// (b) %% literal (other literals are parsed, however)
40624064
// (c) E or O modifiers
40634065
// (d) width parameter
40644066
// It also assumes a valid format string, specifically that '%' is always followed by a flag.
4065-
const _Ctype& _Ctype_fac{_STD use_facet<_Ctype>(_Iosbase.getloc())};
4066-
constexpr _InIt _Last{};
4067+
const auto& _Ctype_fac{_STD use_facet<ctype<_CharT>>(_Iosbase.getloc())};
4068+
constexpr istreambuf_iterator<_CharT, _Traits> _Last{};
40674069

40684070
while (*_Fmt != '\0' && (_State & ~ios_base::eofbit) == ios_base::goodbit) {
40694071
if (_First == _Last) {
@@ -4079,11 +4081,10 @@ namespace chrono {
40794081
return _First;
40804082
}
40814083

4082-
template <class _InIt>
4083-
_NODISCARD ios_base::iostate _Get_fixed(_InIt& _First, unsigned int _Width,
4084-
const ctype<typename _InIt::value_type>& _Ctype_fac,
4085-
const numpunct<typename _InIt::value_type>& _Numpunct_fac) {
4086-
constexpr _InIt _Last{};
4084+
template <class _CharT, class _Traits>
4085+
_NODISCARD ios_base::iostate _Get_fixed(istreambuf_iterator<_CharT, _Traits>& _First, unsigned int _Width,
4086+
const ctype<_CharT>& _Ctype_fac, const numpunct<_CharT>& _Numpunct_fac) {
4087+
constexpr istreambuf_iterator<_CharT, _Traits> _Last{};
40874088

40884089
while (_First != _Last && _Ctype_fac.is(ctype_base::space, *_First) && _Width > 0) {
40894090
++_First;
@@ -4132,10 +4133,10 @@ namespace chrono {
41324133
return _State;
41334134
}
41344135

4135-
template <class _InIt>
4136-
_NODISCARD ios_base::iostate _Get_int(
4137-
_InIt& _First, unsigned int _Width, int& _Val, const ctype<typename _InIt::value_type>& _Ctype_fac) {
4138-
constexpr _InIt _Last{};
4136+
template <class _CharT, class _Traits>
4137+
_NODISCARD ios_base::iostate _Get_int(istreambuf_iterator<_CharT, _Traits>& _First, unsigned int _Width,
4138+
int& _Val, const ctype<_CharT>& _Ctype_fac) {
4139+
constexpr istreambuf_iterator<_CharT, _Traits> _Last{};
41394140

41404141
while (_First != _Last && _Ctype_fac.is(ctype_base::space, *_First) && _Width > 0) {
41414142
++_First;
@@ -4194,10 +4195,10 @@ namespace chrono {
41944195
return _State;
41954196
}
41964197

4197-
template <class _InIt>
4198-
_NODISCARD ios_base::iostate _Get_tz_offset(
4199-
_InIt& _First, const ctype<typename _InIt::value_type>& _Ctype_fac, const bool _Is_modified, int& _Offset) {
4200-
constexpr _InIt _Last{};
4198+
template <class _CharT, class _Traits>
4199+
_NODISCARD ios_base::iostate _Get_tz_offset(istreambuf_iterator<_CharT, _Traits>& _First,
4200+
const ctype<_CharT>& _Ctype_fac, const bool _Is_modified, int& _Offset) {
4201+
constexpr istreambuf_iterator<_CharT, _Traits> _Last{};
42014202
if (_First == _Last) {
42024203
return ios_base::eofbit;
42034204
}
@@ -4267,10 +4268,10 @@ namespace chrono {
42674268
return ios_base::goodbit;
42684269
}
42694270

4270-
template <class _InIt>
4271+
template <class _CharT, class _Traits>
42714272
_NODISCARD ios_base::iostate _Get_tz_name(
4272-
_InIt& _First, const ctype<typename _InIt::value_type>& _Ctype_fac, string& _Tz_name) {
4273-
constexpr _InIt _Last{};
4273+
istreambuf_iterator<_CharT, _Traits>& _First, const ctype<_CharT>& _Ctype_fac, string& _Tz_name) {
4274+
constexpr istreambuf_iterator<_CharT, _Traits> _Last{};
42744275
_Tz_name.clear();
42754276
while (_First != _Last) {
42764277
const char _Ch{_Ctype_fac.narrow(*_First)};
@@ -4388,7 +4389,7 @@ namespace chrono {
43884389
}
43894390
}
43904391

4391-
_CATCH_IO_(_Myis, _Istr)
4392+
_CATCH_IO_(ios_base, _Istr)
43924393
}
43934394

43944395
if (!_Is_complete()) {
@@ -4786,7 +4787,6 @@ public:
47864787
}
47874788

47884789
constexpr void _On_conversion_spec(char _Modifier, _CharT _Type) {
4789-
// NOTE: same performance note from _Basic_format_specs also applies here
47904790
if (_Modifier != '\0' && _Modifier != 'E' && _Modifier != 'O') {
47914791
_Throw_format_error("Invalid modifier specification.");
47924792
}
@@ -4880,6 +4880,8 @@ _NODISCARD constexpr const _CharT* _Parse_chrono_format_specs(
48804880

48814881
// chrono-spec
48824882
while (_Begin != _End && *_Begin != '}') {
4883+
// Note that in this loop, ++_Begin is safe (and we don't need _Fmt_codec)
4884+
// because '%' isn't used as a non-lead-byte in any supported multibyte encoding.
48834885
if (*_Begin == '%') { // conversion-spec
48844886
if (++_Begin == _End) {
48854887
_Throw_format_error("Invalid format string - missing type after %");
@@ -5524,9 +5526,9 @@ namespace chrono {
55245526
_CharT _Fmt_str[4];
55255527
_Os << _STD put_time(&_Time, _Fmt_string({._Type = _Gregorian_type}, _Fmt_str));
55265528
return true;
5529+
} else {
5530+
return false;
55275531
}
5528-
5529-
return false;
55305532
case 'r':
55315533
// put_time uses _Strftime in order to bypass reference-counting that locale uses. This function
55325534
// takes the locale information by pointer, but the pointer (from _Gettnames) returns a copy.
@@ -5544,16 +5546,21 @@ namespace chrono {
55445546
if constexpr (_Is_specialization_v<_Ty, duration>) {
55455547
_Os << _STD abs(_Duration_cast_underflow_to_zero<days>(_Val).count());
55465548
return true;
5549+
} else {
5550+
return false;
55475551
}
5548-
return false;
55495552
case 'q':
55505553
if constexpr (_Is_specialization_v<_Ty, duration>) {
55515554
_Write_unit_suffix<typename _Ty::period>(_Os);
5555+
} else {
5556+
_STL_INTERNAL_CHECK(false);
55525557
}
55535558
return true;
55545559
case 'Q':
55555560
if constexpr (_Is_specialization_v<_Ty, duration>) {
55565561
_Os << _STD abs(_Val.count());
5562+
} else {
5563+
_STL_INTERNAL_CHECK(false);
55575564
}
55585565
return true;
55595566
case 'm': // Print months as a decimal, even if invalid.
@@ -5715,7 +5722,7 @@ namespace chrono {
57155722
case 'Y':
57165723
if constexpr (is_same_v<_Ty, year>) {
57175724
return _Val.ok();
5718-
} else if constexpr (_Is_any_of_v<_Ty, year_month> || _Is_ymd) {
5725+
} else if constexpr (is_same_v<_Ty, year_month> || _Is_ymd) {
57195726
return _Val.year().ok();
57205727
}
57215728
break;

stl/inc/yvals.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,8 @@ class _CRTIMP2_PURE_IMPORT _EmptyLockit { // empty lock class used for bin compa
451451
catch (...) {
452452
#define _CATCH_END }
453453

454-
#define _RERAISE throw
455-
#define _THROW(x) throw x
454+
#define _RERAISE throw
455+
#define _THROW(...) throw __VA_ARGS__
456456

457457
#else // ^^^ _HAS_EXCEPTIONS / !_HAS_EXCEPTIONS vvv
458458
#define _TRY_BEGIN \
@@ -475,7 +475,7 @@ class _CRTIMP2_PURE_IMPORT _EmptyLockit { // empty lock class used for bin compa
475475
#endif
476476

477477
#define _RERAISE
478-
#define _THROW(x) x._Raise()
478+
#define _THROW(...) __VA_ARGS__._Raise()
479479
#endif // ^^^ !_HAS_EXCEPTIONS ^^^
480480
_STD_END
481481

0 commit comments

Comments
 (0)