[libcxx-commits] [libcxx] [libc++] Add __is_transparently_comparable_v optimizations for set and multiset [Issue 187105] (PR #189735)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Apr 1 09:13:55 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Michael Levine (levinem)
<details>
<summary>Changes</summary>
This PR relates to https://github.com/llvm/llvm-project/issues/187105 and https://github.com/llvm/llvm-project/pull/188799 but only handles the `std::set` and `std::multiset` portion.
It adds `__is_transparently_comparable_v` checks to `std::set` and `std::multiset`'s `find`, `count`, `contains`, `lower_bound`, `upper_bound`, and `equal_range` functions.
Tests in https://github.com/llvm/llvm-project/pull/187345 can be expanded to cover these new optimizations.
Assisted by: Claude Code
---
Full diff: https://github.com/llvm/llvm-project/pull/189735.diff
1 Files Affected:
- (modified) libcxx/include/set (+60-20)
``````````diff
diff --git a/libcxx/include/set b/libcxx/include/set
index 695b6c87e3984..ff1de085c1d8b 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -825,11 +825,15 @@ public:
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
# if _LIBCPP_STD_VER >= 14
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
return __tree_.find(__k);
}
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
return __tree_.find(__k);
}
@@ -839,7 +843,9 @@ public:
return __tree_.__count_unique(__k);
}
# if _LIBCPP_STD_VER >= 14
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
return __tree_.__count_multi(__k);
}
@@ -847,7 +853,9 @@ public:
# if _LIBCPP_STD_VER >= 20
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
return find(__k) != end();
}
@@ -864,12 +872,16 @@ public:
// The transparent versions of the lookup functions use the _multi version, since a non-element key is allowed to
// match multiple elements.
# if _LIBCPP_STD_VER >= 14
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
return __tree_.__lower_bound_multi(__k);
}
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
return __tree_.__lower_bound_multi(__k);
}
@@ -884,11 +896,15 @@ public:
}
# if _LIBCPP_STD_VER >= 14
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
return __tree_.__upper_bound_multi(__k);
}
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
return __tree_.__upper_bound_multi(__k);
}
@@ -901,11 +917,15 @@ public:
return __tree_.__equal_range_unique(__k);
}
# if _LIBCPP_STD_VER >= 14
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
return __tree_.__equal_range_multi(__k);
}
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
return __tree_.__equal_range_multi(__k);
}
@@ -1302,11 +1322,15 @@ public:
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
# if _LIBCPP_STD_VER >= 14
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
return __tree_.find(__k);
}
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
return __tree_.find(__k);
}
@@ -1316,7 +1340,9 @@ public:
return __tree_.__count_multi(__k);
}
# if _LIBCPP_STD_VER >= 14
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
return __tree_.__count_multi(__k);
}
@@ -1324,7 +1350,9 @@ public:
# if _LIBCPP_STD_VER >= 20
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
return find(__k) != end();
}
@@ -1339,12 +1367,16 @@ public:
}
# if _LIBCPP_STD_VER >= 14
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
return __tree_.__lower_bound_multi(__k);
}
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
return __tree_.__lower_bound_multi(__k);
}
@@ -1359,11 +1391,15 @@ public:
}
# if _LIBCPP_STD_VER >= 14
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
return __tree_.__upper_bound_multi(__k);
}
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
return __tree_.__upper_bound_multi(__k);
}
@@ -1376,11 +1412,15 @@ public:
return __tree_.__equal_range_multi(__k);
}
# if _LIBCPP_STD_VER >= 14
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
return __tree_.__equal_range_multi(__k);
}
- template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
+ template <typename _K2,
+ class _Comp = _Compare,
+ enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
return __tree_.__equal_range_multi(__k);
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/189735
More information about the libcxx-commits
mailing list