[libcxx-commits] [libcxx] 6ffc41b - [libcxx][ranges] Add `random_access_{iterator, range}`.

via libcxx-commits libcxx-commits at lists.llvm.org
Tue May 4 21:43:02 PDT 2021


Author: zoecarver
Date: 2021-05-04T21:42:55-07:00
New Revision: 6ffc41b014f304a76f9a7eab39c122e0a9d7fcb8

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

LOG: [libcxx][ranges] Add `random_access_{iterator,range}`.

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

Added: 
    libcxx/test/libcxx/iterators/iterator.concepts/iterator.concept.random.access/subsumption.compile.pass.cpp
    libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/random_access_iterator.compile.pass.cpp
    libcxx/test/std/ranges/range.refinements/random_access_range.compile.pass.cpp

Modified: 
    libcxx/include/__iterator/concepts.h
    libcxx/include/__ranges/concepts.h
    libcxx/include/iterator
    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/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/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.path/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp
    libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/ranges/range.refinements/subsumption.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

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h
index c83fd92364c8..0dd8a72210ee 100644
--- a/libcxx/include/__iterator/concepts.h
+++ b/libcxx/include/__iterator/concepts.h
@@ -137,7 +137,22 @@ concept bidirectional_iterator =
     { __i-- } -> same_as<_Ip>;
   };
 
-  // clang-format on
+template<class _Ip>
+concept random_access_iterator =
+  bidirectional_iterator<_Ip> &&
+  derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> &&
+  totally_ordered<_Ip> &&
+  sized_sentinel_for<_Ip, _Ip> &&
+  requires(_Ip __i, const _Ip __j, const iter_
diff erence_t<_Ip> __n) {
+    { __i += __n } -> same_as<_Ip&>;
+    { __j +  __n } -> same_as<_Ip>;
+    { __n +  __j } -> same_as<_Ip>;
+    { __i -= __n } -> same_as<_Ip&>;
+    { __j -  __n } -> same_as<_Ip>;
+    {  __j[__n]  } -> same_as<iter_reference_t<_Ip>>;
+  };
+
+// clang-format on
 
 #endif // !defined(_LIBCPP_HAS_NO_RANGES)
 

diff  --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h
index 578b153ad00e..8c28df35fefe 100644
--- a/libcxx/include/__ranges/concepts.h
+++ b/libcxx/include/__ranges/concepts.h
@@ -62,6 +62,10 @@ namespace ranges {
 
   template <class _Tp>
   concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp> >;
+
+  template <class _Tp>
+  concept random_access_range =
+      bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp> >;
 } // namespace ranges
 
 #endif // !defined(_LIBCPP_HAS_NO_RANGES)

diff  --git a/libcxx/include/iterator b/libcxx/include/iterator
index 97677feee030..ad98d8ca7b70 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -87,6 +87,10 @@ template<class I>
 template<class I>
   concept bidirectional_iterator = see below;              // since C++20
 
+// [iterator.concept.random.access], concept random_access_iterator
+template<class I>
+  concept random_access_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/test/libcxx/iterators/iterator.concepts/iterator.concept.random.access/subsumption.compile.pass.cpp b/libcxx/test/libcxx/iterators/iterator.concepts/iterator.concept.random.access/subsumption.compile.pass.cpp
new file mode 100644
index 000000000000..4730307d8a51
--- /dev/null
+++ b/libcxx/test/libcxx/iterators/iterator.concepts/iterator.concept.random.access/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
+
+// template<class T>
+// concept random_access_iterator;
+
+#include <iterator>
+
+#include <concepts>
+
+template<std::bidirectional_iterator I>
+requires std::derived_from<std::_ITER_CONCEPT<I>, std::random_access_iterator_tag>
+constexpr bool check_subsumption() {
+  return false;
+}
+
+template<std::random_access_iterator>
+constexpr bool check_subsumption() {
+  return true;
+}
+
+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 1f2707a9c9eb..c74dcfa5a747 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
@@ -23,6 +23,7 @@ using const_reverse_iterator = std::map<int, int>::const_reverse_iterator;
 using value_type = std::pair<const int, int>;
 
 static_assert(std::bidirectional_iterator<iterator>);
+static_assert(!std::random_access_iterator<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
@@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::bidirectional_iterator<const_iterator>);
+static_assert(!std::random_access_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);

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 cd2b299816c6..8cf2edc0fd75 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
@@ -24,8 +24,10 @@ static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
 static_assert(stdr::bidirectional_range<range>);
 static_assert(!stdr::view<range>);
+static_assert(!stdr::random_access_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::bidirectional_range<range const>);
 static_assert(!stdr::view<range const>);
+static_assert(!stdr::random_access_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 1f223d9984a6..21a612ac350e 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
@@ -23,6 +23,7 @@ using const_reverse_iterator = std::multimap<int, int>::const_reverse_iterator;
 using value_type = std::pair<const int, int>;
 
 static_assert(std::bidirectional_iterator<iterator>);
+static_assert(!std::random_access_iterator<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
@@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::bidirectional_iterator<const_iterator>);
+static_assert(!std::random_access_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);

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 46975cde7300..8113a791fb99 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
@@ -24,8 +24,10 @@ static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
 static_assert(stdr::bidirectional_range<range>);
 static_assert(!stdr::view<range>);
+static_assert(!stdr::random_access_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::bidirectional_range<range const>);
 static_assert(!stdr::view<range const>);
+static_assert(!stdr::random_access_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 f09efa6aed00..6c89f2df7d7f 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
@@ -23,6 +23,7 @@ using const_reverse_iterator = std::multiset<int>::const_reverse_iterator;
 using value_type = int;
 
 static_assert(std::bidirectional_iterator<iterator>);
+static_assert(!std::random_access_iterator<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
@@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::bidirectional_iterator<const_iterator>);
+static_assert(!std::random_access_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(std::sentinel_for<const_iterator, iterator>);

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 40db2fe172e8..549b081d417b 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
@@ -24,8 +24,10 @@ static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
 static_assert(stdr::bidirectional_range<range>);
 static_assert(!stdr::view<range>);
+static_assert(!stdr::random_access_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::bidirectional_range<range const>);
 static_assert(!stdr::view<range const>);
+static_assert(!stdr::random_access_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 662bf74fa261..f33771f20926 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
@@ -23,6 +23,7 @@ using const_reverse_iterator = std::set<int>::const_reverse_iterator;
 using value_type = int;
 
 static_assert(std::bidirectional_iterator<iterator>);
+static_assert(!std::random_access_iterator<iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
@@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::bidirectional_iterator<const_iterator>);
+static_assert(!std::random_access_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);

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 30bae62187dd..987d46b067ea 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
@@ -21,11 +21,15 @@ using range = std::set<int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::bidirectional_range<range>);
+static_assert(!stdr::random_access_range<range>);
 static_assert(stdr::common_range<range>);
 static_assert(stdr::input_range<range>);
 static_assert(!stdr::view<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::bidirectional_range<range const>);
+static_assert(!stdr::random_access_range<range const>);
 static_assert(stdr::common_range<range const>);
 static_assert(stdr::input_range<range>);
 static_assert(!stdr::view<range const>);

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 2816cd29b6f3..3010bd367804 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
@@ -21,7 +21,7 @@ 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::bidirectional_iterator<iterator>);
+static_assert(std::random_access_iterator<iterator>);
 static_assert(std::indirectly_writable<iterator, int>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
@@ -32,7 +32,7 @@ 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::bidirectional_iterator<const_iterator>);
+static_assert(std::random_access_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, int>);
 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/array/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp
index 7794dfe1f58f..e62c086fc71b 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
@@ -20,12 +20,13 @@
 using range = std::array<int, 10>;
 namespace stdr = std::ranges;
 
+static_assert(!stdr::view<range>);
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
-static_assert(stdr::bidirectional_range<range>);
-static_assert(!stdr::view<range>);
+static_assert(stdr::random_access_range<range>);
+
 
+static_assert(!stdr::view<range const>);
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
-static_assert(stdr::bidirectional_range<range const>);
-static_assert(!stdr::view<range const>);
+static_assert(stdr::random_access_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 f301f4d61123..79543203f1aa 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
@@ -22,7 +22,7 @@ using reverse_iterator = std::deque<int>::reverse_iterator;
 using const_reverse_iterator = std::deque<int>::const_reverse_iterator;
 using value_type = int;
 
-static_assert(std::bidirectional_iterator<iterator>);
+static_assert(std::random_access_iterator<iterator>);
 static_assert(std::indirectly_writable<iterator, value_type>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
@@ -33,7 +33,7 @@ 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::bidirectional_iterator<const_iterator>);
+static_assert(std::random_access_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 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/deque/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp
index bece15281b4f..22be6066546e 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
@@ -22,10 +22,10 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
-static_assert(stdr::bidirectional_range<range>);
+static_assert(stdr::random_access_range<range>);
 static_assert(!stdr::view<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
-static_assert(stdr::bidirectional_range<range const>);
+static_assert(stdr::random_access_range<range const>);
 static_assert(!stdr::view<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 3acaa34bb33d..fe3e1486ecfd 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
@@ -23,6 +23,7 @@ using const_reverse_iterator = std::list<int>::const_reverse_iterator;
 using value_type = int;
 
 static_assert(std::bidirectional_iterator<iterator>);
+static_assert(!std::random_access_iterator<iterator>);
 static_assert(std::indirectly_writable<iterator, value_type>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
@@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::bidirectional_iterator<const_iterator>);
+static_assert(!std::random_access_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 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/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp
index 19966094b700..76b73c75ec26 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
@@ -24,8 +24,10 @@ static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
 static_assert(stdr::bidirectional_range<range>);
 static_assert(!stdr::view<range>);
+static_assert(!stdr::random_access_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::bidirectional_range<range const>);
 static_assert(!stdr::view<range const>);
+static_assert(!stdr::random_access_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 1fc5f5d6c386..06770fc7cedb 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
@@ -22,7 +22,8 @@ using reverse_iterator = std::vector<bool>::reverse_iterator;
 using const_reverse_iterator = std::vector<bool>::const_reverse_iterator;
 using value_type = bool;
 
-static_assert(std::bidirectional_iterator<iterator>);
+static_assert(std::random_access_iterator<iterator>);
+static_assert(std::random_access_iterator<reverse_iterator>);
 static_assert(!std::indirectly_writable<iterator, value_type>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
@@ -33,7 +34,8 @@ 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::bidirectional_iterator<const_iterator>);
+static_assert(std::random_access_iterator<const_iterator>);
+static_assert(std::random_access_iterator<const_reverse_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 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/vector.bool/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp
index b6f3268cbcd0..57200cd92774 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
@@ -22,10 +22,10 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
-static_assert(stdr::bidirectional_range<range>);
+static_assert(stdr::random_access_range<range>);
 static_assert(!stdr::view<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
-static_assert(stdr::bidirectional_range<range const>);
+static_assert(stdr::random_access_range<range const>);
 static_assert(!stdr::view<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 c8a76470debe..148d68633819 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
@@ -22,7 +22,8 @@ using reverse_iterator = std::vector<int>::reverse_iterator;
 using const_reverse_iterator = std::vector<int>::const_reverse_iterator;
 using value_type = int;
 
-static_assert(std::bidirectional_iterator<iterator>);
+static_assert(std::random_access_iterator<iterator>);
+static_assert(std::random_access_iterator<reverse_iterator>);
 static_assert(std::indirectly_writable<iterator, value_type>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
@@ -33,7 +34,8 @@ 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::bidirectional_iterator<const_iterator>);
+static_assert(std::random_access_iterator<const_iterator>);
+static_assert(std::random_access_iterator<const_reverse_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 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/vector/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp
index 50620b2cc7ba..ecd13461cb57 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
@@ -22,10 +22,10 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
-static_assert(stdr::bidirectional_range<range>);
+static_assert(stdr::random_access_range<range>);
 static_assert(!stdr::view<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
-static_assert(stdr::bidirectional_range<range const>);
+static_assert(stdr::random_access_range<range const>);
 static_assert(!stdr::view<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 d0c4663e1187..b4fa79f745ce 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
@@ -22,10 +22,10 @@ namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
-static_assert(stdr::bidirectional_range<range>);
+static_assert(stdr::random_access_range<range>);
 static_assert(!stdr::view<range>);
 
 static_assert(std::same_as<stdr::iterator_t<range const>, range::iterator>);
 static_assert(stdr::common_range<range const>);
-static_assert(stdr::bidirectional_range<range const>);
+static_assert(stdr::random_access_range<range const>);
 static_assert(!stdr::view<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 355ece63681c..0e147c753340 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
@@ -20,7 +20,7 @@ using iterator = std::span<int>::iterator;
 using reverse_iterator = std::span<int>::reverse_iterator;
 using value_type = int;
 
-static_assert(std::bidirectional_iterator<iterator>);
+static_assert(std::random_access_iterator<iterator>);
 static_assert(std::indirectly_writable<iterator, value_type>);
 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.path/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp
index 31a7070f64e6..78689946a32d 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
@@ -23,8 +23,10 @@ static_assert(std::same_as<stdr::iterator_t<fs::path>, fs::path::iterator>);
 static_assert(stdr::common_range<fs::path>);
 static_assert(stdr::bidirectional_range<fs::path>);
 static_assert(!stdr::view<fs::path>);
+static_assert(!stdr::random_access_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::bidirectional_range<fs::path const>);
 static_assert(!stdr::view<fs::path const>);
+static_assert(!stdr::random_access_range<fs::path const>);

diff  --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp
index b3d0e9c931d3..aefe415ccfcb 100644
--- a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp
@@ -18,12 +18,12 @@
 #include <concepts>
 
 template<std::forward_iterator I>
-[[nodiscard]] constexpr bool check_subsumption() {
+constexpr bool check_subsumption() {
   return false;
 }
 
 template<std::bidirectional_iterator>
-[[nodiscard]] constexpr bool check_subsumption() {
+constexpr bool check_subsumption() {
   return true;
 }
 

diff  --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/random_access_iterator.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/random_access_iterator.compile.pass.cpp
new file mode 100644
index 000000000000..976af9d9ef81
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/random_access_iterator.compile.pass.cpp
@@ -0,0 +1,218 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// template<class T>
+// concept random_access_iterator;
+
+#include <iterator>
+
+#include "test_iterators.h"
+#include "test_macros.h"
+
+static_assert(!std::random_access_iterator<cpp17_input_iterator<int*> >);
+static_assert(!std::random_access_iterator<cpp20_input_iterator<int*> >);
+static_assert(!std::random_access_iterator<forward_iterator<int*> >);
+static_assert(!std::random_access_iterator<bidirectional_iterator<int*> >);
+static_assert( std::random_access_iterator<random_access_iterator<int*> >);
+static_assert( std::random_access_iterator<contiguous_iterator<int*> >);
+
+static_assert(std::random_access_iterator<int*>);
+static_assert(std::random_access_iterator<int const*>);
+static_assert(std::random_access_iterator<int volatile*>);
+static_assert(std::random_access_iterator<int const volatile*>);
+
+struct wrong_iterator_category {
+    typedef std::bidirectional_iterator_tag iterator_category;
+    typedef int                             value_type;
+    typedef std::ptr
diff _t                  
diff erence_type;
+    typedef int*                            pointer;
+    typedef int&                            reference;
+    typedef wrong_iterator_category         self;
+
+    reference operator*() const;
+    pointer operator->() const;
+    friend bool operator==(const self&, const self&);
+    friend bool operator< (const self&, const self&);
+    friend bool operator<=(const self&, const self&);
+    friend bool operator> (const self&, const self&);
+    friend bool operator>=(const self&, const self&);
+
+    self& operator++();
+    self operator++(int);
+
+    self& operator--();
+    self operator--(int);
+
+    self& operator+=(
diff erence_type n);
+    self operator+(
diff erence_type n) const;
+    friend self operator+(
diff erence_type n, self x);
+
+    self& operator-=(
diff erence_type n);
+    self operator-(
diff erence_type n) const;
+    
diff erence_type operator-(const self&) const;
+
+    reference operator[](
diff erence_type n) const;
+};
+static_assert(std::bidirectional_iterator<wrong_iterator_category>);
+static_assert(!std::random_access_iterator<wrong_iterator_category>);
+
+template<class Child>
+struct common_base {
+    typedef std::random_access_iterator_tag iterator_category;
+    typedef int                             value_type;
+    typedef std::ptr
diff _t                  
diff erence_type;
+    typedef int*                            pointer;
+    typedef int&                            reference;
+    typedef Child                           self;
+
+    reference operator*() const;
+    pointer operator->() const;
+    friend bool operator==(const self&, const self&);
+    friend bool operator< (const self&, const self&);
+    friend bool operator<=(const self&, const self&);
+    friend bool operator> (const self&, const self&);
+    friend bool operator>=(const self&, const self&);
+
+    self& operator++();
+    self operator++(int);
+
+    self& operator--();
+    self operator--(int);
+};
+
+struct simple_random_access_iterator
+  : common_base<simple_random_access_iterator> {
+
+    self& operator+=(
diff erence_type n);
+    self operator+(
diff erence_type n) const;
+    friend self operator+(
diff erence_type n, self x);
+
+    self& operator-=(
diff erence_type n);
+    self operator-(
diff erence_type n) const;
+    
diff erence_type operator-(const self&) const;
+
+    reference operator[](
diff erence_type n) const;
+};
+static_assert(std::bidirectional_iterator<simple_random_access_iterator>);
+static_assert(std::random_access_iterator<simple_random_access_iterator>);
+
+struct no_plus_equals
+  : common_base<no_plus_equals> {
+
+ /* self& operator+=(
diff erence_type n); */
+    self operator+(
diff erence_type n) const;
+    friend self operator+(
diff erence_type n, self x);
+
+    self& operator-=(
diff erence_type n);
+    self operator-(
diff erence_type n) const;
+    
diff erence_type operator-(const self&) const;
+
+    reference operator[](
diff erence_type n) const;
+};
+static_assert( std::bidirectional_iterator<no_plus_equals>);
+static_assert(!std::random_access_iterator<no_plus_equals>);
+
+struct no_plus_
diff erence_type
+  : common_base<no_plus_
diff erence_type> {
+
+    self& operator+=(
diff erence_type n);
+ /* self operator+(
diff erence_type n) const; */
+    friend self operator+(
diff erence_type n, self x);
+
+    self& operator-=(
diff erence_type n);
+    self operator-(
diff erence_type n) const;
+    
diff erence_type operator-(const self&) const;
+
+    reference operator[](
diff erence_type n) const;
+};
+static_assert( std::bidirectional_iterator<no_plus_
diff erence_type>);
+static_assert(!std::random_access_iterator<no_plus_
diff erence_type>);
+
+struct 
diff erence_type_no_plus
+  : common_base<
diff erence_type_no_plus> {
+
+    self& operator+=(
diff erence_type n);
+    self operator+(
diff erence_type n) const;
+ /* friend self operator+(
diff erence_type n, self x); */
+
+    self& operator-=(
diff erence_type n);
+    self operator-(
diff erence_type n) const;
+    
diff erence_type operator-(const self&) const;
+
+    reference operator[](
diff erence_type n) const;
+};
+static_assert( std::bidirectional_iterator<
diff erence_type_no_plus>);
+static_assert(!std::random_access_iterator<
diff erence_type_no_plus>);
+
+struct no_minus_equals
+  : common_base<no_minus_equals> {
+
+    self& operator+=(
diff erence_type n);
+    self operator+(
diff erence_type n) const;
+    friend self operator+(
diff erence_type n, self x);
+
+ /* self& operator-=(
diff erence_type n); */
+    self operator-(
diff erence_type n) const;
+    
diff erence_type operator-(const self&) const;
+
+    reference operator[](
diff erence_type n) const;
+};
+static_assert( std::bidirectional_iterator<no_minus_equals>);
+static_assert(!std::random_access_iterator<no_minus_equals>);
+
+struct no_minus
+  : common_base<no_minus> {
+
+    self& operator+=(
diff erence_type n);
+    self operator+(
diff erence_type n) const;
+    friend self operator+(
diff erence_type n, self x);
+
+    self& operator-=(
diff erence_type n);
+ /* self operator-(
diff erence_type n) const; */
+    
diff erence_type operator-(const self&) const;
+
+    reference operator[](
diff erence_type n) const;
+};
+static_assert( std::bidirectional_iterator<no_minus>);
+static_assert(!std::random_access_iterator<no_minus>);
+
+struct not_sized_sentinel
+  : common_base<not_sized_sentinel> {
+
+    self& operator+=(
diff erence_type n);
+    self operator+(
diff erence_type n) const;
+    friend self operator+(
diff erence_type n, self x);
+
+    self& operator-=(
diff erence_type n);
+    self operator-(
diff erence_type n) const;
+ /* 
diff erence_type operator-(const self&) const; */
+
+    reference operator[](
diff erence_type n) const;
+};
+static_assert( std::bidirectional_iterator<not_sized_sentinel>);
+static_assert(!std::random_access_iterator<not_sized_sentinel>);
+
+struct no_subscript
+  : common_base<no_subscript> {
+
+    self& operator+=(
diff erence_type n);
+    self operator+(
diff erence_type n) const;
+    friend self operator+(
diff erence_type n, self x);
+
+    self& operator-=(
diff erence_type n);
+    self operator-(
diff erence_type n) const;
+    
diff erence_type operator-(const self&) const;
+
+ /* reference operator[](
diff erence_type n) const; */
+};
+static_assert( std::bidirectional_iterator<no_subscript>);
+static_assert(!std::random_access_iterator<no_subscript>);

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 dac2c4dbcf05..3165caf234c7 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
@@ -28,14 +28,15 @@ template<class I1>
 using reverse_bidirectional_iterator = std::reverse_iterator<bidirectional_iterator<int*>>;
 static_assert(common_reverse_iterator_checks<reverse_bidirectional_iterator>());
 static_assert(std::bidirectional_iterator<reverse_bidirectional_iterator>);
+static_assert(!std::random_access_iterator<reverse_bidirectional_iterator>);
 static_assert(!std::sized_sentinel_for<reverse_bidirectional_iterator, reverse_bidirectional_iterator>);
 
 using reverse_random_access_iterator = std::reverse_iterator<random_access_iterator<int*>>;
 static_assert(common_reverse_iterator_checks<reverse_random_access_iterator>());
-static_assert(std::bidirectional_iterator<reverse_random_access_iterator>);
+static_assert(std::random_access_iterator<reverse_random_access_iterator>);
 static_assert(std::sized_sentinel_for<reverse_random_access_iterator, reverse_random_access_iterator>);
 
 using reverse_contiguous_iterator = std::reverse_iterator<contiguous_iterator<int*>>;
 static_assert(common_reverse_iterator_checks<reverse_contiguous_iterator>());
-static_assert(std::bidirectional_iterator<reverse_contiguous_iterator>);
+static_assert(std::random_access_iterator<reverse_contiguous_iterator>);
 static_assert(std::sized_sentinel_for<reverse_contiguous_iterator, reverse_contiguous_iterator>);

diff  --git a/libcxx/test/std/ranges/range.refinements/random_access_range.compile.pass.cpp b/libcxx/test/std/ranges/range.refinements/random_access_range.compile.pass.cpp
new file mode 100644
index 000000000000..5a2820734dd9
--- /dev/null
+++ b/libcxx/test/std/ranges/range.refinements/random_access_range.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
+
+// template<range _Rp>
+// concept random_access_range;
+
+#include <ranges>
+
+#include "test_range.h"
+#include "test_iterators.h"
+
+namespace ranges = std::ranges;
+
+template <template <class...> class I>
+constexpr bool check_range() {
+  constexpr bool result = ranges::random_access_range<test_range<I> >;
+  static_assert(ranges::random_access_range<test_range<I> const> == result);
+  static_assert(ranges::random_access_range<test_non_const_common_range<I> > == result);
+  static_assert(ranges::random_access_range<test_non_const_range<I> > == result);
+  static_assert(ranges::random_access_range<test_common_range<I> > == result);
+  static_assert(ranges::random_access_range<test_common_range<I> const> == result);
+  static_assert(!ranges::random_access_range<test_non_const_common_range<I> const>);
+  static_assert(!ranges::random_access_range<test_non_const_range<I> const>);
+  return result;
+}
+
+static_assert(!check_range<cpp20_input_iterator>());
+static_assert(!check_range<forward_iterator>());
+static_assert(!check_range<bidirectional_iterator>());
+static_assert(check_range<random_access_iterator>());
+static_assert(check_range<contiguous_iterator>());

diff  --git a/libcxx/test/std/ranges/range.refinements/subsumption.compile.pass.cpp b/libcxx/test/std/ranges/range.refinements/subsumption.compile.pass.cpp
index c0896e0efcbc..4b33d00ca31e 100644
--- a/libcxx/test/std/ranges/range.refinements/subsumption.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.refinements/subsumption.compile.pass.cpp
@@ -71,3 +71,17 @@ requires true
 // clang-format on
 
 static_assert(check_bidirectional_range_subsumption<range>());
+
+template<std::ranges::bidirectional_range R>
+requires std::random_access_iterator<std::ranges::iterator_t<R> >
+constexpr bool check_random_access_range_subsumption() {
+  return false;
+}
+
+template<std::ranges::random_access_range>
+requires true
+constexpr bool check_random_access_range_subsumption() {
+  return true;
+}
+
+static_assert(check_random_access_range_subsumption<range>());

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 044acfceb915..764d79b555b1 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
@@ -21,10 +21,10 @@ 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::bidirectional_range<std::cmatch>);
+static_assert(stdr::random_access_range<std::cmatch>);
 static_assert(!stdr::view<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::bidirectional_range<std::cmatch const>);
+static_assert(stdr::random_access_range<std::cmatch const>);
 static_assert(!stdr::view<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 46b26bcd143d..7d926acfeb74 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
@@ -21,10 +21,10 @@ 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::bidirectional_range<std::string>);
+static_assert(stdr::random_access_range<std::string>);
 static_assert(!stdr::view<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::bidirectional_range<std::string const>);
+static_assert(stdr::random_access_range<std::string const>);
 static_assert(!stdr::view<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 5aa1b60bdc4d..7cf60157e180 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
@@ -22,7 +22,7 @@ using reverse_iterator = std::string::reverse_iterator;
 using const_reverse_iterator = std::string::const_reverse_iterator;
 using value_type = char;
 
-static_assert(std::bidirectional_iterator<iterator>);
+static_assert(std::random_access_iterator<iterator>);
 static_assert(std::indirectly_writable<iterator, value_type>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
@@ -33,7 +33,7 @@ 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::bidirectional_iterator<const_iterator>);
+static_assert(std::random_access_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_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 8f9da5ac99ff..b30f6b4dcbf7 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
@@ -21,10 +21,10 @@ 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::bidirectional_range<std::string_view>);
+static_assert(stdr::random_access_range<std::string_view>);
 static_assert(!stdr::view<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::bidirectional_range<std::string_view const>);
+static_assert(stdr::random_access_range<std::string_view const>);
 static_assert(!stdr::view<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 f86f49184360..cd6b3790782a 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
@@ -21,7 +21,7 @@ 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::bidirectional_iterator<iterator>);
+static_assert(std::random_access_iterator<iterator>);
 static_assert(!std::indirectly_writable<iterator, char>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
@@ -32,7 +32,7 @@ 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::bidirectional_iterator<const_iterator>);
+static_assert(std::random_access_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, char>);
 static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);


        


More information about the libcxx-commits mailing list