From 1cf344d9465a924536f548e87386977ea5cf908c Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Mon, 6 Feb 2023 17:35:42 -0800 Subject: [PATCH] [libc++] Implement LWG3657 std::hash This is implemented as a DR on top of C++17. Differential Revision: https://reviews.llvm.org/D143452 --- libcxx/docs/Status/Cxx2bIssues.csv | 2 +- libcxx/include/__filesystem/path.h | 13 +++++++++++++ libcxx/include/filesystem | 3 +++ .../class.path/path.member/path.compare.pass.cpp | 8 ++++++++ .../path.nonmember/hash.tested_elswhere.compile.pass.cpp | 10 ++++++++++ ...pass.cpp => hash_value.tested_elswhere.compile.pass.cpp} | 9 ++------- 6 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash.tested_elswhere.compile.pass.cpp rename libcxx/test/std/input.output/filesystems/class.path/path.nonmember/{hash_value_tested_elswhere.pass.cpp => hash_value.tested_elswhere.compile.pass.cpp} (67%) diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv index cac68bc..dbcdcb3 100644 --- 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 index 4e6912f..aad0beb 100644 --- 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_AVAILABILITY_FILESYSTEM_POP _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 index 7efa4ed..8d01a81 100644 --- 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 index 3e194a7..365aa1c 100644 --- 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 @@ void test_compare_basic() 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.tested_elswhere.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash.tested_elswhere.compile.pass.cpp new file mode 100644 index 0000000..b69e224 --- /dev/null +++ b/libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash.tested_elswhere.compile.pass.cpp @@ -0,0 +1,10 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// 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 similarity index 67% 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 index 1efeba1..9d7260d 100644 --- 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 -- 2.7.4