diff --git a/include/functional b/include/functional index 1486a8e0..fdb8e0f2 100644 --- a/include/functional +++ b/include/functional @@ -2399,6 +2399,22 @@ struct _LIBCPP_TYPE_VIS_ONLY hash } }; +#if _LIBCPP_STD_VER > 11 +template +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{}(static_cast(__v)); + } +}; +#endif + // struct hash in _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 00000000..9e44bfb7 --- /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. +// +//===----------------------------------------------------------------------===// + +// + +// Hashing a struct w/o a defined hash should fail. + +#include +#include +#include + +struct X {}; + +int main() +{ + X x; + size_t h = std::hash{} ( 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 00000000..b5cd6f84 --- /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. +// +//===----------------------------------------------------------------------===// + +// + +// make sure that we can hash enumeration values +// Not very portable + +#include <__config> + +#if _LIBCPP_STD_VER > 11 + +#include +#include +#include +#include + +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 +void +test() +{ + static_assert((std::is_base_of, + std::hash >::value), ""); + typedef typename std::underlying_type::type under_type; + + std::hash h1; + std::hash h2; + for (int i = 0; i <= 5; ++i) + { + T t(static_cast (i)); + if (sizeof(T) <= sizeof(std::size_t)) + assert(h1(t) == h2(static_cast(i))); + } +} + +int main() +{ + test(); + + test(); + test(); + test(); + test(); + + test(); +} +#else +int main () {} +#endif diff --git a/www/cxx1y_status.html b/www/cxx1y_status.html index 3c46244f..afd51eba 100644 --- a/www/cxx1y_status.html +++ b/www/cxx1y_status.html @@ -145,7 +145,7 @@ 2128Absence of global functions cbegin/cendBristolComplete 2145error_category default constructorBristolComplete 2147Unclear hint type in Allocator's allocate functionBristolComplete - 2148Hashing enums should be supported directly by std::hashBristol + 2148Hashing enums should be supported directly by std::hashBristolComplete 2149Concerns about 20.8/5BristolComplete 2162allocator_traits::max_size missing noexceptBristolComplete 2163nth_element requires inconsistent post-conditionsBristolComplete