Skip to content

[libc++][chrono] Loads leap-seconds.list in tzdb. #82113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libcxx/docs/Status/Cxx20Issues.csv
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@
"`3355 <https://wg21.link/LWG3355>`__","The memory algorithms should support move-only input iterators introduced by P1207","Prague","|Complete|","15.0","|ranges|"
"`3356 <https://wg21.link/LWG3356>`__","``__cpp_lib_nothrow_convertible``\ should be ``__cpp_lib_is_nothrow_convertible``\ ","Prague","|Complete|","12.0"
"`3358 <https://wg21.link/LWG3358>`__","|sect|\ [span.cons] is mistaken that ``to_address``\ can throw","Prague","|Complete|","17.0"
"`3359 <https://wg21.link/LWG3359>`__","``<chrono>``\ leap second support should allow for negative leap seconds","Prague","","","|chrono|"
"`3359 <https://wg21.link/LWG3359>`__","``<chrono>``\ leap second support should allow for negative leap seconds","Prague","|Complete|","19.0","|chrono|"
"`3360 <https://wg21.link/LWG3360>`__","``three_way_comparable_with``\ is inconsistent with similar concepts","Prague","|Nothing To Do|","","|spaceship|"
"`3362 <https://wg21.link/LWG3362>`__","Strike ``stop_source``\ 's ``operator!=``\ ","Prague","",""
"`3363 <https://wg21.link/LWG3363>`__","``drop_while_view``\ should opt-out of ``sized_range``\ ","Prague","|Nothing To Do|","","|ranges|"
Expand All @@ -286,7 +286,7 @@
"`3380 <https://wg21.link/LWG3380>`__","``common_type``\ and comparison categories","Prague","|Complete|","15.0","|spaceship|"
"`3381 <https://wg21.link/LWG3381>`__","``begin``\ and ``data``\ must agree for ``contiguous_range``\ ","Prague","|Nothing To Do|","","|ranges|"
"`3382 <https://wg21.link/LWG3382>`__","NTTP for ``pair``\ and ``array``\ ","Prague","",""
"`3383 <https://wg21.link/LWG3383>`__","|sect|\ [time.zone.leap.nonmembers] ``sys_seconds``\ should be replaced with ``seconds``\ ","Prague","","","|chrono|"
"`3383 <https://wg21.link/LWG3383>`__","|sect|\ [time.zone.leap.nonmembers] ``sys_seconds``\ should be replaced with ``seconds``\ ","Prague","|Complete|","19.0","|chrono|"
"`3384 <https://wg21.link/LWG3384>`__","``transform_view::*sentinel*``\ has an incorrect ``operator-``\ ","Prague","|Complete|","15.0","|ranges|"
"`3385 <https://wg21.link/LWG3385>`__","``common_iterator``\ is not sufficiently constrained for non-copyable iterators","Prague","|Complete|","15.0","|ranges|"
"`3387 <https://wg21.link/LWG3387>`__","|sect|\ [range.reverse.view] ``reverse_view<V>``\ unintentionally requires ``range<const V>``\ ","Prague","|Complete|","15.0","|ranges|"
Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx20Papers.csv
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
"`P1970R2 <https://wg21.link/P1970R2>`__","LWG","Consistency for size() functions: Add ranges::ssize","Prague","|Complete|","15.0","|ranges|"
"`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","* *",""
"`P1981R0 <https://wg21.link/P1981R0>`__","LWG","Rename leap to leap_second","Prague","|Complete|","19.0","|chrono|"
"`P1982R0 <https://wg21.link/P1982R0>`__","LWG","Rename link to time_zone_link","Prague","|Complete|","19.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|"
Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/SpaceshipProjects.csv
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Section,Description,Dependencies,Assignee,Complete
| `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,|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.leap.nonmembers] <https://wg21.link/time.zone.leap.nonmembers>`_,"`chrono::time_leap_seconds`",A ``<chrono>`` implementation,Mark de Wever,|Complete|
`[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>`_
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ set(files
__chrono/formatter.h
__chrono/hh_mm_ss.h
__chrono/high_resolution_clock.h
__chrono/leap_second.h
__chrono/literals.h
__chrono/month.h
__chrono/month_weekday.h
Expand Down
126 changes: 126 additions & 0 deletions libcxx/include/__chrono/leap_second.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// -*- 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_LEAP_SECOND_H
#define _LIBCPP___CHRONO_LEAP_SECOND_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/duration.h>
# include <__chrono/system_clock.h>
# include <__chrono/time_point.h>
# include <__compare/ordering.h>
# include <__compare/three_way_comparable.h>
# include <__config>

# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif

_LIBCPP_BEGIN_NAMESPACE_STD

# if _LIBCPP_STD_VER >= 20

namespace chrono {

class leap_second {
public:
struct __constructor_tag;
[[nodiscard]]
_LIBCPP_HIDE_FROM_ABI explicit constexpr leap_second(__constructor_tag&&, sys_seconds __date, seconds __value)
: __date_(__date), __value_(__value) {}

_LIBCPP_HIDE_FROM_ABI leap_second(const leap_second&) = default;
_LIBCPP_HIDE_FROM_ABI leap_second& operator=(const leap_second&) = default;

_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr sys_seconds date() const noexcept { return __date_; }

_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr seconds value() const noexcept { return __value_; }

private:
sys_seconds __date_;
seconds __value_;
};

_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const leap_second& __x, const leap_second& __y) {
return __x.date() == __y.date();
}

_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering operator<=>(const leap_second& __x, const leap_second& __y) {
return __x.date() <=> __y.date();
}

template <class _Duration>
_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const leap_second& __x, const sys_time<_Duration>& __y) {
return __x.date() == __y;
}

