[libc++] Fix uses of non-empty transparent comparator in <map> (#152624)
The `__get_value()` member function was removed in LLVM 21, but the calls in `<map>` weren't removed. This patch completes the removal and adds regression test cases. Fixes #152543. (cherry picked from commit 7ae1424286203e37f6238e9349b1bfbe873ebabf)
This commit is contained in:
parent
ba87d05c55
commit
c092e2af14
@ -692,12 +692,12 @@ public:
|
||||
# if _LIBCPP_STD_VER >= 14
|
||||
template <typename _K2>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const {
|
||||
return __comp_(__x, __y.__get_value().first);
|
||||
return __comp_(__x, __y.first);
|
||||
}
|
||||
|
||||
template <typename _K2>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const {
|
||||
return __comp_(__x.__get_value().first, __y);
|
||||
return __comp_(__x.first, __y);
|
||||
}
|
||||
# endif
|
||||
};
|
||||
|
||||
@ -33,6 +33,10 @@ int main(int, char**) {
|
||||
typedef std::map<int, double, transparent_less_not_referenceable> M;
|
||||
assert(M().count(C2Int{5}) == 0);
|
||||
}
|
||||
{
|
||||
using M = std::map<int, double, transparent_less_nonempty>;
|
||||
assert(M().count(C2Int{5}) == 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -40,6 +40,13 @@ int main(int, char**) {
|
||||
P result = example.equal_range(C2Int{5});
|
||||
assert(result.first == result.second);
|
||||
}
|
||||
{
|
||||
using M = std::map<int, double, transparent_less_nonempty>;
|
||||
using P = std::pair<typename M::iterator, typename M::iterator>;
|
||||
M example;
|
||||
P result = example.equal_range(C2Int{5});
|
||||
assert(result.first == result.second);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -36,6 +36,11 @@ int main(int, char**) {
|
||||
M example;
|
||||
assert(example.find(C2Int{5}) == example.end());
|
||||
}
|
||||
{
|
||||
using M = std::map<int, double, transparent_less_nonempty>;
|
||||
M example;
|
||||
assert(example.find(C2Int{5}) == example.end());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -36,6 +36,11 @@ int main(int, char**) {
|
||||
M example;
|
||||
assert(example.lower_bound(C2Int{5}) == example.end());
|
||||
}
|
||||
{
|
||||
using M = std::map<int, double, transparent_less_nonempty>;
|
||||
M example;
|
||||
assert(example.lower_bound(C2Int{5}) == example.end());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -36,6 +36,11 @@ int main(int, char**) {
|
||||
M example;
|
||||
assert(example.upper_bound(C2Int{5}) == example.end());
|
||||
}
|
||||
{
|
||||
using M = std::map<int, double, transparent_less_nonempty>;
|
||||
M example;
|
||||
assert(example.upper_bound(C2Int{5}) == example.end());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -33,6 +33,10 @@ int main(int, char**) {
|
||||
typedef std::multimap<int, double, transparent_less_not_referenceable> M;
|
||||
assert(M().count(C2Int{5}) == 0);
|
||||
}
|
||||
{
|
||||
using M = std::multimap<int, double, transparent_less_nonempty>;
|
||||
assert(M().count(C2Int{5}) == 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -40,6 +40,13 @@ int main(int, char**) {
|
||||
P result = example.equal_range(C2Int{5});
|
||||
assert(result.first == result.second);
|
||||
}
|
||||
{
|
||||
using M = std::multimap<int, double, transparent_less_nonempty>;
|
||||
using P = std::pair<typename M::iterator, typename M::iterator>;
|
||||
M example;
|
||||
P result = example.equal_range(C2Int{5});
|
||||
assert(result.first == result.second);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -36,6 +36,11 @@ int main(int, char**) {
|
||||
M example;
|
||||
assert(example.find(C2Int{5}) == example.end());
|
||||
}
|
||||
{
|
||||
using M = std::multimap<int, double, transparent_less_nonempty>;
|
||||
M example;
|
||||
assert(example.find(C2Int{5}) == example.end());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -36,6 +36,11 @@ int main(int, char**) {
|
||||
M example;
|
||||
assert(example.lower_bound(C2Int{5}) == example.end());
|
||||
}
|
||||
{
|
||||
using M = std::multimap<int, double, transparent_less_nonempty>;
|
||||
M example;
|
||||
assert(example.lower_bound(C2Int{5}) == example.end());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -36,6 +36,11 @@ int main(int, char**) {
|
||||
M example;
|
||||
assert(example.upper_bound(C2Int{5}) == example.end());
|
||||
}
|
||||
{
|
||||
using M = std::multimap<int, double, transparent_less_nonempty>;
|
||||
M example;
|
||||
assert(example.upper_bound(C2Int{5}) == example.end());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -36,6 +36,17 @@ struct transparent_less_not_referenceable
|
||||
using is_transparent = void () const &; // it's a type; a weird one, but a type
|
||||
};
|
||||
|
||||
// Prevent regression when empty base class optimization is not suitable.
|
||||
// See https://github.com/llvm/llvm-project/issues/152543.
|
||||
struct transparent_less_nonempty {
|
||||
template <class T, class U>
|
||||
constexpr bool operator()(T&& t, U&& u) const {
|
||||
return std::forward<T>(t) < std::forward<U>(u);
|
||||
}
|
||||
struct is_transparent {
|
||||
} pad_; // making this comparator non-empty
|
||||
};
|
||||
|
||||
struct transparent_less_no_type
|
||||
{
|
||||
template <class T, class U>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user