[libcxx-commits] [libcxx] 38225d6 - [libcxx][iterator] adds `std::input_or_output_iterator` and `std::sentinel_for`

Christopher Di Bella via libcxx-commits libcxx-commits at lists.llvm.org
Sat Apr 24 08:50:12 PDT 2021


Author: Christopher Di Bella
Date: 2021-04-24T15:49:21Z
New Revision: 38225d692163fc697006d8a769479459fdfc32fa

URL: https://github.com/llvm/llvm-project/commit/38225d692163fc697006d8a769479459fdfc32fa
DIFF: https://github.com/llvm/llvm-project/commit/38225d692163fc697006d8a769479459fdfc32fa.diff

LOG: [libcxx][iterator] adds `std::input_or_output_iterator` and `std::sentinel_for`

Implements parts of:
    * P0896R4 The One Ranges Proposal`

Depends on D100080

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

Added: 
    libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.iterator/input_or_output_iterator.compile.pass.cpp
    libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.iterator/subsumption.compile.pass.cpp
    libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sentinel_for.compile.pass.cpp
    libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sentinel_for.subsumption.compile.pass.cpp

Modified: 
    libcxx/include/__iterator/concepts.h
    libcxx/include/iterator
    libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h
index bd1ec849f445..3a9b6280d40b 100644
--- a/libcxx/include/__iterator/concepts.h
+++ b/libcxx/include/__iterator/concepts.h
@@ -84,6 +84,21 @@ concept incrementable =
     { __i++ } -> same_as<_Ip>;
   };
 
+// [iterator.concept.iterator]
+template<class _Ip>
+concept input_or_output_iterator =
+  requires(_Ip __i) {
+    { *__i } -> __referenceable;
+  } &&
+  weakly_incrementable<_Ip>;
+
+// [iterator.concept.sentinel]
+template<class _Sp, class _Ip>
+concept sentinel_for =
+  semiregular<_Sp> &&
+  input_or_output_iterator<_Ip> &&
+  __weakly_equality_comparable_with<_Sp, _Ip>;
+
 // clang-format on
 
 #endif // !defined(_LIBCPP_HAS_NO_RANGES)

diff  --git a/libcxx/include/iterator b/libcxx/include/iterator
index 2ec32941029d..151931bc4b0e 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -60,6 +60,14 @@ template<class I>
 template<class I>
   concept incrementable = see below;                       // since C++20
 
+// [iterator.concept.iterator], concept input_­or_­output_­iterator
+  template<class I>
+    concept input_or_output_iterator = see below;          // since C++20
+
+// [iterator.concept.sentinel], concept sentinel_­for
+template<class S, class I>
+  concept sentinel_for = see below;                        // since C++20
+
 template<class Category, class T, class Distance = ptr
diff _t,
          class Pointer = T*, class Reference = T&>
 struct iterator

diff  --git a/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp
index 043e764c4e5b..46cbf2fd3da5 100644
--- a/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp
@@ -19,12 +19,24 @@
 
 using iterator = std::map<int, int>::iterator;
 using const_iterator = std::map<int, int>::const_iterator;
+using reverse_iterator = std::map<int, int>::reverse_iterator;
+using const_reverse_iterator = std::map<int, int>::const_reverse_iterator;
 using value_type = iterator::value_type;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<const_iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);

diff  --git a/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp
index 03bc35e45144..6b1a4a9a5816 100644
--- a/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp
@@ -19,12 +19,24 @@
 
 using iterator = std::multimap<int, int>::iterator;
 using const_iterator = std::multimap<int, int>::const_iterator;
+using reverse_iterator = std::multimap<int, int>::reverse_iterator;
+using const_reverse_iterator = std::multimap<int, int>::const_reverse_iterator;
 using value_type = iterator::value_type;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<const_iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);

diff  --git a/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp
index ba21aa7655a7..a152d2697b34 100644
--- a/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp
@@ -19,12 +19,22 @@
 
 using iterator = std::multiset<int>::iterator;
 using const_iterator = std::multiset<int>::const_iterator;
+using reverse_iterator = std::multiset<int>::reverse_iterator;
+using const_reverse_iterator = std::multiset<int>::const_reverse_iterator;
 using value_type = iterator::value_type;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);

diff  --git a/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp
index 877690d07601..15f32b30fa57 100644
--- a/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp
@@ -19,12 +19,24 @@
 
 using iterator = std::set<int>::iterator;
 using const_iterator = std::set<int>::const_iterator;
+using reverse_iterator = std::set<int>::reverse_iterator;
+using const_reverse_iterator = std::set<int>::const_reverse_iterator;
 using value_type = iterator::value_type;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp
index a6b1bc37ca0d..ee376f290efd 100644
--- a/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp
@@ -19,11 +19,23 @@
 
 using iterator = std::array<int, 10>::iterator;
 using const_iterator = std::array<int, 10>::const_iterator;
+using reverse_iterator = std::array<int, 10>::reverse_iterator;
+using const_reverse_iterator = std::array<int, 10>::const_reverse_iterator;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, int>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, int>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp
index b63deee0a4d6..a3fcc4fa768e 100644
--- a/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp
@@ -19,12 +19,24 @@
 
 using iterator = std::deque<int>::iterator;
 using const_iterator = std::deque<int>::const_iterator;
+using reverse_iterator = std::deque<int>::reverse_iterator;
+using const_reverse_iterator = std::deque<int>::const_reverse_iterator;
 using value_type = iterator::value_type;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp
index 960443d97534..f3953b166f69 100644
--- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp
@@ -24,7 +24,13 @@ using value_type = iterator::value_type;
 static_assert(std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<const_iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp
index 4e2274c229ed..94ea2fdb2e0b 100644
--- a/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp
@@ -19,12 +19,24 @@
 
 using iterator = std::list<int>::iterator;
 using const_iterator = std::list<int>::const_iterator;
+using reverse_iterator = std::list<int>::reverse_iterator;
+using const_reverse_iterator = std::list<int>::const_reverse_iterator;
 using value_type = iterator::value_type;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp
index 2293fc185212..66ffccc34304 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp
@@ -19,12 +19,24 @@
 
 using iterator = std::vector<bool>::iterator;
 using const_iterator = std::vector<bool>::const_iterator;
+using reverse_iterator = std::vector<bool>::reverse_iterator;
+using const_reverse_iterator = std::vector<bool>::const_reverse_iterator;
 using value_type = iterator::value_type;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp
index cf03ae6fd46c..de3e622e3424 100644
--- a/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp
@@ -19,12 +19,24 @@
 
 using iterator = std::vector<int>::iterator;
 using const_iterator = std::vector<int>::const_iterator;
+using reverse_iterator = std::vector<int>::reverse_iterator;
+using const_reverse_iterator = std::vector<int>::const_reverse_iterator;
 using value_type = iterator::value_type;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp
index 07bcb4e93e56..4b760b60a3f6 100644
--- a/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp
@@ -26,15 +26,32 @@ using value_type = iterator::value_type;
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, local_iterator>);
+static_assert(!std::sentinel_for<iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(!std::sentinel_for<const_iterator, local_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<local_iterator>);
-static_assert(!std::indirectly_writable<local_iterator, value_type>);
 static_assert(std::incrementable<local_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(!std::sentinel_for<local_iterator, iterator>);
+static_assert(!std::sentinel_for<local_iterator, const_iterator>);
+static_assert(std::sentinel_for<local_iterator, local_iterator>);
+static_assert(std::sentinel_for<local_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_local_iterator>);
 static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
 static_assert(std::incrementable<const_local_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(!std::sentinel_for<const_local_iterator, iterator>);
+static_assert(!std::sentinel_for<const_local_iterator, const_iterator>);
+static_assert(std::sentinel_for<const_local_iterator, local_iterator>);
+static_assert(std::sentinel_for<const_local_iterator, const_local_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp
index 11c81460c1cd..192576b03ad6 100644
--- a/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp
@@ -26,15 +26,35 @@ using value_type = iterator::value_type;
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, local_iterator>);
+static_assert(!std::sentinel_for<iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, local_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<local_iterator>);
 static_assert(!std::indirectly_writable<local_iterator, value_type>);
 static_assert(std::incrementable<local_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(!std::sentinel_for<local_iterator, iterator>);
+static_assert(!std::sentinel_for<local_iterator, const_iterator>);
+static_assert(std::sentinel_for<local_iterator, local_iterator>);
+static_assert(std::sentinel_for<local_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_local_iterator>);
 static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
 static_assert(std::incrementable<const_local_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(!std::sentinel_for<const_local_iterator, iterator>);
+static_assert(!std::sentinel_for<const_local_iterator, const_iterator>);
+static_assert(std::sentinel_for<const_local_iterator, local_iterator>);
+static_assert(std::sentinel_for<const_local_iterator, const_local_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp
index 925048bb5510..55447ac0c739 100644
--- a/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp
@@ -26,15 +26,35 @@ using value_type = iterator::value_type;
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, local_iterator>);
+static_assert(!std::sentinel_for<iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, local_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<local_iterator>);
 static_assert(!std::indirectly_writable<local_iterator, value_type>);
 static_assert(std::incrementable<local_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(!std::sentinel_for<local_iterator, iterator>);
+static_assert(!std::sentinel_for<local_iterator, const_iterator>);
+static_assert(std::sentinel_for<local_iterator, local_iterator>);
+static_assert(std::sentinel_for<local_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_local_iterator>);
 static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
 static_assert(std::incrementable<const_local_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(!std::sentinel_for<const_local_iterator, iterator>);
+static_assert(!std::sentinel_for<const_local_iterator, const_iterator>);
+static_assert(std::sentinel_for<const_local_iterator, local_iterator>);
+static_assert(std::sentinel_for<const_local_iterator, const_local_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp
index 54e1e905ce2f..7854fbe71475 100644
--- a/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp
@@ -26,15 +26,32 @@ using value_type = iterator::value_type;
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, local_iterator>);
+static_assert(!std::sentinel_for<iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(!std::sentinel_for<const_iterator, local_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<local_iterator>);
-static_assert(!std::indirectly_writable<local_iterator, value_type>);
 static_assert(std::incrementable<local_iterator>);
+static_assert(std::input_or_output_iterator<local_iterator>);
+static_assert(!std::sentinel_for<local_iterator, iterator>);
+static_assert(!std::sentinel_for<local_iterator, const_iterator>);
+static_assert(std::sentinel_for<local_iterator, local_iterator>);
+static_assert(std::sentinel_for<local_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_local_iterator>);
 static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
 static_assert(std::incrementable<const_local_iterator>);
+static_assert(std::input_or_output_iterator<const_local_iterator>);
+static_assert(!std::sentinel_for<const_local_iterator, iterator>);
+static_assert(!std::sentinel_for<const_local_iterator, const_iterator>);
+static_assert(std::sentinel_for<const_local_iterator, local_iterator>);
+static_assert(std::sentinel_for<const_local_iterator, const_local_iterator>);

diff  --git a/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp
index 77236c2e8f57..6273fdd0bf46 100644
--- a/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp
@@ -18,8 +18,12 @@
 #include <iterator>
 
 using iterator = std::span<int>::iterator;
+using reverse_iterator = std::span<int>::reverse_iterator;
 using value_type = iterator::value_type;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);

diff  --git a/libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp
index 70a25c3b4110..527b4447a757 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp
@@ -21,9 +21,13 @@ static_assert(std::indirectly_readable<fs::directory_iterator>);
 static_assert(!std::indirectly_writable<fs::directory_iterator, fs::directory_iterator::value_type>);
 static_assert(std::weakly_incrementable<fs::directory_iterator>);
 static_assert(!std::incrementable<fs::directory_iterator>);
+static_assert(std::input_or_output_iterator<fs::directory_iterator>);
+static_assert(std::sentinel_for<fs::directory_iterator, fs::directory_iterator>);
 
 static_assert(std::indirectly_readable<fs::recursive_directory_iterator>);
 static_assert(
     !std::indirectly_writable<fs::recursive_directory_iterator, fs::recursive_directory_iterator::value_type>);
 static_assert(std::weakly_incrementable<fs::recursive_directory_iterator>);
 static_assert(!std::incrementable<fs::recursive_directory_iterator>);
+static_assert(std::input_or_output_iterator<fs::recursive_directory_iterator>);
+static_assert(std::sentinel_for<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);

diff  --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.iterator/input_or_output_iterator.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.iterator/input_or_output_iterator.compile.pass.cpp
new file mode 100644
index 000000000000..ead0d4ccfafc
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.iterator/input_or_output_iterator.compile.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: gcc-10
+// XFAIL: msvc && clang
+
+// template<class In>
+// concept input_or_output_iterator;
+
+#include <iterator>
+
+#include "test_iterators.h"
+
+static_assert(std::input_or_output_iterator<int*>);
+static_assert(std::input_or_output_iterator<int const*>);
+static_assert(std::input_or_output_iterator<int volatile*>);
+static_assert(std::input_or_output_iterator<int const volatile*>);
+
+static_assert(std::input_or_output_iterator<input_iterator<int*> >);
+static_assert(std::input_or_output_iterator<input_iterator<int const*> >);
+static_assert(std::input_or_output_iterator<input_iterator<int volatile*> >);
+static_assert(std::input_or_output_iterator<input_iterator<int const volatile*> >);
+
+static_assert(std::input_or_output_iterator<forward_iterator<int*> >);
+static_assert(std::input_or_output_iterator<forward_iterator<int const*> >);
+static_assert(std::input_or_output_iterator<forward_iterator<int volatile*> >);
+static_assert(std::input_or_output_iterator<forward_iterator<int const volatile*> >);
+
+static_assert(std::input_or_output_iterator<bidirectional_iterator<int*> >);
+static_assert(std::input_or_output_iterator<bidirectional_iterator<int const*> >);
+static_assert(std::input_or_output_iterator<bidirectional_iterator<int volatile*> >);
+static_assert(std::input_or_output_iterator<bidirectional_iterator<int const volatile*> >);
+
+static_assert(std::input_or_output_iterator<random_access_iterator<int*> >);
+static_assert(std::input_or_output_iterator<random_access_iterator<int const*> >);
+static_assert(std::input_or_output_iterator<random_access_iterator<int volatile*> >);
+static_assert(std::input_or_output_iterator<random_access_iterator<int const volatile*> >);
+
+static_assert(!std::input_or_output_iterator<void*>);
+static_assert(!std::input_or_output_iterator<void const*>);
+static_assert(!std::input_or_output_iterator<void volatile*>);
+static_assert(!std::input_or_output_iterator<void const volatile*>);
+
+struct S {};
+static_assert(!std::input_or_output_iterator<S>);
+static_assert(!std::input_or_output_iterator<int S::*>);
+static_assert(!std::input_or_output_iterator<int (S::*)()>);
+static_assert(!std::input_or_output_iterator<int (S::*)() const>);
+static_assert(!std::input_or_output_iterator<int (S::*)() volatile>);
+
+struct missing_dereference {
+  using 
diff erence_type = std::ptr
diff _t;
+
+  missing_dereference& operator++();
+  missing_dereference& operator++(int);
+};
+static_assert(std::weakly_incrementable<missing_dereference> && !std::input_or_output_iterator<missing_dereference>);
+
+struct void_dereference {
+  using 
diff erence_type = std::ptr
diff _t;
+
+  void operator*();
+  void_dereference& operator++();
+  void_dereference& operator++(int);
+};
+static_assert(std::weakly_incrementable<void_dereference> && !std::input_or_output_iterator<void_dereference>);
+
+struct not_weakly_incrementable {
+  int operator*() const;
+};
+static_assert(!std::input_or_output_iterator<not_weakly_incrementable>);

diff  --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.iterator/subsumption.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.iterator/subsumption.compile.pass.cpp
new file mode 100644
index 000000000000..b169463470cb
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.iterator/subsumption.compile.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: gcc-10
+// XFAIL: msvc && clang
+
+// template<class In>
+// concept input_or_output_iterator;
+
+#include <iterator>
+
+// clang-format off
+template<std::weakly_incrementable>
+[[nodiscard]] constexpr bool check_subsumption() {
+  return false;
+}
+
+template<std::input_or_output_iterator>
+[[nodiscard]] constexpr bool check_subsumption() {
+  return true;
+}
+// clang-format on
+
+static_assert(check_subsumption<int*>());

diff  --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sentinel_for.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sentinel_for.compile.pass.cpp
new file mode 100644
index 000000000000..a0874c907a0a
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sentinel_for.compile.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: gcc-10
+// XFAIL: msvc && clang
+
+// template<class S, class I>
+// concept sentinel_for;
+
+#include <iterator>
+
+static_assert(std::sentinel_for<int*, int*>);
+static_assert(!std::sentinel_for<int*, long*>);
+struct nth_element_sentinel {
+  bool operator==(int*) const;
+};
+static_assert(std::sentinel_for<nth_element_sentinel, int*>);
+static_assert(std::sentinel_for<nth_element_sentinel, int*>);
+
+struct not_semiregular {
+  not_semiregular() = delete;
+  bool operator==(int*) const;
+};
+static_assert(!std::sentinel_for<not_semiregular, int*>);
+
+struct weakly_equality_comparable_with_int {
+  bool operator==(int) const;
+};
+static_assert(!std::sentinel_for<weakly_equality_comparable_with_int, int>);
+
+struct move_only_iterator {
+  using value_type = int;
+  using 
diff erence_type = std::ptr
diff _t;
+
+  move_only_iterator() = default;
+
+  move_only_iterator(move_only_iterator&&) = default;
+  move_only_iterator& operator=(move_only_iterator&&) = default;
+
+  move_only_iterator(move_only_iterator const&) = delete;
+  move_only_iterator& operator=(move_only_iterator const&) = delete;
+
+  value_type operator*() const;
+  move_only_iterator& operator++();
+  move_only_iterator operator++(int);
+
+  bool operator==(move_only_iterator const&) const = default;
+};
+static_assert(std::movable<move_only_iterator> && !std::copyable<move_only_iterator> &&
+              std::input_or_output_iterator<move_only_iterator> &&
+              !std::sentinel_for<move_only_iterator, move_only_iterator>);

diff  --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sentinel_for.subsumption.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sentinel_for.subsumption.compile.pass.cpp
new file mode 100644
index 000000000000..b086affddb8c
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sentinel_for.subsumption.compile.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: gcc-10
+// XFAIL: msvc && clang
+
+// template<class S, class I>
+// concept sentinel_for;
+
+#include <iterator>
+
+#include <concepts>
+#include <vector>
+
+// clang-format off
+template<std::input_or_output_iterator, std::semiregular>
+[[nodiscard]] constexpr bool check_sentinel_subsumption() {
+  return false;
+}
+
+template<class I, std::sentinel_for<I> >
+[[nodiscard]] constexpr bool check_subsumption() {
+  return true;
+}
+// clang-format on
+
+static_assert(check_subsumption<std::vector<int>::iterator, std::vector<int>::iterator>());

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp
index 3d7e99676929..105b2b18befc 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -21,3 +21,5 @@ using iterator = std::back_insert_iterator<std::vector<int> >;
 static_assert(!std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, int>);
 static_assert(!std::weakly_incrementable<iterator>);
+static_assert(!std::input_or_output_iterator<iterator>);
+static_assert(!std::sentinel_for<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp
index 26a8461d9b03..eb02d06c3411 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -21,3 +21,5 @@ using iterator = std::front_insert_iterator<std::list<int> >;
 static_assert(!std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, int>);
 static_assert(!std::weakly_incrementable<iterator>);
+static_assert(!std::input_or_output_iterator<iterator>);
+static_assert(!std::sentinel_for<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/iterator_concept_conformance.compile.pass.cpp
index e63d209877e7..9376157d5704 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -21,3 +21,5 @@ using iterator = std::insert_iterator<std::vector<int> >;
 static_assert(!std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, int>);
 static_assert(!std::weakly_incrementable<iterator>);
+static_assert(!std::input_or_output_iterator<iterator>);
+static_assert(!std::sentinel_for<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp
index 76329e43aaa1..49f392e9f832 100644
--- a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -19,3 +19,5 @@ using iterator = std::move_iterator<int*>;
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, int>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp
index c610c3073ff0..2ea97d934de4 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp
@@ -16,6 +16,12 @@
 #include <iterator>
 
 using iterator = std::reverse_iterator<int*>;
+
 static_assert(std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, int>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+
+using other_iterator = std::reverse_iterator<float*>;
+static_assert(std::sentinel_for<iterator, other_iterator>);

diff  --git a/libcxx/test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp
index 9d84b7b6faaf..1b4da23363dd 100644
--- a/libcxx/test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -21,3 +21,5 @@ using iterator = std::istream_iterator<int, std::istream>;
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, int>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
index 52d6006f226c..ef50781234b2 100644
--- a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -23,3 +23,5 @@ static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, char>);
 static_assert(std::weakly_incrementable<iterator>);
 static_assert(!std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp
index 9bab69ee2633..d68c33b54d77 100644
--- a/libcxx/test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -21,3 +21,5 @@ using iterator = std::ostream_iterator<int, std::ostream>;
 static_assert(!std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, int>);
 static_assert(!std::weakly_incrementable<iterator>);
+static_assert(!std::input_or_output_iterator<iterator>);
+static_assert(!std::sentinel_for<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
index cd2bba45b936..c2743c2ab3c2 100644
--- a/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -22,3 +22,5 @@ using iterator = std::ostreambuf_iterator<char>;
 static_assert(!std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, char>);
 static_assert(!std::weakly_incrementable<iterator>);
+static_assert(!std::input_or_output_iterator<iterator>);
+static_assert(!std::sentinel_for<iterator, iterator>);

diff  --git a/libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp
index c55bc00b395f..38565e4300ec 100644
--- a/libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp
@@ -20,3 +20,5 @@
 static_assert(std::indirectly_readable<std::cregex_iterator>);
 static_assert(!std::indirectly_writable<std::cregex_iterator, char>);
 static_assert(std::incrementable<std::cregex_iterator>);
+static_assert(std::input_or_output_iterator<std::cregex_iterator>);
+static_assert(std::sentinel_for<std::cregex_iterator, std::cregex_iterator>);

diff  --git a/libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp
index 50cae5607be9..63027cb709f7 100644
--- a/libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp
@@ -20,3 +20,5 @@
 static_assert(std::indirectly_readable<std::cregex_token_iterator>);
 static_assert(!std::indirectly_writable<std::cregex_token_iterator, char>);
 static_assert(std::incrementable<std::cregex_token_iterator>);
+static_assert(std::input_or_output_iterator<std::cregex_token_iterator>);
+static_assert(std::sentinel_for<std::cregex_token_iterator, std::cregex_token_iterator>);

diff  --git a/libcxx/test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp
index 838a71c03a0c..8ff56b9482d7 100644
--- a/libcxx/test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp
@@ -19,12 +19,23 @@
 
 using iterator = std::string::iterator;
 using const_iterator = std::string::const_iterator;
+using reverse_iterator = std::string::reverse_iterator;
+using const_reverse_iterator = std::string::const_reverse_iterator;
 using value_type = iterator::value_type;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(std::indirectly_writable<iterator, value_type>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);

diff  --git a/libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp
index 29292f881d68..5a4fe8701cd9 100644
--- a/libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp
@@ -19,11 +19,23 @@
 
 using iterator = std::string_view::iterator;
 using const_iterator = std::string_view::const_iterator;
+using reverse_iterator = std::string_view::reverse_iterator;
+using const_reverse_iterator = std::string_view::const_reverse_iterator;
 
 static_assert(std::indirectly_readable<iterator>);
 static_assert(!std::indirectly_writable<iterator, char>);
 static_assert(std::incrementable<iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, char>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
+static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);


        


More information about the libcxx-commits mailing list