template <class _Duration>
_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const leap_second& __x, const sys_time<_Duration>& __y) {
return __x.date() < __y;
}

template <class _Duration>
_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const sys_time<_Duration>& __x, const leap_second& __y) {
return __x < __y.date();
}

template <class _Duration>
_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const leap_second& __x, const sys_time<_Duration>& __y) {
return __y < __x;
}

template <class _Duration>
_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const sys_time<_Duration>& __x, const leap_second& __y) {
return __y < __x;
}

template <class _Duration>
_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const leap_second& __x, const sys_time<_Duration>& __y) {
return !(__y < __x);
}

template <class _Duration>
_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const sys_time<_Duration>& __x, const leap_second& __y) {
return !(__y < __x);
}

template <class _Duration>
_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const leap_second& __x, const sys_time<_Duration>& __y) {
return !(__x < __y);
}

template <class _Duration>
_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const sys_time<_Duration>& __x, const leap_second& __y) {
return !(__x < __y);
}

# ifndef _LIBCPP_COMPILER_GCC
// This requirement cause a compilation loop in GCC-13 and running out of memory.
// TODO TZDB Test whether GCC-14 fixes this.
template <class _Duration>
requires three_way_comparable_with<sys_seconds, sys_time<_Duration>>
_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(const leap_second& __x, const sys_time<_Duration>& __y) {
return __x.date() <=> __y;
}
# endif
Comment on lines +108 to +116
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GCC trunk now errors on this saying the requirement is depending on itself: https://gcc.godbolt.org/z/aE5jPnnre

Can we fix it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not conforming.
It should have a same_as<_Duration, std::chrono::seconds> || three_way_comparable_with<sys_seconds, sys_time<_Duration> constraint or something like that @mordante

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cor3ntin Thanks for filing the LWG-issue!
@zyn0217 @cor3ntin I've filed #104700, lets continue the discussion there. I'll try to look at this issue soon.


} // namespace chrono

# endif //_LIBCPP_STD_VER >= 20

_LIBCPP_END_NAMESPACE_STD

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)

#endif // _LIBCPP___CHRONO_LEAP_SECOND_H
3 changes: 3 additions & 0 deletions libcxx/include/__chrono/tzdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// Enable the contents of the header only when libc++ was built with experimental features enabled.
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)

# include <__chrono/leap_second.h>
# include <__chrono/time_zone.h>
# include <__chrono/time_zone_link.h>
# include <__config>
Expand All @@ -40,6 +41,8 @@ struct tzdb {
string version;
vector<time_zone> zones;
vector<time_zone_link> links;

vector<leap_second> leap_seconds;
};

} // namespace chrono
Expand Down
39 changes: 39 additions & 0 deletions libcxx/include/chrono
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ struct tzdb {
string version;
vector<time_zone> zones;
vector<time_zone_link> links;
vector<leap_second> leap_seconds;
};

class tzdb_list { // C++20
Expand Down Expand Up @@ -731,6 +732,43 @@ 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.leap], leap second support
class leap_second { // C++20
public:
leap_second(const leap_second&) = default;
leap_second& operator=(const leap_second&) = default;

// unspecified additional constructors

constexpr sys_seconds date() const noexcept;
constexpr seconds value() const noexcept;
};

constexpr bool operator==(const leap_second& x, const leap_second& y); // C++20
constexpr strong_ordering operator<=>(const leap_second& x, const leap_second& y);

template<class Duration> // C++20
constexpr bool operator==(const leap_second& x, const sys_time<Duration>& y);
template<class Duration> // C++20
constexpr bool operator< (const leap_second& x, const sys_time<Duration>& y);
template<class Duration> // C++20
constexpr bool operator< (const sys_time<Duration>& x, const leap_second& y);
template<class Duration> // C++20
constexpr bool operator> (const leap_second& x, const sys_time<Duration>& y);
template<class Duration> // C++20
constexpr bool operator> (const sys_time<Duration>& x, const leap_second& y);
template<class Duration> // C++20
constexpr bool operator<=(const leap_second& x, const sys_time<Duration>& y);
template<class Duration> // C++20
constexpr bool operator<=(const sys_time<Duration>& x, const leap_second& y);
template<class Duration> // C++20
constexpr bool operator>=(const leap_second& x, const sys_time<Duration>& y);
template<class Duration> // C++20
constexpr bool operator>=(const sys_time<Duration>& x, const leap_second& y);
template<class Duration> // C++20
requires three_way_comparable_with<sys_seconds, sys_time<Duration>>
constexpr auto operator<=>(const leap_second& x, const sys_time<Duration>& y);

// [time.zone.link], class time_zone_link
class time_zone_link { // C++20
public:
Expand Down Expand Up @@ -862,6 +900,7 @@ 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/leap_second.h>
# include <__chrono/time_zone.h>
# include <__chrono/time_zone_link.h>
# include <__chrono/tzdb.h>
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/libcxx.imp
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@
{ include: [ "<__chrono/formatter.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/hh_mm_ss.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/high_resolution_clock.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/leap_second.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/literals.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/month.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/month_weekday.h>", "private", "<chrono>", "public" ] },
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,7 @@ module std_private_chrono_high_resolution_clock [system] {
export std_private_chrono_steady_clock
export std_private_chrono_system_clock
}
module std_private_chrono_leap_second [system] { header "__chrono/leap_second.h" }
module std_private_chrono_literals [system] { header "__chrono/literals.h" }
module std_private_chrono_month [system] { header "__chrono/month.h" }
module std_private_chrono_month_weekday [system] { header "__chrono/month_weekday.h" }
Expand Down
28 changes: 13 additions & 15 deletions libcxx/modules/std/chrono.inc
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,7 @@ export namespace std {
using std::chrono::reload_tzdb;
using std::chrono::remote_version;

# endif // !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) &&
// !defined(_LIBCPP_HAS_NO_LOCALIZATION)

# if 0
# if 0
// [time.zone.exception], exception classes
using std::chrono::ambiguous_local_time;
using std::chrono::nonexistent_local_time;
Expand All @@ -221,11 +218,11 @@ export namespace std {

// [time.zone.timezone], class time_zone
using std::chrono::choose;
# endif
# ifdef _LIBCPP_ENABLE_EXPERIMENTAL
# endif // if 0

using std::chrono::time_zone;
# endif
# if 0

# if 0

// [time.zone.zonedtraits], class template zoned_traits
using std::chrono::zoned_traits;
Expand All @@ -234,22 +231,23 @@ export namespace std {
using std::chrono::zoned_time;

using std::chrono::zoned_seconds;
# endif // if 0

// [time.zone.leap], leap second support
using std::chrono::leap_second;
# endif

# ifdef _LIBCPP_ENABLE_EXPERIMENTAL
// [time.zone.link], class time_zone_link
using std::chrono::time_zone_link;
# endif

# if 0
# if 0
// [time.format], formatting
using std::chrono::local_time_format;
# endif
#endif // _LIBCPP_ENABLE_EXPERIMENTAL
} // namespace chrono
# endif
# endif // _LIBCPP_ENABLE_EXPERIMENTAL
#endif // !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) &&
// !defined(_LIBCPP_HAS_NO_LOCALIZATION)

} // namespace chrono

#ifndef _LIBCPP_HAS_NO_LOCALIZATION
using std::formatter;
Expand Down
1 change: 1 addition & 0 deletions libcxx/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ endif()

if (LIBCXX_ENABLE_LOCALIZATION AND LIBCXX_ENABLE_FILESYSTEM AND LIBCXX_ENABLE_TIME_ZONE_DATABASE)
list(APPEND LIBCXX_EXPERIMENTAL_SOURCES
include/tzdb/leap_second_private.h
include/tzdb/time_zone_link_private.h
include/tzdb/time_zone_private.h
include/tzdb/types_private.h
Expand Down
27 changes: 27 additions & 0 deletions libcxx/src/include/tzdb/leap_second_private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// -*- 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_SRC_INCLUDE_TZDB_LEAP_SECOND_PRIVATE_H
#define _LIBCPP_SRC_INCLUDE_TZDB_LEAP_SECOND_PRIVATE_H

#include <chrono>

_LIBCPP_BEGIN_NAMESPACE_STD

namespace chrono {

struct leap_second::__constructor_tag {};

} // namespace chrono

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_SRC_INCLUDE_TZDB_LEAP_SECOND_PRIVATE_H
Loading