[libcxx-commits] [libcxx] 7c17731 - [libcxx][ranges] adds `ranges::range`, `ranges::common_range`, and range aliases

Christopher Di Bella via libcxx-commits libcxx-commits at lists.llvm.org
Fri Apr 30 09:59:50 PDT 2021


Author: Christopher Di Bella
Date: 2021-04-30T16:56:42Z
New Revision: 7c17731596e9cb05b861f1a1be35fb827d33f632

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

LOG: [libcxx][ranges] adds `ranges::range`, `ranges::common_range`, and range aliases

* `std::ranges::range`
* `std::ranges::sentinel_t`
* `std::ranges::range_difference_t`
* `std::ranges::range_value_t`
* `std::ranges::range_reference_t`
* `std::ranges::range_rvalue_reference_t`
* `std::ranges::common_range`

`range_size_t` depends on `sized_range` and will be added alongside it.

Implements parts of:
    * P0896R4 The One Ranges Proposal`

Depends on D100255.

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

Added: 
    libcxx/include/__ranges/concepts.h
    libcxx/test/std/ranges/range.range/helper_aliases.compile.pass.cpp
    libcxx/test/std/ranges/range.range/range.compile.pass.cpp
    libcxx/test/std/ranges/range.range/sentinel_t.compile.pass.cpp
    libcxx/test/std/ranges/range.refinements/common_range.compile.pass.cpp

Modified: 
    libcxx/include/CMakeLists.txt
    libcxx/include/ranges
    libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector/range_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/range_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/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/views/range_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/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/string.view/range_concept_conformance.compile.pass.cpp
    libcxx/test/support/test_range.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 0bcaa191e5274..18fec97e51853 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -36,6 +36,7 @@ set(files
   __node_handle
   __nullptr
   __ranges/access.h
+  __ranges/concepts.h
   __ranges/enable_borrowed_range.h
   __split_buffer
   __sso_allocator

diff  --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h
new file mode 100644
index 0000000000000..aeed55ce07eca
--- /dev/null
+++ b/libcxx/include/__ranges/concepts.h
@@ -0,0 +1,66 @@
+// -*- C++ -*-
+//===--------------------- __ranges/concepts.h ----------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+#ifndef _LIBCPP_RANGES_CONCEPTS_H
+#define _LIBCPP_RANGES_CONCEPTS_H
+
+#include <__config>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// clang-format off
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+  // [range.range]
+  template <class _Tp>
+  concept range = requires(_Tp& __t) {
+    ranges::begin(__t); // sometimes equality-preserving
+    ranges::end(__t);
+  };
+
+  // `iterator_t` defined in <__ranges/begin.h>
+
+  template <range _Rp>
+  using sentinel_t = decltype(ranges::end(declval<_Rp&>()));
+
+  template <range _Rp>
+  using range_
diff erence_t = iter_
diff erence_t<iterator_t<_Rp> >;
+
+  template <range _Rp>
+  using range_value_t = iter_value_t<iterator_t<_Rp> >;
+
+  template <range _Rp>
+  using range_reference_t = iter_reference_t<iterator_t<_Rp> >;
+
+  template <range _Rp>
+  using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp> >;
+
+  // [range.refinements], other range refinements
+  template <class _Tp>
+  concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp> >;
+} // namespace ranges
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+// clang-format on
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP_RANGES_CONCEPTS_H

diff  --git a/libcxx/include/ranges b/libcxx/include/ranges
index 64feb76d03523..a4eda8d332210 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -26,17 +26,37 @@ namespace std::ranges {
   }
 
   // [range.range], ranges
+  template<class T>
+    concept range = see below;
+
   template<class T>
     inline constexpr bool enable_borrowed_range = false;
 
   template<class T>
     using iterator_t = decltype(ranges::begin(declval<T&>()));
+  template<class T>
+    using iterator_t = decltype(ranges::begin(declval<T&>()));
+  template<range R>
+    using sentinel_t = decltype(ranges::end(declval<R&>()));
+  template<range R>
+    using range_
diff erence_t = iter_
diff erence_t<iterator_t<R>>;
+  template<range R>
+    using range_value_t = iter_value_t<iterator_t<R>>;
+  template<range R>
+    using range_reference_t = iter_reference_t<iterator_t<R>>;
+  template<range R>
+    using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
+
+  // [range.refinements], other range refinements
+  template <class _Tp>
+    concept common_range = see below;
 }
 
 */
 
 #include <__config>
 #include <__ranges/access.h>
+#include <__ranges/concepts.h>
 #include <__ranges/enable_borrowed_range.h>
 #include <compare>          // Required by the standard.
 #include <initializer_list> // Required by the standard.

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 04d8d63ab03ad..4918db186d496 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
@@ -22,4 +22,7 @@ using range = std::map<int, int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 c076d16c7a6ea..9443d3fa419a6 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
@@ -22,4 +22,7 @@ using range = std::multimap<int, int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 da82cba43c440..ae1745d2ef23d 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
@@ -22,4 +22,7 @@ using range = std::multiset<int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 66ec7b3974d41..8ba25cbf75a31 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
@@ -22,4 +22,7 @@ using range = std::set<int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 35fb25c626d23..a44354dd6297e 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
@@ -22,4 +22,7 @@ using range = std::array<int, 10>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 07601dc08eba1..50e94f71d9e90 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,4 +22,7 @@ using range = std::deque<int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 40f62a7b7b22b..32bc9fa416d1f 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
@@ -22,4 +22,7 @@ using range = std::forward_list<int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 9230e6a2e4803..b958ce68b7e54 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
@@ -22,4 +22,7 @@ using range = std::list<int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 d72535c5e2a65..8127962c9e02f 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,4 +22,7 @@ using range = std::vector<bool>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 d5a635330627c..4c807fe8c31f6 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,4 +22,7 @@ using range = std::vector<int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 968f5189185b6..c5abbae2d27a7 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
@@ -22,4 +22,7 @@ using range = std::unordered_map<int, int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 f8cfa03e4d1f7..9de46840efa5d 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
@@ -22,4 +22,7 @@ using range = std::unordered_multimap<int, int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 267cd6fd506ff..45b7a66040e09 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
@@ -22,4 +22,7 @@ using range = std::unordered_multiset<int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_range<range const>);

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 e3a2e4b61fd8c..4c84bbfa3c418 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
@@ -22,4 +22,7 @@ using range = std::unordered_set<int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
+static_assert(stdr::common_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 216faf3673f8f..696ee6a6508ad 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,3 +22,7 @@ using range = std::span<int>;
 namespace stdr = std::ranges;
 
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
+static_assert(stdr::common_range<range>);
+
+static_assert(std::same_as<stdr::iterator_t<range const>, range::iterator>);
+static_assert(stdr::common_range<range const>);

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 c7cfc4d0bc528..27e96a741782e 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
@@ -9,7 +9,7 @@
 // UNSUPPORTED: c++03, c++11, c++14, c++17
 // UNSUPPORTED: libcpp-no-concepts
 // UNSUPPORTED: gcc-10
-// XFAIL: msvc && clang
+// XFAIL: *
 
 // directory_iterator, recursive_directory_iterator
 
@@ -21,6 +21,13 @@
 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(std::same_as<stdr::iterator_t<fs::directory_iterator const>, fs::directory_iterator>);
+static_assert(stdr::common_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(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>);

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 a3c55c4d7449e..163130bf0918e 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
@@ -21,4 +21,7 @@
 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(std::same_as<stdr::iterator_t<fs::path const>, fs::path::const_iterator>);
+static_assert(stdr::common_range<fs::path const>);

diff  --git a/libcxx/test/std/ranges/range.range/helper_aliases.compile.pass.cpp b/libcxx/test/std/ranges/range.range/helper_aliases.compile.pass.cpp
new file mode 100644
index 0000000000000..cfcbe319fd348
--- /dev/null
+++ b/libcxx/test/std/ranges/range.range/helper_aliases.compile.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 R>
+// using range_
diff erence_t = iter_
diff erence_t<iterator_t<R>>;
+
+// template<range R>
+// using range_value_t = iter_value_t<iterator_t<R>>;
+
+// template<range R>
+// using range_reference_t = iter_reference_t<iterator_t<R>>;
+
+// template<range R>
+// using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
+
+#include <ranges>
+
+#include <concepts>
+
+#include "test_range.h"
+
+namespace stdr = std::ranges;
+
+static_assert(std::same_as<stdr::range_
diff erence_t<test_range<> >, std::iter_
diff erence_t<int*> >);
+static_assert(std::same_as<stdr::range_value_t<test_range<> >, std::iter_value_t<int*> >);
+static_assert(std::same_as<stdr::range_reference_t<test_range<> >, std::iter_reference_t<int*> >);
+static_assert(std::same_as<stdr::range_rvalue_reference_t<test_range<> >, std::iter_rvalue_reference_t<int*> >);

diff  --git a/libcxx/test/std/ranges/range.range/range.compile.pass.cpp b/libcxx/test/std/ranges/range.range/range.compile.pass.cpp
new file mode 100644
index 0000000000000..4d9440caad963
--- /dev/null
+++ b/libcxx/test/std/ranges/range.range/range.compile.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 range;
+
+#include <ranges>
+
+#include <vector>
+
+#include "test_range.h"
+
+namespace stdr = std::ranges;
+
+static_assert(stdr::range<test_range<> >);
+
+struct incompatible_iterators {
+  int* begin();
+  long* end();
+};
+static_assert(!stdr::range<incompatible_iterators>);
+
+struct int_begin_int_end {
+  int begin();
+  int end();
+};
+static_assert(!stdr::range<int_begin_int_end>);
+
+struct iterator_begin_int_end {
+  int* begin();
+  int end();
+};
+static_assert(!stdr::range<iterator_begin_int_end>);
+
+struct int_begin_iterator_end {
+  int begin();
+  int* end();
+};
+static_assert(!stdr::range<int_begin_iterator_end>);

diff  --git a/libcxx/test/std/ranges/range.range/sentinel_t.compile.pass.cpp b/libcxx/test/std/ranges/range.range/sentinel_t.compile.pass.cpp
new file mode 100644
index 0000000000000..9a972b0d52552
--- /dev/null
+++ b/libcxx/test/std/ranges/range.range/sentinel_t.compile.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// UNSUPPORTED: gcc-10
+// XFAIL: msvc && clang
+
+// template<range _Rp>
+// using sentinel_t = decltype(ranges::end(declval<_Rp&>()));
+
+#include <ranges>
+
+#include <concepts>
+
+#include "test_iterators.h"
+#include "test_range.h"
+
+namespace stdr = std::ranges;
+
+static_assert(std::same_as<stdr::sentinel_t<test_range<> >, sentinel>);
+static_assert(std::same_as<stdr::sentinel_t<test_range<> const>, sentinel>);
+static_assert(std::same_as<stdr::sentinel_t<test_non_const_range<> >, sentinel>);
+static_assert(std::same_as<stdr::sentinel_t<test_common_range<> >, input_iterator<int*> >);
+static_assert(std::same_as<stdr::sentinel_t<test_common_range<> const>, input_iterator<int const*> >);
+static_assert(std::same_as<stdr::sentinel_t<test_non_const_common_range<> >, input_iterator<int*> >);

diff  --git a/libcxx/test/std/ranges/range.refinements/common_range.compile.pass.cpp b/libcxx/test/std/ranges/range.refinements/common_range.compile.pass.cpp
new file mode 100644
index 0000000000000..90cf0b77b17c1
--- /dev/null
+++ b/libcxx/test/std/ranges/range.refinements/common_range.compile.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// XFAIL: msvc && clang
+
+// template<class T>
+// concept common_range;
+
+#include <ranges>
+
+#include "test_iterators.h"
+#include "test_range.h"
+
+namespace stdr = std::ranges;
+
+static_assert(!stdr::common_range<test_range<input_iterator> >);
+static_assert(!stdr::common_range<test_range<input_iterator> const>);
+
+static_assert(!stdr::common_range<test_non_const_range<input_iterator> >);
+static_assert(!stdr::common_range<test_non_const_range<input_iterator> const>);
+
+static_assert(stdr::common_range<test_common_range<input_iterator> >);
+static_assert(stdr::common_range<test_common_range<input_iterator> const>);
+
+static_assert(stdr::common_range<test_non_const_common_range<input_iterator> >);
+static_assert(!stdr::common_range<test_non_const_common_range<input_iterator> const>);
+
+struct subtly_not_common {
+  int* begin() const;
+  int const* end() const;
+};
+static_assert(stdr::range<subtly_not_common> && !stdr::common_range<subtly_not_common>);
+static_assert(stdr::range<subtly_not_common const> && !stdr::common_range<subtly_not_common const>);
+
+struct common_range_non_const_only {
+  int* begin() const;
+  int* end();
+  int const* end() const;
+};
+static_assert(stdr::range<common_range_non_const_only>&& stdr::common_range<common_range_non_const_only>);
+static_assert(stdr::range<common_range_non_const_only const> && !stdr::common_range<common_range_non_const_only const>);
+
+struct common_range_const_only {
+  int* begin();
+  int const* begin() const;
+  int const* end() const;
+};
+static_assert(stdr::range<common_range_const_only> && !stdr::common_range<common_range_const_only>);
+static_assert(stdr::range<common_range_const_only const>&& stdr::common_range<common_range_const_only const>);

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 6eed856594b08..10f48a967b77c 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,4 +21,7 @@
 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(std::same_as<stdr::iterator_t<std::cmatch const>, std::cmatch::const_iterator>);
+static_assert(stdr::common_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 634a8ccde884b..c352dda37a6d3 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,4 +21,7 @@
 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(std::same_as<stdr::iterator_t<std::string const>, std::string::const_iterator>);
+static_assert(stdr::common_range<std::string const>);

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 7395d42ef7284..595a12fc3d69d 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,4 +21,7 @@
 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(std::same_as<stdr::iterator_t<std::string_view const>, std::string_view::const_iterator>);
+static_assert(stdr::common_range<std::string_view const>);

diff  --git a/libcxx/test/support/test_range.h b/libcxx/test/support/test_range.h
index 0619767afe95a..3e9c94abb8ecd 100644
--- a/libcxx/test/support/test_range.h
+++ b/libcxx/test/support/test_range.h
@@ -22,7 +22,7 @@ struct sentinel {
 };
 
 // clang-format off
-template <template <class...> class I>
+template <template <class...> class I = input_iterator>
 requires std::input_or_output_iterator<I<int*> >
 struct test_range {
   I<int*> begin();
@@ -31,23 +31,23 @@ struct test_range {
   sentinel end() const;
 };
 
-template <template <class...> class I>
+template <template <class...> class I = input_iterator>
 requires std::input_or_output_iterator<I<int*> >
 struct test_non_const_range {
   I<int*> begin();
   sentinel end();
 };
 
-template <template <class...> class I>
+template <template <class...> class I = input_iterator>
 requires std::input_or_output_iterator<I<int*> >
 struct test_common_range {
   I<int*> begin();
   I<int const*> begin() const;
   I<int*> end();
-  I<int*> end() const;
+  I<int const*> end() const;
 };
 
-template <template <class...> class I>
+template <template <class...> class I = input_iterator>
 requires std::input_or_output_iterator<I<int*> >
 struct test_non_const_common_range {
   I<int*> begin();


        


More information about the libcxx-commits mailing list