From 6d6dade0997a414431bf852742cd68c24d274e27 Mon Sep 17 00:00:00 2001 From: Mark de Wever 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 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 `__","Expression in ``year::ok()``\ returns clause is ill-formed","Cologne","|Complete|","" "","","","","","" "`3231 `__","``year_month_day_last::day``\ specification does not cover ``!ok()``\ values","Belfast","|Nothing To Do|","" -"`3225 `__","``zoned_time``\ converting constructor shall not be ``noexcept``\ ","Belfast","","","|chrono|" +"`3225 `__","``zoned_time``\ converting constructor shall not be ``noexcept``\ ","Belfast","|Complete|","19.0","|chrono|" "`3190 `__","``std::allocator::allocate``\ sometimes returns too little storage","Belfast","|Complete|","14.0" "`3218 `__","Modifier for ``%d``\ parse flag does not match POSIX and ``format``\ specification","Belfast","","","|chrono| |format|" "`3224 `__","``zoned_time``\ constructor from ``TimeZonePtr``\ does not specify initialization of ``tp_``\ ","Belfast","|Complete|","19.0","|chrono|" @@ -199,7 +199,7 @@ "`3194 `__","``ConvertibleTo``\ prose does not match code","Prague","|Complete|","13.0" "`3200 `__","``midpoint``\ should not constrain ``T``\ is complete","Prague","|Nothing To Do|","" "`3201 `__","``lerp``\ should be marked as ``noexcept``\ ","Prague","|Complete|","" -"`3226 `__","``zoned_time``\ constructor from ``string_view``\ should accept ``zoned_time``\ ","Prague","","","|chrono|" +"`3226 `__","``zoned_time``\ constructor from ``string_view``\ should accept ``zoned_time``\ ","Prague","|Complete|","19.0","|chrono|" "`3233 `__","Broken requirements for ``shared_ptr``\ converting constructors","Prague","|Complete|","19.0" "`3237 `__","LWG 3038 and 3190 have inconsistent PRs","Prague","|Complete|","16.0" "`3238 `__","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 + // 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 - // 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 + _LIBCPP_HIDE_FROM_ABI zoned_time(const zoned_time<_Duration2, _TimeZonePtr>& __zt) + requires is_convertible_v, 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() -> to_sys(local_time<_Duration>{})), + sys_time>) + : __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() -> to_sys(local_time<_Duration>{})), + sys_time>) + : 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>) + : __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() -> to_sys(local_time<_Duration>{}, choose::earliest)), + sys_time>) + : zoned_time{__traits::locate_zone(__name), __tp, __c} {} + + template + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const zoned_time<_Duration2, _TimeZonePtr2>& __zt) + requires is_convertible_v, sys_time<_Duration>> + : __zone_{std::move(__zone)}, __tp_{__zt.get_sys_time()} {} + + // per wording choose has no effect + template + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const zoned_time<_Duration2, _TimeZonePtr2>& __zt, choose) + requires is_convertible_v, sys_time<_Duration>> + : __zone_{std::move(__zone)}, __tp_{__zt.get_sys_time()} {} + + template + _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<_Duration>>) + : zoned_time{__traits::locate_zone(__name), __zt} {} + + template + _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<_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 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 #include #include +#include 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 + std::chrono::sys_time> + to_sys(const std::chrono::local_time& local) const { + return std::chrono::sys_time>{ + 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 + +// + +// template +// class zoned_time; +// +// zoned_time(string_view name, const local_time& st); + +#include +#include + +#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, std::string_view, cr::sys_seconds>); + + cr::zoned_time 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; + static_assert(!std::constructible_from, std::string_view, cr::local_seconds>); + } + + { + using ptr = offset_time_zone; + static_assert(!std::constructible_from, std::string_view, cr::local_seconds>); + } + + { + using ptr = offset_time_zone; + static_assert(std::constructible_from, std::string_view, cr::local_seconds>); + + ptr tz; + cr::zoned_time 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; + static_assert(std::constructible_from, std::string_view, cr::local_seconds>); + + ptr tz; + cr::zoned_time 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 + +// + +// template +// class zoned_time; +// +// zoned_time(string_view name, const local_time& st, choose c); + +#include +#include +#include + +#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 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 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 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, + std::string_view, + cr::local_seconds, + cr::choose>); + + static_assert(!std::constructible_from< cr::zoned_time>, + std::string_view, + cr::local_seconds, + cr::choose>); + + static_assert( + !std::constructible_from< cr::zoned_time>, + std::string_view, + cr::local_seconds, + cr::choose>); + + static_assert( + !std::constructible_from< cr::zoned_time>, + std::string_view, + cr::local_seconds, + cr::choose>); + + static_assert(!std::constructible_from< cr::zoned_time>, + 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 + +// + +// template +// class zoned_time; +// +// zoned_time(string_view name, const sys_time& st); + +#include +#include + +#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, std::string_view, cr::sys_seconds>); + + cr::zoned_time 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; + static_assert(!std::constructible_from, std::string_view, cr::sys_seconds>); + } + + { + using ptr = offset_time_zone; + static_assert(!std::constructible_from, std::string_view, cr::sys_seconds>); + } + + { + using ptr = offset_time_zone; + static_assert(std::constructible_from, std::string_view, cr::sys_seconds>); + + ptr tz; + cr::zoned_time 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; + static_assert(std::constructible_from, std::string_view, cr::sys_seconds>); + + ptr tz; + cr::zoned_time 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 + +// + +// template +// class zoned_time; + +// template +// zoned_time(string_view name, const zoned_time& y); + +#include +#include +#include + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +template <> +struct cr::zoned_traits { + 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> is true. + { + using duration = cr::microseconds; + using time_point = cr::sys_time; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert(std::constructible_from, std::string_view, cr::zoned_time>); + cr::zoned_time 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; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert(std::constructible_from, std::string_view, cr::zoned_time>); + cr::zoned_time 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; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert(std::constructible_from, std::string_view, cr::zoned_time>); + cr::zoned_time 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> is false. + { + using duration = cr::milliseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from, std::string_view, cr::zoned_time>); + } + { + using duration = cr::microseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from, std::string_view, cr::zoned_time>); + } + { + using duration = cr::nanoseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from, std::string_view, cr::zoned_time>); + } +} + +static void test_locate_zone() { + using duration = cr::microseconds; + using time_point = cr::sys_time; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + + { + using ptr = const cr::time_zone*; + static_assert( + std::constructible_from, std::string_view, cr::zoned_time>); + ptr tz = cr::locate_zone("UTC"); + cr::zoned_time zt2{"UTC", zt}; + + assert(zt2.get_time_zone() == tz); + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } + + { + using ptr = offset_time_zone; + static_assert( + !std::constructible_from, std::string_view, cr::zoned_time>); + } + { + using ptr = offset_time_zone; + static_assert( + !std::constructible_from, std::string_view, cr::zoned_time>); + } + { + using ptr = offset_time_zone; + static_assert( + std::constructible_from, std::string_view, cr::zoned_time>); + + ptr tz; + cr::zoned_time 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; + static_assert( + std::constructible_from, std::string_view, cr::zoned_time>); + + ptr tz; + cr::zoned_time 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 + +// + +// template +// class zoned_time; + +// template +// zoned_time(string_view name, const zoned_time& y, choose c); + +#include +#include +#include + +#include "../test_offset_time_zone.h" + +namespace cr = std::chrono; + +template <> +struct cr::zoned_traits { + 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> is true. + { + using duration = cr::microseconds; + using time_point = cr::sys_time; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert( + std:: + constructible_from, std::string_view, cr::zoned_time, cr::choose>); + cr::zoned_time 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; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert( + std:: + constructible_from, std::string_view, cr::zoned_time, cr::choose>); + cr::zoned_time 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; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert( + std:: + constructible_from, std::string_view, cr::zoned_time, cr::choose>); + cr::zoned_time 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> is false. + { + using duration = cr::milliseconds; + + using duration2 = cr::seconds; + static_assert( + !std:: + constructible_from, std::string_view, cr::zoned_time, cr::choose>); + } + { + using duration = cr::microseconds; + + using duration2 = cr::seconds; + static_assert( + !std:: + constructible_from, std::string_view, cr::zoned_time, cr::choose>); + } + { + using duration = cr::nanoseconds; + + using duration2 = cr::seconds; + static_assert( + !std:: + constructible_from, std::string_view, cr::zoned_time, cr::choose>); + } +} + +static void test_locate_zone() { + using duration = cr::microseconds; + using time_point = cr::sys_time; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + + { + using ptr = const cr::time_zone*; + static_assert(std::constructible_from, + std::string_view, + cr::zoned_time, + cr::choose>); + ptr tz = cr::locate_zone("UTC"); + cr::zoned_time 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; + static_assert(!std::constructible_from, + std::string_view, + cr::zoned_time, + cr::choose>); + } + { + using ptr = offset_time_zone; + static_assert(!std::constructible_from, + std::string_view, + cr::zoned_time, + cr::choose>); + } + { + using ptr = offset_time_zone; + static_assert(std::constructible_from, + std::string_view, + cr::zoned_time, + cr::choose>); + + ptr tz; + cr::zoned_time 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; + static_assert(std::constructible_from, + std::string_view, + cr::zoned_time, + cr::choose>); + + ptr tz; + cr::zoned_time 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 + +// + +// template +// class zoned_time; +// +// zoned_time(TimeZonePtr z, const local_time& st); + +#include +#include +#include + +#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 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; + ptr tz{"60"}; + cr::zoned_time 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; + static_assert(std::constructible_from, ptr>); + static_assert(!std::convertible_to>); + + ptr tz{"60"}; + cr::zoned_time 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; + static_assert(std::constructible_from, ptr>); + static_assert(!std::convertible_to>); + + ptr tz{"60"}; + cr::zoned_time 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; + static_assert(std::constructible_from, ptr>); + static_assert(!std::convertible_to>); + + ptr tz{"60"}; + cr::zoned_time 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 + +// + +// template +// class zoned_time; +// +// zoned_time(TimeZonePtr z, const local_time& st, choose c); + +#include +#include +#include + +#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 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 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 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, + const cr::time_zone*, + cr::local_seconds, + cr::choose>); + + static_assert(!std::constructible_from>, + offset_time_zone, + cr::local_seconds, + cr::choose>); + + static_assert( + !std::constructible_from>, + offset_time_zone, + cr::local_seconds, + cr::choose>); + + static_assert( + !std::constructible_from>, + offset_time_zone, + cr::local_seconds, + cr::choose>); + + static_assert(!std::constructible_from>, + offset_time_zone, + 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 + +// + +// template +// class zoned_time; +// +// zoned_time(TimeZonePtr z, const sys_time& st); + +#include +#include +#include + +#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, ptr>); + static_assert(!std::convertible_to>); + + ptr tz = cr::locate_zone("UTC"); + cr::zoned_time 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; + static_assert(std::constructible_from, ptr>); + static_assert(!std::convertible_to>); + + ptr tz; + cr::zoned_time 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; + static_assert(std::constructible_from, ptr>); + static_assert(!std::convertible_to>); + + ptr tz; + cr::zoned_time 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; + static_assert(std::constructible_from, ptr>); + static_assert(!std::convertible_to>); + + ptr tz; + cr::zoned_time 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; + static_assert(std::constructible_from, ptr>); + static_assert(!std::convertible_to>); + + ptr tz; + cr::zoned_time 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 + +// + +// template +// class zoned_time; + +// template +// zoned_time(TimeZonePtr z, const zoned_time& y); + +#include +#include +#include + +namespace cr = std::chrono; + +template <> +struct cr::zoned_traits { + 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> is true. + { + using duration = cr::microseconds; + using time_point = cr::sys_time; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert( + std::constructible_from, const cr::time_zone*, cr::zoned_time>); + cr::zoned_time 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; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert( + std::constructible_from, const cr::time_zone*, cr::zoned_time>); + cr::zoned_time 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; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert( + std::constructible_from, const cr::time_zone*, cr::zoned_time>); + cr::zoned_time 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> is false. + { + using duration = cr::milliseconds; + + using duration2 = cr::seconds; + static_assert( + !std::constructible_from, const cr::time_zone*, cr::zoned_time>); + } + { + using duration = cr::microseconds; + + using duration2 = cr::seconds; + static_assert( + !std::constructible_from, const cr::time_zone*, cr::zoned_time>); + } + { + using duration = cr::nanoseconds; + + using duration2 = cr::seconds; + static_assert( + !std::constructible_from, const cr::time_zone*, cr::zoned_time>); + } + + 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 + +// + +// template +// class zoned_time; + +// template +// zoned_time(TimeZonePtr z, const zoned_time& y, choose); + +#include +#include +#include + +namespace cr = std::chrono; + +template <> +struct cr::zoned_traits { + 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> is true. + { + using duration = cr::microseconds; + using time_point = cr::sys_time; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert(std::constructible_from, + const cr::time_zone*, + cr::zoned_time, + cr::choose>); + cr::zoned_time 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; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert(std::constructible_from, + const cr::time_zone*, + cr::zoned_time, + cr::choose>); + cr::zoned_time 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; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert(std::constructible_from, + const cr::time_zone*, + cr::zoned_time, + cr::choose>); + cr::zoned_time 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> is false. + { + using duration = cr::milliseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from, + const cr::time_zone*, + cr::zoned_time, + cr::choose>); + } + { + using duration = cr::microseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from, + const cr::time_zone*, + cr::zoned_time, + cr::choose>); + } + { + using duration = cr::nanoseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from, + const cr::time_zone*, + cr::zoned_time, + 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 + +// + +// template +// class zoned_time; + +// template +// zoned_time(const zoned_time& y); + +#include +#include +#include + +namespace cr = std::chrono; + +int main(int, char**) { + // is_convertible_v, sys_time> is true. + { + using duration = cr::microseconds; + using time_point = cr::sys_time; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert(std::constructible_from, cr::zoned_time>); + cr::zoned_time zt2{zt}; + + assert(zt2.get_sys_time() == time_point2{duration2{42'000}}); + } + { + using duration = cr::milliseconds; + using time_point = cr::sys_time; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert(std::constructible_from, cr::zoned_time>); + cr::zoned_time zt2{zt}; + + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000}}); + } + { + using duration = cr::seconds; + using time_point = cr::sys_time; + cr::zoned_time zt{time_point{duration{42}}}; + + using duration2 = cr::nanoseconds; + using time_point2 = cr::sys_time; + static_assert(std::constructible_from, cr::zoned_time>); + cr::zoned_time zt2{zt}; + + assert(zt2.get_sys_time() == time_point2{duration2{42'000'000'000}}); + } + // is_convertible_v, sys_time> is false. + { + using duration = cr::milliseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from, cr::zoned_time>); + } + { + using duration = cr::microseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from, cr::zoned_time>); + } + { + using duration = cr::nanoseconds; + + using duration2 = cr::seconds; + static_assert(!std::constructible_from, cr::zoned_time>); + } + + return 0; +}