[libcxx-commits] [libcxx] 1cf344d - [libc++] Implement LWG3657 std::hash<filesystem::path>

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Feb 7 22:06:25 PST 2023


Author: Louis Dionne
Date: 2023-02-07T22:06:17-08:00
New Revision: 1cf344d9465a924536f548e87386977ea5cf908c

URL: https://github.com/llvm/llvm-project/commit/1cf344d9465a924536f548e87386977ea5cf908c
DIFF: https://github.com/llvm/llvm-project/commit/1cf344d9465a924536f548e87386977ea5cf908c.diff

LOG: [libc++] Implement LWG3657 std::hash<filesystem::path>

This is implemented as a DR on top of C++17.

Differential Revision: https://reviews.llvm.org/D143452

Added: 
    libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash.tested_elswhere.compile.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash_value.tested_elswhere.compile.pass.cpp

Modified: 
    libcxx/docs/Status/Cxx2bIssues.csv
    libcxx/include/__filesystem/path.h
    libcxx/include/filesystem
    libcxx/test/std/input.output/filesystems/class.path/path.member/path.compare.pass.cpp

Removed: 
    libcxx/test/std/input.output/filesystems/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp


################################################################################
diff  --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv
index cac68bc37ee96..dbcdcb34861cb 100644
--- a/libcxx/docs/Status/Cxx2bIssues.csv
+++ b/libcxx/docs/Status/Cxx2bIssues.csv
@@ -155,7 +155,7 @@
 "`3649 <https://wg21.link/LWG3649>`__","[fund.ts.v2] Reinstate and bump ``__cpp_lib_experimental_memory_resource`` feature test macro","February 2022","",""
 "`3650 <https://wg21.link/LWG3650>`__","Are ``std::basic_string`` 's ``iterator`` and ``const_iterator`` constexpr iterators?","February 2022","|Nothing to do|",""
 "`3654 <https://wg21.link/LWG3654>`__","``basic_format_context::arg(size_t)`` should be ``noexcept`` ","February 2022","|Complete|","15.0","|format|"
-"`3657 <https://wg21.link/LWG3657>`__","``std::hash<std::filesystem::path>`` is not enabled","February 2022","",""
+"`3657 <https://wg21.link/LWG3657>`__","``std::hash<std::filesystem::path>`` is not enabled","February 2022","|Complete|","17.0"
 "`3660 <https://wg21.link/LWG3660>`__","``iterator_traits<common_iterator>::pointer`` should conform to ยง[iterator.traits]","February 2022","|Complete|","14.0","|ranges|"
 "`3661 <https://wg21.link/LWG3661>`__","``constinit atomic<shared_ptr<T>> a(nullptr);`` should work","February 2022","",""
 "","","","","",""

diff  --git a/libcxx/include/__filesystem/path.h b/libcxx/include/__filesystem/path.h
index 4e6912fcf3e75..aad0beb0c6063 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 <cstddef>
@@ -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 7efa4ed2b39fd..8d01a81c6137c 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<filesystem::path>;
+
     template <class Source>
       path u8path(const Source& source);
     template <class InputIterator>

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 3e194a7816132..365aa1cce9a1d 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<fs::path>()(p1);
+      auto h2 = std::hash<fs::path>()(p2);
+      assert((h1 == h2) == (p1 == p2));
+      // check signature
+      ASSERT_SAME_TYPE(size_t, decltype(std::hash<fs::path>()(p1)));
+      ASSERT_NOEXCEPT(std::hash<fs::path>()(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 0000000000000..b69e22476f746
--- /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 1efeba193c360..9d7260d89f551 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


        


More information about the libcxx-commits mailing list