[libcxx-commits] [libcxx] [libc++][chrono] Loads tzdata.zi in tzdb. (PR #74928)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Dec 9 04:01:41 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Mark de Wever (mordante)

<details>
<summary>Changes</summary>

This implements the loading of the tzdata.zi file and store its contents in the tzdb struct.

This adds all required members except:
- the leap seconds,
- the locate_zone, and
- current_zone.

The class time_zone is incomplete and only contains the parts needed for storing the parsed data.

The class time_zone_link is fully implemented including its non-member functions.

Implements parts of:
- P0355 Extending <chrono> to Calendars and Time Zones
- P1614 The Mothership has Landed

Implements:
- P1982 Rename link to time_zone_link

---

Patch is 91.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74928.diff


31 Files Affected:

- (modified) libcxx/docs/Status/Cxx20Papers.csv (+1-1) 
- (modified) libcxx/docs/Status/SpaceshipProjects.csv (+2-2) 
- (modified) libcxx/include/CMakeLists.txt (+3) 
- (added) libcxx/include/__chrono/time_zone.h (+75) 
- (added) libcxx/include/__chrono/time_zone_link.h (+72) 
- (added) libcxx/include/__chrono/time_zone_types.h (+112) 
- (modified) libcxx/include/__chrono/tzdb.h (+9) 
- (modified) libcxx/include/chrono (+32-8) 
- (modified) libcxx/modules/std/chrono.inc (+4) 
- (modified) libcxx/src/tz.cpp (+483) 
- (modified) libcxx/test/libcxx/diagnostics/chrono.nodiscard_extensions.compile.pass.cpp (+16) 
- (modified) libcxx/test/libcxx/diagnostics/chrono.nodiscard_extensions.verify.cpp (+19) 
- (added) libcxx/test/libcxx/time/time.zone/time.zone.db/links.pass.cpp (+102) 
- (added) libcxx/test/libcxx/time/time.zone/time.zone.db/rules.pass.cpp (+565) 
- (added) libcxx/test/libcxx/time/time.zone/time.zone.db/zones.pass.cpp (+371) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx03.csv (+2) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx11.csv (+2) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx14.csv (+2) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx17.csv (+2) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx20.csv (+2) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx23.csv (+2) 
- (modified) libcxx/test/libcxx/transitive_includes/cxx26.csv (+2) 
- (modified) libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.access/get_tzdb.pass.cpp (+12-2) 
- (modified) libcxx/test/std/time/time.zone/time.zone.db/time.zone.db.tzdb/tzdb.members.pass.cpp (+8-1) 
- (added) libcxx/test/std/time/time.zone/time.zone.link/time.zone.link.members/name.pass.cpp (+35) 
- (added) libcxx/test/std/time/time.zone/time.zone.link/time.zone.link.members/target.pass.cpp (+34) 
- (added) libcxx/test/std/time/time.zone/time.zone.link/time.zone.link.nonmembers/comparison.pass.cpp (+36) 
- (added) libcxx/test/std/time/time.zone/time.zone.link/types.compile.pass.cpp (+30) 
- (added) libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/name.pass.cpp (+35) 
- (added) libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.nonmembers/comparison.pass.cpp (+36) 
- (added) libcxx/test/std/time/time.zone/time.zone.timezone/types.compile.pass.cpp (+30) 


``````````diff
diff --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv
index 13c126c1ba8be..53d57acacf01a 100644
--- a/libcxx/docs/Status/Cxx20Papers.csv
+++ b/libcxx/docs/Status/Cxx20Papers.csv
@@ -180,7 +180,7 @@
 "`P1973R1 <https://wg21.link/P1973R1>`__","LWG","Rename ""_default_init"" Functions, Rev1","Prague","|Complete|","16.0"
 "`P1976R2 <https://wg21.link/P1976R2>`__","LWG","Fixed-size span construction from dynamic range","Prague","|Complete|","11.0","|ranges|"
 "`P1981R0 <https://wg21.link/P1981R0>`__","LWG","Rename leap to leap_second","Prague","* *",""
-"`P1982R0 <https://wg21.link/P1982R0>`__","LWG","Rename link to time_zone_link","Prague","* *",""
+"`P1982R0 <https://wg21.link/P1982R0>`__","LWG","Rename link to time_zone_link","Prague","|Complete|","18.0","|chrono|"
 "`P1983R0 <https://wg21.link/P1983R0>`__","LWG","Wording for GB301, US296, US292, US291, and US283","Prague","|Complete|","15.0","|ranges|"
 "`P1994R1 <https://wg21.link/P1994R1>`__","LWG","elements_view needs its own sentinel","Prague","|Complete|","16.0","|ranges|"
 "`P2002R1 <https://wg21.link/P2002R1>`__","CWG","Defaulted comparison specification cleanups","Prague","* *",""
diff --git a/libcxx/docs/Status/SpaceshipProjects.csv b/libcxx/docs/Status/SpaceshipProjects.csv
index aaa9278a50c1e..c8221078e9a8d 100644
--- a/libcxx/docs/Status/SpaceshipProjects.csv
+++ b/libcxx/docs/Status/SpaceshipProjects.csv
@@ -171,10 +171,10 @@ Section,Description,Dependencies,Assignee,Complete
 | `month_weekday_last <https://reviews.llvm.org/D152699>`_
 | `year_month_weekday <https://reviews.llvm.org/D152699>`_
 | `year_month_weekday_last <https://reviews.llvm.org/D152699>`_",None,Hristo Hristov,|Complete|
-`[time.zone.nonmembers] <https://wg21.link/time.zone.nonmembers>`_,"`chrono::time_zone`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
+`[time.zone.nonmembers] <https://wg21.link/time.zone.nonmembers>`_,"`chrono::time_zone`",A ``<chrono>`` implementation,Mark de Wever,|Complete|
 `[time.zone.zonedtime.nonmembers] <https://wg21.link/time.zone.zonedtime.nonmembers>`_,"`chrono::zoned_time`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
 `[time.zone.leap.nonmembers] <https://wg21.link/time.zone.leap.nonmembers>`_,"`chrono::time_leap_seconds`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
-`[time.zone.link.nonmembers] <https://wg21.link/time.zone.link.nonmembers>`_,"`chrono::time_zone_link`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
+`[time.zone.link.nonmembers] <https://wg21.link/time.zone.link.nonmembers>`_,"`chrono::time_zone_link`",A ``<chrono>`` implementation,Mark de Wever,|Complete|
 - `5.13 Clause 28: Localization library <https://wg21.link/p1614r2#clause-28-localization-library>`_,,,,
 "| `[locale] <https://wg21.link/locale>`_
 | `[locale.operators] <https://wg21.link/locale.operators>`_",| remove ops `locale <https://reviews.llvm.org/D152654>`_,None,Hristo Hristov,|Complete|
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index d8faf6467b79a..a71d2f0a02b3f 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -287,6 +287,9 @@ set(files
   __chrono/steady_clock.h
   __chrono/system_clock.h
   __chrono/time_point.h
+  __chrono/time_zone.h
+  __chrono/time_zone_link.h
+  __chrono/time_zone_types.h
   __chrono/tzdb.h
   __chrono/tzdb_list.h
   __chrono/weekday.h
diff --git a/libcxx/include/__chrono/time_zone.h b/libcxx/include/__chrono/time_zone.h
new file mode 100644
index 0000000000000..7b6f689511a2c
--- /dev/null
+++ b/libcxx/include/__chrono/time_zone.h
@@ -0,0 +1,75 @@
+// -*- 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_TIME_ZONE_H
+#define _LIBCPP___CHRONO_TIME_ZONE_H
+
+#include <version>
+// Enable the contents of the header only when libc++ was built with experimental features enabled.
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+
+#  include <__chrono/time_zone_types.h>
+#  include <__compare/strong_order.h>
+#  include <__config>
+#  include <string>
+#  include <string_view>
+#  include <vector>
+
+#  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 {
+
+class _LIBCPP_AVAILABILITY_TZDB time_zone {
+public:
+  explicit time_zone(string&& __name) : __name_(std::move(__name)) {}
+
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name_; }
+
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI vector<__tz::__continuation>& __continuations() { return __continuations_; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const vector<__tz::__continuation>& __continuations() const {
+    return __continuations_;
+  }
+
+private:
+  string __name_;
+  // Note the first line has a name + __continuation, the other lines
+  // are just __continuations. So there is always at least one item in
+  // the vector.
+  vector<__tz::__continuation> __continuations_;
+};
+
+_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool
+operator==(const time_zone& __x, const time_zone& __y) noexcept {
+  return __x.name() == __y.name();
+}
+
+_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering
+operator<=>(const time_zone& __x, const time_zone& __y) noexcept {
+  return __x.name() <=> __y.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_INCOMPLETE_TZDB)
+
+#endif // _LIBCPP___CHRONO_TIME_ZONE_H
diff --git a/libcxx/include/__chrono/time_zone_link.h b/libcxx/include/__chrono/time_zone_link.h
new file mode 100644
index 0000000000000..42fd3bb63ca20
--- /dev/null
+++ b/libcxx/include/__chrono/time_zone_link.h
@@ -0,0 +1,72 @@
+// -*- 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_TIME_ZONE_LINK_H
+#define _LIBCPP___CHRONO_TIME_ZONE_LINK_H
+
+#include <version>
+// Enable the contents of the header only when libc++ was built with experimental features enabled.
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+
+#  include <__compare/strong_order.h>
+#  include <__config>
+#  include <string>
+#  include <string_view>
+
+#  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 {
+
+class _LIBCPP_AVAILABILITY_TZDB time_zone_link {
+public:
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI explicit time_zone_link(string_view __name, string_view __target)
+      : __name_{__name}, __target_{__target} {}
+
+  time_zone_link(time_zone_link&&)            = default;
+  time_zone_link& operator=(time_zone_link&&) = default;
+
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name_; }
+  _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view target() const noexcept { return __target_; }
+
+private:
+  string __name_;
+  // TODO TZDB instead of the name we can store the pointer to a zone. These
+  // pointers are immutable. This makes it possible to directly return a
+  // pointer in the time_zone in the 'locate_zone' function.
+  string __target_;
+};
+
+_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool
+operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept {
+  return __x.name() == __y.name();
+}
+
+_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering
+operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept {
+  return __x.name() <=> __y.name();
+}
+
+} // namespace chrono
+
+#  endif //_LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+
+#endif // _LIBCPP___CHRONO_TIME_ZONE_LINK_H
diff --git a/libcxx/include/__chrono/time_zone_types.h b/libcxx/include/__chrono/time_zone_types.h
new file mode 100644
index 0000000000000..e8d7b7ddf8465
--- /dev/null
+++ b/libcxx/include/__chrono/time_zone_types.h
@@ -0,0 +1,112 @@
+// -*- 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_TIME_ZONE_TYPES_H
+#define _LIBCPP___CHRONO_TIME_ZONE_TYPES_H
+
+#include <version>
+// Enable the contents of the header only when libc++ was built with experimental features enabled.
+#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+
+#  include <__chrono/day.h>
+#  include <__chrono/duration.h>
+#  include <__chrono/month.h>
+#  include <__chrono/weekday.h>
+#  include <__chrono/year.h>
+#  include <__config>
+#  include <string>
+#  include <variant>
+
+#  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::__tz {
+
+// Sun>=8   first Sunday on or after the eighth
+// Sun<=25  last Sunday on or before the 25th
+struct _LIBCPP_AVAILABILITY_TZDB __constrained_weekday {
+  /*  year_month_day operator()(year __year, month __month);*/ // needed but not implemented
+
+  weekday __weekday;
+  enum __comparison_t { __le, __ge } __comparison;
+  day __day;
+};
+
+// The on field has a few alternative presentations
+//  5        the fifth of the month
+//  lastSun  the last Sunday in the month
+//  lastMon  the last Monday in the month
+//  Sun>=8   first Sunday on or after the eighth
+//  Sun<=25  last Sunday on or before the 25th
+using __on = variant<day, weekday_last, __constrained_weekday>;
+
+enum class _LIBCPP_AVAILABILITY_TZDB __clock { __local, __standard, __universal };
+
+struct _LIBCPP_AVAILABILITY_TZDB __at {
+  seconds __time{0};
+  __tz::__clock __clock{__tz::__clock::__local};
+};
+
+struct _LIBCPP_AVAILABILITY_TZDB __save {
+  seconds __time;
+  bool __is_dst;
+};
+
+// The names of the fields match the fields of a Rule.
+struct _LIBCPP_AVAILABILITY_TZDB __rule {
+  year __from;
+  year __to;
+  month __in_month; // __in is a reserved name
+  __tz::__on __on;
+  __tz::__at __at;
+  __tz::__save __save;
+  string __letters;
+};
+
+struct _LIBCPP_AVAILABILITY_TZDB __continuation {
+  seconds __stdoff;
+
+  // The RULES is either a SAVE or a NAME.
+  // The size_t is used as cache. After loading the rules they are
+  // sorted and remain stable, then an index in the vector can be
+  // used.
+  // If this field contains - then standard time always
+  // applies. This is indicated by the monostate.
+  using __rules_t = variant<monostate, __tz::__save, string, size_t>;
+
+  __rules_t __rules;
+
+  string __format;
+  // TODO TZDB until can be contain more than just a year.
+  // Parts of the UNTIL, the optional parts are default initialized
+  //    optional<year> __until_;
+  year __year = chrono::year::min();
+  month __in_month{January}; // __in is a reserved name
+  __tz::__on __on{chrono::day{1}};
+  __tz::__at __at{chrono::seconds{0}, __tz::__clock::__local};
+};
+
+} // namespace chrono::__tz
+
+#  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_INCOMPLETE_TZDB)
+
+#endif // _LIBCPP___CHRONO_TIME_ZONE_TYPES_H
diff --git a/libcxx/include/__chrono/tzdb.h b/libcxx/include/__chrono/tzdb.h
index bd7b05d478e50..fc230c550327d 100644
--- a/libcxx/include/__chrono/tzdb.h
+++ b/libcxx/include/__chrono/tzdb.h
@@ -16,7 +16,13 @@
 // Enable the contents of the header only when libc++ was built with experimental features enabled.
 #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
 
