gcc/libstdc++-v3/testsuite/20_util
Jonathan Wakely 01ba02caa9
libstdc++: Refactor std::hash specializations
This attempts to simplify and clean up our std::hash code. The primary
benefit is improved diagnostics for users when they do something wrong
involving std::hash or unordered containers. An additional benefit is
that for the unstable ABI (--enable-symvers=gnu-versioned-namespace) we
can reduce the memory footprint of several std::hash specializations.

In the current design, __hash_enum is a base class of the std::hash
primary template, but the partial specialization of __hash_enum for
non-enum types is disabled.  This means that if a user forgets to
specialize std::hash for their class type (or forgets to use a custom
hash function for unordered containers) they get error messages about
std::__hash_enum not being constructible.  This is confusing when there
is no enum type involved: why should users care about __hash_enum not
being constructible if they're not trying to hash enums?

This change makes the std::hash primary template only derive from
__hash_enum when the template argument type is an enum. Otherwise, it
derives directly from a new class template, __hash_not_enabled. This new
class template defines the deleted members that cause a given std::hash
specialization to be a disabled specialization (as per P0513R0). Now
when users try to use a disabled specialization, they get more
descriptive errors that mention __hash_not_enabled instead of
__hash_enum.

Additionally, adjust __hash_base to remove the deprecated result_type
and argument_type typedefs for C++20 and later.

In the current code we use a __poison_hash base class in the std::hash
specializations for std::unique_ptr, std::optional, and std::variant.
The primary template of __poison_hash has deleted special members, which
is used to conditionally disable the derived std::hash specialization.
This can also result in confusing diagnostics, because seeing "poison"
in an enabled specialization is misleading. Only some uses of
__poison_hash actually "poison" anything, i.e. cause a specialization to
be disabled. In other cases it's just an empty base class that does
nothing.

This change removes __poison_hash and changes the std::hash
specializations that were using it to conditionally derive from
__hash_not_enabled instead. When the std::hash specialization is
enabled, there is no more __poison_hash base class. However, to preserve
the ABI properties of those std::hash specializations, we need to
replace __poison_hash with some other empty base class. This is needed
because in the current code std::hash<std::variant<int, const int>> has
two __poison_hash<int> base classes, which must have unique addresses,
so sizeof(std::hash<std::variant<int, const int>>) == 2. To preserve
this unfortunate property, a new __hash_empty_base class is used as a
base class to re-introduce du0plicate base classes that increase the
class size. For the unstable ABI we don't use __hash_empty_base so the
std::hash<std::variant<T...>> specializations are always size 1, and
the class hierarchy is much simpler so will compile faster.

Additionally, remove the result_type and argument_type typedefs from all
disabled specializations of std::hash for std::unique_ptr,
std::optional, and std::variant. Those typedefs are useless for disabled
specializations, and although the standard doesn't say they must *not*
be present for disabled specializations, it certainly only requires them
for enabled specializations. Finally, for C++20 the typedefs are also
removed from enabled specializations of std::hash for std::unique_ptr,
std::optional, and std::variant.

libstdc++-v3/ChangeLog:

	* doc/xml/manual/evolution.xml: Document removal of nested types
	from std::hash specializations.
	* doc/html/manual/api.html: Regenerate.
	* include/bits/functional_hash.h (__hash_base): Remove
	deprecated nested types for C++20.
	(__hash_empty_base): Define new class template.
	(__is_hash_enabled_for): Define new variable template.
	(__poison_hash): Remove.
	(__hash_not_enabled): Define new class template.
	(__hash_enum): Remove partial specialization for non-enums.
	(hash): Derive from __hash_not_enabled for non-enums, instead of
	__hash_enum.
	* include/bits/unique_ptr.h (__uniq_ptr_hash): Derive from
	__hash_base. Conditionally derive from __hash_empty_base.
	(__uniq_ptr_hash<>): Remove disabled specialization.
	(hash): Do not derive from __hash_base unconditionally.
	Conditionally derive from either __uniq_ptr_hash or
	__hash_not_enabled.
	* include/std/optional (__optional_hash_call_base): Remove.
	(__optional_hash): Define new class template.
	(hash): Derive from either
	(hash): Conditionally derive from either __optional_hash or
	__hash_not_enabled. Remove nested typedefs.
	* include/std/variant (_Base_dedup): Replace __poison_hash with
	__hash_empty_base.
	(__variant_hash_call_base_impl): Remove.
	(__variant_hash): Define new class template.
	(hash): Conditionally derive from either __variant_hash or
	__hash_not_enabled. Remove nested typedefs.
	* testsuite/20_util/optional/hash.cc: Check whether nested types
	are present.
	* testsuite/20_util/variant/hash.cc: Likewise.
	* testsuite/20_util/optional/hash_abi.cc: New test.
	* testsuite/20_util/unique_ptr/hash/abi.cc: New test.
	* testsuite/20_util/unique_ptr/hash/types.cc: New test.
	* testsuite/20_util/variant/hash_abi.cc: New test.
