Skip to content

Commit 1c6dc8d

Browse files
committed
Initial hashing support for chrono
1 parent f03ccef commit 1c6dc8d

File tree

18 files changed

+221
-4
lines changed

18 files changed

+221
-4
lines changed

libcxx/docs/FeatureTestMacroTable.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Status
8888
---------------------------------------------------------- -----------------
8989
``__cpp_lib_byte`` ``201603L``
9090
---------------------------------------------------------- -----------------
91-
``__cpp_lib_chrono`` ``201611L``
91+
``__cpp_lib_chrono`` ``202510L``
9292
---------------------------------------------------------- -----------------
9393
``__cpp_lib_clamp`` ``201603L``
9494
---------------------------------------------------------- -----------------

libcxx/docs/ReleaseNotes/22.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ What's New in Libc++ 22.0.0?
3838
Implemented Papers
3939
------------------
4040

41+
- P2592R3: Hashing support for ``std::chrono`` value classes (`Github <https://llvm.org/PR105358>`__)
4142
- P2321R2: ``zip`` (`Github <https://llvm.org/PR105169>`__) (The paper is partially implemented. ``zip_transform_view``
4243
is implemented in this release)
4344
- P3044R2: sub-``string_view`` from ``string`` (`Github <https://llvm.org/PR148140>`__)

libcxx/docs/Status/Cxx2cPapers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"Paper #","Paper Name","Meeting","Status","First released version","GitHub issue","Notes"
22
"`P2497R0 <https://wg21.link/P2497R0>`__","Testing for success or failure of ``<charconv>`` functions","2023-06 (Varna)","|Complete|","18","`#105357 <https://github.com/llvm/llvm-project/issues/105357>`__",""
3-
"`P2592R3 <https://wg21.link/P2592R3>`__","Hashing support for ``std::chrono`` value classes","2023-06 (Varna)","","","`#105358 <https://github.com/llvm/llvm-project/issues/105358>`__",""
3+
"`P2592R3 <https://wg21.link/P2592R3>`__","Hashing support for ``std::chrono`` value classes","2023-06 (Varna)","|Complete|","22","`#105358 <https://github.com/llvm/llvm-project/issues/105358>`__",""
44
"`P2587R3 <https://wg21.link/P2587R3>`__","``to_string`` or not ``to_string``","2023-06 (Varna)","","","`#105359 <https://github.com/llvm/llvm-project/issues/105359>`__",""
55
"`P2562R1 <https://wg21.link/P2562R1>`__","``constexpr`` Stable Sorting","2023-06 (Varna)","|Complete|","21","`#105360 <https://github.com/llvm/llvm-project/issues/105360>`__",""
66
"`P2545R4 <https://wg21.link/P2545R4>`__","Read-Copy Update (RCU)","2023-06 (Varna)","","","`#105361 <https://github.com/llvm/llvm-project/issues/105361>`__",""

libcxx/include/__chrono/day.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <__chrono/duration.h>
1414
#include <__compare/ordering.h>
1515
#include <__config>
16+
#include <__functional/hash.h>
1617

1718
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1819
# pragma GCC system_header
@@ -92,6 +93,13 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) no
9293

9394
} // namespace chrono
9495

96+
template <>
97+
struct hash<chrono::day> : public __unary_function<chrono::day, size_t> {
98+
_LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::day& __d) const _NOEXCEPT {
99+
return hash<unsigned>{}(static_cast<unsigned>(__d));
100+
}
101+
};
102+
95103
_LIBCPP_END_NAMESPACE_STD
96104

97105
#endif // _LIBCPP_STD_VER >= 20

libcxx/include/__chrono/duration.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <__compare/ordering.h>
1414
#include <__compare/three_way_comparable.h>
1515
#include <__config>
16+
#include <__functional/hash.h>
1617
#include <__type_traits/common_type.h>
1718
#include <__type_traits/enable_if.h>
1819
#include <__type_traits/is_convertible.h>
@@ -538,6 +539,18 @@ using namespace literals::chrono_literals;
538539

539540
#endif // _LIBCPP_STD_VER >= 14
540541

542+
#if _LIBCPP_STD_VER >= 20
543+
544+
template <class _Rep, class _Period>
545+
requires __has_enabled_hash<_Rep>::value
546+
struct hash<chrono::duration<_Rep, _Period>> : public __unary_function<chrono::duration<_Rep, _Period>, size_t> {
547+
_LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::duration<_Rep, _Period>& __d) const {
548+
return hash<_Rep>{}(__d.count());
549+
}
550+
};
551+
552+
#endif // _LIBCPP_STD_VER >= 20
553+
541554
_LIBCPP_END_NAMESPACE_STD
542555

543556
_LIBCPP_POP_MACROS

libcxx/include/__chrono/leap_second.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
# include <__compare/ordering.h>
2323
# include <__compare/three_way_comparable.h>
2424
# include <__config>
25+
# include <__functional/hash.h>
2526
# include <__utility/private_constructor_tag.h>
2627

