-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Loading time_zone and time_zone_link names
#1723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4809b72
98312d8
cf0df74
d89b26f
8a01d01
20b141f
e2b4163
90e692a
d123f58
812abb7
9086249
d246223
b6b0455
9068de9
1eb6fa0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2215,6 +2215,34 @@ namespace chrono { | |
| return hours{_Ret}; | ||
| } | ||
|
|
||
| // [time.zone.timezone] | ||
|
|
||
| // CLASS time_zone | ||
| class time_zone { | ||
| public: | ||
| explicit time_zone(string_view _Name_) : _Name(_Name_) {} | ||
|
|
||
| time_zone(time_zone&&) = default; | ||
| time_zone& operator=(time_zone&&) = default; | ||
|
|
||
| _NODISCARD string_view name() const noexcept { | ||
| return _Name; | ||
| } | ||
|
|
||
| private: | ||
| string _Name; | ||
| }; | ||
|
|
||
| _NODISCARD inline bool operator==(const time_zone& _Left, const time_zone& _Right) noexcept { | ||
| return _Left.name() == _Right.name(); | ||
| } | ||
|
|
||
| #ifdef __cpp_lib_concepts | ||
| _NODISCARD inline strong_ordering operator<=>(const time_zone& _Left, const time_zone& _Right) noexcept { | ||
| return _Left.name() <=> _Right.name(); | ||
| } | ||
| #endif // __cpp_lib_concepts | ||
|
|
||
| // [time.zone.leap] | ||
|
|
||
| // CLASS leap_second | ||
|
|
@@ -2309,15 +2337,116 @@ namespace chrono { | |
| } | ||
| #endif // __cpp_lib_concepts | ||
|
|
||
| // [time.zone.link] | ||
|
|
||
| // CLASS time_zone_link | ||
| class time_zone_link { | ||
| public: | ||
| explicit time_zone_link(string_view _Name_, string_view _Target_) : _Name(_Name_), _Target(_Target_) {} | ||
|
|
||
| time_zone_link(time_zone_link&&) = default; | ||
| time_zone_link& operator=(time_zone_link&&) = default; | ||
|
|
||
| _NODISCARD string_view name() const noexcept { | ||
| return _Name; | ||
| } | ||
|
|
||
| _NODISCARD string_view target() const noexcept { | ||
| return _Target; | ||
| } | ||
|
|
||
| private: | ||
| string _Name; | ||
| string _Target; | ||
| }; | ||
|
|
||
| _NODISCARD inline bool operator==(const time_zone_link& _Left, const time_zone_link& _Right) noexcept { | ||
| return _Left.name() == _Right.name(); | ||
| } | ||
|
|
||
| #ifdef __cpp_lib_concepts | ||
| _NODISCARD inline strong_ordering operator<=>(const time_zone_link& _Left, const time_zone_link& _Right) noexcept { | ||
| return _Left.name() <=> _Right.name(); | ||
| } | ||
| #endif // __cpp_lib_concepts | ||
|
|
||
| // [time.zone.db] | ||
|
|
||
| // TRANSITION: work in progress | ||
| // STRUCT tzdb | ||
| _NODISCARD inline string _Xtzdb_generate_current_zone() { | ||
| unique_ptr<__std_tzdb_current_zone_info, decltype(&__std_tzdb_delete_current_zone)> _Info{ | ||
| __std_tzdb_get_current_zone(), &__std_tzdb_delete_current_zone}; | ||
| if (_Info == nullptr) { | ||
| _Xbad_alloc(); | ||
| } else if (_Info->_Err == __std_tzdb_error::_Win_error) { | ||
| _XGetLastError(); | ||
| } else if (_Info->_Err == __std_tzdb_error::_Icu_error) { | ||
| _Xruntime_error("Internal error loading IANA database information"); | ||
| } | ||
|
|
||
| return {_Info->_Tz_name}; | ||
| } | ||
|
|
||
| template <class _Ty> | ||
| _NODISCARD const _Ty* _Locate_zone_impl(const vector<_Ty>& _Vec, string_view _Name) { | ||
| const auto _Result = _STD find_if(_Vec.begin(), _Vec.end(), [&](auto& _Tz) { return _Tz.name() == _Name; }); | ||
| return _Result == _Vec.end() ? nullptr : &*_Result; | ||
| } | ||
|
|
||
| // STRUCT tzdb | ||
| struct tzdb { | ||
d-winsor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| vector<leap_second, _Crt_allocator<leap_second>> leap_seconds; | ||
| string version; | ||
| vector<time_zone> zones; | ||
| vector<time_zone_link> links; | ||
| vector<leap_second> leap_seconds; | ||
| bool _All_ls_positive; | ||
|
|
||
| _NODISCARD const time_zone* locate_zone(string_view _Tz_name) const { | ||
| auto _Tz = _Locate_zone_impl(zones, _Tz_name); | ||
| if (_Tz == nullptr) { | ||
| const auto _Link = _Locate_zone_impl(links, _Tz_name); | ||
| if (_Link != nullptr) { | ||
| _Tz = _Locate_zone_impl(zones, _Link->target()); | ||
| } | ||
| } | ||
|
|
||
| if (_Tz == nullptr) { | ||
| _Xruntime_error("unable to locate time_zone with given name"); | ||
| } | ||
|
|
||
| return _Tz; | ||
| } | ||
|
|
||
| _NODISCARD const time_zone* current_zone() const { | ||
| return locate_zone(_Xtzdb_generate_current_zone()); | ||
| } | ||
| }; | ||
|
|
||
| _NODISCARD inline tuple<string, decltype(tzdb::zones), decltype(tzdb::links)> _Xtzdb_generate_time_zones() { | ||
| unique_ptr<__std_tzdb_time_zones_info, decltype(&__std_tzdb_delete_time_zones)> _Info{ | ||
| __std_tzdb_get_time_zones(), &__std_tzdb_delete_time_zones}; | ||
| if (_Info == nullptr) { | ||
| _Xbad_alloc(); | ||
| } else if (_Info->_Err == __std_tzdb_error::_Win_error) { | ||
| _XGetLastError(); | ||
| } else if (_Info->_Err == __std_tzdb_error::_Icu_error) { | ||
| _Xruntime_error("Internal error loading IANA database information"); | ||
| } | ||
|
|
||
| decltype(tzdb::zones) _Time_zones; | ||
| decltype(tzdb::links) _Time_zone_links; | ||
| for (size_t _Idx = 0; _Idx < _Info->_Num_time_zones; ++_Idx) { | ||
| const string_view _Name{_Info->_Names[_Idx]}; | ||
| if (_Info->_Links[_Idx] == nullptr) { | ||
| _Time_zones.emplace_back(_Name); | ||
| } else { | ||
| const string_view _Target{_Info->_Links[_Idx]}; | ||
| _Time_zone_links.emplace_back(_Name, _Target); | ||
| } | ||
| } | ||
|
|
||
| return {_Info->_Version, _STD move(_Time_zones), _STD move(_Time_zone_links)}; | ||
| } | ||
|
|
||
| _NODISCARD inline pair<decltype(tzdb::leap_seconds), bool> _Xtzdb_generate_leap_seconds( | ||
| const size_t _Current_size) { | ||
| // Returns empty vector if no new leap seconds are found. | ||
|
|
@@ -2391,7 +2520,7 @@ namespace chrono { | |
| } | ||
| } | ||
|
|
||
| return {_Leap_sec_info, _All_ls_positive}; | ||
| return {_STD move(_Leap_sec_info), _All_ls_positive}; | ||
| } | ||
|
|
||
| // TRANSITION: work in progress | ||
|
|
@@ -2407,8 +2536,10 @@ namespace chrono { | |
| tzdb_list& operator=(const tzdb_list&) = delete; | ||
|
|
||
| tzdb_list() { | ||
| auto [_Version, _Zones, _Links] = _Xtzdb_generate_time_zones(); | ||
| auto [_Leap_sec, _All_ls_positive] = _Xtzdb_generate_leap_seconds(0); | ||
| _Tzdb_list.emplace_front(tzdb{_STD move(_Leap_sec), _All_ls_positive}); | ||
| _Tzdb_list.emplace_front(tzdb{ | ||
| _STD move(_Version), _STD move(_Zones), _STD move(_Links), _STD move(_Leap_sec), _All_ls_positive}); | ||
| } | ||
|
|
||
| _NODISCARD const tzdb& front() const noexcept { | ||
|
|
@@ -2426,7 +2557,17 @@ namespace chrono { | |
| _Unique_lock _Lk(_Tzdb_mutex); | ||
| auto [_Leap_sec, _All_ls_positive] = _Xtzdb_generate_leap_seconds(_Tzdb_list.front().leap_seconds.size()); | ||
| if (!_Leap_sec.empty()) { | ||
| _Tzdb_list.emplace_front(tzdb{_STD move(_Leap_sec), _All_ls_positive}); | ||
| const auto& _Tzdb = _Tzdb_list.front(); | ||
| vector<time_zone> _Zones; | ||
| _STD transform(_Tzdb.zones.begin(), _Tzdb.zones.end(), _STD back_inserter(_Zones), | ||
| [](const auto& _Tz) { return time_zone{_Tz.name()}; }); | ||
| vector<time_zone_link> _Links; | ||
| _STD transform( | ||
| _Tzdb.links.begin(), _Tzdb.links.end(), _STD back_inserter(_Links), [](const auto& _Link) { | ||
| return time_zone_link{_Link.name(), _Link.target()}; | ||
| }); | ||
| _Tzdb_list.emplace_front( | ||
| tzdb{_Tzdb.version, _STD move(_Zones), _STD move(_Links), _STD move(_Leap_sec), _All_ls_positive}); | ||
|
Comment on lines
+2569
to
+2570
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this is the case when we are actually updating information in the I don't want this to hold up this PR because there is other work built on top of this, so I'm also fine with filing a card in the chrono project to revisit this in a follow-up PR.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sounds good to me, lets revisit this |
||
| } | ||
| return _Tzdb_list.front(); | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.