2024-11-13 20:21:41 +00:00
..
add_const Update copyright years. 2024-01-03 12:19:35 +01:00
add_cv Update copyright years. 2024-01-03 12:19:35 +01:00
add_lvalue_reference Update copyright years. 2024-01-03 12:19:35 +01:00
add_pointer Update copyright years. 2024-01-03 12:19:35 +01:00
add_rvalue_reference Update copyright years. 2024-01-03 12:19:35 +01:00
add_volatile Update copyright years. 2024-01-03 12:19:35 +01:00
addressof Update copyright years. 2024-01-03 12:19:35 +01:00
align Update copyright years. 2024-01-03 12:19:35 +01:00
aligned_storage Update copyright years. 2024-01-03 12:19:35 +01:00
aligned_union Update copyright years. 2024-01-03 12:19:35 +01:00
alignment_of Update copyright years. 2024-01-03 12:19:35 +01:00
allocator libstdc++: Do not cast away const-ness in std::construct_at (LWG 3870) 2024-10-09 13:39:15 +01:00
allocator_traits libstdc++: Fix std::allocator_traits::construct constraints [PR108619] 2024-08-23 13:39:36 +01:00
any libstdc++: Simplify std::any to fix -Wdeprecated-declarations warning 2024-09-03 15:08:44 +01:00
as_const Update copyright years. 2024-01-03 12:19:35 +01:00
assume_aligned Update copyright years. 2024-01-03 12:19:35 +01:00
auto_ptr Update copyright years. 2024-01-03 12:19:35 +01:00
bad_function_call Update copyright years. 2024-01-03 12:19:35 +01:00
bind libstdc++: Fix test FAILs due to -Wreturn-local-addr 2024-09-27 16:28:12 +01:00
bitset libstdc++: Make std::vector<bool>::reference constructor private [PR115098] 2024-08-23 13:18:19 +01:00
bool_constant Update copyright years. 2024-01-03 12:19:35 +01:00
common_reference Update copyright years. 2024-01-03 12:19:35 +01:00
common_type/requirements Update copyright years. 2024-01-03 12:19:35 +01:00
conditional/requirements Update copyright years. 2024-01-03 12:19:35 +01:00
decay/requirements Update copyright years. 2024-01-03 12:19:35 +01:00
declval/requirements Update copyright years. 2024-01-03 12:19:35 +01:00
default_delete libstdc++: fix testcase regexp 2024-08-28 05:40:48 -04:00
duration libstdc++: Fix some test failures with -fno-char8_t 2024-10-11 07:52:36 +01:00
duration_cast Update copyright years. 2024-01-03 12:19:35 +01:00
enable_if/requirements Update copyright years. 2024-01-03 12:19:35 +01:00
enable_shared_from_this Update copyright years. 2024-01-03 12:19:35 +01:00
exchange Update copyright years. 2024-01-03 12:19:35 +01:00
expected libstdc++: Constrain std::expected comparisons (P3379R0) 2024-10-14 16:48:49 +01:00
extent Update copyright years. 2024-01-03 12:19:35 +01:00
forward Update copyright years. 2024-01-03 12:19:35 +01:00
forward_like libstdc++: use concrete return type for std::forward_like 2024-08-03 09:05:05 -04:00
from_chars [libstdc++] [testsuite] xfail double-prec from_chars for float128_t 2024-06-12 19:48:04 -03:00
function libstdc++: Make std::function deduction guide support explicit object functions [PR113335] 2024-02-02 13:54:02 +00:00
function_objects libstdc++: fix uses of explicit object parameter [PR116038] 2024-07-25 09:02:13 -04:00
has_unique_object_representations Update copyright years. 2024-01-03 12:19:35 +01:00
has_virtual_destructor Update copyright years. 2024-01-03 12:19:35 +01:00
hash libstdc++: Use dg-additional-files in some non-I/O tests 2024-07-24 12:25:26 +01:00
headers libstdc++: Add missing feature-test macro in various headers 2024-09-03 15:07:15 +01:00
in_place Update copyright years. 2024-01-03 12:19:35 +01:00
integer_comparisons libstdc++: Fix tests that fail with -fno-char8_t 2024-04-08 17:44:18 +01:00
integer_sequence Update copyright years. 2024-01-03 12:19:35 +01:00
integral_constant Update copyright years. 2024-01-03 12:19:35 +01:00
invoke_result Update copyright years. 2024-01-03 12:19:35 +01:00
is_abstract Update copyright years. 2024-01-03 12:19:35 +01:00
is_aggregate Update copyright years. 2024-01-03 12:19:35 +01:00
is_arithmetic Update copyright years. 2024-01-03 12:19:35 +01:00
is_array Update copyright years. 2024-01-03 12:19:35 +01:00
is_assignable Update copyright years. 2024-01-03 12:19:35 +01:00
is_base_of Update copyright years. 2024-01-03 12:19:35 +01:00
is_bounded_array Update copyright years. 2024-01-03 12:19:35 +01:00
is_class Update copyright years. 2024-01-03 12:19:35 +01:00
is_complete_or_unbounded Update copyright years. 2024-01-03 12:19:35 +01:00
is_compound Update copyright years. 2024-01-03 12:19:35 +01:00
is_const Update copyright years. 2024-01-03 12:19:35 +01:00
is_constant_evaluated Update copyright years. 2024-01-03 12:19:35 +01:00
is_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_convertible Update copyright years. 2024-01-03 12:19:35 +01:00
is_copy_assignable Update copyright years. 2024-01-03 12:19:35 +01:00
is_copy_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_default_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_destructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_empty Update copyright years. 2024-01-03 12:19:35 +01:00
is_enum Update copyright years. 2024-01-03 12:19:35 +01:00
is_final Update copyright years. 2024-01-03 12:19:35 +01:00
is_floating_point Update copyright years. 2024-01-03 12:19:35 +01:00
is_function Update copyright years. 2024-01-03 12:19:35 +01:00
is_fundamental Update copyright years. 2024-01-03 12:19:35 +01:00
is_implicitly_default_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_integral Update copyright years. 2024-01-03 12:19:35 +01:00
is_invocable libstdc++: Optimize std::is_invocable compilation performance 2024-06-13 05:56:53 -07:00
is_layout_compatible
is_literal_type Update copyright years. 2024-01-03 12:19:35 +01:00
is_lvalue_reference Update copyright years. 2024-01-03 12:19:35 +01:00
is_member_function_pointer Update copyright years. 2024-01-03 12:19:35 +01:00
is_member_object_pointer Update copyright years. 2024-01-03 12:19:35 +01:00
is_member_pointer Update copyright years. 2024-01-03 12:19:35 +01:00
is_move_assignable Update copyright years. 2024-01-03 12:19:35 +01:00
is_move_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_nothrow_assignable Update copyright years. 2024-01-03 12:19:35 +01:00
is_nothrow_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_nothrow_convertible Update copyright years. 2024-01-03 12:19:35 +01:00
is_nothrow_copy_assignable Update copyright years. 2024-01-03 12:19:35 +01:00
is_nothrow_copy_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_nothrow_default_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_nothrow_destructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_nothrow_invocable libstdc++: Optimize std::is_nothrow_invocable compilation performance 2024-06-13 05:57:01 -07:00
is_nothrow_move_assignable Update copyright years. 2024-01-03 12:19:35 +01:00
is_nothrow_move_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_nothrow_swappable Update copyright years. 2024-01-03 12:19:35 +01:00
is_nothrow_swappable_with Update copyright years. 2024-01-03 12:19:35 +01:00
is_null_pointer Update copyright years. 2024-01-03 12:19:35 +01:00
is_object Update copyright years. 2024-01-03 12:19:35 +01:00
is_pod Update copyright years. 2024-01-03 12:19:35 +01:00
is_pointer Update copyright years. 2024-01-03 12:19:35 +01:00
is_pointer_interconvertible
is_polymorphic Update copyright years. 2024-01-03 12:19:35 +01:00
is_reference Update copyright years. 2024-01-03 12:19:35 +01:00
is_rvalue_reference Update copyright years. 2024-01-03 12:19:35 +01:00
is_same Update copyright years. 2024-01-03 12:19:35 +01:00
is_scalar Update copyright years. 2024-01-03 12:19:35 +01:00
is_scoped_enum Update copyright years. 2024-01-03 12:19:35 +01:00
is_signed Update copyright years. 2024-01-03 12:19:35 +01:00
is_standard_layout Update copyright years. 2024-01-03 12:19:35 +01:00
is_swappable Update copyright years. 2024-01-03 12:19:35 +01:00
is_swappable_with Update copyright years. 2024-01-03 12:19:35 +01:00
is_trivial Update copyright years. 2024-01-03 12:19:35 +01:00
is_trivially_assignable Update copyright years. 2024-01-03 12:19:35 +01:00
is_trivially_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_trivially_copy_assignable Update copyright years. 2024-01-03 12:19:35 +01:00
is_trivially_copy_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_trivially_copyable Update copyright years. 2024-01-03 12:19:35 +01:00
is_trivially_default_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_trivially_destructible libstdc++: Optimize std::is_trivially_destructible_v 2024-01-07 00:58:45 +00:00
is_trivially_move_assignable Update copyright years. 2024-01-03 12:19:35 +01:00
is_trivially_move_constructible Update copyright years. 2024-01-03 12:19:35 +01:00
is_unbounded_array Update copyright years. 2024-01-03 12:19:35 +01:00
is_union Update copyright years. 2024-01-03 12:19:35 +01:00
is_unsigned Update copyright years. 2024-01-03 12:19:35 +01:00
is_virtual_base_of libstdc++: add std::is_virtual_base_of 2024-10-05 14:34:29 -04:00
is_void Update copyright years. 2024-01-03 12:19:35 +01:00
is_volatile Update copyright years. 2024-01-03 12:19:35 +01:00
logical_traits Update copyright years. 2024-01-03 12:19:35 +01:00
make_signed/requirements Update copyright years. 2024-01-03 12:19:35 +01:00
make_unsigned/requirements Update copyright years. 2024-01-03 12:19:35 +01:00
memory_resource Update copyright years. 2024-01-03 12:19:35 +01:00
monotonic_buffer_resource Update copyright years. 2024-01-03 12:19:35 +01:00
move Update copyright years. 2024-01-03 12:19:35 +01:00
move_if_noexcept Update copyright years. 2024-01-03 12:19:35 +01:00
move_only_function
nonesuch Update copyright years. 2024-01-03 12:19:35 +01:00
optional libstdc++: Refactor std::hash specializations 2024-11-13 20:21:41 +00:00
owner_less Update copyright years. 2024-01-03 12:19:35 +01:00
pair libstdc++: Constrain std::expected comparisons (P3379R0) 2024-10-14 16:48:49 +01:00
pointer_safety Update copyright years. 2024-01-03 12:19:35 +01:00
pointer_traits Update copyright years. 2024-01-03 12:19:35 +01:00
polymorphic_allocator Update copyright years. 2024-01-03 12:19:35 +01:00
rank Update copyright years. 2024-01-03 12:19:35 +01:00
ratio libstdc++: #ifdef out #pragma GCC system_header 2024-09-25 08:20:45 -04:00
raw_storage_iterator Update copyright years. 2024-01-03 12:19:35 +01:00
reference_from_temporary Update copyright years. 2024-01-03 12:19:35 +01:00
reference_wrapper libstdc++: Add std::reference_wrapper comparison operators for C++26 2024-04-15 19:26:09 +01:00
remove_all_extents Update copyright years. 2024-01-03 12:19:35 +01:00
remove_const Update copyright years. 2024-01-03 12:19:35 +01:00
remove_cv Update copyright years. 2024-01-03 12:19:35 +01:00
remove_cvref Update copyright years. 2024-01-03 12:19:35 +01:00
remove_extent Update copyright years. 2024-01-03 12:19:35 +01:00
remove_pointer Update copyright years. 2024-01-03 12:19:35 +01:00
remove_reference Update copyright years. 2024-01-03 12:19:35 +01:00
remove_volatile Update copyright years. 2024-01-03 12:19:35 +01:00
result_of Update copyright years. 2024-01-03 12:19:35 +01:00
scoped_allocator libstdc++: Add missing feature-test macro in various headers 2024-09-03 15:07:15 +01:00
shared_ptr Update copyright years. 2024-01-03 12:19:35 +01:00
smartptr.adapt libstdc++: Add test for LWG Issue 3897 2023-12-05 16:40:43 +00:00
specialized_algorithms libstdc++: Inline memmove optimizations for std::copy etc. [PR115444] 2024-10-18 14:49:34 +01:00
steady_clock Update copyright years. 2024-01-03 12:19:35 +01:00
synchronized_pool_resource Update copyright years. 2024-01-03 12:19:35 +01:00
system_clock Update copyright years. 2024-01-03 12:19:35 +01:00
time_point Update copyright years. 2024-01-03 12:19:35 +01:00
time_point_cast Update copyright years. 2024-01-03 12:19:35 +01:00
to_address libstdc++: Optimize std::to_address 2024-06-07 10:26:18 +01:00
to_chars [libstdc++] [testsuite] xfail double-prec from_chars for float128_t 2024-06-12 19:48:04 -03:00
to_underlying Update copyright years. 2024-01-03 12:19:35 +01:00
tuple libstdc++: Constrain std::expected comparisons (P3379R0) 2024-10-14 16:48:49 +01:00
type_identity/requirements Update copyright years. 2024-01-03 12:19:35 +01:00
typeindex Update copyright years. 2024-01-03 12:19:35 +01:00
underlying_type/requirements Update copyright years. 2024-01-03 12:19:35 +01:00
unique_ptr libstdc++: Refactor std::hash specializations 2024-11-13 20:21:41 +00:00
unreachable
unsynchronized_pool_resource Update copyright years. 2024-01-03 12:19:35 +01:00
unwrap_reference Update copyright years. 2024-01-03 12:19:35 +01:00
uses_allocator Update copyright years. 2024-01-03 12:19:35 +01:00
variant libstdc++: Refactor std::hash specializations 2024-11-13 20:21:41 +00:00
void_t Update copyright years. 2024-01-03 12:19:35 +01:00
weak_ptr Update copyright years. 2024-01-03 12:19:35 +01:00
rel_ops.cc Update copyright years. 2024-01-03 12:19:35 +01:00
temporary_buffer.cc libstdc++: Handle extended alignment in std::get_temporary_buffer [PR105258] 2024-06-03 21:17:54 +01:00
variable_templates_for_traits.cc Update copyright years. 2024-01-03 12:19:35 +01:00