mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 07:31:28 +00:00
[libc++][chrono] Adds tzdb_list implementation.
This is the first step to implement time zone support in libc++. This adds the complete tzdb_list class and a minimal tzdb class. The tzdb class only contains the version, which is used by reload_tzdb. Next to these classes it contains documentation and build system support needed for time zone support. The code depends on the IANA Time Zone Database, which should be available on the platform used or provided by the libc++ vendors. The code is labeled as experimental since there will be ABI breaks during development; the tzdb class needs to have the standard headers. Implements parts of: - P0355 Extending <chrono> to Calendars and Time Zones Addresses: - LWG3319 Properly reference specification of IANA time zone database Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D154282
This commit is contained in:
parent
460840c09d
commit
f78f93bc9f
@ -87,6 +87,24 @@ option(LIBCXX_ENABLE_WIDE_CHARACTERS
|
||||
support the C functionality for wide characters. When wide characters are
|
||||
not supported, several parts of the library will be disabled, notably the
|
||||
wide character specializations of std::basic_string." ON)
|
||||
|
||||
# To use time zone support in libc++ the platform needs to have the IANA
|
||||
# database installed. Libc++ will fail to build if this is enabled on a
|
||||
# platform that does not provide the IANA database. The default is set to the
|
||||
# current implementation state on the different platforms.
|
||||
#
|
||||
# TODO TZDB make the default always ON when most platforms ship with the IANA
|
||||
# database.
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(ENABLE_TIME_ZONE_DATABASE_DEFAULT ON)
|
||||
else()
|
||||
set(ENABLE_TIME_ZONE_DATABASE_DEFAULT OFF)
|
||||
endif()
|
||||
option(LIBCXX_ENABLE_TIME_ZONE_DATABASE
|
||||
"Whether to include support for time zones in the library. Disabling
|
||||
time zone support can be useful when porting to platforms that don't
|
||||
ship the IANA time zone database. When time zones are not supported,
|
||||
time zone support in <chrono> will be disabled." ${ENABLE_TIME_ZONE_DATABASE_DEFAULT})
|
||||
option(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS
|
||||
"Whether to turn on vendor availability annotations on declarations that depend
|
||||
on definitions in a shared library. By default, we assume that we're not building
|
||||
@ -756,6 +774,7 @@ config_define_if_not(LIBCXX_ENABLE_LOCALIZATION _LIBCPP_HAS_NO_LOCALIZATION)
|
||||
config_define_if_not(LIBCXX_ENABLE_UNICODE _LIBCPP_HAS_NO_UNICODE)
|
||||
config_define_if_not(LIBCXX_ENABLE_WIDE_CHARACTERS _LIBCPP_HAS_NO_WIDE_CHARACTERS)
|
||||
config_define_if_not(LIBCXX_ENABLE_STD_MODULES _LIBCPP_HAS_NO_STD_MODULES)
|
||||
config_define_if_not(LIBCXX_ENABLE_TIME_ZONE_DATABASE _LIBCPP_HAS_NO_TIME_ZONE_DATABASE)
|
||||
config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
|
||||
if (LIBCXX_HARDENING_MODE STREQUAL "hardened")
|
||||
config_define(1 _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT)
|
||||
|
1
libcxx/cmake/caches/Generic-no-tzdb.cmake
Normal file
1
libcxx/cmake/caches/Generic-no-tzdb.cmake
Normal file
@ -0,0 +1 @@
|
||||
set(LIBCXX_ENABLE_TIME_ZONE_DATABASE OFF CACHE BOOL "")
|
@ -255,6 +255,15 @@ libc++ specific options
|
||||
support for ``wchar_t``. This is especially useful in embedded settings where
|
||||
C Standard Libraries don't always provide all the usual bells and whistles.
|
||||
|
||||
.. option:: LIBCXX_ENABLE_TIME_ZONE_DATABASE:BOOL
|
||||
|
||||
**Default**: ``ON``
|
||||
|
||||
Whether to include support for time zones in the library. Disabling
|
||||
time zone support can be useful when porting to platforms that don't
|
||||
ship the IANA time zone database. When time zones are not supported,
|
||||
time zone support in <chrono> will be disabled.
|
||||
|
||||
.. option:: LIBCXX_INSTALL_LIBRARY_DIR:PATH
|
||||
|
||||
**Default**: ``lib${LIBCXX_LIBDIR_SUFFIX}``
|
||||
|
122
libcxx/docs/DesignDocs/TimeZone.rst
Normal file
122
libcxx/docs/DesignDocs/TimeZone.rst
Normal file
@ -0,0 +1,122 @@
|
||||
=================
|
||||
Time Zone Support
|
||||
=================
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Starting with C++20 the ``<chrono>`` library has support for time zones.
|
||||
These are available in the
|
||||
`IANA Time Zone Database <https://data.iana.org/time-zones/tz-link.html>`_.
|
||||
This page describes the design decisions and trade-offs made to implement this
|
||||
feature. This page contains several links with more information regarding the
|
||||
contents of the IANA database, this page assumes the reader is familiar with
|
||||
this information.
|
||||
|
||||
Which version of the Time Zone Database to use
|
||||
==============================================
|
||||
|
||||
The data of the database is available on several platforms in different forms:
|
||||
|
||||
- Typically Unix systems ship the database as
|
||||
`TZif files <https://www.rfc-editor.org/rfc/rfc8536.html>`_. This format has
|
||||
3 versions and the ``time_zone_link`` information is not always available.
|
||||
If available, they are symlinks in the file system.
|
||||
These files don't provide the database version information. This information
|
||||
is needed for the functions ``std::chrono:: remote_version()`` and
|
||||
``std::chrono::reload_tzdb()``.
|
||||
|
||||
- On several Unix systems the time zone source files are available. These files
|
||||
are stored in several regions, mainly the continents. This file contains a
|
||||
large amount of comment with historical information regarding time zones.
|
||||
The format is documented in the
|
||||
`IANA documentation <https://data.iana.org/time-zones/tz-how-to.html>`_
|
||||
and in the `man page <https://man7.org/linux/man-pages/man8/zic.8.html>`_ of zic.
|
||||
The disadvantage of this version is that at least Linux versions don't have
|
||||
the database version information. This information is needed for the functions
|
||||
``std::chrono:: remote_version()`` and ``std::chrono::reload_tzdb()``.
|
||||
|
||||
- On Linux systems ``tzdata.zi`` is available. This contains the same
|
||||
information as the source files but in one file without the comments. This
|
||||
file uses the same format as the sources, but shortens the names. For example
|
||||
``Rule`` is abbreviated to ``R``. This file contains the database version
|
||||
information.
|
||||
|
||||
The disadvantage of the ``TZif`` format (which is a binary format) is that it's
|
||||
not possible to get the proper ``time_zone_link`` information on all platforms.
|
||||
The time zone database version number is also missing from ``TZif`` files.
|
||||
Since the time zone database is supposed to contain both these informations,
|
||||
``TZif`` files can't be used to create a conforming implementation.
|
||||
|
||||
Since it's easier to parse one file than a set of files we decided
|
||||
to use the ``tzdata.zi``. The other benefit is that the ``tzdata.zi`` file
|
||||
contains the database version information needed for a conforming
|
||||
implementation.
|
||||
|
||||
The ``tzdata.zi`` file is not available on all platforms as of August 2023, so
|
||||
some vendors will need to make changes to their platform. Most vendors already
|
||||
ship the database, so they only need to adjust the packaging of their time zone
|
||||
package to include the files we require. One notable exception is Windows,
|
||||
where no IANA time zone database is provided at all. However it's possible for
|
||||
Windows packagers to add these files to their libc++ packages. The IANA
|
||||
databases can be
|
||||
`downloaded <https://data.iana.org/time-zones/releases/>`_.
|
||||
|
||||
An alternative would be to ship the database with libc++, either as a file or
|
||||
compiled in the dylib. The text file is about 112 KB. For now libc++ will not
|
||||
ship this file. If it's hard to get vendors to ship these files we can
|
||||
reconsider based on that information.
|
||||
|
||||
Leap seconds
|
||||
------------
|
||||
|
||||
For the leap seconds libc++ will use the source file ``leap-seconds.list``.
|
||||
This file is easier to parse than the ``leapseconds`` file. Both files are
|
||||
present on Linux, but not always on other platforms. Since these platforms need
|
||||
to change their packaging for ``tzdata.zi``, adding two instead of one files
|
||||
seems a small change.
|
||||
|
||||
|
||||
Updating the Time Zone Database
|
||||
===============================
|
||||
|
||||
Per `[time.zone.db.remote]/1 <http://eel.is/c++draft/time.zone#db.remote-1>`_
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
The local time zone database is that supplied by the implementation when the
|
||||
program first accesses the database, for example via current_zone(). While the
|
||||
program is running, the implementation may choose to update the time zone
|
||||
database. This update shall not impact the program in any way unless the
|
||||
program calls the functions in this subclause. This potentially updated time
|
||||
zone database is referred to as the remote time zone database.
|
||||
|
||||
There is an update mechanism in libc++, however this is not done automatically.
|
||||
Invoking the function ``std::chrono::remote_version()`` will parse the version
|
||||
information of the ``tzdata.zi`` file and return that information. Similarly,
|
||||
``std::chrono::reload_tzdb()`` will parse the ``tzdata.zi`` and
|
||||
``leap-seconds.list`` again. This makes it possible to update the database if
|
||||
needed by the application and gives the user full power over the update policy.
|
||||
|
||||
This approach has several advantages:
|
||||
|
||||
- It is simple to implement.
|
||||
- The library does not need to start a periodic background process to poll
|
||||
changes to the filesystem. When using a background process, it may become
|
||||
active when the application is busy with its core task, taking away resources
|
||||
from that task.
|
||||
- If there is no threading available this polling
|
||||
becomes more involved. For example, query the file every *x* calls to
|
||||
``std::chrono::get_tzdb()``. This mean calls to ``std::chrono::get_tzdb()``
|
||||
would have different performance characteristics.
|
||||
|
||||
The small drawback is:
|
||||
|
||||
- On platforms with threading enabled updating the database may take longer.
|
||||
On these platforms the remote database could have been loaded in a background
|
||||
process.
|
||||
|
||||
Another issue with the automatic update is that it may not be considered
|
||||
Standard compliant, since the Standard uses the wording "This update shall not
|
||||
impact the program in any way". Using resources could be considered as
|
||||
impacting the program.
|
35
libcxx/docs/ImplementationDefinedBehavior.rst
Normal file
35
libcxx/docs/ImplementationDefinedBehavior.rst
Normal file
@ -0,0 +1,35 @@
|
||||
.. _implementation-defined-behavior:
|
||||
|
||||
===============================
|
||||
Implementation-defined behavior
|
||||
===============================
|
||||
|
||||
Contains the implementation details of the implementation-defined behavior in
|
||||
libc++. Implementation-defined is mandated to be documented by the Standard.
|
||||
|
||||
.. note:
|
||||
This page is far from complete.
|
||||
|
||||
|
||||
Implementation-defined behavior
|
||||
===============================
|
||||
|
||||
Updating the Time Zone Database
|
||||
-------------------------------
|
||||
|
||||
The Standard allows implementations to automatically update the
|
||||
*remote time zone database*. Libc++ opts not to do that. Instead calling
|
||||
|
||||
- ``std::chrono::remote_version()`` will update the version information of the
|
||||
*remote time zone database*,
|
||||
- ``std::chrono::reload_tzdb()``, if needed, will update the entire
|
||||
*remote time zone database*.
|
||||
|
||||
This offers a way for users to update the *remote time zone database* and
|
||||
give them full control over the process.
|
||||
|
||||
Listed in the index of implementation-defined behavior
|
||||
======================================================
|
||||
|
||||
The order of the entries matches the entries in the
|
||||
`draft of the Standard <http://eel.is/c++draft/impldefindex>`_.
|
@ -49,6 +49,15 @@ Paper Status
|
||||
.. [#note-P0883.2] P0883: ``ATOMIC_FLAG_INIT`` was marked deprecated in version 14.0, but was undeprecated with the implementation of LWG3659 in version 15.0.
|
||||
.. [#note-P2231] P2231: Optional is complete. The changes to variant haven't been implemented yet.
|
||||
.. [#note-P0660] P0660: Section 32.3 Stop Tokens is complete. ``jthread`` hasn't been implemented yet.
|
||||
.. [#note-P0355] P0355: The implementation status is:
|
||||
|
||||
* ``Calendars`` mostly done in Clang 7
|
||||
* ``Input parsers`` not done
|
||||
* ``Stream output`` Obsolete due to `P1361R2 <https://wg21.link/P1361R2>`_ "Integration of chrono with text formatting"
|
||||
* ``Time zone and leap seconds`` In Progress
|
||||
* ``TAI clock`` not done
|
||||
* ``GPS clock`` not done
|
||||
* ``UTC clock`` not done
|
||||
|
||||
.. _issues-status-cxx20:
|
||||
|
||||
|
@ -241,7 +241,7 @@
|
||||
"`3316 <https://wg21.link/LWG3316>`__","Correctly define epoch for ``utc_clock``\ / ``utc_timepoint``\ ","Prague","","","|chrono|"
|
||||
"`3317 <https://wg21.link/LWG3317>`__","Incorrect ``operator<<``\ for floating-point durations","Prague","","","|chrono|"
|
||||
"`3318 <https://wg21.link/LWG3318>`__","Clarify whether clocks can represent time before their epoch","Prague","","","|chrono|"
|
||||
"`3319 <https://wg21.link/LWG3319>`__","Properly reference specification of IANA time zone database","Prague","","","|chrono|"
|
||||
"`3319 <https://wg21.link/LWG3319>`__","Properly reference specification of IANA time zone database","Prague","|Nothing To Do|","","|chrono|"
|
||||
"`3320 <https://wg21.link/LWG3320>`__","``span::cbegin/cend``\ methods produce different results than ``std::[ranges::]cbegin/cend``\ ","Prague","|Complete|",""
|
||||
"`3321 <https://wg21.link/LWG3321>`__","``uninitialized_construct_using_allocator``\ should use ``construct_at``\ ","Prague","|Complete|","16.0"
|
||||
"`3323 <https://wg21.link/LWG3323>`__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","|Complete|","16.0","|ranges|"
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
@ -17,7 +17,7 @@
|
||||
"`P0768R1 <https://wg21.link/P0768R1>`__","CWG","Library Support for the Spaceship (Comparison) Operator","Albuquerque","|Complete|",""
|
||||
"`P0777R1 <https://wg21.link/P0777R1>`__","LWG","Treating Unnecessary ``decay``\ ","Albuquerque","|Complete|","7.0"
|
||||
"`P0122R7 <https://wg21.link/P0122R7>`__","LWG","<span>","Jacksonville","|Complete|","7.0"
|
||||
"`P0355R7 <https://wg21.link/P0355R7>`__","LWG","Extending chrono to Calendars and Time Zones","Jacksonville","|In Progress|",""
|
||||
"`P0355R7 <https://wg21.link/P0355R7>`__","LWG","Extending chrono to Calendars and Time Zones","Jacksonville","|Partial| [#note-P0355]_",""
|
||||
"`P0551R3 <https://wg21.link/P0551R3>`__","LWG","Thou Shalt Not Specialize ``std``\ Function Templates!","Jacksonville","|Complete|","11.0"
|
||||
"`P0753R2 <https://wg21.link/P0753R2>`__","LWG","Manipulators for C++ Synchronized Buffered Ostream","Jacksonville","",""
|
||||
"`P0754R2 <https://wg21.link/P0754R2>`__","LWG","<version>","Jacksonville","|Complete|","7.0"
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
@ -369,6 +369,13 @@ which no dialect declares as such (See the second form described above).
|
||||
* ``byteswap``
|
||||
* ``cbrt``
|
||||
* ``ceil``
|
||||
* ``chrono::tzdb_list::begin``
|
||||
* ``chrono::tzdb_list::cbegin``
|
||||
* ``chrono::tzdb_list::cend``
|
||||
* ``chrono::tzdb_list::end``
|
||||
* ``chrono::get_tzdb_list``
|
||||
* ``chrono::get_tzdb``
|
||||
* ``chrono::remote_version``
|
||||
* ``clamp``
|
||||
* ``copysign``
|
||||
* ``count_if``
|
||||
|
@ -40,6 +40,7 @@ Getting Started with libc++
|
||||
BuildingLibcxx
|
||||
TestingLibcxx
|
||||
Contributing
|
||||
ImplementationDefinedBehavior
|
||||
Modules
|
||||
Hardening
|
||||
ReleaseProcedure
|
||||
@ -193,6 +194,7 @@ Design Documents
|
||||
DesignDocs/UniquePtrTrivialAbi
|
||||
DesignDocs/UnspecifiedBehaviorRandomization
|
||||
DesignDocs/VisibilityMacros
|
||||
DesignDocs/TimeZone
|
||||
|
||||
|
||||
Build Bots and Test Coverage
|
||||
|
@ -283,6 +283,8 @@ set(files
|
||||
__chrono/steady_clock.h
|
||||
__chrono/system_clock.h
|
||||
__chrono/time_point.h
|
||||
__chrono/tzdb.h
|
||||
__chrono/tzdb_list.h
|
||||
__chrono/weekday.h
|
||||
__chrono/year.h
|
||||
__chrono/year_month.h
|
||||
|
@ -174,6 +174,11 @@
|
||||
// # define _LIBCPP_AVAILABILITY_HAS_NO_PMR
|
||||
# define _LIBCPP_AVAILABILITY_PMR
|
||||
|
||||
// This controls the availability of the C++20 time zone database.
|
||||
// The parser code is built in the library.
|
||||
// # define _LIBCPP_AVAILABILITY_HAS_NO_TZDB
|
||||
# define _LIBCPP_AVAILABILITY_TZDB
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
// shared_mutex and shared_timed_mutex
|
||||
@ -348,6 +353,9 @@
|
||||
# define _LIBCPP_AVAILABILITY_PMR
|
||||
# endif
|
||||
|
||||
# define _LIBCPP_AVAILABILITY_HAS_NO_TZDB
|
||||
# define _LIBCPP_AVAILABILITY_TZDB __attribute__((unavailable))
|
||||
|
||||
#else
|
||||
|
||||
// ...New vendors can add availability markup here...
|
||||
|
45
libcxx/include/__chrono/tzdb.h
Normal file
45
libcxx/include/__chrono/tzdb.h
Normal file
@ -0,0 +1,45 @@
|
||||
// -*- 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_TZDB_H
|
||||
#define _LIBCPP___CHRONO_TZDB_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 <string>
|
||||
|
||||
# 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 {
|
||||
|
||||
struct _LIBCPP_AVAILABILITY_TZDB tzdb {
|
||||
string version;
|
||||
};
|
||||
|
||||
} // 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_TZDB_H
|
81
libcxx/include/__chrono/tzdb_list.h
Normal file
81
libcxx/include/__chrono/tzdb_list.h
Normal file
@ -0,0 +1,81 @@
|
||||
// -*- 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_TZDB_LIST_H
|
||||
#define _LIBCPP___CHRONO_TZDB_LIST_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 <__availability>
|
||||
# include <__chrono/tzdb.h>
|
||||
# include <forward_list>
|
||||
# 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 tzdb_list {
|
||||
public:
|
||||
_LIBCPP_EXPORTED_FROM_ABI explicit tzdb_list(tzdb&& __tzdb);
|
||||
_LIBCPP_EXPORTED_FROM_ABI ~tzdb_list();
|
||||
|
||||
tzdb_list(const tzdb_list&) = delete;
|
||||
tzdb_list& operator=(const tzdb_list&) = delete;
|
||||
|
||||
using const_iterator = forward_list<tzdb>::const_iterator;
|
||||
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const tzdb& front() const noexcept;
|
||||
|
||||
_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;
|
||||
|
||||
private:
|
||||
class __impl;
|
||||
__impl* __impl_;
|
||||
};
|
||||
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list();
|
||||
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const tzdb& get_tzdb() {
|
||||
return get_tzdb_list().front();
|
||||
}
|
||||
|
||||
_LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI const tzdb& reload_tzdb();
|
||||
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version();
|
||||
|
||||
} // 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_TZDB_LIST_H
|
@ -397,10 +397,8 @@
|
||||
// easier to grep for target specific flags once the feature is complete.
|
||||
# if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY)
|
||||
# define _LIBCPP_HAS_NO_INCOMPLETE_PSTL
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY)
|
||||
# define _LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN
|
||||
# define _LIBCPP_HAS_NO_INCOMPLETE_TZDB
|
||||
# endif
|
||||
|
||||
// Need to detect which libc we're using if we're on Linux.
|
||||
|
@ -28,6 +28,7 @@
|
||||
#cmakedefine _LIBCPP_HAS_NO_LOCALIZATION
|
||||
#cmakedefine _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
#cmakedefine _LIBCPP_HAS_NO_STD_MODULES
|
||||
#cmakedefine _LIBCPP_HAS_NO_TIME_ZONE_DATABASE
|
||||
|
||||
// PSTL backends
|
||||
#cmakedefine _LIBCPP_PSTL_CPU_BACKEND_SERIAL
|
||||
|
@ -677,6 +677,39 @@ constexpr bool is_pm(hours const& h) noexcept;
|
||||
constexpr hours make12(const hours& h) noexcept;
|
||||
constexpr hours make24(const hours& h, bool is_pm) noexcept;
|
||||
|
||||
// [time.zone.db], time zone database
|
||||
struct tzdb { // C++20
|
||||
string version;
|
||||
};
|
||||
|
||||
class tzdb_list { // C++20
|
||||
public:
|
||||
tzdb_list(const tzdb_list&) = delete;
|
||||
tzdb_list& operator=(const tzdb_list&) = delete;
|
||||
|
||||
// unspecified additional constructors
|
||||
|
||||
class const_iterator;
|
||||
|
||||
const tzdb& front() const noexcept;
|
||||
|
||||
const_iterator erase_after(const_iterator p);
|
||||
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
|
||||
const_iterator cbegin() const noexcept;
|
||||
const_iterator cend() const noexcept;
|
||||
};
|
||||
|
||||
// [time.zone.db.access], time zone database access
|
||||
const tzdb& get_tzdb(); // C++20
|
||||
tzdb_list& get_tzdb_list(); // C++20
|
||||
|
||||
// [time.zone.db.remote], remote time zone database support
|
||||
const tzdb& reload_tzdb(); // C++20
|
||||
string remote_version(); // C++20
|
||||
|
||||
// 25.10.5, class time_zone // C++20
|
||||
enum class choose {earliest, latest};
|
||||
class time_zone;
|
||||
@ -799,6 +832,11 @@ constexpr chrono::year operator ""y(unsigned lo
|
||||
# include <__chrono/statically_widen.h>
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
|
||||
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
|
||||
# include <__chrono/tzdb.h>
|
||||
# include <__chrono/tzdb_list.h>
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
|
@ -1191,6 +1191,14 @@ module std_private_chrono_system_clock [system] {
|
||||
header "__chrono/system_clock.h"
|
||||
export std_private_chrono_time_point
|
||||
}
|
||||
module std_private_chrono_tzdb [system] {
|
||||
header "__chrono/tzdb.h"
|
||||
export *
|
||||
}
|
||||
module std_private_chrono_tzdb_list [system] {
|
||||
header "__chrono/tzdb_list.h"
|
||||
export *
|
||||
}
|
||||
module std_private_chrono_time_point [system] { header "__chrono/time_point.h" }
|
||||
module std_private_chrono_weekday [system] { header "__chrono/weekday.h" }
|
||||
module std_private_chrono_year [system] { header "__chrono/year.h" }
|
||||
|
@ -190,21 +190,27 @@ export namespace std {
|
||||
using std::chrono::make12;
|
||||
using std::chrono::make24;
|
||||
|
||||
#if 0
|
||||
#if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
|
||||
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
|
||||
|
||||
// [time.zone.db], time zone database
|
||||
using std::chrono::tzdb;
|
||||
using std::chrono::tzdb_list;
|
||||
|
||||
// [time.zone.db.access], time zone database access
|
||||
using std::chrono::current_zone;
|
||||
// using std::chrono::current_zone;
|
||||
using std::chrono::get_tzdb;
|
||||
using std::chrono::get_tzdb_list;
|
||||
using std::chrono::locate_zone;
|
||||
// using std::chrono::locate_zone;
|
||||
|
||||
// [time.zone.db.remote], remote time zone database support
|
||||
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
|
||||
// [time.zone.exception], exception classes
|
||||
using std::chrono::ambiguous_local_time;
|
||||
using std::chrono::nonexistent_local_time;
|
||||
|
@ -326,6 +326,13 @@ if (LIBCXX_PSTL_CPU_BACKEND STREQUAL "libdispatch")
|
||||
)
|
||||
endif()
|
||||
|
||||
if (LIBCXX_ENABLE_LOCALIZATION AND LIBCXX_ENABLE_FILESYSTEM AND LIBCXX_ENABLE_TIME_ZONE_DATABASE)
|
||||
list(APPEND LIBCXX_EXPERIMENTAL_SOURCES
|
||||
tz.cpp
|
||||
tzdb_list.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES})
|
||||
target_link_libraries(cxx_experimental PUBLIC cxx-headers)
|
||||
if (LIBCXX_ENABLE_SHARED)
|
||||
|
146
libcxx/src/tz.cpp
Normal file
146
libcxx/src/tz.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
// Contains a parser for the IANA time zone data files.
|
||||
//
|
||||
// These files can be found at https://data.iana.org/time-zones/ and are in the
|
||||
// public domain. Information regarding the input can be found at
|
||||
// https://data.iana.org/time-zones/tz-how-to.html and
|
||||
// https://man7.org/linux/man-pages/man8/zic.8.html.
|
||||
//
|
||||
// As indicated at https://howardhinnant.github.io/date/tz.html#Installation
|
||||
// For Windows another file seems to be required
|
||||
// https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml
|
||||
// This file seems to contain the mapping of Windows time zone name to IANA
|
||||
// time zone names.
|
||||
//
|
||||
// However this article mentions another way to do the mapping on Windows
|
||||
// https://devblogs.microsoft.com/oldnewthing/20210527-00/?p=105255
|
||||
// This requires Windows 10 Version 1903, which was released in May of 2019
|
||||
// and considered end of life in December 2020
|
||||
// https://learn.microsoft.com/en-us/lifecycle/announcements/windows-10-1903-end-of-servicing
|
||||
//
|
||||
// TODO TZDB Implement the Windows mapping in tzdb::current_zone
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace chrono {
|
||||
|
||||
// This function is weak so it can be overriden in the tests. The
|
||||
// declaration is in the test header test/support/test_tzdb.h
|
||||
_LIBCPP_WEAK string_view __libcpp_tzdb_directory() {
|
||||
#if defined(__linux__)
|
||||
return "/usr/share/zoneinfo/";
|
||||
#else
|
||||
# error "unknown path to the IANA Time Zone Database"
|
||||
#endif
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool __is_whitespace(int __c) { return __c == ' ' || __c == '\t'; }
|
||||
|
||||
static void __skip_optional_whitespace(istream& __input) {
|
||||
while (chrono::__is_whitespace(__input.peek()))
|
||||
__input.get();
|
||||
}
|
||||
|
||||
static void __skip_mandatory_whitespace(istream& __input) {
|
||||
if (!chrono::__is_whitespace(__input.get()))
|
||||
std::__throw_runtime_error("corrupt tzdb: expected whitespace");
|
||||
|
||||
chrono::__skip_optional_whitespace(__input);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
static void __matches(istream& __input, string_view __expected) {
|
||||
for (auto __c : __expected)
|
||||
if (std::tolower(__input.get()) != __c)
|
||||
std::__throw_runtime_error((string("corrupt tzdb: expected string '") + string(__expected) + '\'').c_str());
|
||||
}
|
||||
|
||||
[[nodiscard]] static string __parse_string(istream& __input) {
|
||||
string __result;
|
||||
while (true) {
|
||||
int __c = __input.get();
|
||||
switch (__c) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
__input.unget();
|
||||
[[fallthrough]];
|
||||
case istream::traits_type::eof():
|
||||
if (__result.empty())
|
||||
std::__throw_runtime_error("corrupt tzdb: expected a string");
|
||||
|
||||
return __result;
|
||||
|
||||
default:
|
||||
__result.push_back(__c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static string __parse_version(istream& __input) {
|
||||
// The first line in tzdata.zi contains
|
||||
// # version YYYYw
|
||||
// The parser expects this pattern
|
||||
// #\s*version\s*\(.*)
|
||||
// This part is not documented.
|
||||
chrono::__matches(__input, '#');
|
||||
chrono::__skip_optional_whitespace(__input);
|
||||
chrono::__matches(__input, "version");
|
||||
chrono::__skip_mandatory_whitespace(__input);
|
||||
return chrono::__parse_string(__input);
|
||||
}
|
||||
|
||||
static tzdb __make_tzdb() {
|
||||
tzdb __result;
|
||||
|
||||
filesystem::path __root = chrono::__libcpp_tzdb_directory();
|
||||
ifstream __tzdata{__root / "tzdata.zi"};
|
||||
|
||||
__result.version = chrono::__parse_version(__tzdata);
|
||||
return __result;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Public API
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list() {
|
||||
static tzdb_list __result{chrono::__make_tzdb()};
|
||||
return __result;
|
||||
}
|
||||
|
||||
_LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI const tzdb& reload_tzdb() {
|
||||
if (chrono::remote_version() == chrono::get_tzdb().version)
|
||||
return chrono::get_tzdb();
|
||||
|
||||
return chrono::get_tzdb_list().__emplace_front(chrono::__make_tzdb());
|
||||
}
|
||||
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version() {
|
||||
filesystem::path __root = chrono::__libcpp_tzdb_directory();
|
||||
ifstream __tzdata{__root / "tzdata.zi"};
|
||||
return chrono::__parse_version(__tzdata);
|
||||
}
|
||||
|
||||
} // namespace chrono
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
113
libcxx/src/tzdb_list.cpp
Normal file
113
libcxx/src/tzdb_list.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <__mutex/unique_lock.h>
|
||||
#include <forward_list>
|
||||
|
||||
// When threads are not available the locking is not required.
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
# include <shared_mutex>
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace chrono {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Private API
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class tzdb_list::__impl {
|
||||
public:
|
||||
explicit __impl(tzdb&& __tzdb) { __tzdb_.push_front(std::move(__tzdb)); }
|
||||
|
||||
using const_iterator = tzdb_list::const_iterator;
|
||||
|
||||
const tzdb& front() const noexcept {
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
shared_lock __lock{__mutex_};
|
||||
#endif
|
||||
return __tzdb_.front();
|
||||
}
|
||||
|
||||
const_iterator erase_after(const_iterator __p) {
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
unique_lock __lock{__mutex_};
|
||||
#endif
|
||||
return __tzdb_.erase_after(__p);
|
||||
}
|
||||
|
||||
tzdb& __emplace_front(tzdb&& __tzdb) {
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
unique_lock __lock{__mutex_};
|
||||
#endif
|
||||
return __tzdb_.emplace_front(std::move(__tzdb));
|
||||
}
|
||||
|
||||
const_iterator begin() const noexcept {
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
shared_lock __lock{__mutex_};
|
||||
#endif
|
||||
return __tzdb_.begin();
|
||||
}
|
||||
const_iterator end() const noexcept {
|
||||
// forward_list<T>::end does not access the list, so no need to take a lock.
|
||||
return __tzdb_.end();
|
||||
}
|
||||
|
||||
const_iterator cbegin() const noexcept { return begin(); }
|
||||
const_iterator cend() const noexcept { return end(); }
|
||||
|
||||
private:
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
mutable shared_mutex __mutex_;
|
||||
#endif
|
||||
forward_list<tzdb> __tzdb_;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Public API
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
_LIBCPP_EXPORTED_FROM_ABI tzdb_list::tzdb_list(tzdb&& __tzdb) : __impl_{new __impl(std::move(__tzdb))} {}
|
||||
|
||||
_LIBCPP_EXPORTED_FROM_ABI tzdb_list::~tzdb_list() { delete __impl_; }
|
||||
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const tzdb& tzdb_list::front() const noexcept {
|
||||
return __impl_->front();
|
||||
}
|
||||
|
||||
_LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::erase_after(const_iterator __p) {
|
||||
return __impl_->erase_after(__p);
|
||||
}
|
||||
|
||||
_LIBCPP_EXPORTED_FROM_ABI tzdb& tzdb_list::__emplace_front(tzdb&& __tzdb) {
|
||||
return __impl_->__emplace_front(std::move(__tzdb));
|
||||
}
|
||||
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::begin() const noexcept {
|
||||
return __impl_->begin();
|
||||
}
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::end() const noexcept {
|
||||
return __impl_->end();
|
||||
}
|
||||
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::cbegin() const noexcept {
|
||||
return __impl_->cbegin();
|
||||
}
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::cend() const noexcept {
|
||||
return __impl_->cend();
|
||||
}
|
||||
|
||||
} // namespace chrono
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
@ -0,0 +1,37 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Check that format functions aren't marked [[nodiscard]] when
|
||||
// _LIBCPP_DISBALE_NODISCARD_EXT is defined
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14 ,c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_NODISCARD_EXT
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
void test() {
|
||||
std::chrono::tzdb_list& list = std::chrono::get_tzdb_list();
|
||||
list.front();
|
||||
list.begin();
|
||||
list.end();
|
||||
list.cbegin();
|
||||
list.cend();
|
||||
|
||||
std::chrono::get_tzdb_list();
|
||||
std::chrono::get_tzdb();
|
||||
std::chrono::remote_version();
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Check that format functions are marked [[nodiscard]] as a conforming extension
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14 ,c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
void test() {
|
||||
std::chrono::tzdb_list& list = std::chrono::get_tzdb_list();
|
||||
list.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
list.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
list.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
list.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
list.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
|
||||
namespace crno = std::chrono;
|
||||
crno::get_tzdb_list(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
crno::get_tzdb(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
crno::remote_version(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
|
||||
}
|
@ -30,3 +30,7 @@
|
||||
#ifdef _LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN
|
||||
# error "-fexperimental-library should enable the stop_token"
|
||||
#endif
|
||||
|
||||
#ifdef _LIBCPP_HAS_NO_INCOMPLETE_TZDB
|
||||
# error "-fexperimental-library should enable the chrono TZDB"
|
||||
#endif
|
||||
|
@ -0,0 +1,71 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
//
|
||||
// class tzdb_list;
|
||||
//
|
||||
// const_iterator erase_after(const_iterator p);
|
||||
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
|
||||
#include "filesystem_test_helper.h"
|
||||
#include "test_macros.h"
|
||||
#include "test_tzdb.h"
|
||||
|
||||
scoped_test_env env;
|
||||
[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
|
||||
const std::filesystem::path data = env.create_file("zoneinfo/tzdata.zi");
|
||||
|
||||
std::string_view std::chrono::__libcpp_tzdb_directory() {
|
||||
static std::string result = dir.string();
|
||||
return result;
|
||||
}
|
||||
|
||||
static void write(std::string_view input) { std::ofstream{data}.write(input.data(), input.size()); }
|
||||
|
||||
int main(int, const char**) {
|
||||
write("# version 1");
|
||||
std::chrono::tzdb_list& list = std::chrono::get_tzdb_list(); // [1]
|
||||
|
||||
write("# version 2");
|
||||
std::chrono::reload_tzdb(); // [2, 1]
|
||||
|
||||
assert(std::distance(list.begin(), list.end()) == 2);
|
||||
assert(list.front().version == "2");
|
||||
|
||||
list.erase_after(list.begin()); // [2]
|
||||
assert(std::distance(list.begin(), list.end()) == 1);
|
||||
assert(list.front().version == "2");
|
||||
|
||||
write("# version 3");
|
||||
std::chrono::reload_tzdb(); // [3, 2]
|
||||
assert(std::distance(list.begin(), list.end()) == 2);
|
||||
|
||||
write("# version 4");
|
||||
std::chrono::reload_tzdb(); // [4, 3, 2]
|
||||
assert(std::distance(list.begin(), list.end()) == 3);
|
||||
assert(list.front().version == "4");
|
||||
|
||||
std::chrono::tzdb_list::const_iterator it = ++list.begin();
|
||||
assert(it->version == "3");
|
||||
|
||||
list.erase_after(it); // [4, 3]
|
||||
assert(std::distance(list.begin(), list.end()) == 2);
|
||||
assert(list.front().version == "4");
|
||||
assert(it->version == "3");
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
|
||||
// const tzdb& reload_tzdb();
|
||||
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
|
||||
#include "filesystem_test_helper.h"
|
||||
#include "test_macros.h"
|
||||
#include "test_tzdb.h"
|
||||
|
||||
scoped_test_env env;
|
||||
[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
|
||||
const std::filesystem::path data = env.create_file("zoneinfo/tzdata.zi");
|
||||
|
||||
std::string_view std::chrono::__libcpp_tzdb_directory() {
|
||||
static std::string result = dir.string();
|
||||
return result;
|
||||
}
|
||||
|
||||
static void write(std::string_view input) { std::ofstream{data}.write(input.data(), input.size()); }
|
||||
|
||||
int main(int, const char**) {
|
||||
write("# version old_version");
|
||||
const std::chrono::tzdb_list& list = std::chrono::get_tzdb_list();
|
||||
std::string version = "new_version";
|
||||
|
||||
assert(list.front().version == "old_version");
|
||||
assert(std::distance(list.begin(), list.end()) == 1);
|
||||
assert(std::distance(list.cbegin(), list.cend()) == 1);
|
||||
|
||||
write("# version new_version");
|
||||
assert(std::chrono::remote_version() == version);
|
||||
|
||||
std::chrono::reload_tzdb();
|
||||
|
||||
assert(std::distance(list.begin(), list.end()) == 2);
|
||||
assert(std::distance(list.cbegin(), list.cend()) == 2);
|
||||
assert(list.front().version == version);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
|
||||
// Tests the IANA database version parsing.
|
||||
// This is not part of the public tzdb interface.
|
||||
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "assert_macros.h"
|
||||
#include "concat_macros.h"
|
||||
#include "filesystem_test_helper.h"
|
||||
#include "test_tzdb.h"
|
||||
|
||||
scoped_test_env env;
|
||||
[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
|
||||
const std::filesystem::path data = env.create_file("zoneinfo/tzdata.zi");
|
||||
|
||||
std::string_view std::chrono::__libcpp_tzdb_directory() {
|
||||
static std::string result = dir.string();
|
||||
return result;
|
||||
}
|
||||
|
||||
static void test(std::string_view input, std::string_view expected) {
|
||||
std::ofstream{data}.write(input.data(), input.size());
|
||||
std::string version = std::chrono::remote_version();
|
||||
|
||||
TEST_REQUIRE(
|
||||
version == expected,
|
||||
TEST_WRITE_CONCATENATED(
|
||||
"\nInput ", input, "\nExpected version ", expected, "\nActual version ", version, '\n'));
|
||||
}
|
||||
|
||||
static void test_exception(std::string_view input, [[maybe_unused]] std::string_view what) {
|
||||
std::ofstream{data}.write(input.data(), input.size());
|
||||
|
||||
TEST_VALIDATE_EXCEPTION(
|
||||
std::runtime_error,
|
||||
[&]([[maybe_unused]] const std::runtime_error& e) {
|
||||
TEST_LIBCPP_REQUIRE(
|
||||
e.what() == what,
|
||||
TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
|
||||
},
|
||||
TEST_IGNORE_NODISCARD std::chrono::remote_version());
|
||||
}
|
||||
|
||||
int main(int, const char**) {
|
||||
test_exception("", "corrupt tzdb: expected character '#'");
|
||||
test_exception("#version", "corrupt tzdb: expected whitespace");
|
||||
test("#version \t ABCD", "ABCD");
|
||||
test("#Version \t ABCD", "ABCD");
|
||||
test("#vErsion \t ABCD", "ABCD");
|
||||
test("#verSion \t ABCD", "ABCD");
|
||||
test("#VERSION \t ABCD", "ABCD");
|
||||
test("# \t version \t 2023a", "2023a");
|
||||
|
||||
return 0;
|
||||
}
|
@ -64,7 +64,7 @@ else:
|
||||
{lit_header_restrictions.get(header, '')}
|
||||
|
||||
// TODO: Fix this test to make it work with localization or wide characters disabled
|
||||
// UNSUPPORTED{BLOCKLIT}: no-localization, no-wide-characters
|
||||
// UNSUPPORTED{BLOCKLIT}: no-localization, no-wide-characters, no-threads, no-filesystem, libcpp-has-no-incomplete-tzdb, no-tzdb
|
||||
|
||||
// When built with modules, this test doesn't work because --trace-includes doesn't
|
||||
// report the stack of includes correctly.
|
||||
|
@ -119,9 +119,11 @@ chrono cstddef
|
||||
chrono cstdint
|
||||
chrono cstring
|
||||
chrono ctime
|
||||
chrono forward_list
|
||||
chrono limits
|
||||
chrono ratio
|
||||
chrono stdexcept
|
||||
chrono string
|
||||
chrono string_view
|
||||
chrono tuple
|
||||
chrono type_traits
|
||||
|
|
@ -119,9 +119,11 @@ chrono cstddef
|
||||
chrono cstdint
|
||||
chrono cstring
|
||||
chrono ctime
|
||||
chrono forward_list
|
||||
chrono limits
|
||||
chrono ratio
|
||||
chrono stdexcept
|
||||
chrono string
|
||||
chrono string_view
|
||||
chrono tuple
|
||||
chrono type_traits
|
||||
|
|
@ -119,9 +119,11 @@ chrono cstddef
|
||||
chrono cstdint
|
||||
chrono cstring
|
||||
chrono ctime
|
||||
chrono forward_list
|
||||
chrono limits
|
||||
chrono ratio
|
||||
chrono stdexcept
|
||||
chrono string
|
||||
chrono string_view
|
||||
chrono tuple
|
||||
chrono type_traits
|
||||
|
|
@ -119,9 +119,11 @@ chrono cstddef
|
||||
chrono cstdint
|
||||
chrono cstring
|
||||
chrono ctime
|
||||
chrono forward_list
|
||||
chrono limits
|
||||
chrono ratio
|
||||
chrono stdexcept
|
||||
chrono string
|
||||
chrono string_view
|
||||
chrono tuple
|
||||
chrono type_traits
|
||||
|
|
@ -121,6 +121,7 @@ chrono cstddef
|
||||
chrono cstdint
|
||||
chrono cstring
|
||||
chrono ctime
|
||||
chrono forward_list
|
||||
chrono limits
|
||||
chrono locale
|
||||
chrono optional
|
||||
|
|
@ -73,6 +73,7 @@ chrono compare
|
||||
chrono cstddef
|
||||
chrono cstdint
|
||||
chrono ctime
|
||||
chrono forward_list
|
||||
chrono initializer_list
|
||||
chrono limits
|
||||
chrono locale
|
||||
|
|
@ -73,6 +73,7 @@ chrono compare
|
||||
chrono cstddef
|
||||
chrono cstdint
|
||||
chrono ctime
|
||||
chrono forward_list
|
||||
chrono initializer_list
|
||||
chrono limits
|
||||
chrono locale
|
||||
|
|
@ -0,0 +1,31 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
|
||||
// const tzdb& get_tzdb();
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, const char**) {
|
||||
const std::chrono::tzdb& db = std::chrono::get_tzdb();
|
||||
|
||||
assert(!db.version.empty());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
|
||||
// const tzdb& get_tzdb_list();
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, const char**) {
|
||||
const std::chrono::tzdb_list& list = std::chrono::get_tzdb_list();
|
||||
|
||||
assert(!list.front().version.empty());
|
||||
assert(std::distance(list.begin(), list.end()) == 1);
|
||||
assert(std::distance(list.cbegin(), list.cend()) == 1);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
//
|
||||
// class tzdb_list;
|
||||
//
|
||||
// const_iterator erase_after(const_iterator p);
|
||||
//
|
||||
// [time.zone.db.list]/5
|
||||
// Preconditions: The iterator following p is dereferenceable.
|
||||
//
|
||||
// Since there is no Standard way to create a second entry it's not
|
||||
// possible to fullfill this precondition. This is tested in a libc++
|
||||
// specific test.
|
||||
|
||||
#include <chrono>
|
||||
#include <concepts>
|
||||
|
||||
std::chrono::tzdb_list& list = std::chrono::get_tzdb_list();
|
||||
static_assert(std::same_as<decltype(list.erase_after(std::chrono::tzdb_list::const_iterator{})),
|
||||
std::chrono::tzdb_list::const_iterator>);
|
@ -0,0 +1,29 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
//
|
||||
// class tzdb_list;
|
||||
//
|
||||
// const tzdb& front() const noexcept;
|
||||
|
||||
#include <chrono>
|
||||
|
||||
int main(int, char**) {
|
||||
const std::chrono::tzdb_list& list = std::chrono::get_tzdb_list();
|
||||
[[maybe_unused]] const std::chrono::tzdb& _ = list.front();
|
||||
static_assert(noexcept(list.front()));
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
//
|
||||
// class tzdb_list;
|
||||
//
|
||||
// const_iterator begin() const noexcept;
|
||||
// const_iterator end() const noexcept;
|
||||
//
|
||||
// const_iterator cbegin() const noexcept;
|
||||
// const_iterator cend() const noexcept;
|
||||
|
||||
#include <chrono>
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char**) {
|
||||
const std::chrono::tzdb_list& list = std::chrono::get_tzdb_list();
|
||||
using it = std::chrono::tzdb_list::const_iterator;
|
||||
|
||||
static_assert(noexcept(list.begin()));
|
||||
static_assert(noexcept(list.end()));
|
||||
static_assert(noexcept(list.cbegin()));
|
||||
static_assert(noexcept(list.cend()));
|
||||
|
||||
std::same_as<it> auto begin = list.begin();
|
||||
std::same_as<it> auto end = list.end();
|
||||
assert(std::distance(begin, end) == 1);
|
||||
|
||||
std::same_as<it> auto cbegin = list.cbegin();
|
||||
assert(begin == cbegin);
|
||||
|
||||
std::same_as<it> auto cend = list.cend();
|
||||
assert(end == cend);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
|
||||
// class tzdb_list {
|
||||
// public:
|
||||
// tzdb_list(const tzdb_list&) = delete;
|
||||
// tzdb_list& operator=(const tzdb_list&) = delete;
|
||||
//
|
||||
// ...
|
||||
//
|
||||
// };
|
||||
//
|
||||
// [time.zone.db.list]/1
|
||||
// The tzdb_list database is a singleton; the unique object of type
|
||||
// tzdb_list can be accessed via the get_tzdb_list() function.
|
||||
////
|
||||
// This means the class may not have a default constructor.
|
||||
|
||||
#include <chrono>
|
||||
#include <concepts>
|
||||
|
||||
static_assert(!std::copyable<std::chrono::tzdb_list>);
|
||||
static_assert(!std::movable<std::chrono::tzdb_list>);
|
||||
static_assert(!std::default_initializable<std::chrono::tzdb_list>);
|
@ -0,0 +1,45 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
|
||||
// Note there is no Standard way to change the remote database used.
|
||||
// That is tested in
|
||||
// test/libcxx/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.pass.cpp
|
||||
|
||||
// const tzdb& reload_tzdb();
|
||||
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <iterator>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, const char**) {
|
||||
const std::chrono::tzdb_list& list = std::chrono::get_tzdb_list();
|
||||
std::string version = list.front().version;
|
||||
assert(!version.empty());
|
||||
|
||||
assert(std::distance(list.begin(), list.end()) == 1);
|
||||
assert(std::distance(list.cbegin(), list.cend()) == 1);
|
||||
assert(std::chrono::remote_version() == version);
|
||||
|
||||
std::chrono::reload_tzdb();
|
||||
|
||||
assert(std::distance(list.begin(), list.end()) == 1);
|
||||
assert(std::distance(list.cbegin(), list.cend()) == 1);
|
||||
assert(std::chrono::remote_version() == version);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
|
||||
// const string remote_version();
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, const char**) {
|
||||
std::string version = std::chrono::remote_version();
|
||||
assert(!version.empty());
|
||||
|
||||
assert(version == std::chrono::get_tzdb().version);
|
||||
assert(version == std::chrono::get_tzdb_list().front().version);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
|
||||
|
||||
// XFAIL: libcpp-has-no-incomplete-tzdb
|
||||
// XFAIL: availability-tzdb-missing
|
||||
|
||||
// <chrono>
|
||||
|
||||
// struct tzdb {
|
||||
// string version;
|
||||
// vector<time_zone> zones;
|
||||
// vector<time_zone_link> links;
|
||||
// vector<leap_second> leap_seconds;
|
||||
//
|
||||
// ...
|
||||
// };
|
||||
|
||||
#include <chrono>
|
||||
#include <cassert>
|
||||
#include <concepts>
|
||||
#include <string>
|
||||
|
||||
#include "assert_macros.h"
|
||||
|
||||
int main(int, const char**) {
|
||||
std::chrono::tzdb tzdb;
|
||||
|
||||
static_assert(std::same_as<decltype(tzdb.version), std::string>);
|
||||
tzdb.version = "version";
|
||||
assert(tzdb.version == "version");
|
||||
|
||||
// TODO TZDB add the other data members
|
||||
|
||||
return 0;
|
||||
}
|
31
libcxx/test/support/test_tzdb.h
Normal file
31
libcxx/test/support/test_tzdb.h
Normal file
@ -0,0 +1,31 @@
|
||||
// -*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SUPPORT_TEST_TZDB_H
|
||||
#define SUPPORT_TEST_TZDB_H
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#if defined(_LIBCPP_VERSION)
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace chrono {
|
||||
|
||||
// This function is marked as "overridable" in libc++ only for the test
|
||||
// suite. Therefore the declaration is not in <chrono>.
|
||||
_LIBCPP_AVAILABILITY_TZDB _LIBCPP_OVERRIDABLE_FUNC_VIS string_view __libcpp_tzdb_directory();
|
||||
|
||||
} // namespace chrono
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SUPPORT_TEST_TZDB_H
|
@ -681,6 +681,24 @@ steps:
|
||||
limit: 2
|
||||
timeout_in_minutes: 120
|
||||
|
||||
- label: "No time zone database"
|
||||
command: "libcxx/utils/ci/run-buildbot generic-no-tzdb"
|
||||
artifact_paths:
|
||||
- "**/test-results.xml"
|
||||
- "**/*.abilist"
|
||||
env:
|
||||
CC: "clang-${LLVM_HEAD_VERSION}"
|
||||
CXX: "clang++-${LLVM_HEAD_VERSION}"
|
||||
ENABLE_CLANG_TIDY: "On"
|
||||
agents:
|
||||
queue: "libcxx-builders"
|
||||
os: "linux"
|
||||
retry:
|
||||
automatic:
|
||||
- exit_status: -1 # Agent was lost
|
||||
limit: 2
|
||||
timeout_in_minutes: 120
|
||||
|
||||
- label: "No experimental features"
|
||||
command: "libcxx/utils/ci/run-buildbot generic-no-experimental"
|
||||
artifact_paths:
|
||||
|
@ -459,6 +459,11 @@ generic-no-wide-characters)
|
||||
generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-wide-characters.cmake"
|
||||
check-runtimes
|
||||
;;
|
||||
generic-no-tzdb)
|
||||
clean
|
||||
generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-tzdb.cmake"
|
||||
check-runtimes
|
||||
;;
|
||||
generic-no-experimental)
|
||||
clean
|
||||
generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-experimental.cmake"
|
||||
|
@ -302,6 +302,7 @@ macros = {
|
||||
"_LIBCPP_HAS_NO_RANDOM_DEVICE": "no-random-device",
|
||||
"_LIBCPP_HAS_NO_LOCALIZATION": "no-localization",
|
||||
"_LIBCPP_HAS_NO_WIDE_CHARACTERS": "no-wide-characters",
|
||||
"_LIBCPP_HAS_NO_TIME_ZONE_DATABASE": "no-tzdb",
|
||||
"_LIBCPP_HAS_NO_UNICODE": "libcpp-has-no-unicode",
|
||||
"_LIBCPP_HAS_NO_STD_MODULES": "libcpp-has-no-std-modules",
|
||||
"_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH": "libcpp-pstl-cpu-backend-libdispatch",
|
||||
@ -556,6 +557,15 @@ DEFAULT_FEATURES += [
|
||||
cfg.available_features,
|
||||
),
|
||||
),
|
||||
# Tests that require time zone database support in the built library
|
||||
Feature(
|
||||
name="availability-tzdb-missing",
|
||||
when=lambda cfg: BooleanExpression.evaluate(
|
||||
# TODO(ldionne) Please provide the correct value.
|
||||
"(stdlib=apple-libc++ && target={{.+}}-apple-macosx{{(10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0|13.0)(.0)?}})",
|
||||
cfg.available_features,
|
||||
),
|
||||
),
|
||||
# Tests that require 64-bit architecture
|
||||
Feature(
|
||||
name="32-bit-pointer",
|
||||
|
@ -278,6 +278,7 @@ DEFAULT_PARAMETERS = [
|
||||
else [
|
||||
AddFeature("libcpp-has-no-incomplete-pstl"),
|
||||
AddFeature("libcpp-has-no-experimental-stop_token"),
|
||||
AddFeature("libcpp-has-no-incomplete-tzdb"),
|
||||
],
|
||||
),
|
||||
Parameter(
|
||||
|
Loading…
Reference in New Issue
Block a user