This moves std::tai_clock::now() and std::tai_clock::now() definitions from header inlines to static members invoked via a normal function call, in service of stabilizing the C++20 ABI.
It marks tai_clock and gps_clock "is_steady = true", as they are not subject to adjudicated discontinuities, unlike civil time with annual spring and fall changes, and UTC with irregular leap seconds. Even if no more UTC leap seconds are ordered, as is likely, relating historical UTC time points to an absolute reference depends on using a table of past leap seconds, so utc_clock::is_steady remains false. GPS time, by contrast, is at a constant offset from TAI. It changes #if guards to mention the actual __cpp_lib_* feature gated, not just the language version, for clarity. New global function symbols std::chrono::tai_clock::now and std::chrono::gps_clock::now are exported. libstdc++-v3/ChangeLog: * include/std/chrono: Remove inline impls. * src/c++20/clock.cc: New file for out-of-line impls. * src/c++20/Makefile.in: Mention clock.cc * src/c++20/Makefile.am: Mention clock.cc --- libstdc++-v3/include/std/chrono | 32 +++++++++--------- libstdc++-v3/src/c++20/Makefile.am | 2 +- libstdc++-v3/src/c++20/Makefile.in | 4 +-- libstdc++-v3/src/c++20/clock.cc | 52 ++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 20 deletions(-) create mode 100644 libstdc++-v3/src/c++20/clock.cc diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index cb8213e2f9f..7fb5d4ec4c7 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -22,6 +22,8 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +// [time] + /** @file include/chrono * This is a Standard C++ Library header. * @ingroup chrono @@ -42,12 +44,16 @@ # include <bits/c++0x_warning.h> #else +#define __glibcxx_want_chrono +#define __glibcxx_want_chrono_udls +#include <bits/version.h> + #include <bits/chrono.h> -#if __cplusplus >= 202002L +#if __cpp_lib_bitops >= 201907L # include <bit> // __countr_zero #endif -#if __cplusplus >= 202002L && _GLIBCXX_HOSTED +#if __cpp_lib_chrono >= 201803L && _GLIBCXX_HOSTED # include <sstream> # include <string> # include <vector> @@ -56,10 +62,6 @@ # include <bits/unique_ptr.h> #endif -#define __glibcxx_want_chrono -#define __glibcxx_want_chrono_udls -#include <bits/version.h> - namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -79,7 +81,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ namespace chrono { -#if __cplusplus >= 202002L +#if __cpp_lib_chrono >= 201803L /// @addtogroup chrono /// @{ struct local_t { }; @@ -175,13 +177,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using period = system_clock::period; using duration = chrono::duration<rep, period>; using time_point = chrono::time_point<tai_clock>; - static constexpr bool is_steady = false; // XXX true for CLOCK_TAI? + static constexpr bool is_steady = true; - // TODO move into lib, use CLOCK_TAI on linux, add extension point. [[nodiscard]] static time_point - now() - { return from_utc(utc_clock::now()); } + now(); // in src/c++20/clock.cc template<typename _Duration> [[nodiscard]] @@ -215,13 +215,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using period = system_clock::period; using duration = chrono::duration<rep, period>; using time_point = chrono::time_point<gps_clock>; - static constexpr bool is_steady = false; // XXX + static constexpr bool is_steady = true; - // TODO move into lib, add extension point. [[nodiscard]] static time_point - now() - { return from_utc(utc_clock::now()); } + now(); // in src/c++20/clock.cc template<typename _Duration> [[nodiscard]] @@ -3321,7 +3319,7 @@ namespace __detail #endif // C++20 } // namespace chrono -#if __cplusplus >= 202002L +#if __cpp_lib_chrono >= 201803L inline namespace literals { inline namespace chrono_literals @@ -3350,7 +3348,7 @@ namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace std -#if __cplusplus >= 202002L && _GLIBCXX_HOSTED +#if __cpp_lib_chrono >= 201803L && _GLIBCXX_HOSTED # include <bits/chrono_io.h> #endif diff --git a/libstdc++-v3/src/c++20/Makefile.am b/libstdc++-v3/src/c++20/Makefile.am index 15e6f3445fb..736558ff24a 100644 --- a/libstdc++-v3/src/c++20/Makefile.am +++ b/libstdc++-v3/src/c++20/Makefile.am @@ -36,7 +36,7 @@ else inst_sources = endif -sources = tzdb.cc format.cc atomic.cc +sources = tzdb.cc format.cc atomic.cc clock.cc vpath % $(top_srcdir)/src/c++20 diff --git a/libstdc++-v3/src/c++20/Makefile.in b/libstdc++-v3/src/c++20/Makefile.in index d9e1615bbca..3cb6d6fea5f 100644 --- a/libstdc++-v3/src/c++20/Makefile.in +++ b/libstdc++-v3/src/c++20/Makefile.in @@ -121,7 +121,7 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libc__20convenience_la_LIBADD = -am__objects_1 = tzdb.lo format.lo atomic.lo +am__objects_1 = tzdb.lo format.lo atomic.lo clock.lo @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = sstream-inst.lo @GLIBCXX_HOSTED_TRUE@am_libc__20convenience_la_OBJECTS = \ @GLIBCXX_HOSTED_TRUE@ $(am__objects_1) $(am__objects_2) @@ -432,7 +432,7 @@ headers = @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \ @ENABLE_EXTERN_TEMPLATE_TRUE@ sstream-inst.cc -sources = tzdb.cc format.cc atomic.cc +sources = tzdb.cc format.cc atomic.cc clock.cc @GLIBCXX_HOSTED_FALSE@libc__20convenience_la_SOURCES = @GLIBCXX_HOSTED_TRUE@libc__20convenience_la_SOURCES = $(sources) $(inst_sources) diff --git a/libstdc++-v3/src/c++20/clock.cc b/libstdc++-v3/src/c++20/clock.cc new file mode 100644 index 00000000000..2ba6e7fd28f --- /dev/null +++ b/libstdc++-v3/src/c++20/clock.cc @@ -0,0 +1,52 @@ +// std::chrono::tai_clock, gps_clock + +// Copyright (C) 2020-2025 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882 +// 30.7.4 [time.clock.tai], 30.7.5 [time.clock.gps] +// P0355R7 + +#include <chrono> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +namespace chrono +{ +#if __cpp_lib_chrono >= 201803L && _GLIBCXX_HOSTED + // TODO use CLOCK_TAI on linux, add extension point. + time_point<tai_clock> + tai_clock::now() + { return from_utc(utc_clock::now()); } + + // TODO add extension point. + time_point<gps_clock> + gps_clock::now() + { return from_utc(utc_clock::now()); } +#endif +} + +_GLIBCXX_END_NAMESPACE_VERSION +} -- 2.50.1