diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv --- a/libcxx/docs/Status/Cxx2bIssues.csv +++ b/libcxx/docs/Status/Cxx2bIssues.csv @@ -155,7 +155,7 @@ "`3649 `__","[fund.ts.v2] Reinstate and bump ``__cpp_lib_experimental_memory_resource`` feature test macro","February 2022","","" "`3650 `__","Are ``std::basic_string`` 's ``iterator`` and ``const_iterator`` constexpr iterators?","February 2022","|Nothing to do|","" "`3654 `__","``basic_format_context::arg(size_t)`` should be ``noexcept`` ","February 2022","|Complete|","15.0","|format|" -"`3657 `__","``std::hash`` is not enabled","February 2022","","" +"`3657 `__","``std::hash`` is not enabled","February 2022","|Complete|","17.0" "`3660 `__","``iterator_traits::pointer`` should conform to ยง[iterator.traits]","February 2022","|Complete|","14.0","|ranges|" "`3661 `__","``constinit atomic> a(nullptr);`` should work","February 2022","","" "","","","","","" diff --git a/libcxx/include/__filesystem/path.h b/libcxx/include/__filesystem/path.h --- a/libcxx/include/__filesystem/path.h +++ b/libcxx/include/__filesystem/path.h @@ -14,6 +14,8 @@ #include <__algorithm/replace_copy.h> #include <__availability> #include <__config> +#include <__functional/unary_function.h> +#include <__fwd/hash.h> #include <__iterator/back_insert_iterator.h> #include <__iterator/iterator_traits.h> #include @@ -1086,6 +1088,17 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM +_LIBCPP_BEGIN_NAMESPACE_STD + +template <> +struct _LIBCPP_AVAILABILITY_FILESYSTEM hash<_VSTD_FS::path> : __unary_function<_VSTD_FS::path, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_VSTD_FS::path const& __p) const noexcept { + return _VSTD_FS::hash_value(__p); + } +}; + +_LIBCPP_END_NAMESPACE_STD + #endif // _LIBCPP_CXX03_LANG #endif // _LIBCPP___FILESYSTEM_PATH_H diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem --- a/libcxx/include/filesystem +++ b/libcxx/include/filesystem @@ -159,6 +159,9 @@ void swap(path& lhs, path& rhs) noexcept; size_t hash_value(const path& p) noexcept; + // [fs.path.hash], hash support + template<> struct hash; + template path u8path(const Source& source); template diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp --- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp @@ -134,6 +134,14 @@ ASSERT_SAME_TYPE(size_t, decltype(hash_value(p1))); ASSERT_NOEXCEPT(hash_value(p1)); } + { // check std::hash + auto h1 = std::hash()(p1); + auto h2 = std::hash()(p2); + assert((h1 == h2) == (p1 == p2)); + // check signature + ASSERT_SAME_TYPE(size_t, decltype(std::hash()(p1))); + ASSERT_NOEXCEPT(std::hash()(p1)); + } } } diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash.tested_elswhere.compile.pass.cpp rename from libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp rename to libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash.tested_elswhere.compile.pass.cpp --- a/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash.tested_elswhere.compile.pass.cpp @@ -6,10 +6,5 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03 - -// The "hash_value" function is tested as part of [path.compare] -// in class.path/path.members/path.compare.pass.cpp -int main(int, char**) { - return 0; -} +// The std::hash specialization is tested as part of [path.compare] +// in libcxx/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash_value.tested_elswhere.compile.pass.cpp rename from libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp rename to libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash_value.tested_elswhere.compile.pass.cpp --- a/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash_value.tested_elswhere.compile.pass.cpp @@ -6,10 +6,5 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03 - -// The "hash_value" function is tested as part of [path.compare] -// in class.path/path.members/path.compare.pass.cpp -int main(int, char**) { - return 0; -} +// The `hash_value` function is tested as part of [path.compare] +// in libcxx/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp