Skip to content

Commit d332d88

Browse files
authored
[libc++][chrono] Loads tzdata.zi in tzdb. (#74928)
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
1 parent ded3ca2 commit d332d88

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2619
-242
lines changed

libcxx/docs/Status/Cxx20Papers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
"`P1973R1 <https://wg21.link/P1973R1>`__","LWG","Rename ""_default_init"" Functions, Rev1","Prague","|Complete|","16.0"
181181
"`P1976R2 <https://wg21.link/P1976R2>`__","LWG","Fixed-size span construction from dynamic range","Prague","|Complete|","11.0","|ranges|"
182182
"`P1981R0 <https://wg21.link/P1981R0>`__","LWG","Rename leap to leap_second","Prague","* *",""
183-
"`P1982R0 <https://wg21.link/P1982R0>`__","LWG","Rename link to time_zone_link","Prague","* *",""
183+
"`P1982R0 <https://wg21.link/P1982R0>`__","LWG","Rename link to time_zone_link","Prague","|Complete|","19.0","|chrono|"
184184
"`P1983R0 <https://wg21.link/P1983R0>`__","LWG","Wording for GB301, US296, US292, US291, and US283","Prague","|Complete|","15.0","|ranges|"
185185
"`P1994R1 <https://wg21.link/P1994R1>`__","LWG","elements_view needs its own sentinel","Prague","|Complete|","16.0","|ranges|"
186186
"`P2002R1 <https://wg21.link/P2002R1>`__","CWG","Defaulted comparison specification cleanups","Prague","* *",""

libcxx/docs/Status/SpaceshipProjects.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,10 @@ Section,Description,Dependencies,Assignee,Complete
171171
| `month_weekday_last <https://reviews.llvm.org/D152699>`_
172172
| `year_month_weekday <https://reviews.llvm.org/D152699>`_
173173
| `year_month_weekday_last <https://reviews.llvm.org/D152699>`_",None,Hristo Hristov,|Complete|
174-
`[time.zone.nonmembers] <https://wg21.link/time.zone.nonmembers>`_,"`chrono::time_zone`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
174+
`[time.zone.nonmembers] <https://wg21.link/time.zone.nonmembers>`_,"`chrono::time_zone`",A ``<chrono>`` implementation,Mark de Wever,|Complete|
175175
`[time.zone.zonedtime.nonmembers] <https://wg21.link/time.zone.zonedtime.nonmembers>`_,"`chrono::zoned_time`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
176176
`[time.zone.leap.nonmembers] <https://wg21.link/time.zone.leap.nonmembers>`_,"`chrono::time_leap_seconds`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
177-
`[time.zone.link.nonmembers] <https://wg21.link/time.zone.link.nonmembers>`_,"`chrono::time_zone_link`",A ``<chrono>`` implementation,Mark de Wever,|In Progress|
177+
`[time.zone.link.nonmembers] <https://wg21.link/time.zone.link.nonmembers>`_,"`chrono::time_zone_link`",A ``<chrono>`` implementation,Mark de Wever,|Complete|
178178
- `5.13 Clause 28: Localization library <https://wg21.link/p1614r2#clause-28-localization-library>`_,,,,
179179
"| `[locale] <https://wg21.link/locale>`_
180180
| `[locale.operators] <https://wg21.link/locale.operators>`_",| remove ops `locale <https://reviews.llvm.org/D152654>`_,None,Hristo Hristov,|Complete|

libcxx/include/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,8 @@ set(files
291291
__chrono/steady_clock.h
292292
__chrono/system_clock.h
293293
__chrono/time_point.h
294+
__chrono/time_zone.h
295+
__chrono/time_zone_link.h
294296
__chrono/tzdb.h
295297
__chrono/tzdb_list.h
296298
__chrono/weekday.h

libcxx/include/__chrono/time_zone.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
11+
12+
#ifndef _LIBCPP___CHRONO_TIME_ZONE_H
13+
#define _LIBCPP___CHRONO_TIME_ZONE_H
14+
15+
#include <version>
16+
// Enable the contents of the header only when libc++ was built with experimental features enabled.
17+
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
18+
19+
# include <__compare/strong_order.h>
20+
# include <__config>
21+
# include <__memory/unique_ptr.h>
22+
# include <string_view>
23+
24+
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25+
# pragma GCC system_header
26+
# endif
27+
28+
_LIBCPP_PUSH_MACROS
29+
# include <__undef_macros>
30+
31+
_LIBCPP_BEGIN_NAMESPACE_STD
32+
33+
# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
34+
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
35+
36+
namespace chrono {
37+
38+
class _LIBCPP_AVAILABILITY_TZDB time_zone {
39+
_LIBCPP_HIDE_FROM_ABI time_zone() = default;
40+
41+
public:
42+
class __impl; // public so it can be used by make_unique.
43+
44+
// The "constructor".
45+
//
46+
// The default constructor is private to avoid the constructor from being
47+
// part of the ABI. Instead use an __ugly_named function as an ABI interface,
48+
// since that gives us the ability to change it in the future.
49+
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI static time_zone __create(unique_ptr<__impl>&& __p);
50+
51+
_LIBCPP_EXPORTED_FROM_ABI ~time_zone();
52+
53+
_LIBCPP_HIDE_FROM_ABI time_zone(time_zone&&) = default;
54+
_LIBCPP_HIDE_FROM_ABI time_zone& operator=(time_zone&&) = default;
55+
56+
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name(); }
57+
58+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI const __impl& __implementation() const noexcept { return *__impl_; }
59+
60+
private:
61+
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string_view __name() const noexcept;
62+
unique_ptr<__impl> __impl_;
63+
};
64+
65+
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool
66+
operator==(const time_zone& __x, const time_zone& __y) noexcept {
67+
return __x.name() == __y.name();
68+
}
69+
70+
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering
71+
operator<=>(const time_zone& __x, const time_zone& __y) noexcept {
72+
return __x.name() <=> __y.name();
73+
}
74+
75+
} // namespace chrono
76+
77+
# endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
78+
// && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
79+
80+
_LIBCPP_END_NAMESPACE_STD
81+
82+
_LIBCPP_POP_MACROS
83+
84+
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
85+
86+
#endif // _LIBCPP___CHRONO_TIME_ZONE_H
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
11+
12+
#ifndef _LIBCPP___CHRONO_TIME_ZONE_LINK_H
13+
#define _LIBCPP___CHRONO_TIME_ZONE_LINK_H
14+
15+
#include <version>
16+
// Enable the contents of the header only when libc++ was built with experimental features enabled.
17+
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
18+
19+
# include <__compare/strong_order.h>
20+
# include <__config>
21+
# include <string>
22+
# include <string_view>
23+
24+
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
25+
# pragma GCC system_header
26+
# endif
27+
28+
_LIBCPP_PUSH_MACROS
29+
# include <__undef_macros>
30+
31+
_LIBCPP_BEGIN_NAMESPACE_STD
32+
33+
# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
34+
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
35+
36+
namespace chrono {
37+
38+
class time_zone_link {
39+
public:
40+
struct __constructor_tag;
41+
_LIBCPP_NODISCARD_EXT
42+
_LIBCPP_HIDE_FROM_ABI explicit time_zone_link(__constructor_tag&&, string_view __name, string_view __target)
43+
: __name_{__name}, __target_{__target} {}
44+
45+
_LIBCPP_HIDE_FROM_ABI time_zone_link(time_zone_link&&) = default;
46+
_LIBCPP_HIDE_FROM_ABI time_zone_link& operator=(time_zone_link&&) = default;
47+
48+
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name_; }
49+
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view target() const noexcept { return __target_; }
50+
51+
private:
52+
string __name_;
53+
// TODO TZDB instead of the name we can store the pointer to a zone. These
54+
// pointers are immutable. This makes it possible to directly return a
55+
// pointer in the time_zone in the 'locate_zone' function.
56+
string __target_;
57+
};
58+
59+
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool
60+
operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept {
61+
return __x.name() == __y.name();
62+
}
63+
64+
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering
65+
operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept {
66+
return __x.name() <=> __y.name();
67+
}
68+
69+
} // namespace chrono
70+
71+
# endif //_LIBCPP_STD_VER >= 20
72+
73+
_LIBCPP_END_NAMESPACE_STD
74+
75+
_LIBCPP_POP_MACROS
76+
77+
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
78+
79+
#endif // _LIBCPP___CHRONO_TIME_ZONE_LINK_H

libcxx/include/__chrono/tzdb.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,30 @@
1616
// Enable the contents of the header only when libc++ was built with experimental features enabled.
1717
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
1818

19+
# include <__chrono/time_zone.h>
20+
# include <__chrono/time_zone_link.h>
21+
# include <__config>
1922
# include <string>
23+
# include <vector>
2024

2125
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2226
# pragma GCC system_header
2327
# endif
2428

29+
_LIBCPP_PUSH_MACROS
30+
# include <__undef_macros>
31+
2532
_LIBCPP_BEGIN_NAMESPACE_STD
2633

2734
# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
2835
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
2936

3037
namespace chrono {
3138

32-
struct _LIBCPP_AVAILABILITY_TZDB tzdb {
39+
struct tzdb {
3340
string version;
41+
vector<time_zone> zones;
42+
vector<time_zone_link> links;
3443
};
3544

3645
} // namespace chrono
@@ -40,6 +49,8 @@ struct _LIBCPP_AVAILABILITY_TZDB tzdb {
4049

4150
_LIBCPP_END_NAMESPACE_STD
4251

52+
_LIBCPP_POP_MACROS
53+
4354
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
4455

4556
#endif // _LIBCPP___CHRONO_TZDB_H

libcxx/include/__chrono/tzdb_list.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818

1919
# include <__availability>
2020
# include <__chrono/tzdb.h>
21+
# include <__config>
22+
# include <__fwd/string.h>
2123
# include <forward_list>
22-
# include <string_view>
2324

2425
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2526
# pragma GCC system_header
@@ -32,9 +33,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3233

3334
namespace chrono {
3435

36+
// TODO TZDB
37+
// Libc++ recently switched to only export __ugly_names from the dylib.
38+
// Since the library is still experimental the functions in this header
39+
// should be adapted to this new style. The other tzdb headers should be
40+
// evaluated too.
41+
3542
class _LIBCPP_AVAILABILITY_TZDB tzdb_list {
3643
public:
37-
_LIBCPP_EXPORTED_FROM_ABI explicit tzdb_list(tzdb&& __tzdb);
44+
class __impl; // public to allow construction in dylib
45+
_LIBCPP_HIDE_FROM_ABI explicit tzdb_list(__impl* __p) : __impl_(__p) {
46+
_LIBCPP_ASSERT_NON_NULL(__impl_ != nullptr, "initialized time_zone without a valid pimpl object");
47+
}
3848
_LIBCPP_EXPORTED_FROM_ABI ~tzdb_list();
3949

4050
tzdb_list(const tzdb_list&) = delete;
@@ -46,16 +56,15 @@ class _LIBCPP_AVAILABILITY_TZDB tzdb_list {
4656

4757
_LIBCPP_EXPORTED_FROM_ABI const_iterator erase_after(const_iterator __p);
4858

49-
_LIBCPP_EXPORTED_FROM_ABI tzdb& __emplace_front(tzdb&& __tzdb);
50-
5159
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const_iterator begin() const noexcept;
5260
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const_iterator end() const noexcept;
5361

5462
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const_iterator cbegin() const noexcept;
5563
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const_iterator cend() const noexcept;
5664

65+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __impl& __implementation() { return *__impl_; }
66+
5767
private:
58-
class __impl;
5968
__impl* __impl_;
6069
};
6170

libcxx/include/chrono

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,8 @@ constexpr hours make24(const hours& h, bool is_pm) noexcept;
686686
// [time.zone.db], time zone database
687687
struct tzdb { // C++20
688688
string version;
689+
vector<time_zone> zones;
690+
vector<time_zone_link> links;
689691
};
690692
691693
class tzdb_list { // C++20
@@ -716,15 +718,34 @@ tzdb_list& get_tzdb_list();
716718
const tzdb& reload_tzdb(); // C++20
717719
string remote_version(); // C++20
718720
719-
// 25.10.5, class time_zone // C++20
721+
// 25.10.5, class time_zone // C++20
720722
enum class choose {earliest, latest};
721-
class time_zone;
722-
bool operator==(const time_zone& x, const time_zone& y) noexcept;
723-
bool operator!=(const time_zone& x, const time_zone& y) noexcept;
724-
bool operator<(const time_zone& x, const time_zone& y) noexcept;
725-
bool operator>(const time_zone& x, const time_zone& y) noexcept;
726-
bool operator<=(const time_zone& x, const time_zone& y) noexcept;
727-
bool operator>=(const time_zone& x, const time_zone& y) noexcept;
723+
class time_zone {
724+
time_zone(time_zone&&) = default;
725+
time_zone& operator=(time_zone&&) = default;
726+
727+
// unspecified additional constructors
728+
729+
string_view name() const noexcept;
730+
};
731+
bool operator==(const time_zone& x, const time_zone& y) noexcept; // C++20
732+
strong_ordering operator<=>(const time_zone& x, const time_zone& y) noexcept; // C++20
733+
734+
// [time.zone.link], class time_zone_link
735+
class time_zone_link { // C++20
736+
public:
737+
time_zone_link(time_zone_link&&) = default;
738+
time_zone_link& operator=(time_zone_link&&) = default;
739+
740+
// unspecified additional constructors
741+
742+
string_view name() const noexcept;
743+
string_view target() const noexcept;
744+
};
745+
746+
bool operator==(const time_zone_link& x, const time_zone_link& y); // C++20
747+
strong_ordering operator<=>(const time_zone_link& x, const time_zone_link& y); // C++20
748+
728749
} // chrono
729750
730751
namespace std {
@@ -842,6 +863,8 @@ constexpr chrono::year operator ""y(unsigned lo
842863

843864
#if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
844865
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
866+
# include <__chrono/time_zone.h>
867+
# include <__chrono/time_zone_link.h>
845868
# include <__chrono/tzdb.h>
846869
# include <__chrono/tzdb_list.h>
847870
#endif

libcxx/include/libcxx.imp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@
288288
{ include: [ "<__chrono/steady_clock.h>", "private", "<chrono>", "public" ] },
289289
{ include: [ "<__chrono/system_clock.h>", "private", "<chrono>", "public" ] },
290290
{ include: [ "<__chrono/time_point.h>", "private", "<chrono>", "public" ] },
291+
{ include: [ "<__chrono/time_zone.h>", "private", "<chrono>", "public" ] },
292+
{ include: [ "<__chrono/time_zone_link.h>", "private", "<chrono>", "public" ] },
291293
{ include: [ "<__chrono/tzdb.h>", "private", "<chrono>", "public" ] },
292294
{ include: [ "<__chrono/tzdb_list.h>", "private", "<chrono>", "public" ] },
293295
{ include: [ "<__chrono/weekday.h>", "private", "<chrono>", "public" ] },

libcxx/include/module.modulemap.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,12 @@ module std_private_chrono_steady_clock [system] {
11561156
header "__chrono/steady_clock.h"
11571157
export std_private_chrono_time_point
11581158
}
1159+
module std_private_chrono_time_zone [system] {
1160+
header "__chrono/time_zone.h"
1161+
}
1162+
module std_private_chrono_time_zone_link [system] {
1163+
header "__chrono/time_zone_link.h"
1164+
}
11591165
module std_private_chrono_system_clock [system] {
11601166
header "__chrono/system_clock.h"
11611167
export std_private_chrono_time_point

libcxx/modules/std/chrono.inc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,11 @@ export namespace std {
221221

222222
// [time.zone.timezone], class time_zone
223223
using std::chrono::choose;
224+
# endif
225+
# ifdef _LIBCPP_ENABLE_EXPERIMENTAL
224226
using std::chrono::time_zone;
227+
# endif
228+
# if 0
225229

226230
// [time.zone.zonedtraits], class template zoned_traits
227231
using std::chrono::zoned_traits;
@@ -233,10 +237,14 @@ export namespace std {
233237

234238
// [time.zone.leap], leap second support
235239
using std::chrono::leap_second;
240+
# endif
236241

242+
# ifdef _LIBCPP_ENABLE_EXPERIMENTAL
237243
// [time.zone.link], class time_zone_link
238244
using std::chrono::time_zone_link;
245+
# endif
239246

247+
# if 0
240248
// [time.format], formatting
241249
using std::chrono::local_time_format;
242250
# endif

0 commit comments

Comments
 (0)