2728
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -122,6 +123,13 @@ class leap_second {
122123

123124
} // namespace chrono
124125

126+
template <>
127+
struct hash<chrono::leap_second> : public __unary_function<chrono::leap_second, size_t> {
128+
_LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::leap_second& __lp) const _NOEXCEPT {
129+
return hash<chrono::seconds>{}(__lp.value());
130+
}
131+
};
132+
125133
# endif // _LIBCPP_STD_VER >= 20
126134

127135
_LIBCPP_END_NAMESPACE_STD

libcxx/include/__chrono/month.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <__chrono/duration.h>
1414
#include <__compare/ordering.h>
1515
#include <__config>
16+
#include <__functional/hash.h>
1617

1718
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1819
# pragma GCC system_header
@@ -108,6 +109,13 @@ inline constexpr month December{12};
108109

109110
} // namespace chrono
110111

112+
template <>
113+
struct hash<chrono::month> : public __unary_function<chrono::month, size_t> {
114+
_LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month& __m) const _NOEXCEPT {
115+
return hash<unsigned>{}(static_cast<unsigned>(__m));
116+
}
117+
};
118+
111119
_LIBCPP_END_NAMESPACE_STD
112120

113121
#endif // _LIBCPP_STD_VER >= 20

libcxx/include/__chrono/month_weekday.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <__chrono/month.h>
1414
#include <__chrono/weekday.h>
1515
#include <__config>
16+
#include <__functional/hash.h>
1617

1718
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1819
# pragma GCC system_header
@@ -98,6 +99,20 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(const weekda
9899
}
99100
} // namespace chrono
100101

102+
template <>
103+
struct hash<chrono::month_weekday> : public __unary_function<chrono::month_weekday, size_t> {
104+
_LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday& __mw) const _NOEXCEPT {
105+
return hash<chrono::month>{}(__mw.month()) ^ hash<chrono::weekday_indexed>{}(__mw.weekday_indexed());
106+
}
107+
};
108+
109+
template <>
110+
struct hash<chrono::month_weekday_last> : public __unary_function<chrono::month_weekday_last, size_t> {
111+
_LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_weekday_last& __mwl) const _NOEXCEPT {
112+
return hash<chrono::month>{}(__mwl.month()) ^ hash<chrono::weekday_last>{}(__mwl.weekday_last());
113+
}
114+
};
115+
101116
_LIBCPP_END_NAMESPACE_STD
102117

103118
#endif // _LIBCPP_STD_VER >= 20

libcxx/include/__chrono/monthday.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <__chrono/month.h>
1616
#include <__compare/ordering.h>
1717
#include <__config>
18+
#include <__functional/hash.h>
1819

1920
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2021
# pragma GCC system_header
@@ -126,6 +127,20 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, int _
126127

127128
} // namespace chrono
128129

130+
template <>
131+
struct hash<chrono::month_day> : public __unary_function<chrono::month_day, size_t> {
132+
_LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day& __md) const _NOEXCEPT {
133+
return hash<chrono::month>{}(__md.month()) ^ hash<chrono::day>{}(__md.day());
134+
}
135+
};
136+
137+
template <>
138+
struct hash<chrono::month_day_last> : public __unary_function<chrono::month_day_last, size_t> {
139+
_LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::month_day_last& __mdl) const _NOEXCEPT {
140+
return hash<chrono::month>{}(__mdl.month());
141+
}
142+
};
143+
129144
_LIBCPP_END_NAMESPACE_STD
130145

131146
#endif // _LIBCPP_STD_VER >= 20

libcxx/include/__chrono/time_point.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <__compare/ordering.h>
1515
#include <__compare/three_way_comparable.h>
1616
#include <__config>
17+
#include <__functional/hash.h>
1718
#include <__type_traits/common_type.h>
1819
#include <__type_traits/enable_if.h>
1920
#include <__type_traits/is_convertible.h>
@@ -224,6 +225,19 @@ operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock,
224225

225226
} // namespace chrono
226227

228+
#if _LIBCPP_STD_VER >= 20
229+
230+
template <class _Clock, class _Duration>
231+
requires __has_enabled_hash<_Duration>::value
232+
struct hash<chrono::time_point<_Clock, _Duration>>
233+
: public __unary_function<chrono::time_point<_Clock, _Duration>, size_t> {
234+
_LIBCPP_HIDE_FROM_ABI size_t operator()(const chrono::time_point<_Clock, _Duration>& __tp) const {
235+
return hash<_Duration>{}(__tp.time_since_epoch());
236+
}
237+
};
238+
239+
#endif // _LIBCPP_STD_VER >= 20
240+
227241
_LIBCPP_END_NAMESPACE_STD
228242

229243
_LIBCPP_POP_MACROS

0 commit comments

Comments
 (0)