LWG Issue 2148: Hashing Enums
llvm-svn: 189831
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 5155a569d184fb2648000bb2a2bde843bf300961
diff --git a/include/functional b/include/functional
index 1486a8e..fdb8e0f 100644
--- a/include/functional
+++ b/include/functional
@@ -2399,6 +2399,22 @@
}
};
+#if _LIBCPP_STD_VER > 11
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY 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
+ {
+ typedef typename underlying_type<_Tp>::type type;
+ return hash<type>{}(static_cast<type>(__v));
+ }
+};
+#endif
+
// struct hash<T*> in <memory>
_LIBCPP_END_NAMESPACE_STD
diff --git a/test/utilities/function.objects/unord.hash/enum.fail.cpp b/test/utilities/function.objects/unord.hash/enum.fail.cpp
new file mode 100644
index 0000000..9e44bfb
--- /dev/null
+++ b/test/utilities/function.objects/unord.hash/enum.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// Hashing a struct w/o a defined hash should fail.
+
+#include <functional>
+#include <cassert>
+#include <type_traits>
+
+struct X {};
+
+int main()
+{
+ X x;
+ size_t h = std::hash<X>{} ( x );
+}
diff --git a/test/utilities/function.objects/unord.hash/enum.pass.cpp b/test/utilities/function.objects/unord.hash/enum.pass.cpp
new file mode 100644
index 0000000..b5cd6f8
--- /dev/null
+++ b/test/utilities/function.objects/unord.hash/enum.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// make sure that we can hash enumeration values
+// Not very portable
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <functional>
+#include <cassert>
+#include <type_traits>
+#include <limits>
+
+enum class Colors { red, orange, yellow, green, blue, indigo, violet };
+enum class Cardinals { zero, one, two, three, five=5 };
+enum class LongColors : short { red, orange, yellow, green, blue, indigo, violet };
+enum class ShortColors : long { red, orange, yellow, green, blue, indigo, violet };
+enum class EightBitColors : uint8_t { red, orange, yellow, green, blue, indigo, violet };
+
+enum Fruits { apple, pear, grape, mango, cantaloupe };
+
+template <class T>
+void
+test()
+{
+ static_assert((std::is_base_of<std::unary_function<T, std::size_t>,
+ std::hash<T> >::value), "");
+ typedef typename std::underlying_type<T>::type under_type;
+
+ std::hash<T> h1;
+ std::hash<under_type> h2;
+ for (int i = 0; i <= 5; ++i)
+ {
+ T t(static_cast<T> (i));
+ if (sizeof(T) <= sizeof(std::size_t))
+ assert(h1(t) == h2(static_cast<under_type>(i)));
+ }
+}
+
+int main()
+{
+ test<Cardinals>();
+
+ test<Colors>();
+ test<ShortColors>();
+ test<LongColors>();
+ test<EightBitColors>();
+
+ test<Fruits>();
+}
+#else
+int main () {}
+#endif
diff --git a/www/cxx1y_status.html b/www/cxx1y_status.html
index 3c46244..afd51eb 100644
--- a/www/cxx1y_status.html
+++ b/www/cxx1y_status.html
@@ -145,7 +145,7 @@
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2128">2128</a></td><td>Absence of global functions cbegin/cend</td><td>Bristol</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2145">2145</a></td><td>error_category default constructor</td><td>Bristol</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2147">2147</a></td><td>Unclear hint type in Allocator's allocate function</td><td>Bristol</td><td>Complete</td></tr>
- <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2148">2148</a></td><td>Hashing enums should be supported directly by std::hash</td><td>Bristol</td><td></td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2148">2148</a></td><td>Hashing enums should be supported directly by std::hash</td><td>Bristol</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2149">2149</a></td><td>Concerns about 20.8/5</td><td>Bristol</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2162">2162</a></td><td>allocator_traits::max_size missing noexcept</td><td>Bristol</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2163">2163</a></td><td>nth_element requires inconsistent post-conditions</td><td>Bristol</td><td>Complete</td></tr>