+#  include <__availability>
+#  include <__chrono/time_zone.h>
+#  include <__chrono/time_zone_link.h>
+#  include <__chrono/time_zone_types.h>
+#  include <__config>
 #  include <string>
+#  include <vector>
 
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #    pragma GCC system_header
@@ -31,6 +37,9 @@ namespace chrono {
 
 struct _LIBCPP_AVAILABILITY_TZDB tzdb {
   string version;
+  vector<pair<string, vector<__tz::__rule>>> __rules;
+  vector<time_zone> zones;
+  vector<time_zone_link> links;
 };
 
 } // namespace chrono
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index b3ed9acc5e5de..8eaeabeae9c8b 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -682,6 +682,8 @@ constexpr hours make24(const hours& h, bool is_pm) noexcept;
 // [time.zone.db], time zone database
 struct tzdb {                                                                    // C++20
   string                 version;
+  vector<time_zone>      zones;
+  vector<time_zone_link> links;
 };
 
 class tzdb_list {                                                                // C++20
@@ -712,15 +714,34 @@ tzdb_list& get_tzdb_list();
 const tzdb& reload_tzdb();                                                       // C++20
 string remote_version();                                                         // C++20
 
-// 25.10.5, class time_zone    // C++20
+// 25.10.5, class time_zone                                                      // C++20
 enum class choose {earliest, latest};
-class time_zone;
-bool operator==(const time_zone& x, const time_zone& y) noexcept;
-bool operator!=(const time_zone& x, const time_zone& y) noexcept;
-bool operator<(const time_zone& x, const time_zone& y) noexcept;
-bool operator>(const time_zone& x, const time_zone& y) noexcept;
-bool operator<=(const time_zone& x, const time_zone& y) noexcept;
-bool operator>=(const time_zone& x, const time_zone& y) noexcept;
+class time_zone {
+  time_zone(time_zone&&) = default;
+  time_zone& operator=(time_zone&&) = default;
+
+  // unspecified additional constructors
+
+  string_view name() const noexcept;
+};
+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.link], class time_zone_link
+class time_zone_link {                                                           // C++20
+public:
+  time_zone_link(time_zone_link&&)            = default;
+  time_zone_link& operator=(time_zone_link&&) = default;
+
+  // unspecified additional constructors
+
+  string_view name()   const noexcept;
+  string_view target() const noexcept;
+};
+
+bool operator==(const time_zone_link& x, const time_zone_link& y);               // C++20
+strong_ordering operator<=>(const time_zone_link& x, const time_zone_link& y);   // C++20
+
 }  // chrono
 
 namespace std {
@@ -838,6 +859,9 @@ constexpr chrono::year                                  operator ""y(unsigned lo
 
 #if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) &&                              \
     !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+#  include <__chrono/time_zone.h>
+#  include <__chrono/time_zone_link.h>
+#  include <__chrono/time_zone_types.h>
 #  include <__chrono/tzdb.h>
 #  include <__chrono/tzdb_list.h>
 #endif
diff --git a/libcxx/modules/std/chrono.inc b/libcxx/modules/std/chrono.inc
index 65dc973936c47..8ebe8d26065dc 100644
--- a/libcxx/modules/std/chrono.inc
+++ b/libcxx/modules/std/chrono.inc
@@ -221,7 +221,9 @@ export namespace std {
 
     // [time.zone.timezone], class time_zone
     using std::chrono::choose;
+#  endif
     using std::chrono::time_zone;
+#  if 0
 
     // [time.zone.zonedtraits], class template zoned_traits
     using std::chrono::zoned_traits;
@@ -233,10 +235,12 @@ export namespace std {
 
     // [time.zone.leap], leap second support
     using std::chrono::leap_second;
+#  endif
 
     // [time.zone.link], class time_zone_link
     using std::chrono::time_zone_link;
 
+#  if 0
     // [time.format], formatting
     using std::chrono::local_time_format;
 #  endif
diff --git a/libcxx/src/tz.cpp b/libcxx/src/tz.cpp
index 4425f0e6b91bd..472cac136dd77 100644
--- a/libcxx/src/tz.cpp
+++ b/libcxx/src/tz.cpp
@@ -8,6 +8,7 @@
 
 // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
 
+#include <algorithm>
 #include <chrono>
 #include <filesystem>
 #include <fstream>
@@ -49,6 +50,10 @@ _LIBCPP_WEAK string_view __libcpp_tzdb_directory() {
 #endif
 }
 
+//===----------------------------------------------------------------------===//
+//                           Details
+//===----------------------------------------------------------------------===//
+
 [[nodiscard]] static bool __is_whitespace(int __c) { return __c == ' ' || __c == '\t'; }
 
 static void __skip_optional_whitespace(istream& __input) {
@@ -63,6 +68,26 @@ static void __skip_mandatory_whitespace(istream& __input) {
   chrono::__skip_optional_whitespace(__input);
 }
 
+[[nodiscard]] static bool __is_eol(int __c) { return __c == '\n' || __c == std::char_traits<char>::eof(); }
+
+static void __skip_line(istream& __input) {
+  while (!chrono::__is_eol(__input.peek())) {
+    __input.get();
+  }
+  __input.get();
+}
+
+static void __skip(istream& __input, char __suffix) {
+  if (std::tolower(__input.peek()) == __suffix)
+    __input.get();
+}
+
+static void __skip(istream& __input, string_view __suffix) {
+  for (auto __c : __suffix)
+    if (std::tolower(__input.peek()) == __c)
+      __input.get();
+}
+
 static void __matches(istream& __input, char __expected) {
   if (std::tolower(__input.get()) != __expected)
     std::__throw_runtime_error((string("corrupt tzdb: expected character '") + __expected + '\'').c_str());
@@ -96,6 +121,369 @@ static void __matches(istream& __input, string_view __expected) {
   }
 }
 
+[[nodiscard]] static int64_t __parse_integral(istream& __input, bool __leading_zero_allowed) {
+  int64_t __result = __input.get();
+  if (__leading_zero_allowed) {
+    if (__result < '0' || __result > '9')
+      std::__throw_runtime_error("corrupt tzdb: expected a digit");
+  } else {
+    if (__result < '1' || __result > '9')
+      std::__throw_runtime_error("corrupt tzdb: expected a non-zero digit");
+  }
+  __result -= '0';
+  while (true) {
+    if (__input.peek() < '0' || __input.peek() > '9')
+      return __result;
+
+    // In order to avoid possible overflows we limit the accepted range.
+    // Most values parsed are expected to be very small:
+    // - 8784 hours in a year
+    // - 31 days in a month
+    // - year no real maximum, these values are expected to be less than
+    //   the range of the year type.
+    //
+    // However the leapseconds use a seconds after epoch value. Using an
+    // int would run into an overflow in 2038. By using a 64-bit value
+    // the range is large enough for the bilions of years. Limiting that
+    // range slightly to make the code easier is not an issue.
+    if (__result > (std::numeric_li...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/74928


More information about the libcxx-commits mailing list