Index: libcxx/include/functional =================================================================== --- libcxx/include/functional +++ libcxx/include/functional @@ -470,6 +470,7 @@ template <> struct hash; template <> struct hash; template <> struct hash; +template <> struct hash; // since C++20 template <> struct hash; template <> struct hash; template <> struct hash; Index: libcxx/include/utility =================================================================== --- libcxx/include/utility +++ libcxx/include/utility @@ -1364,6 +1364,16 @@ size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast(__v);} }; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +template <> +struct _LIBCPP_TEMPLATE_VIS hash + : public unary_function +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast(__v);} +}; +#endif // !_LIBCPP_NO_HAS_CHAR8_T + #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS template <> Index: libcxx/test/libcxx/extensions/hash/specializations.pass.cpp =================================================================== --- libcxx/test/libcxx/extensions/hash/specializations.pass.cpp +++ libcxx/test/libcxx/extensions/hash/specializations.pass.cpp @@ -23,6 +23,9 @@ assert(__gnu_cxx::hash()(42) == 42); assert(__gnu_cxx::hash()(42) == 42); assert(__gnu_cxx::hash()(42) == 42); + #ifdef __cpp_lib_char8_t && __cpp_lib_char8_t >= 201907L + assert(__gnu_cxx::hash()(42) == 42); + #endif // __cpp_lib_char8_t assert(__gnu_cxx::hash()(42) == 42); assert(__gnu_cxx::hash()(42) == 42); assert(__gnu_cxx::hash()(42) == 42);