libstdc++: Fix std::unordered_set::emplace optimization [PR117686]

The __is_key_type specialization that matches a pair<key_type, T>
argument is intended for std::unordered_map, not for
std::unordered_set<std::pair<K,T>>.

This uses a pair<const Args&...> as the template argument for
__is_key_type, so that it won't match a set's key_type.

libstdc++-v3/ChangeLog:

	PR libstdc++/117686
	* include/bits/hashtable.h (_Hashtable::_M_emplace_uniq):
	Adjust usage of __is_key_type to avoid false positive.
	* testsuite/23_containers/unordered_set/insert/117686.cc:
	New test.
This commit is contained in:
Jonathan Wakely 2024-11-19 23:38:19 +00:00 committed by Jonathan Wakely
parent 7c7da10365
commit 4484945c53
No known key found for this signature in database
2 changed files with 18 additions and 2 deletions

View File

@ -2286,9 +2286,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
else if constexpr (sizeof...(_Args) == 2)
{
pair<const _Args&...> __refs(__args...);
if constexpr (__is_key_type<pair<_Args...>>)
if constexpr (__is_key_type<pair<const _Args&...>>)
{
pair<const _Args&...> __refs(__args...);
const auto& __key = _ExtractKey{}(__refs);
__kp = std::__addressof(__key);
}

View File

@ -0,0 +1,16 @@
// { dg-do compile { target c++11 } }
// Bug 117686 - error in unordered_set::emplace
#include <unordered_set>
#include <utility>
struct H {
std::size_t operator()(const std::pair<int, int>&) const { return 0; }
};
void
test_117686()
{
std::unordered_set<std::pair<int, int>, H> s;
s.emplace(1, 2);
}