Implement LWG 2148: Make non-enum default hash specialization well-formed
Summary:
This patch removes the static_assert for non-enum types in the primary hash template. Instead non-enum types create a hash<T> specialization that is not constructible nor callable.
See also:
* http://cplusplus.github.io/LWG/lwg-active.html#2543
* https://llvm.org/bugs/show_bug.cgi?id=28917
Reviewers: mclow.lists, EricWF
Subscribers: mehdi_amini, cfe-commits
Differential Revision: https://reviews.llvm.org/D23331
llvm-svn: 278300
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 45b7b44867f75098c4235bda09fa088d0cb803f3
diff --git a/include/functional b/include/functional
index 2056ffe..db137d1 100644
--- a/include/functional
+++ b/include/functional
@@ -2574,12 +2574,11 @@
};
#if _LIBCPP_STD_VER > 11
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS_ONLY hash
+
+template <class _Tp, bool = is_enum<_Tp>::value>
+struct _LIBCPP_TYPE_VIS_ONLY __enum_hash
: public unary_function<_Tp, size_t>
{
- static_assert(is_enum<_Tp>::value, "This hash only works for enumeration types");
-
_LIBCPP_INLINE_VISIBILITY
size_t operator()(_Tp __v) const _NOEXCEPT
{
@@ -2587,6 +2586,17 @@
return hash<type>{}(static_cast<type>(__v));
}
};
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY __enum_hash<_Tp, false> {
+ __enum_hash() = delete;
+ __enum_hash(__enum_hash const&) = delete;
+ __enum_hash& operator=(__enum_hash const&) = delete;
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY hash : public __enum_hash<_Tp>
+{
+};
#endif