[libcxx-commits] [libcxx] 5f8e431 - [libc++][ranges] Addresses: LWG3719 - Directory iterators should be usable with default sentinel
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Jun 24 07:54:53 PDT 2023
Author: Hristo Hristov
Date: 2023-06-24T17:54:47+03:00
New Revision: 5f8e4315979c266f3610f89d11a48bd43809533d
URL: https://github.com/llvm/llvm-project/commit/5f8e4315979c266f3610f89d11a48bd43809533d
DIFF: https://github.com/llvm/llvm-project/commit/5f8e4315979c266f3610f89d11a48bd43809533d.diff
LOG: [libc++][ranges] Addresses: LWG3719 - Directory iterators should be usable with default sentinel
Addresses: LWG3719 - Directory iterators should be usable with default sentinel
https://wg21.link/LWG3719
Reviewed By: #libc, Mordante
Differential Revision: https://reviews.llvm.org/D153299
Added:
libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/equal.pass.cpp
libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/equal.pass.cpp
libcxx/test/std/re/re.iter/re.regiter/re.regiter.comp/equal.pass.cpp
Modified:
libcxx/docs/Status/Cxx23Issues.csv
libcxx/include/__filesystem/directory_iterator.h
libcxx/include/__filesystem/recursive_directory_iterator.h
libcxx/include/filesystem
libcxx/include/regex
libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.comp/equal.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
index f8f7259877819..6cfff4dc420c2 100644
--- a/libcxx/docs/Status/Cxx23Issues.csv
+++ b/libcxx/docs/Status/Cxx23Issues.csv
@@ -182,7 +182,7 @@
"`3712 <https://wg21.link/LWG3712>`__","``chunk_view`` and ``slide_view`` should not be ``default_initializable``","July 2022","","","|ranges|"
"`3713 <https://wg21.link/LWG3713>`__","Sorted with respect to comparator (only)","July 2022","",""
"`3715 <https://wg21.link/LWG3715>`__","``view_interface::empty`` is overconstrained","July 2022","","","|ranges|"
-"`3719 <https://wg21.link/LWG3719>`__","Directory iterators should be usable with default sentinel","July 2022","","","|ranges|"
+"`3719 <https://wg21.link/LWG3719>`__","Directory iterators should be usable with default sentinel","July 2022","|Complete|","17.0","|ranges|"
"`3721 <https://wg21.link/LWG3721>`__","Allow an ``arg-id`` with a value of zero for ``width`` in ``std-format-spec``","July 2022","|Complete|","16.0","|format|"
"`3724 <https://wg21.link/LWG3724>`__","``decay-copy`` should be constrained","July 2022","|Complete|","14.0"
"","","","","",""
diff --git a/libcxx/include/__filesystem/directory_iterator.h b/libcxx/include/__filesystem/directory_iterator.h
index 2bf17179095f3..5d6b616fd9d84 100644
--- a/libcxx/include/__filesystem/directory_iterator.h
+++ b/libcxx/include/__filesystem/directory_iterator.h
@@ -16,6 +16,7 @@
#include <__filesystem/directory_entry.h>
#include <__filesystem/directory_options.h>
#include <__filesystem/path.h>
+#include <__iterator/default_sentinel.h>
#include <__iterator/iterator_traits.h>
#include <__memory/shared_ptr.h>
#include <__ranges/enable_borrowed_range.h>
@@ -102,6 +103,12 @@ class directory_iterator {
_LIBCPP_HIDE_FROM_ABI
directory_iterator& increment(error_code& __ec) { return __increment(&__ec); }
+# if _LIBCPP_STD_VER >= 20
+
+ _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept { return *this == directory_iterator(); }
+
+# endif
+
private:
inline _LIBCPP_HIDE_FROM_ABI friend bool
operator==(const directory_iterator& __lhs,
diff --git a/libcxx/include/__filesystem/recursive_directory_iterator.h b/libcxx/include/__filesystem/recursive_directory_iterator.h
index e3e50471e9598..b079d6ef70974 100644
--- a/libcxx/include/__filesystem/recursive_directory_iterator.h
+++ b/libcxx/include/__filesystem/recursive_directory_iterator.h
@@ -15,6 +15,7 @@
#include <__filesystem/directory_entry.h>
#include <__filesystem/directory_options.h>
#include <__filesystem/path.h>
+#include <__iterator/default_sentinel.h>
#include <__iterator/iterator_traits.h>
#include <__memory/shared_ptr.h>
#include <__ranges/enable_borrowed_range.h>
@@ -114,6 +115,14 @@ class recursive_directory_iterator {
_LIBCPP_INLINE_VISIBILITY
void disable_recursion_pending() { __rec_ = false; }
+# if _LIBCPP_STD_VER >= 20
+
+ _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept {
+ return *this == recursive_directory_iterator();
+ }
+
+# endif
+
private:
_LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator(const path& __p, directory_options __opt, error_code* __ec);
_LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const;
diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem
index 133c7bea5c802..dfbf7cef3cd56 100644
--- a/libcxx/include/filesystem
+++ b/libcxx/include/filesystem
@@ -236,13 +236,90 @@
friend class directory_iterator; // exposition only
};
- class directory_iterator;
+ class directory_iterator {
+ public:
+ using iterator_category = input_iterator_tag;
+ using value_type = directory_entry;
+ using
diff erence_type = ptr
diff _t;
+ using pointer = const directory_entry*;
+ using reference = const directory_entry&;
+
+ // [fs.dir.itr.members], member functions
+ directory_iterator() noexcept;
+ explicit directory_iterator(const path& p);
+ directory_iterator(const path& p, directory_options options);
+ directory_iterator(const path& p, error_code& ec);
+ directory_iterator(const path& p, directory_options options,
+ error_code& ec);
+ directory_iterator(const directory_iterator& rhs);
+ directory_iterator(directory_iterator&& rhs) noexcept;
+ ~directory_iterator();
+
+ directory_iterator& operator=(const directory_iterator& rhs);
+ directory_iterator& operator=(directory_iterator&& rhs) noexcept;
+
+ const directory_entry& operator*() const;
+ const directory_entry* operator->() const;
+ directory_iterator& operator++();
+ directory_iterator& increment(error_code& ec);
+
+ bool operator==(default_sentinel_t) const noexcept { // since C++20
+ return *this == directory_iterator();
+ }
+
+ // other members as required by [input.iterators], input iterators
+ };
// enable directory_iterator range-based for statements
directory_iterator begin(directory_iterator iter) noexcept;
directory_iterator end(directory_iterator) noexcept;
- class recursive_directory_iterator;
+class recursive_directory_iterator {
+ public:
+ using iterator_category = input_iterator_tag;
+ using value_type = directory_entry;
+ using
diff erence_type = ptr
diff _t;
+ using pointer = const directory_entry*;
+ using reference = const directory_entry&;
+
+ // [fs.rec.dir.itr.members], constructors and destructor
+ recursive_directory_iterator() noexcept;
+ explicit recursive_directory_iterator(const path& p);
+ recursive_directory_iterator(const path& p, directory_options options);
+ recursive_directory_iterator(const path& p, directory_options options,
+ error_code& ec);
+ recursive_directory_iterator(const path& p, error_code& ec);
+ recursive_directory_iterator(const recursive_directory_iterator& rhs);
+ recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
+ ~recursive_directory_iterator();
+
+ // [fs.rec.dir.itr.members], observers
+ directory_options options() const;
+ int depth() const;
+ bool recursion_pending() const;
+
+ const directory_entry& operator*() const;
+ const directory_entry* operator->() const;
+
+ // [fs.rec.dir.itr.members], modifiers
+ recursive_directory_iterator&
+ operator=(const recursive_directory_iterator& rhs);
+ recursive_directory_iterator&
+ operator=(recursive_directory_iterator&& rhs) noexcept;
+
+ recursive_directory_iterator& operator++();
+ recursive_directory_iterator& increment(error_code& ec);
+
+ void pop();
+ void pop(error_code& ec);
+ void disable_recursion_pending();
+
+ bool operator==(default_sentinel_t) const noexcept { // since C++20
+ return *this == recursive_directory_iterator();
+ }
+
+ // other members as required by [input.iterators], input iterators
+ };
// enable recursive_directory_iterator range-based for statements
recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
diff --git a/libcxx/include/regex b/libcxx/include/regex
index dce58c769de52..d72c5e1c0be8d 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -710,7 +710,8 @@ public:
regex_iterator& operator=(const regex_iterator&);
bool operator==(const regex_iterator&) const;
- bool operator!=(const regex_iterator&) const; // Removed in C++20
+ bool operator==(default_sentinel_t) const { return *this == regex_iterator(); } // since C++20
+ bool operator!=(const regex_iterator&) const; // Removed in C++20
const value_type& operator*() const;
const value_type* operator->() const;
@@ -768,7 +769,8 @@ public:
regex_token_iterator& operator=(const regex_token_iterator&);
bool operator==(const regex_token_iterator&) const;
- bool operator!=(const regex_token_iterator&) const; // Removed in C++20
+ bool operator==(default_sentinel_t) const { return *this == regex_token_iterator(); } // since C++20
+ bool operator!=(const regex_token_iterator&) const; // Removed in C++20
const value_type& operator*() const;
const value_type* operator->() const;
@@ -791,6 +793,7 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
#include <__availability>
#include <__config>
#include <__iterator/back_insert_iterator.h>
+#include <__iterator/default_sentinel.h>
#include <__iterator/wrap_iter.h>
#include <__locale>
#include <__memory_resource/polymorphic_allocator.h>
@@ -6429,7 +6432,10 @@ public:
= regex_constants::match_default) = delete;
#endif
- bool operator==(const regex_iterator& __x) const;
+ _LIBCPP_HIDE_FROM_ABI bool operator==(const regex_iterator& __x) const;
+#if _LIBCPP_STD_VER >= 20
+ _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const { return *this == regex_iterator(); }
+#endif
#if _LIBCPP_STD_VER < 20
_LIBCPP_INLINE_VISIBILITY
bool operator!=(const regex_iterator& __x) const {return !(*this == __x);}
@@ -6609,9 +6615,14 @@ public:
regex_token_iterator(const regex_token_iterator&);
regex_token_iterator& operator=(const regex_token_iterator&);
- bool operator==(const regex_token_iterator& __x) const;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_HIDE_FROM_ABI bool operator==(const regex_token_iterator& __x) const;
+#if _LIBCPP_STD_VER >= 20
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const {
+ return *this == regex_token_iterator();
+ }
+#endif
#if _LIBCPP_STD_VER < 20
+ _LIBCPP_INLINE_VISIBILITY
bool operator!=(const regex_token_iterator& __x) const {return !(*this == __x);}
#endif
diff --git a/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/equal.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/equal.pass.cpp
new file mode 100644
index 0000000000000..5299eb0451de0
--- /dev/null
+++ b/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/equal.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <filesystem>
+
+// class directory_iterator
+
+// bool operator==(default_sentinel_t) const noexcept { // since C++20
+// return *this == directory_iterator();
+// }
+
+#include <cassert>
+#include <iterator>
+
+#include "filesystem_include.h"
+#include "test_comparisons.h"
+
+int main(int, char**) {
+ AssertEqualityAreNoexcept<fs::directory_iterator>();
+ AssertEqualityReturnBool<fs::directory_iterator>();
+
+ fs::directory_iterator i;
+ assert(testEquality(i, std::default_sentinel, true));
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/equal.pass.cpp b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/equal.pass.cpp
new file mode 100644
index 0000000000000..1616bcf1300a3
--- /dev/null
+++ b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/equal.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <filesystem>
+
+// class recursive_directory_iterator
+
+// bool operator==(default_sentinel_t) const noexcept { // since C++20
+// return *this == recursive_directory_iterator();
+// }
+
+#include <cassert>
+#include <iterator>
+
+#include "filesystem_include.h"
+#include "test_comparisons.h"
+
+int main(int, char**) {
+ AssertEqualityAreNoexcept<fs::recursive_directory_iterator>();
+ AssertEqualityReturnBool<fs::recursive_directory_iterator>();
+
+ fs::recursive_directory_iterator i;
+ assert(testEquality(i, std::default_sentinel, true));
+
+ return 0;
+}
diff --git a/libcxx/test/std/re/re.iter/re.regiter/re.regiter.comp/equal.pass.cpp b/libcxx/test/std/re/re.iter/re.regiter/re.regiter.comp/equal.pass.cpp
new file mode 100644
index 0000000000000..6c0b16f50c414
--- /dev/null
+++ b/libcxx/test/std/re/re.iter/re.regiter/re.regiter.comp/equal.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <regex>
+
+// class regex_token_iterator<BidirectionalIterator, charT, traits>
+
+// bool operator==(default_sentinel_t) const { return *this == regex_iterator(); } // since C++20
+
+#include <cassert>
+#include <iterator>
+#include <regex>
+
+#include "test_comparisons.h"
+
+int main(int, char**) {
+ AssertEqualityReturnBool<std::cregex_iterator>();
+
+ {
+ std::cregex_iterator i;
+ assert(testEquality(i, std::default_sentinel, true));
+ }
+
+ AssertEqualityReturnBool<std::sregex_token_iterator>();
+
+ {
+ std::sregex_token_iterator i;
+ assert(testEquality(i, std::default_sentinel, true));
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.comp/equal.pass.cpp b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.comp/equal.pass.cpp
index 7ccb700c1d182..ef0fd5cd111ad 100644
--- a/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.comp/equal.pass.cpp
+++ b/libcxx/test/std/re/re.iter/re.tokiter/re.tokiter.comp/equal.pass.cpp
@@ -11,28 +11,45 @@
// class regex_token_iterator<BidirectionalIterator, charT, traits>
// bool operator==(const regex_token_iterator& right) const;
+// bool operator==(default_sentinel_t) const { return *this == regex_token_iterator(); } // since C++20
// bool operator!=(const regex_token_iterator& right) const; // generated by the compiler in C++20
-#include <regex>
#include <cassert>
-#include "test_macros.h"
-
-int main(int, char**)
-{
- {
- std::regex phone_numbers("\\d{3}-\\d{4}");
- const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end";
- std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book)-1,
- phone_numbers, -1);
- assert(i != std::cregex_token_iterator());
- assert(!(i == std::cregex_token_iterator()));
- std::cregex_token_iterator i2 = i;
- assert(i2 == i);
- assert(!(i2 != i));
- ++i;
- assert(!(i2 == i));
- assert(i2 != i);
- }
+#include <iterator>
+#include <regex>
+
+#include "test_comparisons.h"
+
+int main(int, char**) {
+#if _LIBCPP_STD_VER >= 20
+ AssertEqualityReturnBool<std::cregex_token_iterator>();
+
+ {
+ std::cregex_token_iterator i;
+ assert(testEquality(i, std::default_sentinel, true));
+ }
+
+ AssertEqualityReturnBool<std::sregex_token_iterator>();
+
+ {
+ std::sregex_token_iterator i;
+ assert(testEquality(i, std::default_sentinel, true));
+ }
+#endif
+
+ {
+ std::regex phone_numbers("\\d{3}-\\d{4}");
+ const char phone_book[] = "start 555-1234, 555-2345, 555-3456 end";
+ std::cregex_token_iterator i(std::begin(phone_book), std::end(phone_book) - 1, phone_numbers, -1);
+ assert(i != std::cregex_token_iterator());
+ assert(!(i == std::cregex_token_iterator()));
+ std::cregex_token_iterator i2 = i;
+ assert(i2 == i);
+ assert(!(i2 != i));
+ ++i;
+ assert(!(i2 == i));
+ assert(i2 != i);
+ }
return 0;
}
More information about the libcxx-commits
mailing list