diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 5937d4fdc9e1a..26c85f2284e2f 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -421,7 +421,6 @@ namespace std */ #include <__config> -#include <__fwd/functional.h> // This is https://llvm.org/PR56938 #include <__type_traits/add_const.h> #include <__type_traits/add_cv.h> #include <__type_traits/add_lvalue_reference.h> diff --git a/libcxx/test/std/containers/sequences/vector.bool/enabled_hash.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/enabled_hash.pass.cpp index d89984a4a30ba..66361202f8c00 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/enabled_hash.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/enabled_hash.pass.cpp @@ -20,8 +20,8 @@ #include "min_allocator.h" TEST_CONSTEXPR_CXX20 bool test() { - test_hash_enabled_for_type >(); - test_hash_enabled_for_type>>(); + test_hash_enabled >(); + test_hash_enabled>>(); return true; } diff --git a/libcxx/test/std/diagnostics/syserr/syserr.hash/enabled_hash.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.hash/enabled_hash.pass.cpp index 2aab69883174a..e3eae8bfa46bb 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.hash/enabled_hash.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.hash/enabled_hash.pass.cpp @@ -22,8 +22,8 @@ int main(int, char**) { test_library_hash_specializations_available(); { - test_hash_enabled_for_type(); - test_hash_enabled_for_type(); + test_hash_enabled(); + test_hash_enabled(); } return 0; diff --git a/libcxx/test/std/experimental/memory/memory.observer.ptr/hash.pass.cpp b/libcxx/test/std/experimental/memory/memory.observer.ptr/hash.pass.cpp index 7aa5dc8d5b326..fff5f9bae0733 100644 --- a/libcxx/test/std/experimental/memory/memory.observer.ptr/hash.pass.cpp +++ b/libcxx/test/std/experimental/memory/memory.observer.ptr/hash.pass.cpp @@ -33,7 +33,7 @@ void test_hash() { assert(h == std::hash()(&obj)); } - test_hash_enabled_for_type>(); + test_hash_enabled>(); } struct Bar {}; diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.hash_enabled.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.hash_enabled.pass.cpp index dd28c8f4f9b3d..6cc64e1857d99 100644 --- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.hash_enabled.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.hash_enabled.pass.cpp @@ -20,7 +20,7 @@ namespace fs = std::filesystem; int main(int, char**) { test_library_hash_specializations_available(); - test_hash_enabled_for_type(); + test_hash_enabled(); return 0; } diff --git a/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp b/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp index 611f95f0d3ef6..643c6bec637ae 100644 --- a/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp +++ b/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp @@ -53,18 +53,18 @@ struct std::char_traits { int main(int, char**) { test_library_hash_specializations_available(); { - test_hash_enabled_for_type(); + test_hash_enabled(); #ifndef TEST_HAS_NO_WIDE_CHARACTERS - test_hash_enabled_for_type(); + test_hash_enabled(); #endif #ifndef TEST_HAS_NO_CHAR8_T - test_hash_enabled_for_type(); + test_hash_enabled(); #endif - test_hash_enabled_for_type(); - test_hash_enabled_for_type(); - test_hash_enabled_for_type, test_allocator>>(); - test_hash_disabled_for_type, std::allocator>>(); - test_hash_disabled_for_type, std::allocator>>(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_enabled, test_allocator>>(); + test_hash_disabled, std::allocator>>(); + test_hash_disabled, std::allocator>>(); } return 0; diff --git a/libcxx/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp b/libcxx/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp index b2ffd20108389..13abb94569368 100644 --- a/libcxx/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp +++ b/libcxx/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp @@ -53,17 +53,17 @@ struct std::char_traits { int main(int, char**) { test_library_hash_specializations_available(); { - test_hash_enabled_for_type(); + test_hash_enabled(); #ifndef TEST_HAS_NO_WIDE_CHARACTERS - test_hash_enabled_for_type(); + test_hash_enabled(); #endif #ifndef TEST_HAS_NO_CHAR8_T - test_hash_enabled_for_type(); + test_hash_enabled(); #endif - test_hash_enabled_for_type(); - test_hash_enabled_for_type(); - test_hash_disabled_for_type>>(); - test_hash_disabled_for_type>>(); + test_hash_enabled(); + test_hash_enabled(); + test_hash_disabled>>(); + test_hash_disabled>>(); } return 0; diff --git a/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/enabled_hashes.pass.cpp b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/enabled_hashes.pass.cpp index 62c8c7476ab7e..98caff904916a 100644 --- a/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/enabled_hashes.pass.cpp +++ b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/enabled_hashes.pass.cpp @@ -24,7 +24,7 @@ int main(int, char**) { test_library_hash_specializations_available(); { - test_hash_enabled_for_type(); + test_hash_enabled(); } return 0; diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_shared_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_shared_ptr.pass.cpp index 0c3915bf48041..c6d54a82fecaa 100644 --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_shared_ptr.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_shared_ptr.pass.cpp @@ -40,8 +40,8 @@ int main(int, char**) } #if TEST_STD_VER >= 11 { - test_hash_enabled_for_type>(); - test_hash_enabled_for_type>(); + test_hash_enabled>(); + test_hash_enabled>(); } #endif diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp index 707038e53ed10..32fc949354c69 100644 --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp @@ -35,16 +35,16 @@ void test_enabled_with_deleter() { using RawDel = typename std::decay::type; RawDel d(1); UPtr p(nullptr, std::forward(d)); - test_hash_enabled_for_type(p); - test_hash_enabled_for_type(); + test_hash_enabled(p); + test_hash_enabled(); } template void test_disabled_with_deleter() { using UPtr = std::unique_ptr; using pointer = typename UPtr::pointer; - test_hash_disabled_for_type(); - test_hash_disabled_for_type(); + test_hash_disabled(); + test_hash_disabled(); } template diff --git a/libcxx/test/std/utilities/optional/optional.hash/hash.pass.cpp b/libcxx/test/std/utilities/optional/optional.hash/hash.pass.cpp index ae14b571f7388..54cf40740835d 100644 --- a/libcxx/test/std/utilities/optional/optional.hash/hash.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.hash/hash.pass.cpp @@ -63,16 +63,16 @@ int main(int, char**) assert(std::hash>{}(opt) == std::hash{}(*opt)); } { - test_hash_enabled_for_type >(); - test_hash_enabled_for_type >(); - test_hash_enabled_for_type >(); - test_hash_enabled_for_type >(); + test_hash_enabled >(); + test_hash_enabled >(); + test_hash_enabled >(); + test_hash_enabled >(); - test_hash_disabled_for_type>(); - test_hash_disabled_for_type>(); + test_hash_disabled>(); + test_hash_disabled>(); - test_hash_enabled_for_type>(); - test_hash_enabled_for_type>(); + test_hash_enabled>(); + test_hash_enabled>(); } return 0; diff --git a/libcxx/test/std/utilities/template.bitset/bitset.hash/enabled_hash.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.hash/enabled_hash.pass.cpp index 0e34a5f97897b..c2dc2ca893563 100644 --- a/libcxx/test/std/utilities/template.bitset/bitset.hash/enabled_hash.pass.cpp +++ b/libcxx/test/std/utilities/template.bitset/bitset.hash/enabled_hash.pass.cpp @@ -22,10 +22,10 @@ int main(int, char**) { test_library_hash_specializations_available(); { - test_hash_enabled_for_type >(); - test_hash_enabled_for_type >(); - test_hash_enabled_for_type >(); - test_hash_enabled_for_type >(); + test_hash_enabled >(); + test_hash_enabled >(); + test_hash_enabled >(); + test_hash_enabled >(); } return 0; diff --git a/libcxx/test/std/utilities/type.index/type.index.synopsis/hash_type_index.pass.cpp b/libcxx/test/std/utilities/type.index/type.index.synopsis/hash_type_index.pass.cpp index a36175875b695..9c0de17837e6f 100644 --- a/libcxx/test/std/utilities/type.index/type.index.synopsis/hash_type_index.pass.cpp +++ b/libcxx/test/std/utilities/type.index/type.index.synopsis/hash_type_index.pass.cpp @@ -34,7 +34,7 @@ int main(int, char**) } #if TEST_STD_VER >= 11 { - test_hash_enabled_for_type(std::type_index(typeid(int))); + test_hash_enabled(std::type_index(typeid(int))); } #endif diff --git a/libcxx/test/std/utilities/variant/variant.hash/hash.pass.cpp b/libcxx/test/std/utilities/variant/variant.hash/hash.pass.cpp index ffd5f8266ec2b..656b1d83c58c6 100644 --- a/libcxx/test/std/utilities/variant/variant.hash/hash.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.hash/hash.pass.cpp @@ -103,7 +103,7 @@ void test_hash_monostate() { static_assert(std::is_copy_constructible::value, ""); } { - test_hash_enabled_for_type(); + test_hash_enabled(); } } @@ -131,16 +131,16 @@ struct std::hash { void test_hash_variant_enabled() { { - test_hash_enabled_for_type >(); - test_hash_enabled_for_type >(); + test_hash_enabled >(); + test_hash_enabled >(); } { - test_hash_disabled_for_type>(); - test_hash_disabled_for_type>(); + test_hash_disabled>(); + test_hash_disabled>(); } { - test_hash_enabled_for_type>(); - test_hash_enabled_for_type>(); + test_hash_enabled>(); + test_hash_enabled>(); } } diff --git a/libcxx/test/support/poisoned_hash_helper.h b/libcxx/test/support/poisoned_hash_helper.h index a073350c1470e..93b579d2dfde3 100644 --- a/libcxx/test/support/poisoned_hash_helper.h +++ b/libcxx/test/support/poisoned_hash_helper.h @@ -10,131 +10,47 @@ #ifndef SUPPORT_POISONED_HASH_HELPER_H #define SUPPORT_POISONED_HASH_HELPER_H +#include #include #include #include #include #include "test_macros.h" -#include "test_workarounds.h" +#include "type_algorithms.h" -#if TEST_STD_VER < 11 -#error this header may only be used in C++11 or newer -#endif - -template struct TypeList; - -// Test that the specified Hash meets the requirements of an enabled hash -template -TEST_CONSTEXPR_CXX20 void test_hash_enabled(InputKey const& key = InputKey{}); - -template -TEST_CONSTEXPR_CXX20 void test_hash_enabled_for_type(InputKey const& key = InputKey{}) { - return test_hash_enabled, T, InputKey>(key); +template ()(std::declval()))> +constexpr bool can_hash_impl(int) { + return std::is_same::value; } - -// Test that the specified Hash meets the requirements of a disabled hash. -template -void test_hash_disabled(); - -template -void test_hash_disabled_for_type() { - return test_hash_disabled, T>(); +template +constexpr bool can_hash_impl(long) { + return false; } - -namespace PoisonedHashDetail { - enum Enum {}; - enum EnumClass : bool {}; - struct Class {}; +template +constexpr bool can_hash() { + return can_hash_impl(0); } -// Each header that declares the template hash provides enabled -// specializations of hash for nullptr t and all cv-unqualified -// arithmetic, enumeration, and pointer types. -using LibraryHashTypes = TypeList< -#if TEST_STD_VER > 14 - decltype(nullptr), -#endif - bool, - char, - signed char, - unsigned char, -#ifndef TEST_HAS_NO_WIDE_CHARACTERS - wchar_t, -#endif - char16_t, - char32_t, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - unsigned long long, -#ifndef TEST_HAS_NO_INT128 - __int128_t, - __uint128_t, -#endif - float, - double, - long double, - PoisonedHashDetail::Enum, - PoisonedHashDetail::EnumClass, - void*, - void const*, - PoisonedHashDetail::Class* - >; - - -// Test that each of the library hash specializations for arithmetic types, -// enum types, and pointer types are available and enabled. -template -void test_library_hash_specializations_available(Types = Types{}); - - -namespace PoisonedHashDetail { - -template -constexpr bool instantiate(int) { return true; } -template constexpr bool instantiate(long) { return true; } -template constexpr bool instantiate() { return instantiate(0); } - template struct ConvertibleToSimple { - operator To() const { - return To{}; - } + operator To() const { return To{}; } }; template struct ConvertibleTo { To to{}; operator To&() & { return to; } - operator To const&() const & { return to; } + operator To const&() const& { return to; } operator To&&() && { return std::move(to); } - operator To const&&() const && { return std::move(to); } + operator To const&&() const&& { return std::move(to); } }; -template ()(std::declval()))> -constexpr bool can_hash(int) { - return std::is_same::value; -} -template -constexpr bool can_hash(long) { - return false; -} -template -constexpr bool can_hash() { - return can_hash(0); -} -} // namespace PoisonedHashDetail - -template -TEST_CONSTEXPR_CXX20 void test_hash_enabled(InputKey const& key) { - using namespace PoisonedHashDetail; - +// Test that the specified Hash meets the requirements of an enabled hash +template > +TEST_CONSTEXPR_CXX20 void test_hash_enabled(Key const& key = Key{}) { static_assert(std::is_destructible::value, ""); + // Enabled hash requirements static_assert(std::is_default_constructible::value, ""); static_assert(std::is_copy_constructible::value, ""); @@ -167,13 +83,11 @@ TEST_CONSTEXPR_CXX20 void test_hash_enabled(InputKey const& key) { const Hash h{}; assert(h(key) == h(key)); - } -template +// Test that the specified Hash meets the requirements of a disabled hash. +template > void test_hash_disabled() { - using namespace PoisonedHashDetail; - // Disabled hash requirements static_assert(!std::is_default_constructible::value, ""); static_assert(!std::is_copy_constructible::value, ""); @@ -181,11 +95,8 @@ void test_hash_disabled() { static_assert(!std::is_copy_assignable::value, ""); static_assert(!std::is_move_assignable::value, ""); - static_assert(!std::is_function< - typename std::remove_pointer< - typename std::remove_reference::type - >::type - >::value, ""); + static_assert( + !std::is_function::type>::type>::value, ""); // Hashable requirements static_assert(!can_hash(), ""); @@ -205,41 +116,33 @@ void test_hash_disabled() { static_assert(!can_hash const&&>(), ""); } +enum Enum {}; +enum EnumClass : bool {}; +struct Class {}; -template -struct TypeList { - template