libstdc++: Ensure std::hash<__int128> is defined [PR96710]

This is a follow-up to r16-2190-g4faa42ac0dee2c which ensures that
std::hash is always enabled for signed and unsigned __int128. The
standard requires std::hash to be enabled for all arithmetic types.

libstdc++-v3/ChangeLog:

	PR libstdc++/96710
	* include/bits/functional_hash.h (hash<__int128>): Define for
	strict modes.
	(hash<unsigned __int128>): Likewise.
	* testsuite/20_util/hash/int128.cc: New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
This commit is contained in:
Jonathan Wakely
2025-05-16 13:33:23 +01:00
committed by Jonathan Wakely
parent c386f9ffbf
commit 57b9afc9da
2 changed files with 29 additions and 0 deletions

View File

@@ -199,6 +199,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_3 unsigned)
#endif
#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
// In strict modes __GLIBCXX_TYPE_INT_N_0 is not defined for __int128,
// but we want to always treat signed/unsigned __int128 as integral types.
__extension__
_Cxx_hashtable_define_trivial_hash(__int128)
__extension__
_Cxx_hashtable_define_trivial_hash(__int128 unsigned)
#endif
#undef _Cxx_hashtable_define_trivial_hash
struct _Hash_impl

View File

@@ -0,0 +1,20 @@
// { dg-do run { target c++11 } }
// { dg-add-options strict_std }
#include <functional>
#include <testsuite_hooks.h>
int main()
{
#ifdef __SIZEOF_INT128__
std::hash<__int128> h;
__int128 i = (__int128)0x123456789;
VERIFY( h(i) == i );
VERIFY( h(-i) == (std::size_t)-i );
VERIFY( h(~i) == (std::size_t)~i );
std::hash<unsigned __int128> hu;
unsigned __int128 u = i;
VERIFY( hu(u) == u );
VERIFY( hu(~u) == (std::size_t)~u );
#endif
}