[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