https://github.com/mordante updated https://github.com/llvm/llvm-project/pull/95010
>From 6d6dade0997a414431bf852742cd68c24d274e27 Mon Sep 17 00:00:00 2001 From: Mark de Wever <ko...@xs4all.nl> Date: Wed, 17 Apr 2024 21:00:22 +0200 Subject: [PATCH] [libc++][TZDB] Finishes zoned_time constructors. Completes - LWG3225 zoned_time converting constructor shall not be noexcept - LWG3226 zoned_time constructor from string_view should accept zoned_time<Duration2, TimeZonePtr2> Implements parts of: - P0355 Extending to chrono Calendars and Time Zones --- libcxx/docs/Status/Cxx20Issues.csv | 4 +- libcxx/include/__chrono/zoned_time.h | 73 ++++++- .../test_offset_time_zone.h | 10 + .../string_view_local_time.pass.cpp | 74 +++++++ .../string_view_local_time_choose.pass.cpp | 100 ++++++++++ .../string_view_sys_time.pass.cpp | 74 +++++++ ...ned_time_duration2_time_zone_ptr2.pass.cpp | 159 +++++++++++++++ ...e_duration2_time_zone_ptr2_choose.pass.cpp | 181 ++++++++++++++++++ .../time_zone_pointer_local_time.pass.cpp | 82 ++++++++ ...me_zone_pointer_local_time_choose.pass.cpp | 104 ++++++++++ .../time_zone_pointer_sys_time.pass.cpp | 88 +++++++++ ...ned_time_duration2_time_zone_ptr2.pass.cpp | 105 ++++++++++ ...e_duration2_time_zone_ptr2_choose.pass.cpp | 117 +++++++++++ .../zoned_time_duration2.pass.cpp | 88 +++++++++ 14 files changed, 1252 insertions(+), 7 deletions(-) create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_local_time.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_local_time_choose.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_sys_time.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_zoned_time_duration2_time_zone_ptr2.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_zoned_time_duration2_time_zone_ptr2_choose.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_local_time.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_local_time_choose.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_sys_time.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_ptr_zoned_time_duration2_time_zone_ptr2.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_ptr_zoned_time_duration2_time_zone_ptr2_choose.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/zoned_time_duration2.pass.cpp diff --git a/libcxx/docs/Status/Cxx20Issues.csv b/libcxx/docs/Status/Cxx20Issues.csv index 5732d5b5dd0564..faae05d3380cc3 100644 --- a/libcxx/docs/Status/Cxx20Issues.csv +++ b/libcxx/docs/Status/Cxx20Issues.csv @@ -162,7 +162,7 @@ "`3209 <https://wg21.link/LWG3209>`__","Expression in ``year::ok()``\ returns clause is ill-formed","Cologne","|Complete|","" "","","","","","" "`3231 <https://wg21.link/LWG3231>`__","``year_month_day_last::day``\ specification does not cover ``!ok()``\ values","Belfast","|Nothing To Do|","" -"`3225 <https://wg21.link/LWG3225>`__","``zoned_time``\ converting constructor shall not be ``noexcept``\ ","Belfast","","","|chrono|" +"`3225 <https://wg21.link/LWG3225>`__","``zoned_time``\ converting constructor shall not be ``noexcept``\ ","Belfast","|Complete|","19.0","|chrono|" "`3190 <https://wg21.link/LWG3190>`__","``std::allocator::allocate``\ sometimes returns too little storage","Belfast","|Complete|","14.0" "`3218 <https://wg21.link/LWG3218>`__","Modifier for ``%d``\ parse flag does not match POSIX and ``format``\ specification","Belfast","","","|chrono| |format|" "`3224 <https://wg21.link/LWG3224>`__","``zoned_time``\ constructor from ``TimeZonePtr``\ does not specify initialization of ``tp_``\ ","Belfast","|Complete|","19.0","|chrono|" @@ -199,7 +199,7 @@ "`3194 <https://wg21.link/LWG3194>`__","``ConvertibleTo``\ prose does not match code","Prague","|Complete|","13.0" "`3200 <https://wg21.link/LWG3200>`__","``midpoint``\ should not constrain ``T``\ is complete","Prague","|Nothing To Do|","" "`3201 <https://wg21.link/LWG3201>`__","``lerp``\ should be marked as ``noexcept``\ ","Prague","|Complete|","" -"`3226 <https://wg21.link/LWG3226>`__","``zoned_time``\ constructor from ``string_view``\ should accept ``zoned_time<Duration2, TimeZonePtr2>``\ ","Prague","","","|chrono|" +"`3226 <https://wg21.link/LWG3226>`__","``zoned_time``\ constructor from ``string_view``\ should accept ``zoned_time<Duration2, TimeZonePtr2>``\ ","Prague","|Complete|","19.0","|chrono|" "`3233 <https://wg21.link/LWG3233>`__","Broken requirements for ``shared_ptr``\ converting constructors","Prague","|Complete|","19.0" "`3237 <https://wg21.link/LWG3237>`__","LWG 3038 and 3190 have inconsistent PRs","Prague","|Complete|","16.0" "`3238 <https://wg21.link/LWG3238>`__","Insufficiently-defined behavior of ``std::function``\ deduction guides","Prague","|Nothing To Do|","" diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h index d0a5146cd4d066..08f7f37603920a 100644 --- a/libcxx/include/__chrono/zoned_time.h +++ b/libcxx/include/__chrono/zoned_time.h @@ -16,6 +16,7 @@ // Enable the contents of the header only when libc++ was built with experimental features enabled. #if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) +# include <__chrono/calendar.h> # include <__chrono/duration.h> # include <__chrono/system_clock.h> # include <__chrono/time_zone.h> @@ -56,6 +57,11 @@ class zoned_time { static_assert(__is_duration<_Duration>::value, "the program is ill-formed since _Duration is not a specialization of std::chrono::duration"); + // The wording uses the constraints like + // constructible_from<zoned_time, decltype(__traits::locate_zone(string_view{}))> + // Using these constraints in the code causes the compiler to give an + // error that the constraint depends on itself. To avoid that issue use + // the fact it is possible to create this object from a _TimeZonePtr. using __traits = zoned_traits<_TimeZonePtr>; public: @@ -76,14 +82,71 @@ class zoned_time { _LIBCPP_HIDE_FROM_ABI explicit zoned_time(string_view __name) requires(requires { __traits::locate_zone(string_view{}); } && - // The wording uses the constraint - // constructible_from<zoned_time, decltype(__traits::locate_zone(string_view{}))> - // Using this constraint in the code causes the compiler to give an - // error the constraint depends on itself. To avoid that issue use - // the fact it is possible to create this object from a _TimeZonePtr. constructible_from<_TimeZonePtr, decltype(__traits::locate_zone(string_view{}))>) : __zone_{__traits::locate_zone(__name)}, __tp_{} {} + template <class _Duration2> + _LIBCPP_HIDE_FROM_ABI zoned_time(const zoned_time<_Duration2, _TimeZonePtr>& __zt) + requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>> + : __zone_{__zt.get_time_zone()}, __tp_{__zt.get_sys_time()} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const sys_time<_Duration>& __tp) + : __zone_{std::move(__zone)}, __tp_{__tp} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const sys_time<_Duration>& __tp) + requires requires { _TimeZonePtr{__traits::locate_zone(string_view{})}; } + : zoned_time{__traits::locate_zone(__name), __tp} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const local_time<_Duration>& __tp) + requires(is_convertible_v<decltype(std::declval<_TimeZonePtr&>() -> to_sys(local_time<_Duration>{})), + sys_time<duration>>) + : __zone_{std::move(__zone)}, __tp_{__zone_->to_sys(__tp)} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const local_time<_Duration>& __tp) + requires(requires { + _TimeZonePtr{__traits::locate_zone(string_view{})}; + } && is_convertible_v<decltype(std::declval<_TimeZonePtr&>() -> to_sys(local_time<_Duration>{})), + sys_time<duration>>) + : zoned_time{__traits::locate_zone(__name), __tp} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const local_time<_Duration>& __tp, choose __c) + requires(is_convertible_v< + decltype(std::declval<_TimeZonePtr&>() -> to_sys(local_time<_Duration>{}, choose::earliest)), + sys_time<duration>>) + : __zone_{std::move(__zone)}, __tp_{__zone_->to_sys(__tp, __c)} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const local_time<_Duration>& __tp, choose __c) + requires(requires { + _TimeZonePtr{__traits::locate_zone(string_view{})}; + } && is_convertible_v<decltype(std::declval<_TimeZonePtr&>() -> to_sys(local_time<_Duration>{}, choose::earliest)), + sys_time<duration>>) + : zoned_time{__traits::locate_zone(__name), __tp, __c} {} + + template <class _Duration2, class _TimeZonePtr2> + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const zoned_time<_Duration2, _TimeZonePtr2>& __zt) + requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>> + : __zone_{std::move(__zone)}, __tp_{__zt.get_sys_time()} {} + + // per wording choose has no effect + template <class _Duration2, class _TimeZonePtr2> + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const zoned_time<_Duration2, _TimeZonePtr2>& __zt, choose) + requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>> + : __zone_{std::move(__zone)}, __tp_{__zt.get_sys_time()} {} + + template <class _Duration2, class _TimeZonePtr2> + _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const zoned_time<_Duration2, _TimeZonePtr2>& __zt) + requires(requires { + _TimeZonePtr{__traits::locate_zone(string_view{})}; + } && is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>) + : zoned_time{__traits::locate_zone(__name), __zt} {} + + template <class _Duration2, class _TimeZonePtr2> + _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const zoned_time<_Duration2, _TimeZonePtr2>& __zt, choose __c) + requires(requires { + _TimeZonePtr{__traits::locate_zone(string_view{})}; + } && is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>) + : zoned_time{__traits::locate_zone(__name), __zt, __c} {} + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _TimeZonePtr get_time_zone() const { return __zone_; } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_time<duration> get_sys_time() const { return __tp_; } diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/test_offset_time_zone.h b/libcxx/test/std/time/time.zone/time.zone.zonedtime/test_offset_time_zone.h index 22ebd404bb4e0f..c137049bde8aa4 100644 --- a/libcxx/test/std/time/time.zone/time.zone.zonedtime/test_offset_time_zone.h +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/test_offset_time_zone.h @@ -14,6 +14,7 @@ #include <charconv> #include <chrono> #include <string_view> +#include <type_traits> enum class offset_time_zone_flags { none = 0, @@ -39,6 +40,15 @@ class offset_time_zone { std::chrono::seconds offset() const { return offset_; } + offset_time_zone* operator->() { return this; } + + template <class Duration> + std::chrono::sys_time<std::common_type_t<Duration, std::chrono::seconds>> + to_sys(const std::chrono::local_time<Duration>& local) const { + return std::chrono::sys_time<std::common_type_t<Duration, std::chrono::seconds>>{ + local.time_since_epoch() + offset_}; + } + private: std::chrono::seconds offset_; }; diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_local_time.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_local_time.pass.cpp new file mode 100644 index 00000000000000..c7fe8f24db6874 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_local_time.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// zoned_time(string_view name, const local_time<Duration>& st); + +#include <chrono> +#include <concepts> + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +// Verify the results of the constructed object. +int main(int, char**) { + { + using ptr = const cr::time_zone*; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, std::string_view, cr::sys_seconds>); + + cr::zoned_time<cr::seconds> zt{"Etc/GMT+1", cr::local_seconds{cr::seconds{0}}}; + + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == cr::sys_seconds{cr::hours{1}}); + } + + { + using ptr = offset_time_zone<offset_time_zone_flags::none>; + static_assert(!std::constructible_from<cr::zoned_time<cr::seconds, ptr>, std::string_view, cr::local_seconds>); + } + + { + using ptr = offset_time_zone<offset_time_zone_flags::has_default_zone>; + static_assert(!std::constructible_from<cr::zoned_time<cr::seconds, ptr>, std::string_view, cr::local_seconds>); + } + + { + using ptr = offset_time_zone<offset_time_zone_flags::has_locate_zone>; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, std::string_view, cr::local_seconds>); + + ptr tz; + cr::zoned_time<cr::seconds, ptr> zt{"42", cr::local_seconds{cr::seconds{99}}}; + + assert(zt.get_time_zone().offset() == cr::seconds{42}); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{141}}); + } + + { + using ptr = offset_time_zone<offset_time_zone_flags::both>; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, std::string_view, cr::local_seconds>); + + ptr tz; + cr::zoned_time<cr::seconds, ptr> zt{"42", cr::local_seconds{cr::seconds{99}}}; + + assert(zt.get_time_zone().offset() == cr::seconds{42}); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{141}}); + } + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_local_time_choose.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_local_time_choose.pass.cpp new file mode 100644 index 00000000000000..69eb4a17aada4c --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_local_time_choose.pass.cpp @@ -0,0 +1,100 @@ +//===----------------------------------------------------------------------===/ +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// zoned_time(string_view name, const local_time<Duration>& st, choose c); + +#include <chrono> +#include <concepts> +#include <cassert> + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +int main(int, char**) { + // Tests unique conversions. To make sure the test does not depend on changes + // in the database it uses a time zone with a fixed offset. + { + cr::zoned_time<cr::seconds> zt{"Etc/GMT+1", cr::local_seconds{cr::seconds{0}}, cr::choose::earliest}; + + assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1")); + assert(zt.get_sys_time() == cr::sys_seconds{cr::hours{1}}); + } + + // Tests ambiguous conversions. + { + // Z Europe/Berlin 0:53:28 - LMT 1893 Ap + // ... + // 1 DE CE%sT 1980 + // 1 E CE%sT + // + // ... + // R E 1981 ma - Mar lastSu 1u 1 S + // R E 1996 ma - O lastSu 1u 0 - + + using namespace std::literals::chrono_literals; + { + cr::zoned_time<cr::seconds> zt{ + "Europe/Berlin", + cr::local_seconds{(cr::sys_days{cr::September / 28 / 1986} + 2h + 30min).time_since_epoch()}, + cr::choose::earliest}; + + assert(zt.get_time_zone() == cr::locate_zone("Europe/Berlin")); + assert(zt.get_sys_time() == cr::sys_days{cr::September / 28 / 1986} + 0h + 30min); + } + { + cr::zoned_time<cr::seconds> zt{ + "Europe/Berlin", + cr::local_seconds{(cr::sys_days{cr::September / 28 / 1986} + 2h + 30min).time_since_epoch()}, + cr::choose::latest}; + + assert(zt.get_time_zone() == cr::locate_zone("Europe/Berlin")); + assert(zt.get_sys_time() == cr::sys_days{cr::September / 28 / 1986} + 1h + 30min); + } + } + + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, const cr::time_zone*>, + std::string_view, + cr::local_seconds, + cr::choose>); + + static_assert(!std::constructible_from< cr::zoned_time<cr::seconds, offset_time_zone<offset_time_zone_flags::none>>, + std::string_view, + cr::local_seconds, + cr::choose>); + + static_assert( + !std::constructible_from< cr::zoned_time<cr::seconds, offset_time_zone<offset_time_zone_flags::has_default_zone>>, + std::string_view, + cr::local_seconds, + cr::choose>); + + static_assert( + !std::constructible_from< cr::zoned_time<cr::seconds, offset_time_zone<offset_time_zone_flags::has_locate_zone>>, + std::string_view, + cr::local_seconds, + cr::choose>); + + static_assert(!std::constructible_from< cr::zoned_time<cr::seconds, offset_time_zone<offset_time_zone_flags::both>>, + std::string_view, + cr::local_seconds, + cr::choose>); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_sys_time.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_sys_time.pass.cpp new file mode 100644 index 00000000000000..108a4b44706b7a --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_sys_time.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// zoned_time(string_view name, const sys_time<Duration>& st); + +#include <chrono> +#include <concepts> + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +// Verify the results of the constructed object. +int main(int, char**) { + { + using ptr = const cr::time_zone*; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, std::string_view, cr::sys_seconds>); + + cr::zoned_time<cr::seconds> zt{"UTC", cr::sys_seconds{cr::seconds{99}}}; + + assert(zt.get_time_zone() == cr::locate_zone("UTC")); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{99}}); + } + + { + using ptr = offset_time_zone<offset_time_zone_flags::none>; + static_assert(!std::constructible_from<cr::zoned_time<cr::seconds, ptr>, std::string_view, cr::sys_seconds>); + } + + { + using ptr = offset_time_zone<offset_time_zone_flags::has_default_zone>; + static_assert(!std::constructible_from<cr::zoned_time<cr::seconds, ptr>, std::string_view, cr::sys_seconds>); + } + + { + using ptr = offset_time_zone<offset_time_zone_flags::has_locate_zone>; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, std::string_view, cr::sys_seconds>); + + ptr tz; + cr::zoned_time<cr::seconds, ptr> zt{"42", cr::sys_seconds{cr::seconds{99}}}; + + assert(zt.get_time_zone().offset() == cr::seconds{42}); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{99}}); + } + + { + using ptr = offset_time_zone<offset_time_zone_flags::both>; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, std::string_view, cr::sys_seconds>); + + ptr tz; + cr::zoned_time<cr::seconds, ptr> zt{"42", cr::sys_seconds{cr::seconds{99}}}; + + assert(zt.get_time_zone().offset() == cr::seconds{42}); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{99}}); + } + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_zoned_time_duration2_time_zone_ptr2.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_zoned_time_duration2_time_zone_ptr2.pass.cpp new file mode 100644 index 00000000000000..68d7a5c74f47a4 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_zoned_time_duration2_time_zone_ptr2.pass.cpp @@ -0,0 +1,159 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; + +// template<class Duration2, class TimeZonePtr2> +// zoned_time(string_view name, const zoned_time<Duration2, TimeZonePtr2>& y); + +#include <chrono> +#include <concepts> +#include <cassert> + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +template <> +struct cr::zoned_traits<int> { + static int default_zone() { return 0; } +}; + +static void test_duration_conversion() { + using ptr = const cr::time_zone*; + ptr tz = cr::locate_zone("UTC"); + + // is_convertible_v<sys_time<Duration2>, sys_time<Duration>> is true. + { + using duration = cr::microseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert(std::constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>>); + cr::zoned_time<duration2> zt2{"UTC", zt}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } + { + using duration = cr::milliseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert(std::constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>>); + cr::zoned_time<duration2> zt2{"UTC", zt}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000}}); + } + { + using duration = cr::seconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert(std::constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>>); + cr::zoned_time<duration2> zt2{"UTC", zt}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000'000}}); + } + // is_convertible_v<sys_time<Duration2>, sys_time<Duration>> is false. + { + using duration = cr::milliseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>>); + } + { + using duration = cr::microseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>>); + } + { + using duration = cr::nanoseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>>); + } +} + +static void test_locate_zone() { + using duration = cr::microseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + + { + using ptr = const cr::time_zone*; + static_assert( + std::constructible_from<cr::zoned_time<duration2, ptr>, std::string_view, cr::zoned_time<duration, int>>); + ptr tz = cr::locate_zone("UTC"); + cr::zoned_time<duration2, ptr> zt2{"UTC", zt}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } + + { + using ptr = offset_time_zone<offset_time_zone_flags::none>; + static_assert( + !std::constructible_from<cr::zoned_time<duration2, ptr>, std::string_view, cr::zoned_time<duration, int>>); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::has_default_zone>; + static_assert( + !std::constructible_from<cr::zoned_time<duration2, ptr>, std::string_view, cr::zoned_time<duration, int>>); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::has_locate_zone>; + static_assert( + std::constructible_from<cr::zoned_time<duration2, ptr>, std::string_view, cr::zoned_time<duration, int>>); + + ptr tz; + cr::zoned_time<duration2, ptr> zt2{"99", zt}; + + assert(zt2.get_time_zone().offset() == cr::seconds{99}); + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::both>; + static_assert( + std::constructible_from<cr::zoned_time<duration2, ptr>, std::string_view, cr::zoned_time<duration, int>>); + + ptr tz; + cr::zoned_time<duration2, ptr> zt2{"99", zt}; + + assert(zt2.get_time_zone().offset() == cr::seconds{99}); + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } +} + +int main(int, char**) { + test_duration_conversion(); + test_locate_zone(); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_zoned_time_duration2_time_zone_ptr2_choose.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_zoned_time_duration2_time_zone_ptr2_choose.pass.cpp new file mode 100644 index 00000000000000..a96975cc611f9d --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/string_view_zoned_time_duration2_time_zone_ptr2_choose.pass.cpp @@ -0,0 +1,181 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; + +// template<class Duration2, class TimeZonePtr2> +// zoned_time(string_view name, const zoned_time<Duration2, TimeZonePtr2>& y, choose c); + +#include <chrono> +#include <concepts> +#include <cassert> + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +template <> +struct cr::zoned_traits<int> { + static int default_zone() { return 0; } +}; + +static void test_duration_conversion() { + using ptr = const cr::time_zone*; + ptr tz = cr::locate_zone("UTC"); + + // is_convertible_v<sys_time<Duration2>, sys_time<Duration>> is true. + { + using duration = cr::microseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert( + std:: + constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>, cr::choose>); + cr::zoned_time<duration2> zt2{"UTC", zt, cr::choose::earliest}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } + { + using duration = cr::milliseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert( + std:: + constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>, cr::choose>); + cr::zoned_time<duration2> zt2{"UTC", zt, cr::choose::earliest}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000}}); + } + { + using duration = cr::seconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert( + std:: + constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>, cr::choose>); + cr::zoned_time<duration2> zt2{"UTC", zt, cr::choose::earliest}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000'000}}); + } + // is_convertible_v<sys_time<Duration2>, sys_time<Duration>> is false. + { + using duration = cr::milliseconds; + + using duration2 = cr::seconds; + static_assert( + !std:: + constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>, cr::choose>); + } + { + using duration = cr::microseconds; + + using duration2 = cr::seconds; + static_assert( + !std:: + constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>, cr::choose>); + } + { + using duration = cr::nanoseconds; + + using duration2 = cr::seconds; + static_assert( + !std:: + constructible_from<cr::zoned_time<duration2>, std::string_view, cr::zoned_time<duration, int>, cr::choose>); + } +} + +static void test_locate_zone() { + using duration = cr::microseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + + { + using ptr = const cr::time_zone*; + static_assert(std::constructible_from<cr::zoned_time<duration2, ptr>, + std::string_view, + cr::zoned_time<duration, int>, + cr::choose>); + ptr tz = cr::locate_zone("UTC"); + cr::zoned_time<duration2, ptr> zt2{"UTC", zt, cr::choose::earliest}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } + + { + using ptr = offset_time_zone<offset_time_zone_flags::none>; + static_assert(!std::constructible_from<cr::zoned_time<duration2, ptr>, + std::string_view, + cr::zoned_time<duration, int>, + cr::choose>); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::has_default_zone>; + static_assert(!std::constructible_from<cr::zoned_time<duration2, ptr>, + std::string_view, + cr::zoned_time<duration, int>, + cr::choose>); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::has_locate_zone>; + static_assert(std::constructible_from<cr::zoned_time<duration2, ptr>, + std::string_view, + cr::zoned_time<duration, int>, + cr::choose>); + + ptr tz; + cr::zoned_time<duration2, ptr> zt2{"99", zt, cr::choose::earliest}; + + assert(zt2.get_time_zone().offset() == cr::seconds{99}); + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::both>; + static_assert(std::constructible_from<cr::zoned_time<duration2, ptr>, + std::string_view, + cr::zoned_time<duration, int>, + cr::choose>); + + ptr tz; + cr::zoned_time<duration2, ptr> zt2{"99", zt, cr::choose::earliest}; + + assert(zt2.get_time_zone().offset() == cr::seconds{99}); + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } +} + +int main(int, char**) { + test_duration_conversion(); + test_locate_zone(); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_local_time.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_local_time.pass.cpp new file mode 100644 index 00000000000000..72116ca710e439 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_local_time.pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// zoned_time(TimeZonePtr z, const local_time<Duration>& st); + +#include <chrono> +#include <concepts> +#include <cassert> + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +int main(int, char**) { + { + using ptr = const cr::time_zone*; + ptr tz = cr::locate_zone("Etc/GMT+1"); + cr::zoned_time<cr::seconds> zt{tz, cr::local_seconds{cr::seconds{0}}}; + + assert(zt.get_time_zone() == tz); + assert(zt.get_sys_time() == cr::sys_seconds{cr::hours{1}}); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::none>; + ptr tz{"60"}; + cr::zoned_time<cr::seconds, ptr> zt{tz, cr::local_seconds{cr::seconds{42}}}; + + assert(zt.get_time_zone().offset() == tz.offset()); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{102}}); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::has_default_zone>; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, ptr>); + static_assert(!std::convertible_to<ptr, cr::zoned_time<cr::seconds, ptr>>); + + ptr tz{"60"}; + cr::zoned_time<cr::seconds, ptr> zt{tz, cr::local_seconds{cr::seconds{42}}}; + + assert(zt.get_time_zone().offset() == tz.offset()); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{102}}); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::has_locate_zone>; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, ptr>); + static_assert(!std::convertible_to<ptr, cr::zoned_time<cr::seconds, ptr>>); + + ptr tz{"60"}; + cr::zoned_time<cr::seconds, ptr> zt{tz, cr::local_seconds{cr::seconds{42}}}; + + assert(zt.get_time_zone().offset() == tz.offset()); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{102}}); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::both>; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, ptr>); + static_assert(!std::convertible_to<ptr, cr::zoned_time<cr::seconds, ptr>>); + + ptr tz{"60"}; + cr::zoned_time<cr::seconds, ptr> zt{tz, cr::local_seconds{cr::seconds{42}}}; + + assert(zt.get_time_zone().offset() == tz.offset()); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{102}}); + } + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_local_time_choose.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_local_time_choose.pass.cpp new file mode 100644 index 00000000000000..efe78141a5cf26 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_local_time_choose.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// zoned_time(TimeZonePtr z, const local_time<Duration>& st, choose c); + +#include <chrono> +#include <concepts> +#include <cassert> + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +int main(int, char**) { + // Tests unique conversions. To make sure the test is does not depend on changes + // in the database it uses a time zone with a fixed offset. + { + using ptr = const cr::time_zone*; + ptr tz = cr::locate_zone("Etc/GMT+1"); + cr::zoned_time<cr::seconds> zt{tz, cr::local_seconds{cr::seconds{0}}, cr::choose::earliest}; + + assert(zt.get_time_zone() == tz); + assert(zt.get_sys_time() == cr::sys_seconds{cr::hours{1}}); + } + + // Tests ambiguous conversions. + { + // Z Europe/Berlin 0:53:28 - LMT 1893 Ap + // ... + // 1 DE CE%sT 1980 + // 1 E CE%sT + // + // ... + // R E 1981 ma - Mar lastSu 1u 1 S + // R E 1996 ma - O lastSu 1u 0 - + + using namespace std::literals::chrono_literals; + using ptr = const cr::time_zone*; + ptr tz = cr::locate_zone("Europe/Berlin"); + { + cr::zoned_time<cr::seconds> zt{ + tz, + cr::local_seconds{(cr::sys_days{cr::September / 28 / 1986} + 2h + 30min).time_since_epoch()}, + cr::choose::earliest}; + + assert(zt.get_time_zone() == tz); + assert(zt.get_sys_time() == cr::sys_days{cr::September / 28 / 1986} + 0h + 30min); + } + { + cr::zoned_time<cr::seconds> zt{ + tz, + cr::local_seconds{(cr::sys_days{cr::September / 28 / 1986} + 2h + 30min).time_since_epoch()}, + cr::choose::latest}; + + assert(zt.get_time_zone() == tz); + assert(zt.get_sys_time() == cr::sys_days{cr::September / 28 / 1986} + 1h + 30min); + } + } + + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, const cr::time_zone*>, + const cr::time_zone*, + cr::local_seconds, + cr::choose>); + + static_assert(!std::constructible_from<cr::zoned_time<cr::seconds, offset_time_zone<offset_time_zone_flags::none>>, + offset_time_zone<offset_time_zone_flags::none>, + cr::local_seconds, + cr::choose>); + + static_assert( + !std::constructible_from<cr::zoned_time<cr::seconds, offset_time_zone<offset_time_zone_flags::has_default_zone>>, + offset_time_zone<offset_time_zone_flags::has_default_zone>, + cr::local_seconds, + cr::choose>); + + static_assert( + !std::constructible_from<cr::zoned_time<cr::seconds, offset_time_zone<offset_time_zone_flags::has_locate_zone>>, + offset_time_zone<offset_time_zone_flags::has_locate_zone>, + cr::local_seconds, + cr::choose>); + + static_assert(!std::constructible_from<cr::zoned_time<cr::seconds, offset_time_zone<offset_time_zone_flags::both>>, + offset_time_zone<offset_time_zone_flags::both>, + cr::local_seconds, + cr::choose>); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_sys_time.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_sys_time.pass.cpp new file mode 100644 index 00000000000000..d0769cbe1408bf --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_pointer_sys_time.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; +// +// zoned_time(TimeZonePtr z, const sys_time<Duration>& st); + +#include <chrono> +#include <concepts> +#include <cassert> + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +int main(int, char**) { + { + using ptr = const cr::time_zone*; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, ptr>); + static_assert(!std::convertible_to<ptr, cr::zoned_time<cr::seconds, ptr>>); + + ptr tz = cr::locate_zone("UTC"); + cr::zoned_time<cr::seconds> zt{tz, cr::sys_seconds{cr::seconds{42}}}; + + assert(zt.get_time_zone() == tz); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{42}}); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::none>; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, ptr>); + static_assert(!std::convertible_to<ptr, cr::zoned_time<cr::seconds, ptr>>); + + ptr tz; + cr::zoned_time<cr::seconds, ptr> zt{tz, cr::sys_seconds{cr::seconds{42}}}; + + assert(zt.get_time_zone().offset() == tz.offset()); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{42}}); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::has_default_zone>; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, ptr>); + static_assert(!std::convertible_to<ptr, cr::zoned_time<cr::seconds, ptr>>); + + ptr tz; + cr::zoned_time<cr::seconds, ptr> zt{tz, cr::sys_seconds{cr::seconds{42}}}; + + assert(zt.get_time_zone().offset() == tz.offset()); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{42}}); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::has_locate_zone>; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, ptr>); + static_assert(!std::convertible_to<ptr, cr::zoned_time<cr::seconds, ptr>>); + + ptr tz; + cr::zoned_time<cr::seconds, ptr> zt{tz, cr::sys_seconds{cr::seconds{42}}}; + + assert(zt.get_time_zone().offset() == tz.offset()); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{42}}); + } + { + using ptr = offset_time_zone<offset_time_zone_flags::both>; + static_assert(std::constructible_from<cr::zoned_time<cr::seconds, ptr>, ptr>); + static_assert(!std::convertible_to<ptr, cr::zoned_time<cr::seconds, ptr>>); + + ptr tz; + cr::zoned_time<cr::seconds, ptr> zt{tz, cr::sys_seconds{cr::seconds{42}}}; + + assert(zt.get_time_zone().offset() == tz.offset()); + assert(zt.get_sys_time() == cr::sys_seconds{cr::seconds{42}}); + } + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_ptr_zoned_time_duration2_time_zone_ptr2.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_ptr_zoned_time_duration2_time_zone_ptr2.pass.cpp new file mode 100644 index 00000000000000..ea4bd29b46d5be --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_ptr_zoned_time_duration2_time_zone_ptr2.pass.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; + +// template<class Duration2, class TimeZonePtr2> +// zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& y); + +#include <chrono> +#include <concepts> +#include <cassert> + +namespace cr = std::chrono; + +template <> +struct cr::zoned_traits<int> { + static int default_zone() { return 0; } +}; + +int main(int, char**) { + using ptr = const cr::time_zone*; + ptr tz = cr::locate_zone("UTC"); + + // is_convertible_v<sys_time<Duration2>, sys_time<Duration>> is true. + { + using duration = cr::microseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert( + std::constructible_from<cr::zoned_time<duration2>, const cr::time_zone*, cr::zoned_time<duration, int>>); + cr::zoned_time<duration2> zt2{tz, zt}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } + { + using duration = cr::milliseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert( + std::constructible_from<cr::zoned_time<duration2>, const cr::time_zone*, cr::zoned_time<duration, int>>); + cr::zoned_time<duration2> zt2{tz, zt}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000}}); + } + { + using duration = cr::seconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert( + std::constructible_from<cr::zoned_time<duration2>, const cr::time_zone*, cr::zoned_time<duration, int>>); + cr::zoned_time<duration2> zt2{tz, zt}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000'000}}); + } + // is_convertible_v<sys_time<Duration2>, sys_time<Duration>> is false. + { + using duration = cr::milliseconds; + + using duration2 = cr::seconds; + static_assert( + !std::constructible_from<cr::zoned_time<duration2>, const cr::time_zone*, cr::zoned_time<duration, int>>); + } + { + using duration = cr::microseconds; + + using duration2 = cr::seconds; + static_assert( + !std::constructible_from<cr::zoned_time<duration2>, const cr::time_zone*, cr::zoned_time<duration, int>>); + } + { + using duration = cr::nanoseconds; + + using duration2 = cr::seconds; + static_assert( + !std::constructible_from<cr::zoned_time<duration2>, const cr::time_zone*, cr::zoned_time<duration, int>>); + } + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_ptr_zoned_time_duration2_time_zone_ptr2_choose.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_ptr_zoned_time_duration2_time_zone_ptr2_choose.pass.cpp new file mode 100644 index 00000000000000..b548193360ad0a --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/time_zone_ptr_zoned_time_duration2_time_zone_ptr2_choose.pass.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; + +// template<class Duration2, class TimeZonePtr2> +// zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& y, choose); + +#include <chrono> +#include <concepts> +#include <cassert> + +namespace cr = std::chrono; + +template <> +struct cr::zoned_traits<int> { + static int default_zone() { return 0; } +}; + +int main(int, char**) { + using ptr = const cr::time_zone*; + ptr tz = cr::locate_zone("UTC"); + + // is_convertible_v<sys_time<Duration2>, sys_time<Duration>> is true. + { + using duration = cr::microseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert(std::constructible_from<cr::zoned_time<duration2>, + const cr::time_zone*, + cr::zoned_time<duration, int>, + cr::choose>); + cr::zoned_time<duration2> zt2{tz, zt, cr::choose::earliest}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } + { + using duration = cr::milliseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert(std::constructible_from<cr::zoned_time<duration2>, + const cr::time_zone*, + cr::zoned_time<duration, int>, + cr::choose>); + cr::zoned_time<duration2> zt2{tz, zt, cr::choose::earliest}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000}}); + } + { + using duration = cr::seconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration, int> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert(std::constructible_from<cr::zoned_time<duration2>, + const cr::time_zone*, + cr::zoned_time<duration, int>, + cr::choose>); + cr::zoned_time<duration2> zt2{tz, zt, cr::choose::earliest}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000'000}}); + } + // is_convertible_v<sys_time<Duration2>, sys_time<Duration>> is false. + { + using duration = cr::milliseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from<cr::zoned_time<duration2>, + const cr::time_zone*, + cr::zoned_time<duration, int>, + cr::choose>); + } + { + using duration = cr::microseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from<cr::zoned_time<duration2>, + const cr::time_zone*, + cr::zoned_time<duration, int>, + cr::choose>); + } + { + using duration = cr::nanoseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from<cr::zoned_time<duration2>, + const cr::time_zone*, + cr::zoned_time<duration, int>, + cr::choose>); + } + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/zoned_time_duration2.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/zoned_time_duration2.pass.cpp new file mode 100644 index 00000000000000..5a61b3ce4d185f --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtime/time.zone.zonedtime.ctor/zoned_time_duration2.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: no-filesystem, no-localization, no-tzdb + +// XFAIL: libcpp-has-no-experimental-tzdb +// XFAIL: availability-tzdb-missing + +// <chrono> + +// template<class Duration, class TimeZonePtr = const time_zone*> +// class zoned_time; + +// template<class Duration2> +// zoned_time(const zoned_time<Duration2, TimeZonePtr>& y); + +#include <chrono> +#include <concepts> +#include <cassert> + +namespace cr = std::chrono; + +int main(int, char**) { + // is_convertible_v<sys_time<Duration2>, sys_time<Duration>> is true. + { + using duration = cr::microseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert(std::constructible_from<cr::zoned_time<duration2>, cr::zoned_time<duration>>); + cr::zoned_time<duration2> zt2{zt}; + + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } + { + using duration = cr::milliseconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert(std::constructible_from<cr::zoned_time<duration2>, cr::zoned_time<duration>>); + cr::zoned_time<duration2> zt2{zt}; + + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000}}); + } + { + using duration = cr::seconds; + using time_point = cr::sys_time<duration>; + cr::zoned_time<duration> zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time<duration2>; + static_assert(std::constructible_from<cr::zoned_time<duration2>, cr::zoned_time<duration>>); + cr::zoned_time<duration2> zt2{zt}; + + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000'000}}); + } + // is_convertible_v<sys_time<Duration2>, sys_time<Duration>> is false. + { + using duration = cr::milliseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from<cr::zoned_time<duration2>, cr::zoned_time<duration>>); + } + { + using duration = cr::microseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from<cr::zoned_time<duration2>, cr::zoned_time<duration>>); + } + { + using duration = cr::nanoseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from<cr::zoned_time<duration2>, cr::zoned_time<duration>>); + } + + return 0; +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits