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 @@ -110,7 +110,7 @@ `3407 `__,"Some problems with the wording changes of P1739R4","October 2021","","" `3422 `__,"Issues of ``seed_seq``'s constructors","October 2021","","" `3470 `__,"``convertible-to-non-slicing`` seems to reject valid case","October 2021","","" -`3480 `__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges","October 2021","","" +`3480 `__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges","October 2021","|Complete|","14.0" `3498 `__,"Inconsistent ``noexcept``-specifiers for ``basic_syncbuf``","October 2021","","" `3535 `__,"``join_view::iterator::iterator_category`` and ``::iterator_concept`` lie","October 2021","","" `3554 `__,"``chrono::parse`` needs ``const charT*`` and ``basic_string_view`` overloads","October 2021","","" diff --git a/libcxx/docs/Status/RangesIssues.csv b/libcxx/docs/Status/RangesIssues.csv --- a/libcxx/docs/Status/RangesIssues.csv +++ b/libcxx/docs/Status/RangesIssues.csv @@ -85,7 +85,7 @@ `LWG3392 `__,"``ranges::distance()`` cannot be used on a move-only iterator with a sized sentinel",, `LWG3407 `__,"Some problems with the wording changes of P1739R4",, `LWG3470 `__,"``convertible-to-non-slicing`` seems to reject valid case",, -`LWG3480 `__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges",, +`LWG3480 `__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges","|Complete|","14.0" `LWG3535 `__,"``join_view::iterator::iterator_category`` and ``::iterator_concept`` lie",, `LWG3559 `__,"Semantic requirements of ``sized_range`` is circular",, `LWG3560 `__,"``ranges::equal`` and ``ranges::is_permutation`` should short-circuit for ``sized_ranges``",, diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem --- 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 = true; +template <> +inline constexpr bool std::ranges::enable_borrowed_range = true; + +template <> +inline constexpr bool std::ranges::enable_view = true; +template <> +inline constexpr bool std::ranges::enable_view = true; */ #include <__availability> #include <__config> #include <__debug> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/enable_view.h> #include <__utility/forward.h> #include #include @@ -2774,7 +2785,7 @@ directory_entry __elem_; }; -class directory_iterator { +class _LIBCPP_TEMPLATE_VIS directory_iterator { public: typedef directory_entry value_type; typedef ptrdiff_t difference_type; @@ -2869,11 +2880,11 @@ } inline _LIBCPP_INLINE_VISIBILITY directory_iterator -end(const directory_iterator&) noexcept { +end(directory_iterator) noexcept { return directory_iterator(); } -class recursive_directory_iterator { +class _LIBCPP_TEMPLATE_VIS recursive_directory_iterator { public: using value_type = directory_entry; using difference_type = ptrdiff_t; @@ -3001,7 +3012,7 @@ } 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_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 --- 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_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 --- 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 @@ -8,46 +8,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 #include - - static_assert(std::same_as, fs::directory_iterator>); static_assert(std::ranges::common_range); static_assert(std::ranges::input_range); -static_assert(!std::ranges::view); +static_assert(std::ranges::view); static_assert(!std::ranges::sized_range); -static_assert(!std::ranges::borrowed_range); -static_assert(!std::ranges::viewable_range); +static_assert(std::ranges::borrowed_range); +static_assert(std::ranges::viewable_range); -static_assert(std::same_as, fs::directory_iterator>); -static_assert(std::ranges::common_range); -static_assert(std::ranges::input_range); -static_assert(!std::ranges::view); -static_assert(!std::ranges::sized_range); -static_assert(!std::ranges::borrowed_range); -static_assert(!std::ranges::viewable_range); +static_assert(std::same_as, fs::directory_iterator>); +static_assert(std::ranges::common_range); +static_assert(std::ranges::input_range); +static_assert(!std::ranges::view); +static_assert(!std::ranges::sized_range); +static_assert(std::ranges::borrowed_range); +static_assert(std::ranges::viewable_range); -static_assert(std::same_as, fs::recursive_directory_iterator>); -static_assert(std::ranges::common_range); -static_assert(std::ranges::input_range); -static_assert(!std::ranges::view); -static_assert(!std::ranges::sized_range); -static_assert(!std::ranges::borrowed_range); -static_assert(!std::ranges::viewable_range); +static_assert(std::same_as, fs::directory_iterator>); +static_assert(std::ranges::common_range); +static_assert(std::ranges::input_range); +static_assert(!std::ranges::view); +static_assert(!std::ranges::sized_range); +static_assert(std::ranges::borrowed_range); +static_assert(std::ranges::viewable_range); -static_assert(std::same_as, fs::recursive_directory_iterator>); -static_assert(std::ranges::common_range); -static_assert(std::ranges::input_range); -static_assert(!std::ranges::view); -static_assert(!std::ranges::sized_range); -static_assert(!std::ranges::borrowed_range); -static_assert(!std::ranges::viewable_range); 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 --- /dev/null +++ b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/range_concept_conformance.compile.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// recursive_directory_iterator + +#include "filesystem_include.h" + +#include +#include + +static_assert(std::same_as, fs::recursive_directory_iterator>); +static_assert(std::ranges::common_range); +static_assert(std::ranges::input_range); +static_assert(std::ranges::view); +static_assert(!std::ranges::sized_range); +static_assert(std::ranges::borrowed_range); +static_assert(std::ranges::viewable_range); + +static_assert(std::same_as, fs::recursive_directory_iterator>); +static_assert(std::ranges::common_range); +static_assert(std::ranges::input_range); +static_assert(!std::ranges::view); +static_assert(!std::ranges::sized_range); +static_assert(std::ranges::borrowed_range); +static_assert(std::ranges::viewable_range); + +static_assert(std::same_as, fs::recursive_directory_iterator>); +static_assert(std::ranges::common_range); +static_assert(std::ranges::input_range); +static_assert(!std::ranges::view); +static_assert(!std::ranges::sized_range); +static_assert(std::ranges::borrowed_range); +static_assert(std::ranges::viewable_range); 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 --- 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_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 --- /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 + +// + +//template <> +//inline constexpr bool ranges::enable_borrowed_range = true; +//template <> +//inline constexpr bool ranges::enable_borrowed_range = true; + +#include +#include + +template +void test() { + static_assert(std::ranges::enable_borrowed_range); + static_assert(!std::ranges::enable_borrowed_range); + static_assert(!std::ranges::enable_borrowed_range); +} + +void test() { + test(); + test(); +} 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 --- /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 + +// + +//template <> +//inline constexpr bool ranges::enable_view = true; +//template <> +//inline constexpr bool ranges::enable_view = true; + +#include +#include + +template +void test() { + static_assert(std::ranges::enable_view); + static_assert(!std::ranges::enable_view); + static_assert(!std::ranges::enable_view); +} + +void test() { + test(); + test(); +}