https://github.com/mordante created https://github.com/llvm/llvm-project/pull/91059
Implements parts of: - P0355 Extending chrono to Calendars and Time Zones >From 0a602d2268923936a62034faaaf10f2401457d99 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] Implements zoned_traits. Implements parts of: - P0355 Extending chrono to Calendars and Time Zones --- libcxx/include/CMakeLists.txt | 1 + libcxx/include/__chrono/zoned_time.h | 55 +++++++++++++++++++ libcxx/include/chrono | 4 ++ libcxx/include/module.modulemap | 1 + libcxx/modules/std/chrono.inc | 3 +- .../diagnostics/chrono.nodiscard.verify.cpp | 6 ++ .../const_time_zone_default_zone.pass.cpp | 36 ++++++++++++ .../const_time_zone_locate_zone.pass.cpp | 45 +++++++++++++++ .../types.compile.pass.cpp | 32 +++++++++++ 9 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 libcxx/include/__chrono/zoned_time.h create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_default_zone.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_locate_zone.pass.cpp create mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtraits/types.compile.pass.cpp diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 386bd967eed7ab..919f1ae39390a8 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -291,6 +291,7 @@ set(files __chrono/year_month.h __chrono/year_month_day.h __chrono/year_month_weekday.h + __chrono/zoned_time.h __compare/common_comparison_category.h __compare/compare_partial_order_fallback.h __compare/compare_strong_order_fallback.h diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h new file mode 100644 index 00000000000000..c6084426ad72b4 --- /dev/null +++ b/libcxx/include/__chrono/zoned_time.h @@ -0,0 +1,55 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_ZONED_TIME_H +#define _LIBCPP___CHRONO_ZONED_TIME_H + +#include <version> +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +# include <__chrono/time_zone.h> +# include <__chrono/tzdb_list.h> +# include <__config> +# include <__fwd/string_view.h> + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + +namespace chrono { + +template <class> +struct zoned_traits {}; + +template <> +struct zoned_traits<const time_zone*> { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static const time_zone* default_zone() { return chrono::locate_zone("UTC"); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static const time_zone* locate_zone(string_view __name) { + return chrono::locate_zone(__name); + } +}; + +} // namespace chrono + +# endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) + // && !defined(_LIBCPP_HAS_NO_LOCALIZATION) + +_LIBCPP_END_NAMESPACE_STD + +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +#endif // _LIBCPP___CHRONO_ZONED_TIME_H diff --git a/libcxx/include/chrono b/libcxx/include/chrono index d6b889cdde73c4..7d341823755ffb 100644 --- a/libcxx/include/chrono +++ b/libcxx/include/chrono @@ -786,6 +786,9 @@ class time_zone { bool operator==(const time_zone& x, const time_zone& y) noexcept; // C++20 strong_ordering operator<=>(const time_zone& x, const time_zone& y) noexcept; // C++20 +// [time.zone.zonedtraits], class template zoned_traits +template<class T> struct zoned_traits; // C++20 + // [time.zone.leap], leap second support class leap_second { // C++20 public: @@ -959,6 +962,7 @@ constexpr chrono::year operator ""y(unsigned lo # include <__chrono/time_zone_link.h> # include <__chrono/tzdb.h> # include <__chrono/tzdb_list.h> +# include <__chrono/zoned_time.h> # endif #endif diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index e4c154d99602b8..5c0da3e8172571 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -1170,6 +1170,7 @@ module std_private_chrono_year [system] { header "__chrono/yea module std_private_chrono_year_month [system] { header "__chrono/year_month.h" } module std_private_chrono_year_month_day [system] { header "__chrono/year_month_day.h" } module std_private_chrono_year_month_weekday [system] { header "__chrono/year_month_weekday.h" } +module std_private_chrono_zoned_time [system] { header "__chrono/zoned_time.h" } module std_private_compare_common_comparison_category [system] { header "__compare/common_comparison_category.h" } module std_private_compare_compare_partial_order_fallback [system] { header "__compare/compare_partial_order_fallback.h" } diff --git a/libcxx/modules/std/chrono.inc b/libcxx/modules/std/chrono.inc index 9e16f09bd31afb..bd6cb6c835645c 100644 --- a/libcxx/modules/std/chrono.inc +++ b/libcxx/modules/std/chrono.inc @@ -220,11 +220,10 @@ export namespace std { using std::chrono::choose; using std::chrono::time_zone; -# if 0 - // [time.zone.zonedtraits], class template zoned_traits using std::chrono::zoned_traits; +# if 0 // [time.zone.zonedtime], class template zoned_time using std::chrono::zoned_time; diff --git a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp index cba7916ff2c646..6fed41bdb43edb 100644 --- a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp @@ -72,4 +72,10 @@ void test() { leap.date(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} leap.value(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } + + { + using t = std::chrono::zoned_traits<const std::chrono::time_zone*>; + t::default_zone(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + t::locate_zone(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } } diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_default_zone.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_default_zone.pass.cpp new file mode 100644 index 00000000000000..c6527094bb6215 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_default_zone.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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<> struct zoned_traits<const time_zone*>; + +// static const time_zone* default_zone(); + +#include <chrono> +#include <cassert> + +int main(int, char**) { + std::same_as<const std::chrono::time_zone*> decltype(auto) tz = + std::chrono::zoned_traits<const std::chrono::time_zone*>::default_zone(); + assert(tz); + + // The time zone "UTC" can be a link, this means tz->name() can be something + // differently. For example, "Etc/UTC". Instead validate whether same time + // zone is returned by comparing the addresses. + const std::chrono::time_zone* expected = std::chrono::locate_zone("UTC"); + assert(tz == expected); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_locate_zone.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_locate_zone.pass.cpp new file mode 100644 index 00000000000000..1c8184455f23cf --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_locate_zone.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// 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<> struct zoned_traits<const time_zone*>; + +// static const time_zone* locate_zone(string_view name); + +#include <chrono> +#include <cassert> +#include <concepts> + +#include "assert_macros.h" + +static void test(std::string_view name) { + std::same_as<const std::chrono::time_zone*> decltype(auto) tz = + std::chrono::zoned_traits<const std::chrono::time_zone*>::locate_zone(name); + + const std::chrono::time_zone* expected = std::chrono::locate_zone(name); + assert(tz == expected); +} + +int main(int, char**) { + test("UTC"); + test("Europe/Berlin"); + test("Asia/Hong_Kong"); + + TEST_THROWS_TYPE(std::runtime_error, + TEST_IGNORE_NODISCARD std::chrono::zoned_traits<const std::chrono::time_zone*>::locate_zone( + "there_is_no_time_zone_with_this_name")); + + return 0; +} diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtraits/types.compile.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtraits/types.compile.pass.cpp new file mode 100644 index 00000000000000..03c18215f3c302 --- /dev/null +++ b/libcxx/test/std/time/time.zone/time.zone.zonedtraits/types.compile.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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 T> struct zoned_traits {}; +// +// A specialization for const time_zone* is provided by the implementation: +// template<> struct zoned_traits<const time_zone*> { ... } + +#include <chrono> +#include <type_traits> + +// This test test whether non-specialized versions exhibit the expected +// behavior. (Note these specializations are not really useful.) +static_assert(std::is_trivial_v<std::chrono::zoned_traits<int>>); +static_assert(std::is_trivial_v<std::chrono::zoned_traits<float>>); +static_assert(std::is_trivial_v<std::chrono::zoned_traits<void*>>); + +struct foo {}; +static_assert(std::is_trivial_v<std::chrono::zoned_traits<foo>>); _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits