Skip to content

[libc++][chrono] Loads tzdata.zi in tzdb. #74928

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 3 commits into from
Feb 17, 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
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx20Papers.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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|","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|"
"`P2002R1 <https://wg21.link/P2002R1>`__","CWG","Defaulted comparison specification cleanups","Prague","* *",""
Expand Down
4 changes: 2 additions & 2 deletions libcxx/docs/Status/SpaceshipProjects.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ set(files
__chrono/steady_clock.h
__chrono/system_clock.h
__chrono/time_point.h
__chrono/time_zone.h
__chrono/time_zone_link.h
__chrono/tzdb.h
__chrono/tzdb_list.h
__chrono/weekday.h
Expand Down
86 changes: 86 additions & 0 deletions libcxx/include/__chrono/time_zone.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// -*- 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 <__compare/strong_order.h>
# include <__config>
# include <__memory/unique_ptr.h>
# include <string_view>

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

_LIBCPP_PUSH_MACROS
# include <__undef_macros>

_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 {
_LIBCPP_HIDE_FROM_ABI time_zone() = default;

public:
class __impl; // public so it can be used by make_unique.

// The "constructor".
//
// The default constructor is private to avoid the constructor from being
// part of the ABI. Instead use an __ugly_named function as an ABI interface,
// since that gives us the ability to change it in the future.
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI static time_zone __create(unique_ptr<__impl>&& __p);

_LIBCPP_EXPORTED_FROM_ABI ~time_zone();

_LIBCPP_HIDE_FROM_ABI time_zone(time_zone&&) = default;
_LIBCPP_HIDE_FROM_ABI time_zone& operator=(time_zone&&) = default;

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

[[nodiscard]] _LIBCPP_HIDE_FROM_ABI const __impl& __implementation() const noexcept { return *__impl_; }

private:
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string_view __name() const noexcept;
unique_ptr<__impl> __impl_;
};

_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

_LIBCPP_POP_MACROS

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)

#endif // _LIBCPP___CHRONO_TIME_ZONE_H
79 changes: 79 additions & 0 deletions libcxx/include/__chrono/time_zone_link.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// -*- 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_PUSH_MACROS
# include <__undef_macros>

_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 time_zone_link {
public:
struct __constructor_tag;
_LIBCPP_NODISCARD_EXT
_LIBCPP_HIDE_FROM_ABI explicit time_zone_link(__constructor_tag&&, string_view __name, string_view __target)
: __name_{__name}, __target_{__target} {}

_LIBCPP_HIDE_FROM_ABI time_zone_link(time_zone_link&&) = default;
_LIBCPP_HIDE_FROM_ABI 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

_LIBCPP_POP_MACROS

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)

#endif // _LIBCPP___CHRONO_TIME_ZONE_LINK_H
13 changes: 12 additions & 1 deletion libcxx/include/__chrono/tzdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,30 @@
// 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.h>
# include <__chrono/time_zone_link.h>
# include <__config>
# include <string>
# include <vector>

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

_LIBCPP_PUSH_MACROS
# include <__undef_macros>

_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 {

struct _LIBCPP_AVAILABILITY_TZDB tzdb {
struct tzdb {
string version;
vector<time_zone> zones;
vector<time_zone_link> links;
};

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

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)

#endif // _LIBCPP___CHRONO_TZDB_H
19 changes: 14 additions & 5 deletions libcxx/include/__chrono/tzdb_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@

# include <__availability>
# include <__chrono/tzdb.h>
# include <__config>
# include <__fwd/string.h>
# include <forward_list>
# include <string_view>

# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
Expand All @@ -32,9 +33,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD

namespace chrono {

// TODO TZDB
// Libc++ recently switched to only export __ugly_names from the dylib.
// Since the library is still experimental the functions in this header
// should be adapted to this new style. The other tzdb headers should be
// evaluated too.

class _LIBCPP_AVAILABILITY_TZDB tzdb_list {
public:
_LIBCPP_EXPORTED_FROM_ABI explicit tzdb_list(tzdb&& __tzdb);
class __impl; // public to allow construction in dylib
_LIBCPP_HIDE_FROM_ABI explicit tzdb_list(__impl* __p) : __impl_(__p) {
_LIBCPP_ASSERT_NON_NULL(__impl_ != nullptr, "initialized time_zone without a valid pimpl object");
}
_LIBCPP_EXPORTED_FROM_ABI ~tzdb_list();

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

_LIBCPP_EXPORTED_FROM_ABI const_iterator erase_after(const_iterator __p);

_LIBCPP_EXPORTED_FROM_ABI tzdb& __emplace_front(tzdb&& __tzdb);

_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const_iterator begin() const noexcept;
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const_iterator end() const noexcept;

_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const_iterator cbegin() const noexcept;
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const_iterator cend() const noexcept;

[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __impl& __implementation() { return *__impl_; }

private:
class __impl;
__impl* __impl_;
};

Expand Down
39 changes: 31 additions & 8 deletions libcxx/include/chrono
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,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
Expand Down Expand Up @@ -716,15 +718,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 {
Expand Down Expand Up @@ -842,6 +863,8 @@ 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/tzdb.h>
# include <__chrono/tzdb_list.h>
#endif
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/libcxx.imp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@
{ include: [ "<__chrono/steady_clock.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/system_clock.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/time_point.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/time_zone.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/time_zone_link.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/tzdb.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/tzdb_list.h>", "private", "<chrono>", "public" ] },
{ include: [ "<__chrono/weekday.h>", "private", "<chrono>", "public" ] },
Expand Down
6 changes: 6 additions & 0 deletions libcxx/include/module.modulemap.in
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,12 @@ module std_private_chrono_steady_clock [system] {
header "__chrono/steady_clock.h"
export std_private_chrono_time_point
}
module std_private_chrono_time_zone [system] {
header "__chrono/time_zone.h"
}
module std_private_chrono_time_zone_link [system] {
header "__chrono/time_zone_link.h"
}
module std_private_chrono_system_clock [system] {
header "__chrono/system_clock.h"
export std_private_chrono_time_point
Expand Down
8 changes: 8 additions & 0 deletions libcxx/modules/std/chrono.inc
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,11 @@ export namespace std {

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

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

// [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
// [time.format], formatting
using std::chrono::local_time_format;
# endif
Expand Down
Loading