[libcxx-commits] [libcxx] 1fa27f2 - [libc++] LWG3480: make (recursive_)directory_iterator C++20 ranges
Joe Loser via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Oct 14 09:03:11 PDT 2021
Author: Joe Loser
Date: 2021-10-14T12:02:18-04:00
New Revision: 1fa27f2a10e8eec15387aba7eeff65d7d332b9af
URL: https://github.com/llvm/llvm-project/commit/1fa27f2a10e8eec15387aba7eeff65d7d332b9af
DIFF: https://github.com/llvm/llvm-project/commit/1fa27f2a10e8eec15387aba7eeff65d7d332b9af.diff
LOG: [libc++] LWG3480: make (recursive_)directory_iterator C++20 ranges
Implement LWG3480 which enables `directory_iterator` and
`recursive_directory_iterator` to be both a `borrowed_range` and a
`view`.
Reviewed By: ldionne, #libc
Differential Revision: https://reviews.llvm.org/D111644
Added:
libcxx/test/std/input.output/filesystems/class.rec.dir.itr/range_concept_conformance.compile.pass.cpp
libcxx/test/std/input.output/filesystems/fs.filesystem.synopsis/enable_borrowed_range.compile.pass.cpp
libcxx/test/std/input.output/filesystems/fs.filesystem.synopsis/enable_view.compile.pass.cpp
Modified:
libcxx/docs/Status/Cxx2bIssues.csv
libcxx/docs/Status/RangesIssues.csv
libcxx/include/filesystem
libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp
libcxx/test/std/input.output/filesystems/class.directory_iterator/range_concept_conformance.compile.pass.cpp
libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv
index 12a293b912d2d..1fb95412741bd 100644
--- a/libcxx/docs/Status/Cxx2bIssues.csv
+++ b/libcxx/docs/Status/Cxx2bIssues.csv
@@ -110,7 +110,7 @@
`3407 <https://wg21.link/LWG3407>`__,"Some problems with the wording changes of P1739R4","October 2021","",""
`3422 <https://wg21.link/LWG3422>`__,"Issues of ``seed_seq``'s constructors","October 2021","",""
`3470 <https://wg21.link/LWG3470>`__,"``convertible-to-non-slicing`` seems to reject valid case","October 2021","",""
-`3480 <https://wg21.link/LWG3480>`__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges","October 2021","",""
+`3480 <https://wg21.link/LWG3480>`__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges","October 2021","|Complete|","14.0"
`3498 <https://wg21.link/LWG3498>`__,"Inconsistent ``noexcept``-specifiers for ``basic_syncbuf``","October 2021","",""
`3535 <https://wg21.link/LWG3535>`__,"``join_view::iterator::iterator_category`` and ``::iterator_concept`` lie","October 2021","",""
`3554 <https://wg21.link/LWG3554>`__,"``chrono::parse`` needs ``const charT*`` and ``basic_string_view<charT>`` overloads","October 2021","",""
diff --git a/libcxx/docs/Status/RangesIssues.csv b/libcxx/docs/Status/RangesIssues.csv
index 58367d752d4fe..4e5abfa550eae 100644
--- a/libcxx/docs/Status/RangesIssues.csv
+++ b/libcxx/docs/Status/RangesIssues.csv
@@ -85,7 +85,7 @@
`LWG3392 <https://wg21.link/LWG3392>`__,"``ranges::distance()`` cannot be used on a move-only iterator with a sized sentinel",,
`LWG3407 <https://wg21.link/LWG3407>`__,"Some problems with the wording changes of P1739R4",,
`LWG3470 <https://wg21.link/LWG3470>`__,"``convertible-to-non-slicing`` seems to reject valid case",,
-`LWG3480 <https://wg21.link/LWG3480>`__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges",,
+`LWG3480 <https://wg21.link/LWG3480>`__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges","|Complete|","14.0"
`LWG3535 <https://wg21.link/LWG3535>`__,"``join_view::iterator::iterator_category`` and ``::iterator_concept`` lie",,
`LWG3559 <https://wg21.link/LWG3559>`__,"Semantic requirements of ``sized_range`` is circular",,
`LWG3560 <https://wg21.link/LWG3560>`__,"``ranges::equal`` and ``ranges::is_permutation`` should short-circuit for ``sized_ranges``",,
diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem
index a11d2a4888f40..1fd77af99cc41 100644
--- a/libcxx/include/filesystem
+++ b/libcxx/include/filesystem
@@ -11,7 +11,7 @@
/*
filesystem synopsis
- namespace std { namespace filesystem {
+ namespace std::filesystem {
class path;
@@ -48,13 +48,13 @@
// enable directory_iterator range-based for statements
directory_iterator begin(directory_iterator iter) noexcept;
- directory_iterator end(const directory_iterator&) noexcept;
+ directory_iterator end(directory_iterator) noexcept;
class recursive_directory_iterator;
// enable recursive_directory_iterator range-based for statements
recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
- recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
+ recursive_directory_iterator end(recursive_directory_iterator) noexcept;
class file_status;
@@ -224,14 +224,25 @@
path weakly_canonical(path const& p);
path weakly_canonical(path const& p, error_code& ec);
+} // namespace std::filesystem
-} } // namespaces std::filesystem
+template <>
+inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::directory_iterator> = true;
+template <>
+inline constexpr bool std::ranges::enable_borrowed_range<std::filesystem::recursive_directory_iterator> = true;
+
+template <>
+inline constexpr bool std::ranges::enable_view<std::filesystem::directory_iterator> = true;
+template <>
+inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_directory_iterator> = true;
*/
#include <__availability>
#include <__config>
#include <__debug>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/enable_view.h>
#include <__utility/forward.h>
#include <chrono>
#include <compare>
@@ -2869,7 +2880,7 @@ begin(directory_iterator __iter) noexcept {
}
inline _LIBCPP_INLINE_VISIBILITY directory_iterator
-end(const directory_iterator&) noexcept {
+end(directory_iterator) noexcept {
return directory_iterator();
}
@@ -3001,7 +3012,7 @@ begin(recursive_directory_iterator __iter) noexcept {
}
inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator
-end(const recursive_directory_iterator&) noexcept {
+end(recursive_directory_iterator) noexcept {
return recursive_directory_iterator();
}
@@ -3009,6 +3020,18 @@ _LIBCPP_AVAILABILITY_FILESYSTEM_POP
_LIBCPP_END_NAMESPACE_FILESYSTEM
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+template <>
+inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true;
+template <>
+inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true;
+
+template <>
+inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true;
+template <>
+inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true;
+#endif
+
#endif // !_LIBCPP_CXX03_LANG
_LIBCPP_POP_MACROS
diff --git a/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp
index be8a1be0b023c..f6f0bbe7687a8 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.nonmembers/begin_end.pass.cpp
@@ -30,12 +30,16 @@ TEST_SUITE(directory_iterator_begin_end_tests)
TEST_CASE(test_function_signatures)
{
- directory_iterator d; ((void)d);
+ directory_iterator d;
ASSERT_SAME_TYPE(decltype(begin(d)), directory_iterator);
+ ASSERT_SAME_TYPE(decltype(begin(std::move(d))), directory_iterator);
+ ASSERT_NOEXCEPT(begin(d));
ASSERT_NOEXCEPT(begin(std::move(d)));
ASSERT_SAME_TYPE(decltype(end(d)), directory_iterator);
+ ASSERT_SAME_TYPE(decltype(end(std::move(d))), directory_iterator);
+ ASSERT_NOEXCEPT(end(d));
ASSERT_NOEXCEPT(end(std::move(d)));
}
diff --git a/libcxx/test/std/input.output/filesystems/class.directory_iterator/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_iterator/range_concept_conformance.compile.pass.cpp
index 3218f20c7fb61..fd28f1671867c 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_iterator/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_iterator/range_concept_conformance.compile.pass.cpp
@@ -9,45 +9,35 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
-// XFAIL: *
-// directory_iterator, recursive_directory_iterator
+// directory_iterator
#include "filesystem_include.h"
#include <concepts>
#include <ranges>
-
-
static_assert(std::same_as<std::ranges::iterator_t<fs::directory_iterator>, fs::directory_iterator>);
static_assert(std::ranges::common_range<fs::directory_iterator>);
static_assert(std::ranges::input_range<fs::directory_iterator>);
-static_assert(!std::ranges::view<fs::directory_iterator>);
+static_assert(std::ranges::view<fs::directory_iterator>);
static_assert(!std::ranges::sized_range<fs::directory_iterator>);
-static_assert(!std::ranges::borrowed_range<fs::directory_iterator>);
-static_assert(!std::ranges::viewable_range<fs::directory_iterator>);
-
-static_assert(std::same_as<std::ranges::iterator_t<fs::directory_iterator const>, fs::directory_iterator>);
-static_assert(std::ranges::common_range<fs::directory_iterator const>);
-static_assert(std::ranges::input_range<fs::directory_iterator const>);
-static_assert(!std::ranges::view<fs::directory_iterator const>);
-static_assert(!std::ranges::sized_range<fs::directory_iterator const>);
-static_assert(!std::ranges::borrowed_range<fs::directory_iterator const>);
-static_assert(!std::ranges::viewable_range<fs::directory_iterator const>);
-
-static_assert(std::same_as<std::ranges::iterator_t<fs::recursive_directory_iterator>, fs::recursive_directory_iterator>);
-static_assert(std::ranges::common_range<fs::recursive_directory_iterator>);
-static_assert(std::ranges::input_range<fs::recursive_directory_iterator>);
-static_assert(!std::ranges::view<fs::recursive_directory_iterator>);
-static_assert(!std::ranges::sized_range<fs::recursive_directory_iterator>);
-static_assert(!std::ranges::borrowed_range<fs::recursive_directory_iterator>);
-static_assert(!std::ranges::viewable_range<fs::recursive_directory_iterator>);
-
-static_assert(std::same_as<std::ranges::iterator_t<fs::recursive_directory_iterator const>, fs::recursive_directory_iterator>);
-static_assert(std::ranges::common_range<fs::recursive_directory_iterator const>);
-static_assert(std::ranges::input_range<fs::recursive_directory_iterator const>);
-static_assert(!std::ranges::view<fs::recursive_directory_iterator const>);
-static_assert(!std::ranges::sized_range<fs::recursive_directory_iterator const>);
-static_assert(!std::ranges::borrowed_range<fs::recursive_directory_iterator const>);
-static_assert(!std::ranges::viewable_range<fs::recursive_directory_iterator const>);
+static_assert(std::ranges::borrowed_range<fs::directory_iterator>);
+static_assert(std::ranges::viewable_range<fs::directory_iterator>);
+
+static_assert(std::same_as<std::ranges::iterator_t<fs::directory_iterator&>, fs::directory_iterator>);
+static_assert(std::ranges::common_range<fs::directory_iterator&>);
+static_assert(std::ranges::input_range<fs::directory_iterator&>);
+static_assert(!std::ranges::view<fs::directory_iterator&>);
+static_assert(!std::ranges::sized_range<fs::directory_iterator&>);
+static_assert(std::ranges::borrowed_range<fs::directory_iterator&>);
+static_assert(std::ranges::viewable_range<fs::directory_iterator&>);
+
+static_assert(std::same_as<std::ranges::iterator_t<const fs::directory_iterator&>, fs::directory_iterator>);
+static_assert(std::ranges::common_range<const fs::directory_iterator&>);
+static_assert(std::ranges::input_range<const fs::directory_iterator&>);
+static_assert(!std::ranges::view<const fs::directory_iterator&>);
+static_assert(!std::ranges::sized_range<const fs::directory_iterator&>);
+static_assert(std::ranges::borrowed_range<const fs::directory_iterator&>);
+static_assert(std::ranges::viewable_range<const fs::directory_iterator&>);
+
diff --git a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/range_concept_conformance.compile.pass.cpp
new file mode 100644
index 0000000000000..834e74636ffd3
--- /dev/null
+++ b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/range_concept_conformance.compile.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// UNSUPPORTED: libcpp-has-no-incomplete-ranges
+
+// recursive_directory_iterator
+
+#include "filesystem_include.h"
+
+#include <concepts>
+#include <ranges>
+
+static_assert(std::same_as<std::ranges::iterator_t<fs::recursive_directory_iterator>, fs::recursive_directory_iterator>);
+static_assert(std::ranges::common_range<fs::recursive_directory_iterator>);
+static_assert(std::ranges::input_range<fs::recursive_directory_iterator>);
+static_assert(std::ranges::view<fs::recursive_directory_iterator>);
+static_assert(!std::ranges::sized_range<fs::recursive_directory_iterator>);
+static_assert(std::ranges::borrowed_range<fs::recursive_directory_iterator>);
+static_assert(std::ranges::viewable_range<fs::recursive_directory_iterator>);
+
+static_assert(std::same_as<std::ranges::iterator_t<fs::recursive_directory_iterator&>, fs::recursive_directory_iterator>);
+static_assert(std::ranges::common_range<fs::recursive_directory_iterator&>);
+static_assert(std::ranges::input_range<fs::recursive_directory_iterator&>);
+static_assert(!std::ranges::view<fs::recursive_directory_iterator&>);
+static_assert(!std::ranges::sized_range<fs::recursive_directory_iterator&>);
+static_assert(std::ranges::borrowed_range<fs::recursive_directory_iterator&>);
+static_assert(std::ranges::viewable_range<fs::recursive_directory_iterator&>);
+
+static_assert(std::same_as<std::ranges::iterator_t<const fs::recursive_directory_iterator&>, fs::recursive_directory_iterator>);
+static_assert(std::ranges::common_range<const fs::recursive_directory_iterator&>);
+static_assert(std::ranges::input_range<const fs::recursive_directory_iterator&>);
+static_assert(!std::ranges::view<const fs::recursive_directory_iterator&>);
+static_assert(!std::ranges::sized_range<const fs::recursive_directory_iterator&>);
+static_assert(std::ranges::borrowed_range<const fs::recursive_directory_iterator&>);
+static_assert(std::ranges::viewable_range<const fs::recursive_directory_iterator&>);
diff --git a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
index c4bb5a78ac904..104e419fa9e91 100644
--- a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
@@ -30,12 +30,16 @@ TEST_SUITE(recursive_directory_iterator_begin_end_tests)
TEST_CASE(test_function_signatures)
{
- recursive_directory_iterator d; ((void)d);
+ recursive_directory_iterator d;
ASSERT_SAME_TYPE(decltype(begin(d)), recursive_directory_iterator);
+ ASSERT_SAME_TYPE(decltype(begin(std::move(d))), recursive_directory_iterator);
+ ASSERT_NOEXCEPT(begin(d));
ASSERT_NOEXCEPT(begin(std::move(d)));
ASSERT_SAME_TYPE(decltype(end(d)), recursive_directory_iterator);
+ ASSERT_SAME_TYPE(decltype(end(std::move(d))), recursive_directory_iterator);
+ ASSERT_NOEXCEPT(end(d));
ASSERT_NOEXCEPT(end(std::move(d)));
}
diff --git a/libcxx/test/std/input.output/filesystems/fs.filesystem.synopsis/enable_borrowed_range.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.filesystem.synopsis/enable_borrowed_range.compile.pass.cpp
new file mode 100644
index 0000000000000..e59672a967a8d
--- /dev/null
+++ b/libcxx/test/std/input.output/filesystems/fs.filesystem.synopsis/enable_borrowed_range.compile.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+
+// <filesystem>
+
+// template <>
+// inline constexpr bool ranges::enable_borrowed_range<filesystem::directory_iterator> = true;
+// template <>
+// inline constexpr bool ranges::enable_borrowed_range<filesystem::recursive_directory_iterator> = true;
+
+#include <filesystem>
+#include <ranges>
+
+template<class Range>
+void test() {
+ static_assert(std::ranges::enable_borrowed_range<Range>);
+ static_assert(!std::ranges::enable_borrowed_range<Range&>);
+ static_assert(!std::ranges::enable_borrowed_range<const Range>);
+}
+
+void test() {
+ test<std::filesystem::directory_iterator>();
+ test<std::filesystem::recursive_directory_iterator>();
+}
diff --git a/libcxx/test/std/input.output/filesystems/fs.filesystem.synopsis/enable_view.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.filesystem.synopsis/enable_view.compile.pass.cpp
new file mode 100644
index 0000000000000..336d522dd0735
--- /dev/null
+++ b/libcxx/test/std/input.output/filesystems/fs.filesystem.synopsis/enable_view.compile.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+
+// <filesystem>
+
+// template <>
+// inline constexpr bool ranges::enable_view<filesystem::directory_iterator> = true;
+// template <>
+// inline constexpr bool ranges::enable_view<filesystem::recursive_directory_iterator> = true;
+
+#include <filesystem>
+#include <ranges>
+
+template<class Range>
+void test() {
+ static_assert(std::ranges::enable_view<Range>);
+ static_assert(!std::ranges::enable_view<Range&>);
+ static_assert(!std::ranges::enable_view<const Range>);
+}
+
+void test() {
+ test<std::filesystem::directory_iterator>();
+ test<std::filesystem::recursive_directory_iterator>();
+}
More information about the libcxx-commits
mailing list