Skip to content

Commit 7f89e68

Browse files
committed
[libc++][chrono] Adds the sys_info class.
Adds the sys_info class and time_zone::get_info(). The code still has a few quirks and has not been optimized for performance yet. The returned sys_info is compared against the output of the zdump tool in the test giving confidence the implementation is correct. Implements parts of: - P0355 Extending <chrono> to Calendars and Time Zones Implements: - LWGXXXX The sys_info range should be affected by save
1 parent 7a742c0 commit 7f89e68

File tree

18 files changed

+2648
-2
lines changed

18 files changed

+2648
-2
lines changed

libcxx/docs/Status/Cxx2cIssues.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@
4141
"`4001 <https://wg21.link/LWG4001>`__","``iota_view`` should provide ``empty``","Kona November 2023","","","|ranges|"
4242
"","","","","",""
4343
"`3343 <https://wg21.link/LWG3343>`__","Ordering of calls to ``unlock()`` and ``notify_all()`` in Effects element of ``notify_all_at_thread_exit()`` should be reversed","Not Yet Adopted","|Complete|","16.0",""
44+
"XXXX","","The sys_info range should be affected by save","Not Yet Adopted","|Complete|","19.0"
4445
"","","","","",""

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ set(files
290290
__chrono/parser_std_format_spec.h
291291
__chrono/statically_widen.h
292292
__chrono/steady_clock.h
293+
__chrono/sys_info.h
293294
__chrono/system_clock.h
294295
__chrono/time_point.h
295296
__chrono/time_zone.h

libcxx/include/__chrono/sys_info.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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_SYS_INFO_H
13+
#define _LIBCPP___CHRONO_SYS_INFO_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 <__chrono/duration.h>
20+
# include <__chrono/system_clock.h>
21+
# include <__chrono/time_point.h>
22+
# include <__config>
23+
# include <string>
24+
25+
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26+
# pragma GCC system_header
27+
# endif
28+
29+
_LIBCPP_BEGIN_NAMESPACE_STD
30+
31+
# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
32+
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
33+
34+
namespace chrono {
35+
36+
struct sys_info {
37+
sys_seconds begin;
38+
sys_seconds end;
39+
seconds offset;
40+
minutes save;
41+
string abbrev;
42+
};
43+
44+
} // namespace chrono
45+
46+
# endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
47+
// && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
48+
49+
_LIBCPP_END_NAMESPACE_STD
50+
51+
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
52+
53+
#endif // _LIBCPP___CHRONO_SYS_INFO_H

libcxx/include/__chrono/time_zone.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
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/duration.h>
20+
# include <__chrono/sys_info.h>
21+
# include <__chrono/system_clock.h>
1922
# include <__compare/strong_order.h>
2023
# include <__config>
2124
# include <__memory/unique_ptr.h>
@@ -55,10 +58,18 @@ class _LIBCPP_AVAILABILITY_TZDB time_zone {
5558

5659
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name(); }
5760

61+
template <class _Duration>
62+
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI sys_info get_info(const sys_time<_Duration>& __time) const {
63+
return __get_info(chrono::time_point_cast<seconds>(__time));
64+
}
65+
5866
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI const __impl& __implementation() const noexcept { return *__impl_; }
5967

6068
private:
6169
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string_view __name() const noexcept;
70+
71+
[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI sys_info __get_info(sys_seconds __time) const;
72+
6273
unique_ptr<__impl> __impl_;
6374
};
6475

libcxx/include/chrono

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,15 @@ const time_zone* current_zone()
724724
const tzdb& reload_tzdb(); // C++20
725725
string remote_version(); // C++20
726726
727+
// [time.zone.info], information classes
728+
struct sys_info { // C++20
729+
sys_seconds begin;
730+
sys_seconds end;
731+
seconds offset;
732+
minutes save;
733+
string abbrev;
734+
};
735+
727736
// 25.10.5, class time_zone // C++20
728737
enum class choose {earliest, latest};
729738
class time_zone {
@@ -733,6 +742,9 @@ class time_zone {
733742
// unspecified additional constructors
734743
735744
string_view name() const noexcept;
745+
746+
template<class Duration>
747+
sys_info get_info(const sys_time<Duration>& st) const;
736748
};
737749
bool operator==(const time_zone& x, const time_zone& y) noexcept; // C++20
738750
strong_ordering operator<=>(const time_zone& x, const time_zone& y) noexcept; // C++20
@@ -906,6 +918,7 @@ constexpr chrono::year operator ""y(unsigned lo
906918
#if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
907919
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
908920
# include <__chrono/leap_second.h>
921+
# include <__chrono/sys_info.h>
909922
# include <__chrono/time_zone.h>
910923
# include <__chrono/time_zone_link.h>
911924
# include <__chrono/tzdb.h>

libcxx/include/libcxx.imp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@
287287
{ include: [ "<__chrono/parser_std_format_spec.h>", "private", "<chrono>", "public" ] },
288288
{ include: [ "<__chrono/statically_widen.h>", "private", "<chrono>", "public" ] },
289289
{ include: [ "<__chrono/steady_clock.h>", "private", "<chrono>", "public" ] },
290+
{ include: [ "<__chrono/sys_info.h>", "private", "<chrono>", "public" ] },
290291
{ include: [ "<__chrono/system_clock.h>", "private", "<chrono>", "public" ] },
291292
{ include: [ "<__chrono/time_point.h>", "private", "<chrono>", "public" ] },
292293
{ include: [ "<__chrono/time_zone.h>", "private", "<chrono>", "public" ] },

libcxx/include/module.modulemap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,9 @@ module std_private_chrono_time_zone [system] {
11631163
module std_private_chrono_time_zone_link [system] {
11641164
header "__chrono/time_zone_link.h"
11651165
}
1166+
module std_private_chrono_sys_info [system] {
1167+
header "__chrono/sys_info.h"
1168+
}
11661169
module std_private_chrono_system_clock [system] {
11671170
header "__chrono/system_clock.h"
11681171
export std_private_chrono_time_point

libcxx/modules/std/chrono.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,12 @@ export namespace std {
212212
// [time.zone.exception], exception classes
213213
using std::chrono::ambiguous_local_time;
214214
using std::chrono::nonexistent_local_time;
215+
# endif // if 0
215216

216217
// [time.zone.info], information classes
217218
using std::chrono::sys_info;
218219

220+
# if 0
219221
// [time.zone.timezone], class time_zone
220222
using std::chrono::choose;
221223
# endif // if 0

libcxx/src/include/tzdb/types_private.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,17 @@ namespace chrono::__tz {
3333
// Sun>=8 first Sunday on or after the eighth
3434
// Sun<=25 last Sunday on or before the 25th
3535
struct __constrained_weekday {
36-
/* year_month_day operator()(year __year, month __month);*/ // needed but not implemented
36+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI year_month_day operator()(year __year, month __month) const {
37+
auto __result = static_cast<sys_days>(year_month_day{__year, __month, __day});
38+
weekday __wd{static_cast<sys_days>(__result)};
39+
40+
if (__comparison == __le)
41+
__result -= __wd - __weekday;
42+
else
43+
__result += __weekday - __wd;
44+
45+
return __result;
46+
}
3747

3848
weekday __weekday;
3949
enum __comparison_t { __le, __ge } __comparison;
@@ -85,7 +95,8 @@ struct __continuation {
8595
// used.
8696
// If this field contains - then standard time always
8797
// applies. This is indicated by the monostate.
88-
using __rules_t = variant<monostate, __tz::__save, string, size_t>;
98+
// TODO TZDB Investigate implemention the size_t based caching.
99+
using __rules_t = variant<monostate, __tz::__save, string /*, size_t*/>;
89100

90101
__rules_t __rules;
91102

libcxx/src/include/tzdb/tzdb_list_private.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ class tzdb_list::__impl {
8484
const_iterator cbegin() const noexcept { return begin(); }
8585
const_iterator cend() const noexcept { return end(); }
8686

87+
const __tz::__rules_storage_type& __rules() const noexcept {
88+
#ifndef _LIBCPP_HAS_NO_THREADS
89+
shared_lock __lock{__mutex_};
90+
#endif
91+
return __rules_.front();
92+
}
93+
8794
private:
8895
// Loads the tzdbs
8996
// pre: The caller ensures the locking, if needed, is done.

0 commit comments

Comments
 (0)