From 76e6a5cc0e1f0d9a2f7e6cf07d46ebbfc869a936 Mon Sep 17 00:00:00 2001 From: Rafail Date: Sun, 26 Oct 2025 08:26:14 +0300 Subject: [PATCH 01/11] Initial hashing support for chrono --- libcxx/docs/FeatureTestMacroTable.rst | 2 +- libcxx/docs/ReleaseNotes/22.rst | 1 + libcxx/docs/Status/Cxx2cPapers.csv | 2 +- libcxx/include/__chrono/day.h | 8 +++ libcxx/include/__chrono/duration.h | 13 +++++ libcxx/include/__chrono/leap_second.h | 8 +++ libcxx/include/__chrono/month.h | 8 +++ libcxx/include/__chrono/month_weekday.h | 15 +++++ libcxx/include/__chrono/monthday.h | 15 +++++ libcxx/include/__chrono/time_point.h | 14 +++++ libcxx/include/__chrono/weekday.h | 22 ++++++++ libcxx/include/__chrono/year.h | 8 +++ libcxx/include/__chrono/year_month.h | 8 +++ libcxx/include/__chrono/year_month_day.h | 15 +++++ libcxx/include/__chrono/year_month_weekday.h | 17 ++++++ libcxx/include/__chrono/zoned_time.h | 10 ++++ libcxx/include/version | 4 +- .../time/time.hash/time.hash_enabled.pass.cpp | 55 +++++++++++++++++++ 18 files changed, 221 insertions(+), 4 deletions(-) create mode 100644 libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index 8fba6db871f08..a878c46d35cbe 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -88,7 +88,7 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_byte`` ``201603L`` ---------------------------------------------------------- ----------------- - ``__cpp_lib_chrono`` ``201611L`` + ``__cpp_lib_chrono`` ``202510L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_clamp`` ``201603L`` ---------------------------------------------------------- ----------------- diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst index 25d33a9c2eb50..7ea3529642c90 100644 --- a/libcxx/docs/ReleaseNotes/22.rst +++ b/libcxx/docs/ReleaseNotes/22.rst @@ -38,6 +38,7 @@ What's New in Libc++ 22.0.0? Implemented Papers ------------------ +- P2592R3: Hashing support for ``std::chrono`` value classes (`Github `__) - P2321R2: ``zip`` (`Github `__) (The paper is partially implemented. ``zip_transform_view`` is implemented in this release) - P3044R2: sub-``string_view`` from ``string`` (`Github `__) diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv index a5423acf0d419..493e6a3c9ed44 100644 --- a/libcxx/docs/Status/Cxx2cPapers.csv +++ b/libcxx/docs/Status/Cxx2cPapers.csv @@ -1,6 +1,6 @@ "Paper #","Paper Name","Meeting","Status","First released version","GitHub issue","Notes" "`P2497R0 `__","Testing for success or failure of ```` functions","2023-06 (Varna)","|Complete|","18","`#105357 `__","" -"`P2592R3 `__","Hashing support for ``std::chrono`` value classes","2023-06 (Varna)","","","`#105358 `__","" +"`P2592R3 `__","Hashing support for ``std::chrono`` value classes","2023-06 (Varna)","|Complete|","22","`#105358 `__","" "`P2587R3 `__","``to_string`` or not ``to_string``","2023-06 (Varna)","","","`#105359 `__","" "`P2562R1 `__","``constexpr`` Stable Sorting","2023-06 (Varna)","|Complete|","21","`#105360 `__","" "`P2545R4 `__","Read-Copy Update (RCU)","2023-06 (Varna)","","","`#105361 `__","" diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h index f5b14689a78ac..5c39bf16f72ea 100644 --- a/libcxx/include/__chrono/day.h +++ b/libcxx/include/__chrono/day.h @@ -13,6 +13,7 @@ #include <__chrono/duration.h> #include <__compare/ordering.h> #include <__config> +#include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -92,6 +93,13 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) no } // namespace chrono +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::day& __d) const _NOEXCEPT { + return hash{}(static_cast(__d)); + } +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h index 57fa64d650068..3e04891f5b0c6 100644 --- a/libcxx/include/__chrono/duration.h +++ b/libcxx/include/__chrono/duration.h @@ -13,6 +13,7 @@ #include <__compare/ordering.h> #include <__compare/three_way_comparable.h> #include <__config> +#include <__functional/hash.h> #include <__type_traits/common_type.h> #include <__type_traits/enable_if.h> #include <__type_traits/is_convertible.h> @@ -538,6 +539,18 @@ using namespace literals::chrono_literals; #endif // _LIBCPP_STD_VER >= 14 +#if _LIBCPP_STD_VER >= 20 + +template + requires __has_enabled_hash<_Rep>::value +struct hash> : public __unary_function, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::duration<_Rep, _Period>& __d) const { + return hash<_Rep>{}(__d.count()); + } +}; + +#endif // _LIBCPP_STD_VER >= 20 + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/libcxx/include/__chrono/leap_second.h b/libcxx/include/__chrono/leap_second.h index 1857bef80376e..cf7a2c16626d0 100644 --- a/libcxx/include/__chrono/leap_second.h +++ b/libcxx/include/__chrono/leap_second.h @@ -22,6 +22,7 @@ # include <__compare/ordering.h> # include <__compare/three_way_comparable.h> # include <__config> +# include <__functional/hash.h> # include <__utility/private_constructor_tag.h> # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -122,6 +123,13 @@ class leap_second { } // namespace chrono +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::leap_second& __lp) const _NOEXCEPT { + return hash{}(__lp.value()); + } +}; + # endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__chrono/month.h b/libcxx/include/__chrono/month.h index 77c67d0954efa..d76efd4973193 100644 --- a/libcxx/include/__chrono/month.h +++ b/libcxx/include/__chrono/month.h @@ -13,6 +13,7 @@ #include <__chrono/duration.h> #include <__compare/ordering.h> #include <__config> +#include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -108,6 +109,13 @@ inline constexpr month December{12}; } // namespace chrono +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month& __m) const _NOEXCEPT { + return hash{}(static_cast(__m)); + } +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/month_weekday.h b/libcxx/include/__chrono/month_weekday.h index 7919879655214..a46526eca2853 100644 --- a/libcxx/include/__chrono/month_weekday.h +++ b/libcxx/include/__chrono/month_weekday.h @@ -13,6 +13,7 @@ #include <__chrono/month.h> #include <__chrono/weekday.h> #include <__config> +#include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -98,6 +99,20 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(const weekda } } // namespace chrono +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday& __mw) const _NOEXCEPT { + return hash{}(__mw.month()) ^ hash{}(__mw.weekday_indexed()); + } +}; + +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday_last& __mwl) const _NOEXCEPT { + return hash{}(__mwl.month()) ^ hash{}(__mwl.weekday_last()); + } +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/monthday.h b/libcxx/include/__chrono/monthday.h index 57712cf0b65a8..79c2a4c9f0a42 100644 --- a/libcxx/include/__chrono/monthday.h +++ b/libcxx/include/__chrono/monthday.h @@ -15,6 +15,7 @@ #include <__chrono/month.h> #include <__compare/ordering.h> #include <__config> +#include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -126,6 +127,20 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, int _ } // namespace chrono +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day& __md) const _NOEXCEPT { + return hash{}(__md.month()) ^ hash{}(__md.day()); + } +}; + +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day_last& __mdl) const _NOEXCEPT { + return hash{}(__mdl.month()); + } +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h index bc2c7798a630b..02720ec66228e 100644 --- a/libcxx/include/__chrono/time_point.h +++ b/libcxx/include/__chrono/time_point.h @@ -14,6 +14,7 @@ #include <__compare/ordering.h> #include <__compare/three_way_comparable.h> #include <__config> +#include <__functional/hash.h> #include <__type_traits/common_type.h> #include <__type_traits/enable_if.h> #include <__type_traits/is_convertible.h> @@ -224,6 +225,19 @@ operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, } // namespace chrono +#if _LIBCPP_STD_VER >= 20 + +template + requires __has_enabled_hash<_Duration>::value +struct hash> + : public __unary_function, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::time_point<_Clock, _Duration>& __tp) const { + return hash<_Duration>{}(__tp.time_since_epoch()); + } +}; + +#endif // _LIBCPP_STD_VER >= 20 + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/libcxx/include/__chrono/weekday.h b/libcxx/include/__chrono/weekday.h index 728cbb844633f..2fc988a9f4b57 100644 --- a/libcxx/include/__chrono/weekday.h +++ b/libcxx/include/__chrono/weekday.h @@ -15,6 +15,7 @@ #include <__chrono/system_clock.h> #include <__chrono/time_point.h> #include <__config> +#include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -160,6 +161,27 @@ inline constexpr weekday Saturday{6}; } // namespace chrono +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday& __w) const _NOEXCEPT { + return hash{}(__w.c_encoding()); + } +}; + +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday_indexed& __wi) const _NOEXCEPT { + return hash{}(__wi.weekday()) ^ hash{}(__wi.index()); + } +}; + +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday_last& __wl) const _NOEXCEPT { + return hash{}(__wl.weekday()); + } +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h index 2ae5180cb8fc9..4ee4186dcf533 100644 --- a/libcxx/include/__chrono/year.h +++ b/libcxx/include/__chrono/year.h @@ -13,6 +13,7 @@ #include <__chrono/duration.h> #include <__compare/ordering.h> #include <__config> +#include <__functional/hash.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -109,6 +110,13 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept { } // namespace chrono +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year& __y) const _NOEXCEPT { + return hash{}(static_cast(__y)); + } +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/year_month.h b/libcxx/include/__chrono/year_month.h index cf9234bdb4625..a3e1429527bea 100644 --- a/libcxx/include/__chrono/year_month.h +++ b/libcxx/include/__chrono/year_month.h @@ -15,6 +15,7 @@ #include <__chrono/year.h> #include <__compare/ordering.h> #include <__config> +#include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -116,6 +117,13 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const } // namespace chrono +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month& __ym) const _NOEXCEPT { + return hash{}(__ym.year()) ^ hash{}(__ym.month()); + } +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/year_month_day.h b/libcxx/include/__chrono/year_month_day.h index a0510a14f4ede..b0c05716bdba3 100644 --- a/libcxx/include/__chrono/year_month_day.h +++ b/libcxx/include/__chrono/year_month_day.h @@ -21,6 +21,7 @@ #include <__chrono/year_month.h> #include <__compare/ordering.h> #include <__config> +#include <__functional/hash.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -330,6 +331,20 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool year_month_day::ok() const noexcept } // namespace chrono +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_day& __ymd) const _NOEXCEPT { + return hash{}(__ymd.year()) ^ hash{}(__ymd.month()) ^ hash{}(__ymd.day()); + } +}; + +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_day_last& __ymdl) const _NOEXCEPT { + return hash{}(__ymdl.year()) ^ hash{}(__ymdl.month_day_last()); + } +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/year_month_weekday.h b/libcxx/include/__chrono/year_month_weekday.h index 0c3dd494c8787..6ae704c397b97 100644 --- a/libcxx/include/__chrono/year_month_weekday.h +++ b/libcxx/include/__chrono/year_month_weekday.h @@ -22,6 +22,7 @@ #include <__chrono/year_month.h> #include <__chrono/year_month_day.h> #include <__config> +#include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -280,6 +281,22 @@ year_month_weekday_last::operator-=(const years& __dy) noexcept { } // namespace chrono +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_weekday& __ymw) const _NOEXCEPT { + return hash{}(__ymw.year()) ^ hash{}(__ymw.month()) ^ + hash{}(__ymw.weekday_indexed()); + } +}; + +template <> +struct hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_weekday_last& __ymwl) const _NOEXCEPT { + return hash{}(__ymwl.year()) ^ hash{}(__ymwl.month()) ^ + hash{}(__ymwl.weekday_last()); + } +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h index 8db687a422ab1..5f110d1721502 100644 --- a/libcxx/include/__chrono/zoned_time.h +++ b/libcxx/include/__chrono/zoned_time.h @@ -24,6 +24,7 @@ # include <__chrono/tzdb_list.h> # include <__concepts/constructible.h> # include <__config> +# include <__functional/hash.h> # include <__type_traits/common_type.h> # include <__type_traits/conditional.h> # include <__type_traits/remove_cvref.h> @@ -216,6 +217,15 @@ operator==(const zoned_time<_Duration1, _TimeZonePtr>& __lhs, const zoned_time<_ } // namespace chrono +template + requires __has_enabled_hash<_Duration>::value && __has_enabled_hash<_TimeZonePtr>::value +struct hash> + : public __unary_function, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::zoned_time<_Duration, _TimeZonePtr>& __zt) const { + return hash>{}(__zt.get_sys_time()) ^ hash<_TimeZonePtr>{}(__zt.get_time_zone()); + } +}; + # endif // _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM && // _LIBCPP_HAS_LOCALIZATION diff --git a/libcxx/include/version b/libcxx/include/version index 0fef1bb87cf60..5200d72ed1ea5 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -57,7 +57,7 @@ __cpp_lib_byteswap 202110L __cpp_lib_char8_t 201907L -__cpp_lib_chrono 201611L +__cpp_lib_chrono 202510L __cpp_lib_chrono_udls 201304L __cpp_lib_clamp 201603L __cpp_lib_common_reference 202302L @@ -332,7 +332,7 @@ __cpp_lib_void_t 201411L # define __cpp_lib_bool_constant 201505L # define __cpp_lib_boyer_moore_searcher 201603L # define __cpp_lib_byte 201603L -# define __cpp_lib_chrono 201611L +# define __cpp_lib_chrono 202510L # define __cpp_lib_clamp 201603L # define __cpp_lib_enable_shared_from_this 201603L // # define __cpp_lib_execution 201603L diff --git a/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp b/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp new file mode 100644 index 0000000000000..e935a121c0ab0 --- /dev/null +++ b/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// Test that provides all of the hash specializations. + +#include +#include "poisoned_hash_helper.h" +namespace chrono = std::chrono; + +int main(int, char**) { + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(chrono::weekday_last(chrono::weekday{})); + + test_hash_enabled(); + test_hash_enabled(chrono::month_day_last(chrono::month{})); + + test_hash_enabled(chrono::month_weekday(chrono::month{}, chrono::weekday_indexed{})); + test_hash_enabled(chrono::month_weekday_last(chrono::month{}, chrono::weekday_last(chrono::weekday{}))); + + test_hash_enabled(); + + test_hash_enabled(); + test_hash_enabled(chrono::year_month_day_last(chrono::year{}, chrono::month_day_last(chrono::month{}))); + + test_hash_enabled(); + test_hash_enabled( + chrono::year_month_weekday_last(chrono::year{}, chrono::month{}, chrono::weekday_last(chrono::weekday{}))); + + return 0; +} From d346b34a71bdd17e0e95c7893064adab89fbbc37 Mon Sep 17 00:00:00 2001 From: Rafail Date: Sun, 26 Oct 2025 17:51:01 +0300 Subject: [PATCH 02/11] Update version via script --- libcxx/docs/FeatureTestMacroTable.rst | 4 +++- libcxx/include/version | 7 +++++-- .../support.limits.general/chrono.version.compile.pass.cpp | 4 ++-- .../version.version.compile.pass.cpp | 4 ++-- libcxx/utils/generate_feature_test_macro_components.py | 2 +- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index a878c46d35cbe..51c2c720cdf9a 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -88,7 +88,7 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_byte`` ``201603L`` ---------------------------------------------------------- ----------------- - ``__cpp_lib_chrono`` ``202510L`` + ``__cpp_lib_chrono`` ``201611L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_clamp`` ``201603L`` ---------------------------------------------------------- ----------------- @@ -424,6 +424,8 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_bitset`` ``202306L`` ---------------------------------------------------------- ----------------- + ``__cpp_lib_chrono`` ``202306L`` + ---------------------------------------------------------- ----------------- ``__cpp_lib_constexpr_algorithms`` ``202306L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_constexpr_forward_list`` ``202502L`` diff --git a/libcxx/include/version b/libcxx/include/version index 5200d72ed1ea5..07cc828bd7c53 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -57,7 +57,8 @@ __cpp_lib_byteswap 202110L __cpp_lib_char8_t 201907L -__cpp_lib_chrono 202510L +__cpp_lib_chrono 202306L + 201611L // C++17 __cpp_lib_chrono_udls 201304L __cpp_lib_clamp 201603L __cpp_lib_common_reference 202302L @@ -332,7 +333,7 @@ __cpp_lib_void_t 201411L # define __cpp_lib_bool_constant 201505L # define __cpp_lib_boyer_moore_searcher 201603L # define __cpp_lib_byte 201603L -# define __cpp_lib_chrono 202510L +# define __cpp_lib_chrono 201611L # define __cpp_lib_clamp 201603L # define __cpp_lib_enable_shared_from_this 201603L // # define __cpp_lib_execution 201603L @@ -550,6 +551,8 @@ __cpp_lib_void_t 201411L # undef __cpp_lib_bind_front # define __cpp_lib_bind_front 202306L # define __cpp_lib_bitset 202306L +# undef __cpp_lib_chrono +# define __cpp_lib_chrono 202306L # undef __cpp_lib_constexpr_algorithms # define __cpp_lib_constexpr_algorithms 202306L # define __cpp_lib_constexpr_forward_list 202502L diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp index d5d7a5da4a64d..98b3eda149342 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp @@ -94,8 +94,8 @@ # ifndef __cpp_lib_chrono # error "__cpp_lib_chrono should be defined in c++26" # endif -# if __cpp_lib_chrono != 201611L -# error "__cpp_lib_chrono should have the value 201611L in c++26" +# if __cpp_lib_chrono != 202306L +# error "__cpp_lib_chrono should have the value 202306L in c++26" # endif # ifndef __cpp_lib_chrono_udls diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index 05af1fb0cf14b..1ecba19d39abe 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -6455,8 +6455,8 @@ # ifndef __cpp_lib_chrono # error "__cpp_lib_chrono should be defined in c++26" # endif -# if __cpp_lib_chrono != 201611L -# error "__cpp_lib_chrono should have the value 201611L in c++26" +# if __cpp_lib_chrono != 202306L +# error "__cpp_lib_chrono should have the value 202306L in c++26" # endif # ifndef __cpp_lib_chrono_udls diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index f6f252751b3e3..114f844cc238e 100644 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -300,7 +300,7 @@ def add_version_header(tc): "name": "__cpp_lib_chrono", "values": { "c++17": 201611, - # "c++26": 202306, # P2592R3 Hashing support for std::chrono value classes + "c++26": 202306, # P2592R3 Hashing support for std::chrono value classes }, "headers": ["chrono"], }, From 236fa22874708dfc4012d1031c9a8fa4563515c7 Mon Sep 17 00:00:00 2001 From: Rafail Date: Sun, 26 Oct 2025 18:11:57 +0300 Subject: [PATCH 03/11] Wrap around c++26 macro and test fix --- libcxx/include/__chrono/day.h | 4 ++ libcxx/include/__chrono/duration.h | 4 +- libcxx/include/__chrono/leap_second.h | 4 ++ libcxx/include/__chrono/month.h | 4 ++ libcxx/include/__chrono/month_weekday.h | 4 ++ libcxx/include/__chrono/monthday.h | 4 ++ libcxx/include/__chrono/time_point.h | 4 +- libcxx/include/__chrono/weekday.h | 4 ++ libcxx/include/__chrono/year.h | 4 ++ libcxx/include/__chrono/year_month.h | 4 ++ libcxx/include/__chrono/year_month_day.h | 4 ++ libcxx/include/__chrono/year_month_weekday.h | 4 ++ libcxx/include/__chrono/zoned_time.h | 4 ++ .../time/time.hash/time.hash_enabled.pass.cpp | 62 ++++++++++--------- 14 files changed, 82 insertions(+), 32 deletions(-) diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h index 5c39bf16f72ea..2478f25214912 100644 --- a/libcxx/include/__chrono/day.h +++ b/libcxx/include/__chrono/day.h @@ -93,6 +93,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) no } // namespace chrono +# if _LIBCPP_STD_VER >= 26 + template <> struct hash : public __unary_function { _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::day& __d) const _NOEXCEPT { @@ -100,6 +102,8 @@ struct hash : public __unary_function { } }; +# endif // _LIBCPP_STD_VER >= 26 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h index 3e04891f5b0c6..c92ab4a5ffddf 100644 --- a/libcxx/include/__chrono/duration.h +++ b/libcxx/include/__chrono/duration.h @@ -539,7 +539,7 @@ using namespace literals::chrono_literals; #endif // _LIBCPP_STD_VER >= 14 -#if _LIBCPP_STD_VER >= 20 +#if _LIBCPP_STD_VER >= 26 template requires __has_enabled_hash<_Rep>::value @@ -549,7 +549,7 @@ struct hash> : public __unary_function= 20 +#endif // _LIBCPP_STD_VER >= 26 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__chrono/leap_second.h b/libcxx/include/__chrono/leap_second.h index cf7a2c16626d0..8d3eafbde4639 100644 --- a/libcxx/include/__chrono/leap_second.h +++ b/libcxx/include/__chrono/leap_second.h @@ -123,6 +123,8 @@ class leap_second { } // namespace chrono +# if _LIBCPP_STD_VER >= 26 + template <> struct hash : public __unary_function { _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::leap_second& __lp) const _NOEXCEPT { @@ -130,6 +132,8 @@ struct hash : public __unary_function= 26 + # endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__chrono/month.h b/libcxx/include/__chrono/month.h index d76efd4973193..470451e8153fe 100644 --- a/libcxx/include/__chrono/month.h +++ b/libcxx/include/__chrono/month.h @@ -109,6 +109,8 @@ inline constexpr month December{12}; } // namespace chrono +# if _LIBCPP_STD_VER >= 26 + template <> struct hash : public __unary_function { _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month& __m) const _NOEXCEPT { @@ -116,6 +118,8 @@ struct hash : public __unary_function { } }; +# endif // _LIBCPP_STD_VER >= 26 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/month_weekday.h b/libcxx/include/__chrono/month_weekday.h index a46526eca2853..58ef6b8540351 100644 --- a/libcxx/include/__chrono/month_weekday.h +++ b/libcxx/include/__chrono/month_weekday.h @@ -99,6 +99,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(const weekda } } // namespace chrono +# if _LIBCPP_STD_VER >= 26 + template <> struct hash : public __unary_function { _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday& __mw) const _NOEXCEPT { @@ -113,6 +115,8 @@ struct hash : public __unary_function= 26 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/monthday.h b/libcxx/include/__chrono/monthday.h index 79c2a4c9f0a42..961c131854e9b 100644 --- a/libcxx/include/__chrono/monthday.h +++ b/libcxx/include/__chrono/monthday.h @@ -127,6 +127,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, int _ } // namespace chrono +# if _LIBCPP_STD_VER >= 26 + template <> struct hash : public __unary_function { _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day& __md) const _NOEXCEPT { @@ -141,6 +143,8 @@ struct hash : public __unary_function= 26 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h index 02720ec66228e..85a91e9b35895 100644 --- a/libcxx/include/__chrono/time_point.h +++ b/libcxx/include/__chrono/time_point.h @@ -225,7 +225,7 @@ operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, } // namespace chrono -#if _LIBCPP_STD_VER >= 20 +#if _LIBCPP_STD_VER >= 26 template requires __has_enabled_hash<_Duration>::value @@ -236,7 +236,7 @@ struct hash> } }; -#endif // _LIBCPP_STD_VER >= 20 +#endif // _LIBCPP_STD_VER >= 26 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__chrono/weekday.h b/libcxx/include/__chrono/weekday.h index 2fc988a9f4b57..3842f44f3bf9f 100644 --- a/libcxx/include/__chrono/weekday.h +++ b/libcxx/include/__chrono/weekday.h @@ -161,6 +161,8 @@ inline constexpr weekday Saturday{6}; } // namespace chrono +# if _LIBCPP_STD_VER >= 26 + template <> struct hash : public __unary_function { _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday& __w) const _NOEXCEPT { @@ -182,6 +184,8 @@ struct hash : public __unary_function= 26 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h index 4ee4186dcf533..e2f8985732d4d 100644 --- a/libcxx/include/__chrono/year.h +++ b/libcxx/include/__chrono/year.h @@ -110,6 +110,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept { } // namespace chrono +# if _LIBCPP_STD_VER >= 26 + template <> struct hash : public __unary_function { _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year& __y) const _NOEXCEPT { @@ -117,6 +119,8 @@ struct hash : public __unary_function { } }; +# endif // _LIBCPP_STD_VER >= 26 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/year_month.h b/libcxx/include/__chrono/year_month.h index a3e1429527bea..6d6b14d952982 100644 --- a/libcxx/include/__chrono/year_month.h +++ b/libcxx/include/__chrono/year_month.h @@ -117,6 +117,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const } // namespace chrono +# if _LIBCPP_STD_VER >= 26 + template <> struct hash : public __unary_function { _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month& __ym) const _NOEXCEPT { @@ -124,6 +126,8 @@ struct hash : public __unary_function= 26 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/year_month_day.h b/libcxx/include/__chrono/year_month_day.h index b0c05716bdba3..c1661a1b7614b 100644 --- a/libcxx/include/__chrono/year_month_day.h +++ b/libcxx/include/__chrono/year_month_day.h @@ -331,6 +331,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool year_month_day::ok() const noexcept } // namespace chrono +# if _LIBCPP_STD_VER >= 26 + template <> struct hash : public __unary_function { _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_day& __ymd) const _NOEXCEPT { @@ -345,6 +347,8 @@ struct hash : public __unary_function= 26 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/year_month_weekday.h b/libcxx/include/__chrono/year_month_weekday.h index 6ae704c397b97..ae7e21747d2a4 100644 --- a/libcxx/include/__chrono/year_month_weekday.h +++ b/libcxx/include/__chrono/year_month_weekday.h @@ -281,6 +281,8 @@ year_month_weekday_last::operator-=(const years& __dy) noexcept { } // namespace chrono +# if _LIBCPP_STD_VER >= 26 + template <> struct hash : public __unary_function { _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_weekday& __ymw) const _NOEXCEPT { @@ -297,6 +299,8 @@ struct hash : public __unary_function= 26 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h index 5f110d1721502..595d0ce4d3d1c 100644 --- a/libcxx/include/__chrono/zoned_time.h +++ b/libcxx/include/__chrono/zoned_time.h @@ -217,6 +217,8 @@ operator==(const zoned_time<_Duration1, _TimeZonePtr>& __lhs, const zoned_time<_ } // namespace chrono +# if _LIBCPP_STD_VER >= 26 + template requires __has_enabled_hash<_Duration>::value && __has_enabled_hash<_TimeZonePtr>::value struct hash> @@ -226,6 +228,8 @@ struct hash> } }; +# endif // _LIBCPP_STD_VER >= 26 + # endif // _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM && // _LIBCPP_HAS_LOCALIZATION diff --git a/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp b/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp index e935a121c0ab0..a6082f700a3b3 100644 --- a/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp +++ b/libcxx/test/std/time/time.hash/time.hash_enabled.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 +// REQUIRES: std-at-least-c++26 // @@ -14,42 +14,48 @@ #include #include "poisoned_hash_helper.h" -namespace chrono = std::chrono; int main(int, char**) { - test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(); + + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled(std::chrono::weekday_last(std::chrono::weekday{})); + + test_hash_enabled(); + test_hash_enabled(std::chrono::month_day_last(std::chrono::month{})); + + test_hash_enabled(std::chrono::month_weekday(std::chrono::month{}, std::chrono::weekday_indexed{})); - test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(); + test_hash_enabled( + std::chrono::month_weekday_last(std::chrono::month{}, std::chrono::weekday_last(std::chrono::weekday{}))); - test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(chrono::weekday_last(chrono::weekday{})); + test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(chrono::month_day_last(chrono::month{})); + test_hash_enabled(); - test_hash_enabled(chrono::month_weekday(chrono::month{}, chrono::weekday_indexed{})); - test_hash_enabled(chrono::month_weekday_last(chrono::month{}, chrono::weekday_last(chrono::weekday{}))); + test_hash_enabled( + std::chrono::year_month_day_last(std::chrono::year{}, std::chrono::month_day_last(std::chrono::month{}))); - test_hash_enabled(); + test_hash_enabled(); - test_hash_enabled(); - test_hash_enabled(chrono::year_month_day_last(chrono::year{}, chrono::month_day_last(chrono::month{}))); + test_hash_enabled(std::chrono::year_month_weekday_last( + std::chrono::year{}, std::chrono::month{}, std::chrono::weekday_last(std::chrono::weekday{}))); - test_hash_enabled(); - test_hash_enabled( - chrono::year_month_weekday_last(chrono::year{}, chrono::month{}, chrono::weekday_last(chrono::weekday{}))); + test_hash_enabled(std::chrono::leap_second({}, std::chrono::sys_seconds{}, std::chrono::seconds{})); return 0; } From be75b5a549211fbd531475e3b679fd847bcccc4d Mon Sep 17 00:00:00 2001 From: Rafail Date: Sun, 26 Oct 2025 18:19:56 +0300 Subject: [PATCH 04/11] Add synopsis --- libcxx/include/chrono | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/libcxx/include/chrono b/libcxx/include/chrono index 82e99a31bcc9f..c57f4d5b8e673 100644 --- a/libcxx/include/chrono +++ b/libcxx/include/chrono @@ -1035,6 +1035,49 @@ constexpr chrono::year operator ""y(unsigned lo } // chrono_literals } // literals +namespace std { + template + struct hash; // C++26 + template + struct hash>; // C++26 + template + struct hash>; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template<> + struct hash; // C++26 + template + struct hash>; // C++26 + template<> + struct hash; // C++26 +} // namespace std + } // std */ From dd7aaa2e1752670f0b91a0a5cf14dc96fee6e3e3 Mon Sep 17 00:00:00 2001 From: Rafail Date: Mon, 27 Oct 2025 08:48:07 +0300 Subject: [PATCH 05/11] Fix issues & revert version bump --- libcxx/docs/FeatureTestMacroTable.rst | 2 -- libcxx/include/__chrono/day.h | 4 ++-- libcxx/include/__chrono/duration.h | 4 ++-- libcxx/include/__chrono/leap_second.h | 6 +++--- libcxx/include/__chrono/month.h | 4 ++-- libcxx/include/__chrono/month_weekday.h | 14 +++++++------ libcxx/include/__chrono/monthday.h | 10 +++++----- libcxx/include/__chrono/time_point.h | 5 ++--- libcxx/include/__chrono/weekday.h | 14 ++++++------- libcxx/include/__chrono/year.h | 4 ++-- libcxx/include/__chrono/year_month.h | 6 +++--- libcxx/include/__chrono/year_month_day.h | 15 ++++++++------ libcxx/include/__chrono/year_month_weekday.h | 20 +++++++++++-------- libcxx/include/__chrono/zoned_time.h | 8 ++++---- libcxx/include/version | 5 +---- .../chrono.version.compile.pass.cpp | 4 ++-- .../version.version.compile.pass.cpp | 4 ++-- .../generate_feature_test_macro_components.py | 2 +- 18 files changed, 67 insertions(+), 64 deletions(-) diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index 51c2c720cdf9a..8fba6db871f08 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -424,8 +424,6 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_bitset`` ``202306L`` ---------------------------------------------------------- ----------------- - ``__cpp_lib_chrono`` ``202306L`` - ---------------------------------------------------------- ----------------- ``__cpp_lib_constexpr_algorithms`` ``202306L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_constexpr_forward_list`` ``202502L`` diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h index 2478f25214912..a8de0aa0fe50e 100644 --- a/libcxx/include/__chrono/day.h +++ b/libcxx/include/__chrono/day.h @@ -96,8 +96,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) no # if _LIBCPP_STD_VER >= 26 template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::day& __d) const _NOEXCEPT { +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::day& __d) noexcept { return hash{}(static_cast(__d)); } }; diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h index c92ab4a5ffddf..24865ca9244bc 100644 --- a/libcxx/include/__chrono/duration.h +++ b/libcxx/include/__chrono/duration.h @@ -543,8 +543,8 @@ using namespace literals::chrono_literals; template requires __has_enabled_hash<_Rep>::value -struct hash> : public __unary_function, size_t> { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::duration<_Rep, _Period>& __d) const { +struct hash> { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::duration<_Rep, _Period>& __d) { return hash<_Rep>{}(__d.count()); } }; diff --git a/libcxx/include/__chrono/leap_second.h b/libcxx/include/__chrono/leap_second.h index 8d3eafbde4639..d8d88a20fafbb 100644 --- a/libcxx/include/__chrono/leap_second.h +++ b/libcxx/include/__chrono/leap_second.h @@ -126,9 +126,9 @@ class leap_second { # if _LIBCPP_STD_VER >= 26 template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::leap_second& __lp) const _NOEXCEPT { - return hash{}(__lp.value()); +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::leap_second& __lp) noexcept { + return std::__hash_combine(hash{}(__lp.date()), hash{}(__lp.value())); } }; diff --git a/libcxx/include/__chrono/month.h b/libcxx/include/__chrono/month.h index 470451e8153fe..451d9222b7c9a 100644 --- a/libcxx/include/__chrono/month.h +++ b/libcxx/include/__chrono/month.h @@ -112,8 +112,8 @@ inline constexpr month December{12}; # if _LIBCPP_STD_VER >= 26 template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month& __m) const _NOEXCEPT { +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month& __m) noexcept { return hash{}(static_cast(__m)); } }; diff --git a/libcxx/include/__chrono/month_weekday.h b/libcxx/include/__chrono/month_weekday.h index 58ef6b8540351..dab61a4a89576 100644 --- a/libcxx/include/__chrono/month_weekday.h +++ b/libcxx/include/__chrono/month_weekday.h @@ -102,16 +102,18 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(const weekda # if _LIBCPP_STD_VER >= 26 template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday& __mw) const _NOEXCEPT { - return hash{}(__mw.month()) ^ hash{}(__mw.weekday_indexed()); +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_weekday& __mw) noexcept { + return std::__hash_combine( + hash{}(__mw.month()), hash{}(__mw.weekday_indexed())); } }; template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday_last& __mwl) const _NOEXCEPT { - return hash{}(__mwl.month()) ^ hash{}(__mwl.weekday_last()); +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_weekday_last& __mwl) noexcept { + return std::__hash_combine( + hash{}(__mwl.month()), hash{}(__mwl.weekday_last())); } }; diff --git a/libcxx/include/__chrono/monthday.h b/libcxx/include/__chrono/monthday.h index 961c131854e9b..3d58fb3c003ea 100644 --- a/libcxx/include/__chrono/monthday.h +++ b/libcxx/include/__chrono/monthday.h @@ -130,15 +130,15 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, int _ # if _LIBCPP_STD_VER >= 26 template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day& __md) const _NOEXCEPT { - return hash{}(__md.month()) ^ hash{}(__md.day()); +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_day& __md) noexcept { + return std::__hash_combine(hash{}(__md.month()), hash{}(__md.day())); } }; template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day_last& __mdl) const _NOEXCEPT { +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month_day_last& __mdl) noexcept { return hash{}(__mdl.month()); } }; diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h index 85a91e9b35895..c5da75b5dee23 100644 --- a/libcxx/include/__chrono/time_point.h +++ b/libcxx/include/__chrono/time_point.h @@ -229,9 +229,8 @@ operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, template requires __has_enabled_hash<_Duration>::value -struct hash> - : public __unary_function, size_t> { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::time_point<_Clock, _Duration>& __tp) const { +struct hash> { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::time_point<_Clock, _Duration>& __tp) { return hash<_Duration>{}(__tp.time_since_epoch()); } }; diff --git a/libcxx/include/__chrono/weekday.h b/libcxx/include/__chrono/weekday.h index 3842f44f3bf9f..e12fc0a8a95ca 100644 --- a/libcxx/include/__chrono/weekday.h +++ b/libcxx/include/__chrono/weekday.h @@ -164,22 +164,22 @@ inline constexpr weekday Saturday{6}; # if _LIBCPP_STD_VER >= 26 template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday& __w) const _NOEXCEPT { +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday& __w) noexcept { return hash{}(__w.c_encoding()); } }; template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday_indexed& __wi) const _NOEXCEPT { - return hash{}(__wi.weekday()) ^ hash{}(__wi.index()); +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday_indexed& __wi) noexcept { + return std::__hash_combine(hash{}(__wi.weekday()), hash{}(__wi.index())); } }; template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::weekday_last& __wl) const _NOEXCEPT { +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday_last& __wl) noexcept { return hash{}(__wl.weekday()); } }; diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h index e2f8985732d4d..cb7d892477dbb 100644 --- a/libcxx/include/__chrono/year.h +++ b/libcxx/include/__chrono/year.h @@ -113,8 +113,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept { # if _LIBCPP_STD_VER >= 26 template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year& __y) const _NOEXCEPT { +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year& __y) noexcept { return hash{}(static_cast(__y)); } }; diff --git a/libcxx/include/__chrono/year_month.h b/libcxx/include/__chrono/year_month.h index 6d6b14d952982..5bc4bb390b226 100644 --- a/libcxx/include/__chrono/year_month.h +++ b/libcxx/include/__chrono/year_month.h @@ -120,9 +120,9 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const # if _LIBCPP_STD_VER >= 26 template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month& __ym) const _NOEXCEPT { - return hash{}(__ym.year()) ^ hash{}(__ym.month()); +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month& __ym) noexcept { + return std::__hash_combine(hash{}(__ym.year()), hash{}(__ym.month())); } }; diff --git a/libcxx/include/__chrono/year_month_day.h b/libcxx/include/__chrono/year_month_day.h index c1661a1b7614b..826e8eefe96dd 100644 --- a/libcxx/include/__chrono/year_month_day.h +++ b/libcxx/include/__chrono/year_month_day.h @@ -334,16 +334,19 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool year_month_day::ok() const noexcept # if _LIBCPP_STD_VER >= 26 template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_day& __ymd) const _NOEXCEPT { - return hash{}(__ymd.year()) ^ hash{}(__ymd.month()) ^ hash{}(__ymd.day()); +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_day& __ymd) noexcept { + return std::__hash_combine( + hash{}(__ymd.year()), + std::__hash_combine(hash{}(__ymd.month()), hash{}(__ymd.day()))); } }; template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_day_last& __ymdl) const _NOEXCEPT { - return hash{}(__ymdl.year()) ^ hash{}(__ymdl.month_day_last()); +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_day_last& __ymdl) noexcept { + return std::__hash_combine( + hash{}(__ymdl.year()), hash{}(__ymdl.month_day_last())); } }; diff --git a/libcxx/include/__chrono/year_month_weekday.h b/libcxx/include/__chrono/year_month_weekday.h index ae7e21747d2a4..9b4632d57c7fa 100644 --- a/libcxx/include/__chrono/year_month_weekday.h +++ b/libcxx/include/__chrono/year_month_weekday.h @@ -284,18 +284,22 @@ year_month_weekday_last::operator-=(const years& __dy) noexcept { # if _LIBCPP_STD_VER >= 26 template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_weekday& __ymw) const _NOEXCEPT { - return hash{}(__ymw.year()) ^ hash{}(__ymw.month()) ^ - hash{}(__ymw.weekday_indexed()); +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_weekday& __ymw) noexcept { + return std::__hash_combine( + hash{}(__ymw.year()), + std::__hash_combine( + hash{}(__ymw.month()), hash{}(__ymw.weekday_indexed()))); } }; template <> -struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::year_month_weekday_last& __ymwl) const _NOEXCEPT { - return hash{}(__ymwl.year()) ^ hash{}(__ymwl.month()) ^ - hash{}(__ymwl.weekday_last()); +struct hash { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year_month_weekday_last& __ymwl) noexcept { + return std::__hash_combine( + hash{}(__ymwl.year()), + std::__hash_combine( + hash{}(__ymwl.month()), hash{}(__ymwl.weekday_last()))); } }; diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h index 595d0ce4d3d1c..2c763bce3bd95 100644 --- a/libcxx/include/__chrono/zoned_time.h +++ b/libcxx/include/__chrono/zoned_time.h @@ -221,10 +221,10 @@ operator==(const zoned_time<_Duration1, _TimeZonePtr>& __lhs, const zoned_time<_ template requires __has_enabled_hash<_Duration>::value && __has_enabled_hash<_TimeZonePtr>::value -struct hash> - : public __unary_function, size_t> { - _LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::zoned_time<_Duration, _TimeZonePtr>& __zt) const { - return hash>{}(__zt.get_sys_time()) ^ hash<_TimeZonePtr>{}(__zt.get_time_zone()); +struct hash> { + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::zoned_time<_Duration, _TimeZonePtr>& __zt) { + return std::__hash_combine( + hash>{}(__zt.get_sys_time()), hash<_TimeZonePtr>{}(__zt.get_time_zone())); } }; diff --git a/libcxx/include/version b/libcxx/include/version index 07cc828bd7c53..0fef1bb87cf60 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -57,8 +57,7 @@ __cpp_lib_byteswap 202110L __cpp_lib_char8_t 201907L -__cpp_lib_chrono 202306L - 201611L // C++17 +__cpp_lib_chrono 201611L __cpp_lib_chrono_udls 201304L __cpp_lib_clamp 201603L __cpp_lib_common_reference 202302L @@ -551,8 +550,6 @@ __cpp_lib_void_t 201411L # undef __cpp_lib_bind_front # define __cpp_lib_bind_front 202306L # define __cpp_lib_bitset 202306L -# undef __cpp_lib_chrono -# define __cpp_lib_chrono 202306L # undef __cpp_lib_constexpr_algorithms # define __cpp_lib_constexpr_algorithms 202306L # define __cpp_lib_constexpr_forward_list 202502L diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp index 98b3eda149342..d5d7a5da4a64d 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/chrono.version.compile.pass.cpp @@ -94,8 +94,8 @@ # ifndef __cpp_lib_chrono # error "__cpp_lib_chrono should be defined in c++26" # endif -# if __cpp_lib_chrono != 202306L -# error "__cpp_lib_chrono should have the value 202306L in c++26" +# if __cpp_lib_chrono != 201611L +# error "__cpp_lib_chrono should have the value 201611L in c++26" # endif # ifndef __cpp_lib_chrono_udls diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index 1ecba19d39abe..05af1fb0cf14b 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -6455,8 +6455,8 @@ # ifndef __cpp_lib_chrono # error "__cpp_lib_chrono should be defined in c++26" # endif -# if __cpp_lib_chrono != 202306L -# error "__cpp_lib_chrono should have the value 202306L in c++26" +# if __cpp_lib_chrono != 201611L +# error "__cpp_lib_chrono should have the value 201611L in c++26" # endif # ifndef __cpp_lib_chrono_udls diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index 114f844cc238e..f6f252751b3e3 100644 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -300,7 +300,7 @@ def add_version_header(tc): "name": "__cpp_lib_chrono", "values": { "c++17": 201611, - "c++26": 202306, # P2592R3 Hashing support for std::chrono value classes + # "c++26": 202306, # P2592R3 Hashing support for std::chrono value classes }, "headers": ["chrono"], }, From 5939a5ee82d40e2d188e719b64bbac429d4b468e Mon Sep 17 00:00:00 2001 From: Rafail Date: Mon, 27 Oct 2025 18:59:31 +0300 Subject: [PATCH 06/11] Fix size_t include issues --- libcxx/include/__chrono/day.h | 1 + libcxx/include/__chrono/duration.h | 1 + libcxx/include/__chrono/leap_second.h | 1 + libcxx/include/__chrono/month.h | 1 + libcxx/include/__chrono/month_weekday.h | 1 + libcxx/include/__chrono/monthday.h | 1 + libcxx/include/__chrono/time_point.h | 1 + libcxx/include/__chrono/weekday.h | 1 + libcxx/include/__chrono/year.h | 1 + libcxx/include/__chrono/year_month.h | 1 + libcxx/include/__chrono/year_month_day.h | 1 + libcxx/include/__chrono/year_month_weekday.h | 1 + libcxx/include/__chrono/zoned_time.h | 1 + libcxx/test/libcxx/transitive_includes/cxx26.csv | 3 +++ 14 files changed, 16 insertions(+) diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h index a8de0aa0fe50e..88a5ee5b837fa 100644 --- a/libcxx/include/__chrono/day.h +++ b/libcxx/include/__chrono/day.h @@ -13,6 +13,7 @@ #include <__chrono/duration.h> #include <__compare/ordering.h> #include <__config> +#include <__cstddef/size_t.h> #include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h index 24865ca9244bc..01432bd3fa259 100644 --- a/libcxx/include/__chrono/duration.h +++ b/libcxx/include/__chrono/duration.h @@ -13,6 +13,7 @@ #include <__compare/ordering.h> #include <__compare/three_way_comparable.h> #include <__config> +#include <__cstddef/size_t.h> #include <__functional/hash.h> #include <__type_traits/common_type.h> #include <__type_traits/enable_if.h> diff --git a/libcxx/include/__chrono/leap_second.h b/libcxx/include/__chrono/leap_second.h index d8d88a20fafbb..665056e5a963e 100644 --- a/libcxx/include/__chrono/leap_second.h +++ b/libcxx/include/__chrono/leap_second.h @@ -22,6 +22,7 @@ # include <__compare/ordering.h> # include <__compare/three_way_comparable.h> # include <__config> +# include <__cstddef/size_t.h> # include <__functional/hash.h> # include <__utility/private_constructor_tag.h> diff --git a/libcxx/include/__chrono/month.h b/libcxx/include/__chrono/month.h index 451d9222b7c9a..b9ba29b0e8b6b 100644 --- a/libcxx/include/__chrono/month.h +++ b/libcxx/include/__chrono/month.h @@ -13,6 +13,7 @@ #include <__chrono/duration.h> #include <__compare/ordering.h> #include <__config> +#include <__cstddef/size_t.h> #include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__chrono/month_weekday.h b/libcxx/include/__chrono/month_weekday.h index dab61a4a89576..edb7d386067d8 100644 --- a/libcxx/include/__chrono/month_weekday.h +++ b/libcxx/include/__chrono/month_weekday.h @@ -13,6 +13,7 @@ #include <__chrono/month.h> #include <__chrono/weekday.h> #include <__config> +#include <__cstddef/size_t.h> #include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__chrono/monthday.h b/libcxx/include/__chrono/monthday.h index 3d58fb3c003ea..2a7262be09dc6 100644 --- a/libcxx/include/__chrono/monthday.h +++ b/libcxx/include/__chrono/monthday.h @@ -15,6 +15,7 @@ #include <__chrono/month.h> #include <__compare/ordering.h> #include <__config> +#include <__cstddef/size_t.h> #include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h index c5da75b5dee23..438f065c1d99d 100644 --- a/libcxx/include/__chrono/time_point.h +++ b/libcxx/include/__chrono/time_point.h @@ -14,6 +14,7 @@ #include <__compare/ordering.h> #include <__compare/three_way_comparable.h> #include <__config> +#include <__cstddef/size_t.h> #include <__functional/hash.h> #include <__type_traits/common_type.h> #include <__type_traits/enable_if.h> diff --git a/libcxx/include/__chrono/weekday.h b/libcxx/include/__chrono/weekday.h index e12fc0a8a95ca..f56274c82bc68 100644 --- a/libcxx/include/__chrono/weekday.h +++ b/libcxx/include/__chrono/weekday.h @@ -15,6 +15,7 @@ #include <__chrono/system_clock.h> #include <__chrono/time_point.h> #include <__config> +#include <__cstddef/size_t.h> #include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h index cb7d892477dbb..9223f3cb926ea 100644 --- a/libcxx/include/__chrono/year.h +++ b/libcxx/include/__chrono/year.h @@ -13,6 +13,7 @@ #include <__chrono/duration.h> #include <__compare/ordering.h> #include <__config> +#include <__cstddef/size_t.h> #include <__functional/hash.h> #include diff --git a/libcxx/include/__chrono/year_month.h b/libcxx/include/__chrono/year_month.h index 5bc4bb390b226..e36091c02161b 100644 --- a/libcxx/include/__chrono/year_month.h +++ b/libcxx/include/__chrono/year_month.h @@ -15,6 +15,7 @@ #include <__chrono/year.h> #include <__compare/ordering.h> #include <__config> +#include <__cstddef/size_t.h> #include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__chrono/year_month_day.h b/libcxx/include/__chrono/year_month_day.h index 826e8eefe96dd..0a2aaedd60505 100644 --- a/libcxx/include/__chrono/year_month_day.h +++ b/libcxx/include/__chrono/year_month_day.h @@ -21,6 +21,7 @@ #include <__chrono/year_month.h> #include <__compare/ordering.h> #include <__config> +#include <__cstddef/size_t.h> #include <__functional/hash.h> #include diff --git a/libcxx/include/__chrono/year_month_weekday.h b/libcxx/include/__chrono/year_month_weekday.h index 9b4632d57c7fa..6ed1e21fe97e5 100644 --- a/libcxx/include/__chrono/year_month_weekday.h +++ b/libcxx/include/__chrono/year_month_weekday.h @@ -22,6 +22,7 @@ #include <__chrono/year_month.h> #include <__chrono/year_month_day.h> #include <__config> +#include <__cstddef/size_t.h> #include <__functional/hash.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h index 2c763bce3bd95..b8d33bb7f3ac7 100644 --- a/libcxx/include/__chrono/zoned_time.h +++ b/libcxx/include/__chrono/zoned_time.h @@ -24,6 +24,7 @@ # include <__chrono/tzdb_list.h> # include <__concepts/constructible.h> # include <__config> +# include <__cstddef/size_t.h> # include <__functional/hash.h> # include <__type_traits/common_type.h> # include <__type_traits/conditional.h> diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv index d047b29b63cc6..872bd5e0fe740 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx26.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv @@ -654,6 +654,7 @@ memory_resource cerrno memory_resource climits memory_resource compare memory_resource cstdint +memory_resource cstring memory_resource ctime memory_resource limits memory_resource ratio @@ -663,6 +664,7 @@ mutex cerrno mutex climits mutex compare mutex cstdint +mutex cstring mutex ctime mutex limits mutex ratio @@ -859,6 +861,7 @@ set version shared_mutex cerrno shared_mutex climits shared_mutex cstdint +shared_mutex cstring shared_mutex ctime shared_mutex limits shared_mutex ratio From 152b3dc3f317ed1ff1bec3fc3b29289dac3d9d2b Mon Sep 17 00:00:00 2001 From: Rafail Date: Mon, 27 Oct 2025 19:02:08 +0300 Subject: [PATCH 07/11] Identity for hash --- libcxx/include/__chrono/day.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libcxx/include/__chrono/day.h b/libcxx/include/__chrono/day.h index 88a5ee5b837fa..46822c599192d 100644 --- a/libcxx/include/__chrono/day.h +++ b/libcxx/include/__chrono/day.h @@ -98,9 +98,7 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) no template <> struct hash { - _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::day& __d) noexcept { - return hash{}(static_cast(__d)); - } + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::day& __d) noexcept { return static_cast(__d); } }; # endif // _LIBCPP_STD_VER >= 26 From 616129fddc8b907788da0df8eb3e45a61bfa5ddf Mon Sep 17 00:00:00 2001 From: Rafail Date: Tue, 28 Oct 2025 03:33:20 +0300 Subject: [PATCH 08/11] More identities for hashs --- libcxx/include/__chrono/month.h | 2 +- libcxx/include/__chrono/weekday.h | 6 ++---- libcxx/include/__chrono/year.h | 4 +--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/libcxx/include/__chrono/month.h b/libcxx/include/__chrono/month.h index b9ba29b0e8b6b..669ac66360ab6 100644 --- a/libcxx/include/__chrono/month.h +++ b/libcxx/include/__chrono/month.h @@ -115,7 +115,7 @@ inline constexpr month December{12}; template <> struct hash { _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::month& __m) noexcept { - return hash{}(static_cast(__m)); + return static_cast(__m); } }; diff --git a/libcxx/include/__chrono/weekday.h b/libcxx/include/__chrono/weekday.h index f56274c82bc68..143803495dac8 100644 --- a/libcxx/include/__chrono/weekday.h +++ b/libcxx/include/__chrono/weekday.h @@ -166,15 +166,13 @@ inline constexpr weekday Saturday{6}; template <> struct hash { - _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday& __w) noexcept { - return hash{}(__w.c_encoding()); - } + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday& __w) noexcept { return __w.c_encoding(); } }; template <> struct hash { _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::weekday_indexed& __wi) noexcept { - return std::__hash_combine(hash{}(__wi.weekday()), hash{}(__wi.index())); + return std::__hash_combine(hash{}(__wi.weekday()), __wi.index()); } }; diff --git a/libcxx/include/__chrono/year.h b/libcxx/include/__chrono/year.h index 9223f3cb926ea..aaef38acd92f2 100644 --- a/libcxx/include/__chrono/year.h +++ b/libcxx/include/__chrono/year.h @@ -115,9 +115,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept { template <> struct hash { - _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year& __y) noexcept { - return hash{}(static_cast(__y)); - } + _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::year& __y) noexcept { return static_cast(__y); } }; # endif // _LIBCPP_STD_VER >= 26 From 39c49ce600f7363ecf677547d9d7684a980d4b07 Mon Sep 17 00:00:00 2001 From: Rafail Date: Tue, 28 Oct 2025 13:47:11 +0300 Subject: [PATCH 09/11] Using in module --- libcxx/modules/std/chrono.inc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libcxx/modules/std/chrono.inc b/libcxx/modules/std/chrono.inc index 66eccd8d290ad..982eb8b85fb9c 100644 --- a/libcxx/modules/std/chrono.inc +++ b/libcxx/modules/std/chrono.inc @@ -284,6 +284,10 @@ export namespace std { } // namespace chrono +#if _LIBCPP_STD_VER >= 26 + using std::hash; +#endif + } // namespace std export namespace std::inline literals::inline chrono_literals { // [time.duration.literals], suffixes for duration literals From 5d7304c64ff25c9e279627819685558701de516d Mon Sep 17 00:00:00 2001 From: Rafail Date: Tue, 28 Oct 2025 16:57:03 +0300 Subject: [PATCH 10/11] Transitive includes --- libcxx/test/libcxx/transitive_includes/cxx03.csv | 1 + libcxx/test/libcxx/transitive_includes/cxx11.csv | 1 + libcxx/test/libcxx/transitive_includes/cxx14.csv | 1 + libcxx/test/libcxx/transitive_includes/cxx23.csv | 3 +++ 4 files changed, 6 insertions(+) diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv index c0031543e47bc..255d5ea15162b 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx03.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -1350,6 +1350,7 @@ memory version memory_resource cstddef memory_resource cstdint memory_resource cstdlib +memory_resource cstring memory_resource exception memory_resource iosfwd memory_resource new diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv index c0031543e47bc..255d5ea15162b 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -1350,6 +1350,7 @@ memory version memory_resource cstddef memory_resource cstdint memory_resource cstdlib +memory_resource cstring memory_resource exception memory_resource iosfwd memory_resource new diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv index c2eb5b44e8d7a..311aee93218f2 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -1380,6 +1380,7 @@ memory version memory_resource cstddef memory_resource cstdint memory_resource cstdlib +memory_resource cstring memory_resource exception memory_resource iosfwd memory_resource new diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv index cb23c7a98de1b..0bf79c4ae780f 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx23.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv @@ -669,6 +669,7 @@ memory_resource cerrno memory_resource climits memory_resource compare memory_resource cstdint +memory_resource cstring memory_resource ctime memory_resource limits memory_resource ratio @@ -678,6 +679,7 @@ mutex cerrno mutex climits mutex compare mutex cstdint +mutex cstring mutex ctime mutex limits mutex ratio @@ -876,6 +878,7 @@ set version shared_mutex cerrno shared_mutex climits shared_mutex cstdint +shared_mutex cstring shared_mutex ctime shared_mutex limits shared_mutex ratio From 17cfb4f4d653fd71e18706dac0fa6e9a651a03a2 Mon Sep 17 00:00:00 2001 From: Rafail Date: Wed, 29 Oct 2025 06:14:11 +0300 Subject: [PATCH 11/11] Remove cstring for cxx<17 --- libcxx/test/libcxx/transitive_includes/cxx03.csv | 1 - libcxx/test/libcxx/transitive_includes/cxx11.csv | 1 - libcxx/test/libcxx/transitive_includes/cxx14.csv | 1 - 3 files changed, 3 deletions(-) diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv index 255d5ea15162b..c0031543e47bc 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx03.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -1350,7 +1350,6 @@ memory version memory_resource cstddef memory_resource cstdint memory_resource cstdlib -memory_resource cstring memory_resource exception memory_resource iosfwd memory_resource new diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv index 255d5ea15162b..c0031543e47bc 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -1350,7 +1350,6 @@ memory version memory_resource cstddef memory_resource cstdint memory_resource cstdlib -memory_resource cstring memory_resource exception memory_resource iosfwd memory_resource new diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv index 311aee93218f2..c2eb5b44e8d7a 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -1380,7 +1380,6 @@ memory version memory_resource cstddef memory_resource cstdint memory_resource cstdlib -memory_resource cstring memory_resource exception memory_resource iosfwd memory_resource new