[libcxx-commits] [libcxx] c05d1ee - [libcxx][iterator][ranges] adds `input_iterator` and `input_range`

Christopher Di Bella via libcxx-commits libcxx-commits at lists.llvm.org
Fri Apr 30 15:49:31 PDT 2021


Author: Christopher Di Bella
Date: 2021-04-30T22:49:06Z
New Revision: c05d1eed35f5284c1eafc86e26cf0a304fb0a35b

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

LOG: [libcxx][iterator][ranges] adds `input_iterator` and `input_range`

Implements parts of:
    * P0896R4 The One Ranges Proposal`

Depends on D100269.

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

Added: 
    libcxx/test/libcxx/iterators/iterator.concepts/iterator.concept.input/subsumption.compile.pass.cpp
    libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/input_iterator.compile.pass.cpp
    libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/subsumption.compile.pass.cpp
    libcxx/test/std/ranges/range.refinements/input_range.compile.pass.cpp
    libcxx/test/std/ranges/range.refinements/subsumption.compile.pass.cpp

Modified: 
    libcxx/include/__iterator/concepts.h
    libcxx/include/__ranges/concepts.h
    libcxx/include/iterator
    libcxx/include/ranges
    libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/views/range_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/input.output/filesystems/class.directory_iterator/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/range_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/re/re.results/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/strings/basic.string/range_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/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/support/test_iterators.h
    libcxx/test/support/test_macros.h
    libcxx/test/support/test_range.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h
index 445a88fcb944..df94cf6b3581 100644
--- a/libcxx/include/__iterator/concepts.h
+++ b/libcxx/include/__iterator/concepts.h
@@ -111,6 +111,14 @@ concept sized_sentinel_for =
     { __i - __s } -> same_as<iter_
diff erence_t<_Ip> >;
   };
 
+// [iterator.concept.input]
+template<class _Ip>
+concept input_iterator =
+  input_or_output_iterator<_Ip> &&
+  indirectly_readable<_Ip> &&
+  requires { typename _ITER_CONCEPT<_Ip>; } &&
+  derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>;
+
 // clang-format on
 
 #endif // !defined(_LIBCPP_HAS_NO_RANGES)

diff  --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h
index aeed55ce07ec..bccb8f64a2a1 100644
--- a/libcxx/include/__ranges/concepts.h
+++ b/libcxx/include/__ranges/concepts.h
@@ -51,6 +51,9 @@ namespace ranges {
   using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp> >;
 
   // [range.refinements], other range refinements
+  template <class _Tp>
+  concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp> >;
+
   template <class _Tp>
   concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp> >;
 } // namespace ranges

diff  --git a/libcxx/include/iterator b/libcxx/include/iterator
index 5be87e155a8c..d759eae914ac 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -75,6 +75,10 @@ template<class S, class I>
 template<class S, class I>
   concept sized_sentinel_for = see below;
 
+// [iterator.concept.input], concept input_iterator
+template<class I>
+  concept input_iterator = 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/include/ranges b/libcxx/include/ranges
index a4eda8d33221..ca9f648921dc 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -48,6 +48,9 @@ namespace std::ranges {
     using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
 
   // [range.refinements], other range refinements
+  template<class T>
+    concept input_range = see below;
+
   template <class _Tp>
     concept common_range = see below;
 }

diff  --git a/libcxx/test/libcxx/iterators/iterator.concepts/iterator.concept.input/subsumption.compile.pass.cpp b/libcxx/test/libcxx/iterators/iterator.concepts/iterator.concept.input/subsumption.compile.pass.cpp
new file mode 100644
index 000000000000..73520d965253
--- /dev/null
+++ b/libcxx/test/libcxx/iterators/iterator.concepts/iterator.concept.input/subsumption.compile.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 T>
+// concept input_iterator;
+
+#include <iterator>
+
+#include <concepts>
+
+// clang-format off
+template<std::input_or_output_iterator I>
+requires std::indirectly_readable<I> &&
+         std::derived_from<std::_ITER_CONCEPT<I>, std::input_iterator_tag>
+[[nodiscard]] constexpr bool check_subsumption() {
+  return false;
+}
+
+template<std::input_iterator>
+[[nodiscard]] constexpr bool check_subsumption() {
+  return true;
+}
+// clang-format on
+
+static_assert(check_subsumption<int*>());

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 c205496387ff..82fd0fd9b25a 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
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);

diff  --git a/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp
index 4918db186d49..e778d81862ce 100644
--- a/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 18b5f793d164..d020d7d8d5d4 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
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);

diff  --git a/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp
index 9443d3fa419a..d0c0e383184c 100644
--- a/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 62f287dee3b3..0f86ddf42dd5 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
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);

diff  --git a/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp
index ae1745d2ef23..c6a2e1345efb 100644
--- a/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 f702f3d6c72b..bf62926bfe76 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
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);

diff  --git a/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp
index 8ba25cbf75a3..7e0fdf6cb414 100644
--- a/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range>);

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 958864bc6519..58ac42dfb805 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
@@ -47,3 +47,4 @@ static_assert(std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp
index a44354dd6297..f2762d4bacc2 100644
--- a/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 c40267d73a38..4de9eb9b753b 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
@@ -48,3 +48,4 @@ static_assert(std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp
index 50e94f71d9e9..c9bdb9ec1d6a 100644
--- a/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 88a5d607afda..c00151f9ab9e 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
@@ -29,6 +29,7 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(std::input_iterator<iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -38,3 +39,4 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(std::input_iterator<const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp
index 32bc9fa416d1..c412813b5664 100644
--- a/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 d468744ceda7..a1c0885c231b 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
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -48,3 +49,4 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp
index b958ce68b7e5..f567d2aab4f9 100644
--- a/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 dc06fff2fca7..1c1d95b17d03 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
@@ -48,3 +48,4 @@ static_assert(std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp
index 8127962c9e02..7647ab51ee74 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 a0ba9b24b868..eca4830a00f2 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
@@ -48,3 +48,4 @@ static_assert(std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp
index 4c807fe8c31f..e384a44043bd 100644
--- a/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 343d2963e8d7..e694881e9e81 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
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
+static_assert(std::input_iterator<iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -48,6 +49,7 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_iterator>);
 
 static_assert(std::indirectly_readable<local_iterator>);
 static_assert(!std::indirectly_writable<local_iterator, value_type>);
@@ -61,6 +63,7 @@ static_assert(!std::sized_sentinel_for<local_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<local_iterator>);
 
 static_assert(std::indirectly_readable<const_local_iterator>);
 static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
@@ -74,3 +77,4 @@ static_assert(!std::sized_sentinel_for<const_local_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_local_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp
index c5abbae2d27a..acbdcc92769a 100644
--- a/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 c4580f29f6bb..d0c61cfebdc4 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
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
+static_assert(std::input_iterator<iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -48,6 +49,7 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_iterator>);
 
 static_assert(std::indirectly_readable<local_iterator>);
 static_assert(!std::indirectly_writable<local_iterator, value_type>);
@@ -61,6 +63,7 @@ static_assert(!std::sized_sentinel_for<local_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<local_iterator>);
 
 static_assert(std::indirectly_readable<const_local_iterator>);
 static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
@@ -74,3 +77,4 @@ static_assert(!std::sized_sentinel_for<const_local_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_local_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp
index 9de46840efa5..98b6a07c1355 100644
--- a/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 4da07112cb51..c9990e33b48b 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
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
+static_assert(std::input_iterator<iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -48,6 +49,7 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_iterator>);
 
 static_assert(std::indirectly_readable<local_iterator>);
 static_assert(!std::indirectly_writable<local_iterator, value_type>);
@@ -61,6 +63,7 @@ static_assert(!std::sized_sentinel_for<local_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<local_iterator>);
 
 static_assert(std::indirectly_readable<const_local_iterator>);
 static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
@@ -74,3 +77,4 @@ static_assert(!std::sized_sentinel_for<const_local_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_local_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp
index 45b7a66040e0..128aa003c7e9 100644
--- a/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 e731e8bb5f6c..607f992bdffc 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
@@ -31,6 +31,7 @@ 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::input_iterator<iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -38,6 +39,7 @@ 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::input_iterator<const_iterator>);
 
 static_assert(std::indirectly_readable<local_iterator>);
 static_assert(std::incrementable<local_iterator>);
@@ -46,6 +48,7 @@ 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::input_iterator<local_iterator>);
 
 static_assert(std::indirectly_readable<const_local_iterator>);
 static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
@@ -55,3 +58,4 @@ 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>);
+static_assert(std::input_iterator<const_local_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp
index 4c84bbfa3c41..d266fddb16fa 100644
--- a/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

diff  --git a/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp
index 696ee6a6508a..cb26ed6d7cc5 100644
--- a/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::iterator>);
 static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);

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 ba500b7e0847..0c6aa7dd52c7 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
@@ -29,3 +29,4 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(!std::sentinel_for<iterator, reverse_iterator>);
 static_assert(std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(std::input_iterator<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 af1ce0f69ef8..c14291557432 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
@@ -26,6 +26,7 @@ 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::sized_sentinel_for<fs::directory_iterator, fs::directory_iterator>);
+static_assert(std::input_iterator<fs::directory_iterator>);
 
 static_assert(std::indirectly_readable<fs::recursive_directory_iterator>);
 static_assert(!std::indirectly_writable<fs::recursive_directory_iterator, value_type>);
@@ -34,3 +35,4 @@ 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>);
 static_assert(!std::sized_sentinel_for<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
+static_assert(std::input_iterator<fs::recursive_directory_iterator>);

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 27e96a741782..8b80681aa377 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
@@ -22,12 +22,16 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<fs::directory_iterator>, fs::directory_iterator>);
 static_assert(stdr::common_range<fs::directory_iterator>);
+static_assert(stdr::input_range<fs::directory_iterator>);
 
 static_assert(std::same_as<stdr::iterator_t<fs::directory_iterator const>, fs::directory_iterator>);
 static_assert(stdr::common_range<fs::directory_iterator const>);
+static_assert(stdr::input_range<fs::directory_iterator const>);
 
 static_assert(std::same_as<stdr::iterator_t<fs::recursive_directory_iterator>, fs::recursive_directory_iterator>);
 static_assert(stdr::common_range<fs::recursive_directory_iterator>);
+static_assert(stdr::input_range<fs::directory_iterator>);
 
 static_assert(std::same_as<stdr::iterator_t<fs::recursive_directory_iterator const>, fs::recursive_directory_iterator>);
 static_assert(stdr::common_range<fs::recursive_directory_iterator const>);
+static_assert(stdr::input_range<fs::directory_iterator const>);

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp
index 163130bf0918..9db60e440912 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp
@@ -22,6 +22,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<fs::path>, fs::path::iterator>);
 static_assert(stdr::common_range<fs::path>);
+static_assert(stdr::input_range<fs::path>);
 
 static_assert(std::same_as<stdr::iterator_t<fs::path const>, fs::path::const_iterator>);
 static_assert(stdr::common_range<fs::path const>);
+static_assert(stdr::input_range<fs::path const>);

diff  --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/input_iterator.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/input_iterator.compile.pass.cpp
new file mode 100644
index 000000000000..59c64f4dcd0b
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/input_iterator.compile.pass.cpp
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 T>
+// concept input_iterator;
+
+#include <iterator>
+
+#include "test_iterators.h"
+
+static_assert(std::input_iterator<input_iterator<int*> >);
+static_assert(std::input_iterator<cpp20_input_iterator<int*> >);
+
+struct no_explicit_iter_concept {
+  using value_type = int;
+  using 
diff erence_type = std::ptr
diff _t;
+
+  no_explicit_iter_concept() = default;
+
+  no_explicit_iter_concept(no_explicit_iter_concept&&) = default;
+  no_explicit_iter_concept& operator=(no_explicit_iter_concept&&) = default;
+
+  no_explicit_iter_concept(no_explicit_iter_concept const&) = delete;
+  no_explicit_iter_concept& operator=(no_explicit_iter_concept const&) = delete;
+
+  value_type operator*() const;
+
+  no_explicit_iter_concept& operator++();
+  void operator++(int);
+};
+// ITER-CONCEPT is `random_access_iterator_tag` >:(
+static_assert(std::input_iterator<no_explicit_iter_concept>);
+
+static_assert(std::input_iterator<int*>);
+static_assert(std::input_iterator<int const*>);
+static_assert(std::input_iterator<int volatile*>);
+static_assert(std::input_iterator<int const volatile*>);
+
+struct not_weakly_incrementable {
+  using 
diff erence_type = std::ptr
diff _t;
+  using iterator_concept = std::input_iterator_tag;
+
+  not_weakly_incrementable() = default;
+
+  not_weakly_incrementable(not_weakly_incrementable&&) = default;
+  not_weakly_incrementable& operator=(not_weakly_incrementable&&) = default;
+
+  not_weakly_incrementable(not_weakly_incrementable const&) = delete;
+  not_weakly_incrementable& operator=(not_weakly_incrementable const&) = delete;
+
+  int operator*() const;
+
+  not_weakly_incrementable& operator++();
+};
+static_assert(!std::input_or_output_iterator<not_weakly_incrementable> &&
+              !std::input_iterator<not_weakly_incrementable>);
+
+struct not_indirectly_readable {
+  using 
diff erence_type = std::ptr
diff _t;
+  using iterator_concept = std::input_iterator_tag;
+
+  not_indirectly_readable() = default;
+
+  not_indirectly_readable(not_indirectly_readable&&) = default;
+  not_indirectly_readable& operator=(not_indirectly_readable&&) = default;
+
+  not_indirectly_readable(not_indirectly_readable const&) = delete;
+  not_indirectly_readable& operator=(not_indirectly_readable const&) = delete;
+
+  int operator*() const;
+
+  not_indirectly_readable& operator++();
+  void operator++(int);
+};
+static_assert(!std::indirectly_readable<not_indirectly_readable> && !std::input_iterator<not_indirectly_readable>);
+
+struct bad_iterator_category {
+  using value_type = int;
+  using 
diff erence_type = std::ptr
diff _t;
+  using iterator_category = void;
+
+  bad_iterator_category() = default;
+
+  bad_iterator_category(bad_iterator_category&&) = default;
+  bad_iterator_category& operator=(bad_iterator_category&&) = default;
+
+  bad_iterator_category(bad_iterator_category const&) = delete;
+  bad_iterator_category& operator=(bad_iterator_category const&) = delete;
+
+  value_type operator*() const;
+
+  bad_iterator_category& operator++();
+  void operator++(int);
+};
+static_assert(!std::input_iterator<bad_iterator_category>);
+
+struct bad_iterator_concept {
+  using value_type = int;
+  using 
diff erence_type = std::ptr
diff _t;
+  using iterator_concept = void*;
+
+  bad_iterator_concept() = default;
+
+  bad_iterator_concept(bad_iterator_concept&&) = default;
+  bad_iterator_concept& operator=(bad_iterator_concept&&) = default;
+
+  bad_iterator_concept(bad_iterator_concept const&) = delete;
+  bad_iterator_concept& operator=(bad_iterator_concept const&) = delete;
+
+  value_type operator*() const;
+
+  bad_iterator_concept& operator++();
+  void operator++(int);
+};
+static_assert(!std::input_iterator<bad_iterator_concept>);

diff  --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/subsumption.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/subsumption.compile.pass.cpp
new file mode 100644
index 000000000000..3a18b8a25f94
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/subsumption.compile.pass.cpp
@@ -0,0 +1 @@
+// Due to the need to check _ITER_CONCEPT, this test  is located in `test/libcxx/iterators/iterator.concepts/iterator.concept.input/subsumption.compile.pass.cpp`.

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 5bc7b713a1c3..c6cd99ef988f 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
@@ -24,3 +24,4 @@ static_assert(!std::weakly_incrementable<iterator>);
 static_assert(!std::input_or_output_iterator<iterator>);
 static_assert(!std::sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::input_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 413c31de2b33..ada856316e7b 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
@@ -24,3 +24,4 @@ static_assert(!std::weakly_incrementable<iterator>);
 static_assert(!std::input_or_output_iterator<iterator>);
 static_assert(!std::sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::input_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 9376157d5704..e7dc46579084 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
@@ -23,3 +23,4 @@ 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>);
+static_assert(!std::input_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 485df7cbce21..7d6325caa24f 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
@@ -22,3 +22,4 @@ static_assert(std::incrementable<iterator>);
 static_assert(std::input_or_output_iterator<iterator>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::input_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 f5b908229ed0..4df9058fffaf 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
@@ -23,6 +23,7 @@ static_assert(std::incrementable<iterator>);
 static_assert(std::input_or_output_iterator<iterator>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::input_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 6db860338860..514ba4180433 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
@@ -24,3 +24,4 @@ static_assert(std::incrementable<iterator>);
 static_assert(std::input_or_output_iterator<iterator>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::input_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 2cbe4e087434..70da02944a35 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
@@ -26,3 +26,4 @@ static_assert(!std::incrementable<iterator>);
 static_assert(std::input_or_output_iterator<iterator>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::input_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 efe5a1718037..c0fe91725f0b 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
@@ -24,3 +24,4 @@ static_assert(!std::weakly_incrementable<iterator>);
 static_assert(!std::input_or_output_iterator<iterator>);
 static_assert(!std::sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::input_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 fc28ce9f1aac..86abbc09e95d 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
@@ -25,3 +25,4 @@ static_assert(!std::weakly_incrementable<iterator>);
 static_assert(!std::input_or_output_iterator<iterator>);
 static_assert(!std::sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::input_iterator<iterator>);

diff  --git a/libcxx/test/std/ranges/range.refinements/input_range.compile.pass.cpp b/libcxx/test/std/ranges/range.refinements/input_range.compile.pass.cpp
new file mode 100644
index 000000000000..8ca888533cc7
--- /dev/null
+++ b/libcxx/test/std/ranges/range.refinements/input_range.compile.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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<range _Rp>
+// concept input_range;
+
+#include <ranges>
+
+#include "test_range.h"
+
+namespace stdr = std::ranges;
+
+static_assert(stdr::input_range<test_range<input_iterator> >);
+static_assert(stdr::input_range<test_range<input_iterator> const>);
+
+static_assert(stdr::input_range<test_range<cpp20_input_iterator> >);
+static_assert(stdr::input_range<test_range<cpp20_input_iterator> const>);
+
+static_assert(stdr::input_range<test_non_const_range<input_iterator> >);
+static_assert(stdr::input_range<test_non_const_range<cpp20_input_iterator> >);
+
+static_assert(!stdr::input_range<test_non_const_range<input_iterator> const>);
+static_assert(!stdr::input_range<test_non_const_range<cpp20_input_iterator> const>);
+
+static_assert(stdr::input_range<test_common_range<input_iterator> >);
+static_assert(!stdr::input_range<test_common_range<cpp20_input_iterator> >);
+
+static_assert(stdr::input_range<test_common_range<input_iterator> const>);
+static_assert(!stdr::input_range<test_common_range<cpp20_input_iterator> const>);
+
+static_assert(stdr::input_range<test_non_const_common_range<input_iterator> >);
+static_assert(!stdr::input_range<test_non_const_common_range<cpp20_input_iterator> >);
+
+static_assert(!stdr::input_range<test_non_const_common_range<input_iterator> const>);
+static_assert(!stdr::input_range<test_non_const_common_range<cpp20_input_iterator> const>);

diff  --git a/libcxx/test/std/ranges/range.refinements/subsumption.compile.pass.cpp b/libcxx/test/std/ranges/range.refinements/subsumption.compile.pass.cpp
new file mode 100644
index 000000000000..681146b4f918
--- /dev/null
+++ b/libcxx/test/std/ranges/range.refinements/subsumption.compile.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 T>
+// concept input_iterator;
+
+#include <ranges>
+
+#include <iterator>
+
+struct range {
+  int* begin();
+  int* end();
+};
+
+// clang-format off
+template<std::ranges::range R>
+requires std::input_iterator<std::ranges::iterator_t<R> >
+[[nodiscard]] constexpr bool check_input_range_subsumption() {
+  return false;
+}
+
+template<std::ranges::input_range>
+requires true
+[[nodiscard]] constexpr bool check_input_range_subsumption() {
+  return true;
+}
+// clang-format on
+
+static_assert(check_input_range_subsumption<range>());

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 897e744e19bb..19caf08e7630 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
@@ -23,3 +23,4 @@ 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>);
 static_assert(!std::sized_sentinel_for<std::cregex_iterator, std::cregex_iterator>);
+static_assert(std::input_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 f94382fe71d4..17a49fedce66 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
@@ -23,3 +23,4 @@ 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>);
 static_assert(!std::sized_sentinel_for<std::cregex_token_iterator, std::cregex_token_iterator>);
+static_assert(std::input_iterator<std::cregex_token_iterator>);

diff  --git a/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp
index 10f48a967b77..22eb3b470689 100644
--- a/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp
@@ -22,6 +22,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<std::cmatch>, std::cmatch::iterator>);
 static_assert(stdr::common_range<std::cmatch>);
+static_assert(stdr::input_range<std::cmatch>);
 
 static_assert(std::same_as<stdr::iterator_t<std::cmatch const>, std::cmatch::const_iterator>);
 static_assert(stdr::common_range<std::cmatch const>);
+static_assert(stdr::input_range<std::cmatch const>);

diff  --git a/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp
index c352dda37a6d..2d07397d7de6 100644
--- a/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp
@@ -22,6 +22,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<std::string>, std::string::iterator>);
 static_assert(stdr::common_range<std::string>);
+static_assert(stdr::input_range<std::string>);
 
 static_assert(std::same_as<stdr::iterator_t<std::string const>, std::string::const_iterator>);
 static_assert(stdr::common_range<std::string const>);
+static_assert(stdr::input_range<std::string const>);

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 616fdf6655c0..cae57203cfb8 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
@@ -47,3 +47,4 @@ static_assert(std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);

diff  --git a/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp
index 595a12fc3d69..7fbafdc2a7d7 100644
--- a/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp
@@ -22,6 +22,8 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<std::string_view>, std::string_view::iterator>);
 static_assert(stdr::common_range<std::string_view>);
+static_assert(stdr::input_range<std::string_view>);
 
 static_assert(std::same_as<stdr::iterator_t<std::string_view const>, std::string_view::const_iterator>);
 static_assert(stdr::common_range<std::string_view const>);
+static_assert(stdr::input_range<std::string_view const>);

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 409f19788419..adb21bc29b47 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
@@ -47,3 +47,4 @@ static_assert(std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);

diff  --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
index cc5d018d0d75..cea849f647ab 100644
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -632,6 +632,43 @@ template <typename T>
 bool operator!= (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
 {   return !a.operator==(b); }
 
+#ifdef TEST_SUPPORTS_RANGES
+
+template <class I>
+struct cpp20_input_iterator {
+  using value_type = std::iter_value_t<I>;
+  using 
diff erence_type = std::iter_
diff erence_t<I>;
+  using iterator_concept = std::input_iterator_tag;
+
+  cpp20_input_iterator() = default;
+
+  cpp20_input_iterator(cpp20_input_iterator&&) = default;
+  cpp20_input_iterator& operator=(cpp20_input_iterator&&) = default;
+
+  cpp20_input_iterator(cpp20_input_iterator const&) = delete;
+  cpp20_input_iterator& operator=(cpp20_input_iterator const&) = delete;
+
+  explicit constexpr cpp20_input_iterator(I base) : base_(std::move(base)) {}
+
+  constexpr decltype(auto) operator*() const { return *base_; }
+
+  cpp20_input_iterator& operator++() {
+    ++base_;
+    return *this;
+  }
+
+  void operator++(int) { ++base_; }
+
+  [[nodiscard]] I const& base() const& { return base_; }
+
+  [[nodiscard]] I base() && { return std::move(base_); }
+
+private:
+  I base_ = I();
+};
+
+#endif // TEST_STD_VER > 17 && defined(__cpp_lib_concepts)
+
 #undef DELETE_FUNCTION
 
 #endif // ITERATORS_H

diff  --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index 82a8511ecf59..c39e79b93744 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -312,6 +312,10 @@
 #define LIBCPP_ONLY(...) ((void)0)
 #endif
 
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+#define TEST_SUPPORTS_RANGES
+#endif
+
 #define TEST_IGNORE_NODISCARD (void)
 
 namespace test_macros_detail {

diff  --git a/libcxx/test/support/test_range.h b/libcxx/test/support/test_range.h
index 3e9c94abb8ec..1b13deaedf8c 100644
--- a/libcxx/test/support/test_range.h
+++ b/libcxx/test/support/test_range.h
@@ -18,7 +18,7 @@
 #endif
 
 struct sentinel {
-  bool operator==(std::input_or_output_iterator auto) const;
+  bool operator==(std::input_or_output_iterator auto const&) const;
 };
 
 // clang-format off


        


More information about the libcxx-commits mailing list