From f4ae0d9b7cf9419bb020ebd7edfe6ef8e1dd34ff Mon Sep 17 00:00:00 2001 From: Daniel Winsor Date: Mon, 22 Mar 2021 12:43:09 -0700 Subject: [PATCH 1/5] Version and tzdb_list changes. --- stl/inc/chrono | 53 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/stl/inc/chrono b/stl/inc/chrono index 3d13b2b8620..cf1e6d311be 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -2700,6 +2700,15 @@ namespace chrono { return {_STD move(_Leap_sec_info), _All_ls_positive}; } + _NODISCARD inline string _Xtzdb_update_version(const string_view _Version, const size_t _Num_leap_seconds) { + const auto _Icu_end = _Version.find_last_of('.'); + const auto _Icu_version = _Icu_end == decltype(_Version)::npos + ? string{_Version} + : string{_Version.begin(), + _Version.begin() + static_cast(_Icu_end)}; + return _Icu_version + "." + _STD to_string(_Num_leap_seconds); + } + // TRANSITION: work in progress // CLASS tzdb_list class tzdb_list { @@ -2713,8 +2722,9 @@ 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); + auto [_Icu_version, _Zones, _Links] = _Xtzdb_generate_time_zones(); + auto [_Leap_sec, _All_ls_positive] = _Xtzdb_generate_leap_seconds(0); + auto _Version = _Icu_version + "." + _STD to_string(_Leap_sec.size()); _Tzdb_list.emplace_front(tzdb{ _STD move(_Version), _STD move(_Zones), _STD move(_Links), _STD move(_Leap_sec), _All_ls_positive}); } @@ -2724,6 +2734,26 @@ namespace chrono { return _Tzdb_list.front(); } + _NODISCARD const_iterator erase_after(const_iterator _Where) noexcept { + return _Tzdb_list.erase_after(_Where); + } + + _NODISCARD const_iterator begin() const noexcept { + return _Tzdb_list.begin(); + } + + _NODISCARD const_iterator end() const noexcept { + return _Tzdb_list.end(); + } + + _NODISCARD const_iterator cbegin() const noexcept { + return _Tzdb_list.cbegin(); + } + + _NODISCARD const_iterator cend() const noexcept { + return _Tzdb_list.cend(); + } + template void _Emplace_front(_ArgsTy&&... _Args) { _Unique_lock _Lk(_Tzdb_mutex); @@ -2743,6 +2773,7 @@ namespace chrono { _Tzdb.links.begin(), _Tzdb.links.end(), _STD back_inserter(_Links), [](const auto& _Link) { return time_zone_link{_Link.name(), _Link.target()}; }); + const auto _Version = _Xtzdb_update_version(_Tzdb.version, _Leap_sec.size()); _Tzdb_list.emplace_front( tzdb{_Tzdb.version, _STD move(_Zones), _STD move(_Links), _STD move(_Leap_sec), _All_ls_positive}); } @@ -2827,8 +2858,18 @@ namespace chrono { return _CHRONO get_tzdb_list().front(); } + // FUNCTION locate_zone + _NODISCARD inline const time_zone* locate_zone(string_view _Tz_name) { + return _CHRONO get_tzdb().locate_zone(_Tz_name); + } + + // FUNCTION current_zone + _NODISCARD inline const time_zone* current_zone() { + return _CHRONO get_tzdb().current_zone(); + } + // FUNCTION reload_tzdb - inline const tzdb& reload_tzdb() { + _NODISCARD inline const tzdb& reload_tzdb() { try { return _CHRONO get_tzdb_list()._Reload(); } catch (const exception& _Except) { @@ -2836,6 +2877,12 @@ namespace chrono { } } + _NODISCARD inline string remote_version() { + const auto& _Version = get_tzdb().version; + const auto [_Leap_sec, _Ignore] = _Xtzdb_generate_leap_seconds(get_tzdb().leap_seconds.size()); + return _Leap_sec.empty() ? string{_Version} : _Xtzdb_update_version(_Version, _Leap_sec.size()); + } + // [time.zone.zonedtraits] // STRUCT TEMPLATE zoned_traits From 4c2e0b3519bb9bf48d8a57ef1abc65f9e2ea9c50 Mon Sep 17 00:00:00 2001 From: Daniel Winsor Date: Mon, 22 Mar 2021 12:51:53 -0700 Subject: [PATCH 2/5] More efficient deleters --- stl/inc/chrono | 18 ++++++++---------- stl/inc/xtzdb.h | 34 +++++++++++++++++++++++++++++++++- stl/src/tzdb.cpp | 39 ++++++++++++++++++++++++++------------- 3 files changed, 67 insertions(+), 24 deletions(-) diff --git a/stl/inc/chrono b/stl/inc/chrono index cf1e6d311be..0972d472d6f 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -2377,9 +2377,8 @@ namespace chrono { _NODISCARD sys_info _Get_info(const _Duration& _Dur) const { using _Internal_duration = duration<__std_tzdb_epoch_milli, milli>; const auto _Internal_dur = _CHRONO duration_cast<_Internal_duration>(_Dur); - const unique_ptr<__std_tzdb_sys_info, decltype(&__std_tzdb_delete_sys_info)> _Info{ - __std_tzdb_get_sys_info(_Name.c_str(), _Name.length(), _Internal_dur.count()), - &__std_tzdb_delete_sys_info}; + const unique_ptr<__std_tzdb_sys_info, _Tzdb_deleter<__std_tzdb_sys_info>> _Info{ + __std_tzdb_get_sys_info(_Name.c_str(), _Name.length(), _Internal_dur.count())}; if (_Info == nullptr) { _Xbad_alloc(); } else if (_Info->_Err == __std_tzdb_error::_Win_error) { @@ -2550,8 +2549,8 @@ namespace chrono { // [time.zone.db] _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}; + unique_ptr<__std_tzdb_current_zone_info, _Tzdb_deleter<__std_tzdb_current_zone_info>> _Info{ + __std_tzdb_get_current_zone()}; if (_Info == nullptr) { _Xbad_alloc(); } else if (_Info->_Err == __std_tzdb_error::_Win_error) { @@ -2599,8 +2598,8 @@ namespace chrono { }; _NODISCARD inline tuple _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}; + unique_ptr<__std_tzdb_time_zones_info, _Tzdb_deleter<__std_tzdb_time_zones_info>> _Info{ + __std_tzdb_get_time_zones()}; if (_Info == nullptr) { _Xbad_alloc(); } else if (_Info->_Err == __std_tzdb_error::_Win_error) { @@ -2666,9 +2665,8 @@ namespace chrono { (_STD max)(_Current_size, _STD size(_Known_leap_seconds)) - _Pre_2018_count; size_t _Reg_post_2018_ls_size; // number of post-2018 LSs found in the registry - unique_ptr<__std_tzdb_registry_leap_info[], decltype(&__std_tzdb_delete_reg_leap_seconds)> _Reg_ls_data{ - __std_tzdb_get_reg_leap_seconds(_Known_post_2018_ls_size, &_Reg_post_2018_ls_size), - &__std_tzdb_delete_reg_leap_seconds}; + unique_ptr<__std_tzdb_registry_leap_info[], _Tzdb_deleter<__std_tzdb_registry_leap_info[]>> _Reg_ls_data{ + __std_tzdb_get_reg_leap_seconds(_Known_post_2018_ls_size, &_Reg_post_2018_ls_size)}; if (_Reg_post_2018_ls_size > _Known_post_2018_ls_size && !_Reg_ls_data) { _Xbad_alloc(); // registry has new data, but failed to allocate storage diff --git a/stl/inc/xtzdb.h b/stl/inc/xtzdb.h index a0f1ffb4d8e..63291db3ce5 100644 --- a/stl/inc/xtzdb.h +++ b/stl/inc/xtzdb.h @@ -78,7 +78,6 @@ void __stdcall __std_tzdb_delete_sys_info(__std_tzdb_sys_info* _Info) noexcept; __std_tzdb_registry_leap_info* __stdcall __std_tzdb_get_reg_leap_seconds( size_t _Prev_reg_ls_size, size_t* _Current_reg_ls_size) noexcept; - void __stdcall __std_tzdb_delete_reg_leap_seconds(__std_tzdb_registry_leap_info* _Rlsi) noexcept; _NODISCARD void* __stdcall __std_calloc_crt(size_t _Count, size_t _Size) noexcept; @@ -86,6 +85,39 @@ void __stdcall __std_free_crt(void* _Ptr) noexcept; _END_EXTERN_C +template +struct _Tzdb_deleter { + void operator()(_Ty*) const noexcept {} +}; + +template <> +struct _Tzdb_deleter<__std_tzdb_time_zones_info> { + void operator()(__std_tzdb_time_zones_info* _Info) const noexcept { + __std_tzdb_delete_time_zones(_Info); + } +}; + +template <> +struct _Tzdb_deleter<__std_tzdb_current_zone_info> { + void operator()(__std_tzdb_current_zone_info* _Info) const noexcept { + __std_tzdb_delete_current_zone(_Info); + } +}; + +template <> +struct _Tzdb_deleter<__std_tzdb_sys_info> { + void operator()(__std_tzdb_sys_info* _Info) const noexcept { + __std_tzdb_delete_sys_info(_Info); + } +}; + +template <> +struct _Tzdb_deleter<__std_tzdb_registry_leap_info[]> { + void operator()(__std_tzdb_registry_leap_info* _Info) const noexcept { + __std_tzdb_delete_reg_leap_seconds(_Info); + } +}; + _STD_BEGIN template diff --git a/stl/src/tzdb.cpp b/stl/src/tzdb.cpp index 0e13a44636c..9cf15b2fa39 100644 --- a/stl/src/tzdb.cpp +++ b/stl/src/tzdb.cpp @@ -182,6 +182,20 @@ namespace { return _Fun(en, resultLength, status); } + template <> + struct _Tzdb_deleter { + void operator()(UEnumeration* _En) const noexcept { + __icu_uenum_close(_En); + } + }; + + template <> + struct _Tzdb_deleter { + void operator()(UCalendar* _Cal) const noexcept { + __icu_ucal_close(_Cal); + } + }; + _NODISCARD const char* _Allocate_wide_to_narrow( const char16_t* const _Input, const int _Input_len, __std_tzdb_error& _Err) noexcept { const auto _Code_page = __std_fs_code_page(); @@ -293,16 +307,16 @@ namespace { return _Get_icu_string_impl(_Icu_fn, 12, _Result_len, _Err); } - _NODISCARD _STD unique_ptr _Get_cal( + _NODISCARD _STD unique_ptr> _Get_cal( const char* _Tz, const size_t _Tz_len, __std_tzdb_error& _Err) noexcept { const auto _Tz_name = _Allocate_narrow_to_wide(_Tz, static_cast(_Tz_len), _Err); if (_Tz_name == nullptr) { - return {nullptr, &__icu_ucal_close}; + return nullptr; } UErrorCode _UErr{U_ZERO_ERROR}; - _STD unique_ptr _Cal{ - __icu_ucal_open(_Tz_name.get(), -1, nullptr, UCalendarType::UCAL_DEFAULT, &_UErr), &__icu_ucal_close}; + _STD unique_ptr> _Cal{ + __icu_ucal_open(_Tz_name.get(), -1, nullptr, UCalendarType::UCAL_DEFAULT, &_UErr)}; if (U_FAILURE(_UErr)) { _Err = __std_tzdb_error::_Icu_error; } @@ -330,8 +344,8 @@ _NODISCARD __std_tzdb_time_zones_info* __stdcall __std_tzdb_get_time_zones() noe // _Info == nullptr --> bad_alloc // _Info->_Err == _Win_error --> failed, call GetLastError() // _Info->_Err == _Icu_error --> runtime_error interacting with ICU - _STD unique_ptr<__std_tzdb_time_zones_info, decltype(&__std_tzdb_delete_time_zones)> _Info{ - new (_STD nothrow) __std_tzdb_time_zones_info{}, &__std_tzdb_delete_time_zones}; + _STD unique_ptr<__std_tzdb_time_zones_info, _Tzdb_deleter<__std_tzdb_time_zones_info>> _Info{ + new (_STD nothrow) __std_tzdb_time_zones_info{}}; if (_Info == nullptr) { return nullptr; } @@ -346,9 +360,8 @@ _NODISCARD __std_tzdb_time_zones_info* __stdcall __std_tzdb_get_time_zones() noe return _Report_error(_Info, __std_tzdb_error::_Icu_error); } - _STD unique_ptr _Enum{ - __icu_ucal_openTimeZoneIDEnumeration(USystemTimeZoneType::UCAL_ZONE_TYPE_ANY, nullptr, nullptr, &_UErr), - &__icu_uenum_close}; + _STD unique_ptr> _Enum{ + __icu_ucal_openTimeZoneIDEnumeration(USystemTimeZoneType::UCAL_ZONE_TYPE_ANY, nullptr, nullptr, &_UErr)}; if (U_FAILURE(_UErr)) { return _Report_error(_Info, __std_tzdb_error::_Icu_error); } @@ -429,8 +442,8 @@ _NODISCARD __std_tzdb_current_zone_info* __stdcall __std_tzdb_get_current_zone() // _Info == nullptr --> bad_alloc // _Info->_Err == _Win_error --> failed, call GetLastError() // _Info->_Err == _Icu_error --> runtime_error interacting with ICU - _STD unique_ptr<__std_tzdb_current_zone_info, decltype(&__std_tzdb_delete_current_zone)> _Info{ - new (_STD nothrow) __std_tzdb_current_zone_info{}, &__std_tzdb_delete_current_zone}; + _STD unique_ptr<__std_tzdb_current_zone_info, _Tzdb_deleter<__std_tzdb_current_zone_info>> _Info{ + new (_STD nothrow) __std_tzdb_current_zone_info{}}; if (_Info == nullptr) { return nullptr; } @@ -466,8 +479,8 @@ _NODISCARD __std_tzdb_sys_info* __stdcall __std_tzdb_get_sys_info( // _Info == nullptr --> bad_alloc // _Info->_Err == _Win_error --> failed, call GetLastError() // _Info->_Err == _Icu_error --> runtime_error interacting with ICU - _STD unique_ptr<__std_tzdb_sys_info, decltype(&__std_tzdb_delete_sys_info)> _Info{ - new (_STD nothrow) __std_tzdb_sys_info{}, &__std_tzdb_delete_sys_info}; + _STD unique_ptr<__std_tzdb_sys_info, _Tzdb_deleter<__std_tzdb_sys_info>> _Info{ + new (_STD nothrow) __std_tzdb_sys_info{}}; if (_Info == nullptr) { return nullptr; } From 6bc1bd188a6d57edd54dbf8034565e9a8a1dafa1 Mon Sep 17 00:00:00 2001 From: Daniel Winsor Date: Mon, 22 Mar 2021 13:20:40 -0700 Subject: [PATCH 3/5] Added tests --- .../test.cpp | 47 +++++++++++++++++-- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_time_zones/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_time_zones/test.cpp index f6423830a00..1b517a54a48 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_time_zones/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_time_zones/test.cpp @@ -55,17 +55,52 @@ void try_locate_invalid_zone(const tzdb& my_tzdb, string_view name) { } } -void timezone_names_test() { - const auto& my_tzdb = get_tzdb(); +void timezone_tzdb_list_test() { + const auto& my_tzdb_list = get_tzdb_list(); + + // only one entry in the list unless leap seconds were to change + assert(&my_tzdb_list.front() == &get_tzdb()); + assert(&my_tzdb_list.front() == &reload_tzdb()); + assert(++my_tzdb_list.begin() == my_tzdb_list.end()); + assert(++my_tzdb_list.cbegin() == my_tzdb_list.cend()); +} +void timezone_version_test() { + const auto& my_tzdb = get_tzdb(); assert(my_tzdb.version.empty() == false); + // version should end in .X where X == number leap seconds + const auto pos = my_tzdb.version.find_last_of('.'); + assert(pos != decltype(my_tzdb.version)::npos); + const string leap_seconds{my_tzdb.version, pos + 1}; + assert(leap_seconds.empty() == false); + assert(leap_seconds == std::to_string(my_tzdb.leap_seconds.size())); + + // remote version will only differ if leap seconds info changes, will not occur in tests + const auto& reloaded_tzdb = reload_tzdb(); + assert(reloaded_tzdb.version.empty() == false); + assert(&reloaded_tzdb == &my_tzdb); + + const auto& remote_ver = remote_version(); + assert(remote_ver.empty() == false); + assert(remote_ver == my_tzdb.version); +} + +void timezone_names_test() { + const auto& my_tzdb = get_tzdb(); + test_time_zone_and_link(my_tzdb, "Asia/Thimphu", "Asia/Thimbu"); test_time_zone_and_link(my_tzdb, "America/Tijuana", "America/Ensenada"); - const auto current_zone = my_tzdb.current_zone(); - assert(current_zone != nullptr); - assert(current_zone->name().empty() == false); + const auto curr_zone = current_zone(); + assert(curr_zone != nullptr); + assert(curr_zone->name().empty() == false); + assert(curr_zone == my_tzdb.current_zone()); + + const auto located_zone = locate_zone("UTC"); + assert(located_zone != nullptr); + assert(located_zone->name() == "Etc/UTC"); + assert(located_zone == my_tzdb.locate_zone("UTC")); try_locate_invalid_zone(my_tzdb, "Non/Existent"); @@ -371,6 +406,8 @@ void timezone_precision_test() { bool test() { try { + timezone_tzdb_list_test(); + timezone_version_test(); timezone_names_test(); timezone_sys_info_test(); timezone_to_local_test(); From c6fd8c80565fe7a67f004ebff2d40cb6162a93a4 Mon Sep 17 00:00:00 2001 From: Daniel Winsor Date: Mon, 22 Mar 2021 13:36:58 -0700 Subject: [PATCH 4/5] Shouty comment --- stl/inc/chrono | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stl/inc/chrono b/stl/inc/chrono index 0972d472d6f..977e144c15f 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -2867,7 +2867,7 @@ namespace chrono { } // FUNCTION reload_tzdb - _NODISCARD inline const tzdb& reload_tzdb() { + inline const tzdb& reload_tzdb() { try { return _CHRONO get_tzdb_list()._Reload(); } catch (const exception& _Except) { @@ -2875,10 +2875,11 @@ namespace chrono { } } + // FUNCTION remote_version _NODISCARD inline string remote_version() { const auto& _Version = get_tzdb().version; const auto [_Leap_sec, _Ignore] = _Xtzdb_generate_leap_seconds(get_tzdb().leap_seconds.size()); - return _Leap_sec.empty() ? string{_Version} : _Xtzdb_update_version(_Version, _Leap_sec.size()); + return _Leap_sec.empty() ? _Version : _Xtzdb_update_version(_Version, _Leap_sec.size()); } // [time.zone.zonedtraits] From ed0e19ed56fbfb82f0ad964108537cde1e311756 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 22 Mar 2021 19:00:09 -0700 Subject: [PATCH 5/5] Code review feedback. --- stl/inc/chrono | 21 ++++++++----------- stl/inc/xtzdb.h | 8 +++---- stl/src/tzdb.cpp | 18 +++++++--------- .../test.cpp | 5 +++-- 4 files changed, 23 insertions(+), 29 deletions(-) diff --git a/stl/inc/chrono b/stl/inc/chrono index 977e144c15f..02af136b01e 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -2699,12 +2699,8 @@ namespace chrono { } _NODISCARD inline string _Xtzdb_update_version(const string_view _Version, const size_t _Num_leap_seconds) { - const auto _Icu_end = _Version.find_last_of('.'); - const auto _Icu_version = _Icu_end == decltype(_Version)::npos - ? string{_Version} - : string{_Version.begin(), - _Version.begin() + static_cast(_Icu_end)}; - return _Icu_version + "." + _STD to_string(_Num_leap_seconds); + string _Icu_version{_Version.substr(0, _Version.find_last_of('.'))}; + return _STD move(_Icu_version) + "." + _STD to_string(_Num_leap_seconds); } // TRANSITION: work in progress @@ -2732,7 +2728,7 @@ namespace chrono { return _Tzdb_list.front(); } - _NODISCARD const_iterator erase_after(const_iterator _Where) noexcept { + const_iterator erase_after(const_iterator _Where) noexcept /* strengthened */ { return _Tzdb_list.erase_after(_Where); } @@ -2771,9 +2767,9 @@ namespace chrono { _Tzdb.links.begin(), _Tzdb.links.end(), _STD back_inserter(_Links), [](const auto& _Link) { return time_zone_link{_Link.name(), _Link.target()}; }); - const auto _Version = _Xtzdb_update_version(_Tzdb.version, _Leap_sec.size()); - _Tzdb_list.emplace_front( - tzdb{_Tzdb.version, _STD move(_Zones), _STD move(_Links), _STD move(_Leap_sec), _All_ls_positive}); + auto _Version = _Xtzdb_update_version(_Tzdb.version, _Leap_sec.size()); + _Tzdb_list.emplace_front(tzdb{ + _STD move(_Version), _STD move(_Zones), _STD move(_Links), _STD move(_Leap_sec), _All_ls_positive}); } return _Tzdb_list.front(); } @@ -2877,8 +2873,9 @@ namespace chrono { // FUNCTION remote_version _NODISCARD inline string remote_version() { - const auto& _Version = get_tzdb().version; - const auto [_Leap_sec, _Ignore] = _Xtzdb_generate_leap_seconds(get_tzdb().leap_seconds.size()); + const auto& _Tzdb = _CHRONO get_tzdb(); + const auto& _Version = _Tzdb.version; + const auto [_Leap_sec, _Ignored] = _Xtzdb_generate_leap_seconds(_Tzdb.leap_seconds.size()); return _Leap_sec.empty() ? _Version : _Xtzdb_update_version(_Version, _Leap_sec.size()); } diff --git a/stl/inc/xtzdb.h b/stl/inc/xtzdb.h index 63291db3ce5..73747054ced 100644 --- a/stl/inc/xtzdb.h +++ b/stl/inc/xtzdb.h @@ -85,10 +85,10 @@ void __stdcall __std_free_crt(void* _Ptr) noexcept; _END_EXTERN_C +_STD_BEGIN + template -struct _Tzdb_deleter { - void operator()(_Ty*) const noexcept {} -}; +struct _Tzdb_deleter; template <> struct _Tzdb_deleter<__std_tzdb_time_zones_info> { @@ -118,8 +118,6 @@ struct _Tzdb_deleter<__std_tzdb_registry_leap_info[]> { } }; -_STD_BEGIN - template class _Crt_allocator { public: diff --git a/stl/src/tzdb.cpp b/stl/src/tzdb.cpp index 9cf15b2fa39..c68f6d61fff 100644 --- a/stl/src/tzdb.cpp +++ b/stl/src/tzdb.cpp @@ -182,15 +182,13 @@ namespace { return _Fun(en, resultLength, status); } - template <> - struct _Tzdb_deleter { + struct _UEnumeration_deleter { void operator()(UEnumeration* _En) const noexcept { __icu_uenum_close(_En); } }; - template <> - struct _Tzdb_deleter { + struct _UCalendar_deleter { void operator()(UCalendar* _Cal) const noexcept { __icu_ucal_close(_Cal); } @@ -307,7 +305,7 @@ namespace { return _Get_icu_string_impl(_Icu_fn, 12, _Result_len, _Err); } - _NODISCARD _STD unique_ptr> _Get_cal( + _NODISCARD _STD unique_ptr _Get_cal( const char* _Tz, const size_t _Tz_len, __std_tzdb_error& _Err) noexcept { const auto _Tz_name = _Allocate_narrow_to_wide(_Tz, static_cast(_Tz_len), _Err); if (_Tz_name == nullptr) { @@ -315,7 +313,7 @@ namespace { } UErrorCode _UErr{U_ZERO_ERROR}; - _STD unique_ptr> _Cal{ + _STD unique_ptr _Cal{ __icu_ucal_open(_Tz_name.get(), -1, nullptr, UCalendarType::UCAL_DEFAULT, &_UErr)}; if (U_FAILURE(_UErr)) { _Err = __std_tzdb_error::_Icu_error; @@ -344,7 +342,7 @@ _NODISCARD __std_tzdb_time_zones_info* __stdcall __std_tzdb_get_time_zones() noe // _Info == nullptr --> bad_alloc // _Info->_Err == _Win_error --> failed, call GetLastError() // _Info->_Err == _Icu_error --> runtime_error interacting with ICU - _STD unique_ptr<__std_tzdb_time_zones_info, _Tzdb_deleter<__std_tzdb_time_zones_info>> _Info{ + _STD unique_ptr<__std_tzdb_time_zones_info, _STD _Tzdb_deleter<__std_tzdb_time_zones_info>> _Info{ new (_STD nothrow) __std_tzdb_time_zones_info{}}; if (_Info == nullptr) { return nullptr; @@ -360,7 +358,7 @@ _NODISCARD __std_tzdb_time_zones_info* __stdcall __std_tzdb_get_time_zones() noe return _Report_error(_Info, __std_tzdb_error::_Icu_error); } - _STD unique_ptr> _Enum{ + _STD unique_ptr _Enum{ __icu_ucal_openTimeZoneIDEnumeration(USystemTimeZoneType::UCAL_ZONE_TYPE_ANY, nullptr, nullptr, &_UErr)}; if (U_FAILURE(_UErr)) { return _Report_error(_Info, __std_tzdb_error::_Icu_error); @@ -442,7 +440,7 @@ _NODISCARD __std_tzdb_current_zone_info* __stdcall __std_tzdb_get_current_zone() // _Info == nullptr --> bad_alloc // _Info->_Err == _Win_error --> failed, call GetLastError() // _Info->_Err == _Icu_error --> runtime_error interacting with ICU - _STD unique_ptr<__std_tzdb_current_zone_info, _Tzdb_deleter<__std_tzdb_current_zone_info>> _Info{ + _STD unique_ptr<__std_tzdb_current_zone_info, _STD _Tzdb_deleter<__std_tzdb_current_zone_info>> _Info{ new (_STD nothrow) __std_tzdb_current_zone_info{}}; if (_Info == nullptr) { return nullptr; @@ -479,7 +477,7 @@ _NODISCARD __std_tzdb_sys_info* __stdcall __std_tzdb_get_sys_info( // _Info == nullptr --> bad_alloc // _Info->_Err == _Win_error --> failed, call GetLastError() // _Info->_Err == _Icu_error --> runtime_error interacting with ICU - _STD unique_ptr<__std_tzdb_sys_info, _Tzdb_deleter<__std_tzdb_sys_info>> _Info{ + _STD unique_ptr<__std_tzdb_sys_info, _STD _Tzdb_deleter<__std_tzdb_sys_info>> _Info{ new (_STD nothrow) __std_tzdb_sys_info{}}; if (_Info == nullptr) { return nullptr; diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_time_zones/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_time_zones/test.cpp index 1b517a54a48..a2fa09ee3d5 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_time_zones/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_time_zones/test.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -69,12 +70,12 @@ void timezone_version_test() { const auto& my_tzdb = get_tzdb(); assert(my_tzdb.version.empty() == false); - // version should end in .X where X == number leap seconds + // version should end in .X where X == number of leap seconds const auto pos = my_tzdb.version.find_last_of('.'); assert(pos != decltype(my_tzdb.version)::npos); const string leap_seconds{my_tzdb.version, pos + 1}; assert(leap_seconds.empty() == false); - assert(leap_seconds == std::to_string(my_tzdb.leap_seconds.size())); + assert(leap_seconds == to_string(my_tzdb.leap_seconds.size())); // remote version will only differ if leap seconds info changes, will not occur in tests const auto& reloaded_tzdb = reload_tzdb();