[libcxx-commits] [libcxx] [libc++] Implement P2077R3 Heterogeneous erasure overloads for associative containers (PR #78277)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jan 16 05:50:07 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Mital Ashok (MitalAshok)
<details>
<summary>Changes</summary>
Implements [P2077R3](https://wg21.link/P2077R3).
Note that given a non-const or non-lvalue argument `k`, `m.extract(k)`/`m.erase(k)` converts to a const lvalue, similarly to what would have happened if the functions took by `const _K2&` instead of `_K2&&`. This is intentional since the comparator / hasher+key_equal shouldn't modify the argument. The exact wording is here: https://wg21.link/associative.reqmts.general#<!-- -->123
---
Patch is 110.99 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/78277.diff
57 Files Affected:
- (modified) libcxx/docs/ReleaseNotes/18.rst (+1)
- (modified) libcxx/docs/Status/Cxx23Papers.csv (+2-2)
- (modified) libcxx/include/__hash_table (+4-4)
- (modified) libcxx/include/__tree (+4-4)
- (modified) libcxx/include/map (+36-4)
- (modified) libcxx/include/set (+34-2)
- (modified) libcxx/include/unordered_map (+34-2)
- (modified) libcxx/include/unordered_set (+37-5)
- (modified) libcxx/include/version (+1-1)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/erase_tran.pass.cpp (+58)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/erase_tran1.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/erase_tran2.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/erase_tran3.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/erase_tran4.pass.cpp (+49)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/erase_tran5.pass.cpp (+52)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/extract_tran.pass.cpp (+61)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/extract_tran1.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/extract_tran2.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/extract_tran3.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/extract_tran4.pass.cpp (+49)
- (added) libcxx/test/std/containers/associative/map/map.modifiers/extract_tran5.pass.cpp (+52)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/erase_tran.pass.cpp (+58)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/erase_tran1.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/erase_tran2.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/erase_tran3.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/erase_tran4.pass.cpp (+49)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/erase_tran5.pass.cpp (+52)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/extract_tran.pass.cpp (+61)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/extract_tran1.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/extract_tran2.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/extract_tran3.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/extract_tran4.pass.cpp (+49)
- (added) libcxx/test/std/containers/associative/multimap/multimap.modifiers/extract_tran5.pass.cpp (+52)
- (added) libcxx/test/std/containers/associative/multiset/erase_tran.pass.cpp (+58)
- (added) libcxx/test/std/containers/associative/multiset/erase_tran1.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multiset/erase_tran2.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multiset/erase_tran3.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multiset/erase_tran4.pass.cpp (+49)
- (added) libcxx/test/std/containers/associative/multiset/erase_tran5.pass.cpp (+52)
- (added) libcxx/test/std/containers/associative/multiset/extract_tran.pass.cpp (+61)
- (added) libcxx/test/std/containers/associative/multiset/extract_tran1.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multiset/extract_tran2.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multiset/extract_tran3.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/multiset/extract_tran4.pass.cpp (+49)
- (added) libcxx/test/std/containers/associative/multiset/extract_tran5.pass.cpp (+52)
- (added) libcxx/test/std/containers/associative/set/erase_tran.pass.cpp (+58)
- (added) libcxx/test/std/containers/associative/set/erase_tran1.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/set/erase_tran2.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/set/erase_tran3.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/set/erase_tran4.pass.cpp (+49)
- (added) libcxx/test/std/containers/associative/set/erase_tran5.pass.cpp (+52)
- (added) libcxx/test/std/containers/associative/set/extract_tran.pass.cpp (+61)
- (added) libcxx/test/std/containers/associative/set/extract_tran1.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/set/extract_tran2.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/set/extract_tran3.compile.fail.cpp (+40)
- (added) libcxx/test/std/containers/associative/set/extract_tran4.pass.cpp (+49)
- (added) libcxx/test/std/containers/associative/set/extract_tran5.pass.cpp (+52)
``````````diff
diff --git a/libcxx/docs/ReleaseNotes/18.rst b/libcxx/docs/ReleaseNotes/18.rst
index 62a1fec627d0ca..8db818ef490203 100644
--- a/libcxx/docs/ReleaseNotes/18.rst
+++ b/libcxx/docs/ReleaseNotes/18.rst
@@ -60,6 +60,7 @@ Implemented Papers
- P0521R0 - Proposed Resolution for CA 14 (``shared_ptr`` ``use_count/unique``)
- P1759R6 - Native handles and file streams
- P2517R1 - Add a conditional ``noexcept`` specification to ``std::apply``
+- P2077R3 - Heterogeneous erasure overloads for associative containers
Improvements and New Features
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index ebab3ef735b617..5e091f6151399b 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -30,7 +30,7 @@
"`P1147R1 <https://wg21.link/P1147R1>`__","LWG","Printing ``volatile`` Pointers","October 2021","|Complete|","14.0"
"`P1272R4 <https://wg21.link/P1272R4>`__","LWG","Byteswapping for fun&&nuf","October 2021","|Complete|","14.0"
"`P1675R2 <https://wg21.link/P1675R2>`__","LWG","``rethrow_exception`` must be allowed to copy","October 2021","",""
-"`P2077R3 <https://wg21.link/P2077R3>`__","LWG","Heterogeneous erasure overloads for associative containers","October 2021","",""
+"`P2077R3 <https://wg21.link/P2077R3>`__","LWG","Heterogeneous erasure overloads for associative containers","October 2021","|Complete|","18.0"
"`P2251R1 <https://wg21.link/P2251R1>`__","LWG","Require ``span`` & ``basic_string_view`` to be Trivially Copyable","October 2021","|Complete|","14.0"
"`P2301R1 <https://wg21.link/P2301R1>`__","LWG","Add a ``pmr`` alias for ``std::stacktrace``","October 2021","",""
"`P2321R2 <https://wg21.link/P2321R2>`__","LWG","``zip``","October 2021","|In Progress|","","|ranges|"
@@ -59,7 +59,7 @@
"`P1467R9 <https://wg21.link/P1467R9>`__","LWG","Extended ``floating-point`` types and standard names","July 2022","",""
"`P1642R11 <https://wg21.link/P1642R11>`__","LWG","Freestanding ``[utilities]``, ``[ranges]``, and ``[iterators]``","July 2022","",""
"`P1899R3 <https://wg21.link/P1899R3>`__","LWG","``stride_view``","July 2022","","","|ranges|"
-"`P2093R14 <https://wg21.link/P2093R14>`__","LWG","Formatted output","July 2022","","|Complete|","18.0"
+"`P2093R14 <https://wg21.link/P2093R14>`__","LWG","Formatted output","July 2022","|Complete|","18.0",""
"`P2165R4 <https://wg21.link/P2165R4>`__","LWG","Compatibility between ``tuple``, ``pair`` and ``tuple-like`` objects","July 2022","",""
"`P2278R4 <https://wg21.link/P2278R4>`__","LWG","``cbegin`` should always return a constant iterator","July 2022","","","|ranges|"
"`P2286R8 <https://wg21.link/P2286R8>`__","LWG","Formatting Ranges","July 2022","|Complete|","16.0","|format| |ranges|"
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index 4ca49fe42606c7..0d7c38f9d056f5 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -836,8 +836,8 @@ public:
template <class _Table>
_LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(_Table& __source);
- template <class _NodeHandle>
- _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(key_type const& __key);
+ template <class _NodeHandle, class _Key>
+ _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_find_and_extract(const _Key& __key);
template <class _NodeHandle>
_LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(const_iterator __it);
#endif
@@ -1579,9 +1579,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(const_iter
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
-template <class _NodeHandle>
+template <class _NodeHandle, class _Key>
_LIBCPP_HIDE_FROM_ABI _NodeHandle
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(key_type const& __key) {
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_find_and_extract(const _Key& __key) {
iterator __i = find(__key);
if (__i == end())
return _NodeHandle();
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 2dcc3c614d3660..84cda01df51494 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -1168,8 +1168,8 @@ public:
template <class _Tree>
_LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(_Tree& __source);
- template <class _NodeHandle>
- _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(key_type const&);
+ template <class _NodeHandle, class _Key>
+ _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_find_and_extract(const _Key&);
template <class _NodeHandle>
_LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(const_iterator);
#endif
@@ -1963,8 +1963,8 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(const_iterator __
}
template <class _Tp, class _Compare, class _Allocator>
-template <class _NodeHandle>
-_LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key) {
+template <class _NodeHandle, class _Key>
+_LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_handle_find_and_extract(const _Key& __key) {
iterator __it = find(__key);
if (__it == end())
return _NodeHandle();
diff --git a/libcxx/include/map b/libcxx/include/map
index f122f2ebb15b52..5b3515c228e0b5 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -149,6 +149,8 @@ public:
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
+ template <class K>
+ node_type extract(K&& x); // C++23
insert_return_type insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
@@ -170,8 +172,10 @@ public:
iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
iterator erase(const_iterator position);
- iterator erase(iterator position); // C++14
+ iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
+ template <class K>
+ size_type erase(K&& x); // C++23
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
@@ -428,12 +432,16 @@ public:
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
+ template <class K>
+ node_type extract(K&& x); // C++23
iterator insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
iterator erase(const_iterator position);
- iterator erase(iterator position); // C++14
+ iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
+ template <class K>
+ size_type erase(K&& x); // C++23
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
@@ -1309,6 +1317,12 @@ public:
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p.__i_); }
_LIBCPP_HIDE_FROM_ABI iterator erase(iterator __p) { return __tree_.erase(__p.__i_); }
_LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_unique(__k); }
+#if _LIBCPP_STD_VER >= 23
+ template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value && !(is_convertible_v<_K2&&, iterator> || is_convertible_v<_K2&&, const_iterator>), int> = 0>
+ _LIBCPP_HIDE_FROM_ABI size_type erase(_K2&& __k) {
+ return __tree_.__erase_unique(__k);
+ }
+#endif
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) {
return __tree_.erase(__f.__i_, __l.__i_);
}
@@ -1326,11 +1340,17 @@ public:
return __tree_.template __node_handle_insert_unique<node_type>(__hint.__i_, std::move(__nh));
}
_LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
- return __tree_.template __node_handle_extract<node_type>(__key);
+ return __tree_.template __node_handle_find_and_extract<node_type>(__key);
}
_LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
return __tree_.template __node_handle_extract<node_type>(__it.__i_);
}
+#if _LIBCPP_STD_VER >= 23
+ template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value && !(is_convertible_v<_K2&&, iterator> || is_convertible_v<_K2&&, const_iterator>), int> = 0>
+ _LIBCPP_HIDE_FROM_ABI node_type extract(_K2&& __key) {
+ return __tree_.template __node_handle_find_and_extract<node_type>(__key);
+ }
+#endif
template <class _Compare2>
_LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) {
_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
@@ -1900,6 +1920,12 @@ public:
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p.__i_); }
_LIBCPP_HIDE_FROM_ABI iterator erase(iterator __p) { return __tree_.erase(__p.__i_); }
_LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_multi(__k); }
+#if _LIBCPP_STD_VER >= 23
+ template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value && !(is_convertible_v<_K2&&, iterator> || is_convertible_v<_K2&&, const_iterator>), int> = 0>
+ _LIBCPP_HIDE_FROM_ABI size_type erase(_K2&& __k) {
+ return __tree_.__erase_multi(__k);
+ }
+#endif
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) {
return __tree_.erase(__f.__i_, __l.__i_);
}
@@ -1916,11 +1942,17 @@ public:
return __tree_.template __node_handle_insert_multi<node_type>(__hint.__i_, std::move(__nh));
}
_LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
- return __tree_.template __node_handle_extract<node_type>(__key);
+ return __tree_.template __node_handle_find_and_extract<node_type>(__key);
}
_LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
return __tree_.template __node_handle_extract<node_type>(__it.__i_);
}
+#if _LIBCPP_STD_VER >= 23
+ template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value && !(is_convertible_v<_K2&&, iterator> || is_convertible_v<_K2&&, const_iterator>), int> = 0>
+ _LIBCPP_HIDE_FROM_ABI node_type extract(_K2&& __key) {
+ return __tree_.template __node_handle_find_and_extract<node_type>(__key);
+ }
+#endif
template <class _Compare2>
_LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) {
_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
diff --git a/libcxx/include/set b/libcxx/include/set
index 55ba8f8208be1b..832ed876253c86 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -125,12 +125,16 @@ public:
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
+ template <class K>
+ node_type extract(K&& x); // C++23
insert_return_type insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
+ template <class K>
+ size_type erase(K&& x); // C++23
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
@@ -370,12 +374,16 @@ public:
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
+ template <class K>
+ node_type extract(K&& x); // C++23
iterator insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
+ template <class K>
+ size_type erase(K&& x); // C++23
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
@@ -764,6 +772,12 @@ public:
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p); }
_LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_unique(__k); }
+#if _LIBCPP_STD_VER >= 23
+ template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value && !(is_convertible_v<_K2&&, iterator> || is_convertible_v<_K2&&, const_iterator>), int> = 0>
+ _LIBCPP_HIDE_FROM_ABI size_type erase(_K2&& __k) {
+ return __tree_.__erase_unique(__k);
+ }
+#endif
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) { return __tree_.erase(__f, __l); }
_LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }
@@ -779,11 +793,17 @@ public:
return __tree_.template __node_handle_insert_unique<node_type>(__hint, std::move(__nh));
}
_LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
- return __tree_.template __node_handle_extract<node_type>(__key);
+ return __tree_.template __node_handle_find_and_extract<node_type>(__key);
}
_LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
return __tree_.template __node_handle_extract<node_type>(__it);
}
+#if _LIBCPP_STD_VER >= 23
+ template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value && !(is_convertible_v<_K2&&, iterator> || is_convertible_v<_K2&&, const_iterator>), int> = 0>
+ _LIBCPP_HIDE_FROM_ABI node_type extract(_K2&& __key) {
+ return __tree_.template __node_handle_find_and_extract<node_type>(__key);
+ }
+#endif
template <class _Compare2>
_LIBCPP_HIDE_FROM_ABI void merge(set<key_type, _Compare2, allocator_type>& __source) {
_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
@@ -1222,6 +1242,12 @@ public:
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p); }
_LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_multi(__k); }
+#if _LIBCPP_STD_VER >= 23
+ template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value && !(is_convertible_v<_K2&&, iterator> || is_convertible_v<_K2&&, const_iterator>), int> = 0>
+ _LIBCPP_HIDE_FROM_ABI size_type erase(_K2&& __k) {
+ return __tree_.__erase_multi(__k);
+ }
+#endif
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) { return __tree_.erase(__f, __l); }
_LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }
@@ -1237,11 +1263,17 @@ public:
return __tree_.template __node_handle_insert_multi<node_type>(__hint, std::move(__nh));
}
_LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
- return __tree_.template __node_handle_extract<node_type>(__key);
+ return __tree_.template __node_handle_find_and_extract<node_type>(__key);
}
_LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
return __tree_.template __node_handle_extract<node_type>(__it);
}
+#if _LIBCPP_STD_VER >= 23
+ template <typename _K2, enable_if_t<__is_transparent<_Compare, _K2>::value && !(is_convertible_v<_K2&&, iterator> || is_convertible_v<_K2&&, const_iterator>), int> = 0>
+ _LIBCPP_HIDE_FROM_ABI node_type extract(_K2&& __key) {
+ return __tree_.template __node_handle_find_and_extract<node_type>(__key);
+ }
+#endif
template <class _Compare2>
_LIBCPP_HIDE_FROM_ABI void merge(multiset<key_type, _Compare2, allocator_type>& __source) {
_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map
index 4be25fc1cdd8fe..42889a06ed019a 100644
--- a/libcxx/include/unordered_map
+++ b/libcxx/include/unordered_map
@@ -139,6 +139,8 @@ public:
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
+ template <class K>
+ node_type extract(K&& x); // C++23
insert_return_type insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
@@ -162,6 +164,8 @@ public:
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
+ template <class K>
+ size_type erase(K&& x); // C++23
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
@@ -425,12 +429,16 @@ public:
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
+ template <class K>
+ node_type extract(K&& x); // C++23
iterator insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
+ template <class K>
+ size_type erase(K&& x); // C++23
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
@@ -1322,6 +1330,12 @@ public:
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __table_.erase(__p.__i_); }
_LIBCPP_HIDE_FROM_ABI iterator erase(iterator __p) { return __table_.erase(__p.__i_); }
_LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __table_.__erase_unique(__k); }
+#if _LIBCPP_STD_VER >= 23
+ template <typename _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value && !(is_convertible_v<_K2&&, iterator> || is_convertible_v<_K2&&, const_iterator>), int> = 0>
+ _LIBCPP_HIDE_FROM_ABI size_type erase(_K2&& __k) {
+ return __table_.__erase_unique(__k);
+ }
+#endif
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last) {
return __table_.erase(__first.__i_, __last.__i_);
}
@@ -1339,11 +1353,17 @@ public:
return __table_.template __node_handle_insert_unique<node_type>(__hint.__i_, std::move(__nh));
}
_LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
- return __table_.template __node_handle_extract<node_type>(__key);
+ return __table_.template __node_handle_find_and_extract<node_type>(__key);
}
_LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
return __table_.template __node_handle_extract<node_type>(__it.__i_);
}
+#if _LIBCPP_STD_VER >= 23
+ template <typename _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value && !(is_convertible_v<_K2&&, iterator> || is_convertible_v<_K2&&, const_iterator>), int> = 0>
+ _LIBCPP_HIDE_FROM_ABI node_type extract(_K2&& __key) {
+ return __table_.template __node_handle_find_and_extract<node_type>(__key);
+ }
+#endif
template <class _H2, class _P2>
_LIBCPP_HIDE_FROM_ABI void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source) {
@@ -2073,6 +2093,12 @@ public:
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __table_.erase(__p.__i_); }
_LIBCPP_HIDE_FROM_ABI iterator erase(iterator __p) { return __table_.erase(__p.__i_); }
_LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __table_.__erase_multi(__k); }
+#if _LIBCPP_STD_VER >= 23
+ template <typename _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value && !(is_convertible_v<_K2&&, iterator> || is_convertible_v<_K2&&, const_iterator>), int> = 0>
+ _LIBCPP_HIDE_FROM_ABI size_type erase(_K2&& __k) {
+ return __table_.__erase_multi(__k);
+ }
+#endif
_LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, con...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/78277
More information about the libcxx-commits
mailing list