[libcxx-commits] [libcxx] 3001b48 - [libc++] Implement views::all_t and ranges::viewable_range
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jul 15 04:54:44 PDT 2021
Author: Louis Dionne
Date: 2021-07-15T07:54:33-04:00
New Revision: 3001b48d76bcf10063286efc722a8479522f4c50
URL: https://github.com/llvm/llvm-project/commit/3001b48d76bcf10063286efc722a8479522f4c50
DIFF: https://github.com/llvm/llvm-project/commit/3001b48d76bcf10063286efc722a8479522f4c50.diff
LOG: [libc++] Implement views::all_t and ranges::viewable_range
Differential Revision: https://reviews.llvm.org/D105816
Added:
libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp
libcxx/test/std/ranges/range.adaptors/range.all/all_t.compile.pass.cpp
libcxx/test/std/ranges/range.req/range.refinements/viewable_range.compile.pass.cpp
Modified:
libcxx/docs/Status/RangesPaper.csv
libcxx/include/__ranges/all.h
libcxx/include/__ranges/concepts.h
libcxx/include/__ranges/drop_view.h
libcxx/include/__ranges/transform_view.h
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/ranges/range.adaptors/range.ref.view.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
Removed:
libcxx/test/std/ranges/range.adaptors/range.all.pass.cpp
################################################################################
diff --git a/libcxx/docs/Status/RangesPaper.csv b/libcxx/docs/Status/RangesPaper.csv
index 29c38f3540c3..4ee8d0d74b1d 100644
--- a/libcxx/docs/Status/RangesPaper.csv
+++ b/libcxx/docs/Status/RangesPaper.csv
@@ -119,8 +119,8 @@ Section,Description,Dependencies,Assignee,Complete
| `ranges::bidirectional_range <https://llvm.org/D100278>`_
| `ranges::random_access_range <https://llvm.org/D101316>`_
| ranges::contiguous_range
-| `ranges::common_range <https://llvm.org/D100269>`_
-| ranges::viewable_range",[range.range],Christopher Di Bella,In progress
+| `ranges::common_range <https://llvm.org/D100269>`_",[range.range],Christopher Di Bella,✅
+`[range.refinements]`_,`ranges::viewable_range <https://reviews.llvm.org/D105816>`_,[range.range],Louis Dionne,✅
`[range.utility.helpers] <http://wg21.link/range.utility.helpers>`_,"| *simple-view*
| *has-arrow*
| *not-same-as*","| [range.range]
diff --git a/libcxx/include/__ranges/all.h b/libcxx/include/__ranges/all.h
index d1312d1a213d..6cfe3b8358ec 100644
--- a/libcxx/include/__ranges/all.h
+++ b/libcxx/include/__ranges/all.h
@@ -17,6 +17,7 @@
#include <__ranges/ref_view.h>
#include <__ranges/subrange.h>
#include <__utility/__decay_copy.h>
+#include <__utility/declval.h>
#include <__utility/forward.h>
#include <type_traits>
@@ -68,6 +69,9 @@ inline namespace __cpo {
inline constexpr auto all = __all::__fn{};
} // namespace __cpo
+template<ranges::viewable_range _Range>
+using all_t = decltype(views::all(declval<_Range>()));
+
} // namespace views
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h
index 364275da813b..f314685e3dc9 100644
--- a/libcxx/include/__ranges/concepts.h
+++ b/libcxx/include/__ranges/concepts.h
@@ -112,6 +112,13 @@ namespace ranges {
template <class _Tp>
concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp> >;
+
+ template<class _Tp>
+ concept viewable_range =
+ range<_Tp> && (
+ (view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) ||
+ (!view<remove_cvref_t<_Tp>> && borrowed_range<_Tp>)
+ );
} // namespace ranges
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
diff --git a/libcxx/include/__ranges/drop_view.h b/libcxx/include/__ranges/drop_view.h
index 38c101a8fb56..fe5b80330e25 100644
--- a/libcxx/include/__ranges/drop_view.h
+++ b/libcxx/include/__ranges/drop_view.h
@@ -140,9 +140,7 @@ namespace ranges {
};
template<class _Range>
- drop_view(_Range&&, range_
diff erence_t<_Range>)
- // TODO: this is just recreating all_t.
- -> drop_view<decltype(views::all(std::declval<_Range>()))>;
+ drop_view(_Range&&, range_
diff erence_t<_Range>) -> drop_view<views::all_t<_Range>>;
template<class _Tp>
inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>;
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index e059cbf3b18c..b86cdd3e94d4 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -10,10 +10,11 @@
#define _LIBCPP___RANGES_TRANSFORM_VIEW_H
#include <__config>
-#include <__iterator/iterator_traits.h>
#include <__iterator/concepts.h>
#include <__iterator/iter_swap.h>
+#include <__iterator/iterator_traits.h>
#include <__ranges/access.h>
+#include <__ranges/all.h>
#include <__ranges/concepts.h>
#include <__ranges/copyable_box.h>
#include <__ranges/empty.h>
@@ -93,10 +94,8 @@ class transform_view : public view_interface<transform_view<_View, _Fn>> {
constexpr auto size() const requires sized_range<const _View> { return ranges::size(__base_); }
};
-// TODO: replace the decltype with all_t when that's implemented.
template<class _Range, class _Fn>
-transform_view(_Range&&, _Fn)
- -> transform_view<decltype(views::all(std::declval<_Range>())), _Fn>;
+transform_view(_Range&&, _Fn) -> transform_view<views::all_t<_Range>, _Fn>;
template<class _View>
struct __transform_view_iterator_concept { using type = input_iterator_tag; };
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index 90711cb7d05c..d662e2604e98 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -50,7 +50,7 @@ namespace std::ranges {
template<range R>
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
- // [range.sized]
+ // [range.sized], sized ranges
template<class>
inline constexpr bool disable_sized_range = false;
@@ -85,6 +85,9 @@ namespace std::ranges {
template <class _Tp>
concept common_range = see below;
+ template<class T>
+ concept viewable_range = see below;
+
// [view.interface], class template view_interface
template<class D>
requires is_class_v<D> && same_as<D, remove_cv_t<D>>
@@ -95,6 +98,21 @@ namespace std::ranges {
requires is_object_v<T>
class empty_view;
+ // [range.all], all view
+ namespace views {
+ inline constexpr unspecified all = unspecified;
+
+ template<viewable_range R>
+ using all_t = decltype(all(declval<R>()));
+ }
+
+ template<range R>
+ requires is_object_v<R>
+ class ref_view;
+
+ template<class T>
+ inline constexpr bool enable_borrowed_range<ref_view<T>> = true;
+
// [range.drop], drop view
template<view V>
class drop_view;
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 0b3204c9d775..b098f05e2764 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
@@ -27,6 +27,7 @@ static_assert(!stdr::view<range>);
static_assert(!stdr::random_access_range<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(!stdr::view<range const>);
static_assert(!stdr::random_access_range<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 9b0b9fc995ca..9362e25faf40 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
@@ -27,6 +27,7 @@ static_assert(!stdr::view<range>);
static_assert(!stdr::random_access_range<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(!stdr::view<range const>);
static_assert(!stdr::random_access_range<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 f95952c8bba6..417e19dc0c4d 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
@@ -27,6 +27,7 @@ static_assert(!stdr::view<range>);
static_assert(!stdr::random_access_range<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(!stdr::view<range const>);
static_assert(!stdr::random_access_range<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 a2150558e016..caf6ba28ff68 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
@@ -28,6 +28,7 @@ static_assert(stdr::input_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::bidirectional_range<range const>);
@@ -37,3 +38,4 @@ static_assert(stdr::input_range<range>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 f70af72c9bd3..cfe01e7f745a 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
@@ -27,6 +27,7 @@ static_assert(stdr::random_access_range<range>);
static_assert(stdr::contiguous_range<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(!stdr::view<range const>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
@@ -35,3 +36,4 @@ static_assert(stdr::random_access_range<range const>);
static_assert(stdr::contiguous_range<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 7b248e9846ed..df9f6e8cae3f 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
@@ -27,6 +27,7 @@ static_assert(!stdr::contiguous_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(!stdr::contiguous_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 af237700f943..142dc96c0a94 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
@@ -27,6 +27,7 @@ static_assert(!stdr::bidirectional_range<range>);
static_assert(!stdr::view<range>);
static_assert(!stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(!stdr::bidirectional_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(!stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 bbe6020603e6..75c6d34fa756 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
@@ -27,6 +27,7 @@ static_assert(!stdr::view<range>);
static_assert(!stdr::random_access_range<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(!stdr::view<range const>);
static_assert(!stdr::random_access_range<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 9981d65fd80d..fb028d0b3931 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
@@ -27,6 +27,7 @@ static_assert(!stdr::contiguous_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(!stdr::contiguous_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 117c36b6e1a6..c47413ec262e 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
@@ -27,6 +27,7 @@ static_assert(stdr::contiguous_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(stdr::contiguous_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 450705c3417c..71a72212f59c 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
@@ -27,6 +27,7 @@ static_assert(!stdr::bidirectional_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(!stdr::bidirectional_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 c98d7b85c4e7..e18627241df8 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
@@ -27,6 +27,7 @@ static_assert(!stdr::bidirectional_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(!stdr::bidirectional_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 64332c422ba7..29789d05210d 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
@@ -27,6 +27,7 @@ static_assert(!stdr::bidirectional_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(!stdr::bidirectional_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 922ca43e1242..bd48bbab3d21 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
@@ -27,6 +27,7 @@ static_assert(!stdr::bidirectional_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
+static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(!stdr::bidirectional_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
+static_assert(!stdr::viewable_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 50fdc6a09119..c850c50976e9 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
@@ -27,6 +27,7 @@ static_assert(stdr::contiguous_range<range>);
static_assert(stdr::view<range> && stdr::enable_view<range>);
static_assert(stdr::sized_range<range>);
static_assert(stdr::borrowed_range<range>);
+static_assert(stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::iterator>);
static_assert(stdr::common_range<range const>);
@@ -35,3 +36,4 @@ static_assert(stdr::contiguous_range<range const>);
static_assert(!stdr::view<range const> && !stdr::enable_view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(stdr::borrowed_range<range const>);
+static_assert(stdr::viewable_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 80445f28e25c..ff79c8bd699e 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
@@ -26,6 +26,7 @@ static_assert(stdr::input_range<fs::directory_iterator>);
static_assert(!stdr::view<fs::directory_iterator>);
static_assert(!stdr::sized_range<fs::directory_iterator>);
static_assert(!stdr::borrowed_range<fs::directory_iterator>);
+static_assert(!stdr::viewable_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>);
@@ -33,6 +34,7 @@ static_assert(stdr::input_range<fs::directory_iterator const>);
static_assert(!stdr::view<fs::directory_iterator const>);
static_assert(!stdr::sized_range<fs::directory_iterator const>);
static_assert(!stdr::borrowed_range<fs::directory_iterator const>);
+static_assert(!stdr::viewable_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>);
@@ -40,6 +42,7 @@ static_assert(stdr::input_range<fs::recursive_directory_iterator>);
static_assert(!stdr::view<fs::recursive_directory_iterator>);
static_assert(!stdr::sized_range<fs::recursive_directory_iterator>);
static_assert(!stdr::borrowed_range<fs::recursive_directory_iterator>);
+static_assert(!stdr::viewable_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>);
@@ -47,3 +50,4 @@ static_assert(stdr::input_range<fs::recursive_directory_iterator const>);
static_assert(!stdr::view<fs::recursive_directory_iterator const>);
static_assert(!stdr::sized_range<fs::recursive_directory_iterator const>);
static_assert(!stdr::borrowed_range<fs::recursive_directory_iterator const>);
+static_assert(!stdr::viewable_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 47cec87ffac6..b9b70d0725f7 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
@@ -26,6 +26,7 @@ static_assert(!stdr::view<fs::path>);
static_assert(!stdr::random_access_range<fs::path>);
static_assert(!stdr::sized_range<fs::path>);
static_assert(!stdr::borrowed_range<fs::path>);
+static_assert(!stdr::viewable_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>);
@@ -34,3 +35,4 @@ static_assert(!stdr::view<fs::path const>);
static_assert(!stdr::random_access_range<fs::path const>);
static_assert(!stdr::sized_range<fs::path const>);
static_assert(!stdr::borrowed_range<fs::path const>);
+static_assert(!stdr::viewable_range<fs::path const>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.all.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp
similarity index 100%
rename from libcxx/test/std/ranges/range.adaptors/range.all.pass.cpp
rename to libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp
diff --git a/libcxx/test/std/ranges/range.adaptors/range.all/all_t.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.all/all_t.compile.pass.cpp
new file mode 100644
index 000000000000..5aaf03c5a2b4
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.all/all_t.compile.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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<viewable_range R>
+// using all_t = decltype(views::all(declval<R>()));
+
+#include <ranges>
+
+#include "test_iterators.h"
+#include "test_range.h"
+
+struct View : test_range<cpp20_input_iterator>, std::ranges::view_base { };
+struct Range : test_range<cpp20_input_iterator> { };
+struct BorrowableRange : test_range<forward_iterator> { };
+template<>
+inline constexpr bool std::ranges::enable_borrowed_range<BorrowableRange> = true;
+
+// When T is a view, returns decay-copy(T)
+ASSERT_SAME_TYPE(std::views::all_t<View>, View);
+ASSERT_SAME_TYPE(std::views::all_t<View&>, View);
+ASSERT_SAME_TYPE(std::views::all_t<View const>, View);
+ASSERT_SAME_TYPE(std::views::all_t<View const&>, View);
+
+// Otherwise, when T is a reference to a range, returns ref_view<T>
+ASSERT_SAME_TYPE(std::views::all_t<Range&>, std::ranges::ref_view<Range>);
+ASSERT_SAME_TYPE(std::views::all_t<Range const&>, std::ranges::ref_view<Range const>);
+ASSERT_SAME_TYPE(std::views::all_t<BorrowableRange&>, std::ranges::ref_view<BorrowableRange>);
+ASSERT_SAME_TYPE(std::views::all_t<BorrowableRange const&>, std::ranges::ref_view<BorrowableRange const>);
+
+// Otherwise, returns subrange<iterator_t<T>, sentinel_t<R>>
+ASSERT_SAME_TYPE(std::views::all_t<BorrowableRange>, std::ranges::subrange<forward_iterator<int*>, sentinel>);
+ASSERT_SAME_TYPE(std::views::all_t<BorrowableRange const>, std::ranges::subrange<forward_iterator<int const*>, sentinel>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.ref.view.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.ref.view.pass.cpp
index 5baf128e8800..9278bd086093 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.ref.view.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.ref.view.pass.cpp
@@ -10,7 +10,9 @@
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
-// std::ranges::ref_view
+// template<range R>
+// requires is_object_v<R>
+// class ref_view;
#include <ranges>
diff --git a/libcxx/test/std/ranges/range.req/range.refinements/viewable_range.compile.pass.cpp b/libcxx/test/std/ranges/range.req/range.refinements/viewable_range.compile.pass.cpp
new file mode 100644
index 000000000000..3cef347a98c2
--- /dev/null
+++ b/libcxx/test/std/ranges/range.req/range.refinements/viewable_range.compile.pass.cpp
@@ -0,0 +1,133 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 R>
+// concept viewable_range;
+
+#include <ranges>
+#include <type_traits>
+
+#include "test_iterators.h"
+#include "test_range.h"
+
+// The constraints we have in viewable_range are:
+// range<T>
+// view<remove_cvref_t<T>>
+// constructible_from<remove_cvref_t<T>, T>
+// borrowed_range<T>
+//
+// We test all the relevant combinations of satisfying/not satisfying those constraints.
+
+// viewable_range<T> is not satisfied for (range=false, view=*, constructible_from=*, borrowed_range=*)
+struct T1 { };
+static_assert(!std::ranges::range<T1>);
+
+static_assert(!std::ranges::viewable_range<T1>);
+static_assert(!std::ranges::viewable_range<T1&>);
+static_assert(!std::ranges::viewable_range<T1 const>);
+static_assert(!std::ranges::viewable_range<T1 const&>);
+
+// viewable_range<T> is satisfied for (range=true, view=true, constructible_from=true, borrowed_range=true)
+struct T2 : test_range<cpp20_input_iterator>, std::ranges::view_base {
+ T2(T2 const&) = default;
+};
+template<> constexpr bool std::ranges::enable_borrowed_range<T2> = true;
+static_assert(std::ranges::range<T2>);
+static_assert(std::ranges::view<T2>);
+static_assert(std::constructible_from<T2, T2>);
+static_assert(std::ranges::borrowed_range<T2>);
+
+static_assert(std::ranges::viewable_range<T2>);
+static_assert(std::ranges::viewable_range<T2&>);
+static_assert(std::ranges::viewable_range<T2 const>);
+static_assert(std::ranges::viewable_range<T2 const&>);
+
+// viewable_range<T> is satisfied for (range=true, view=true, constructible_from=true, borrowed_range=false)
+struct T3 : test_range<cpp20_input_iterator>, std::ranges::view_base {
+ T3(T3 const&) = default;
+};
+template<> constexpr bool std::ranges::enable_borrowed_range<T3> = false;
+static_assert(std::ranges::range<T3>);
+static_assert(std::ranges::view<T3>);
+static_assert(std::constructible_from<T3, T3>);
+static_assert(!std::ranges::borrowed_range<T3>);
+
+static_assert(std::ranges::viewable_range<T3>);
+static_assert(std::ranges::viewable_range<T3&>);
+static_assert(std::ranges::viewable_range<T3 const>);
+static_assert(std::ranges::viewable_range<T3 const&>);
+
+// viewable_range<T> is not satisfied for (range=true, view=true, constructible_from=false, borrowed_range=true)
+struct T4 : test_range<cpp20_input_iterator>, std::ranges::view_base {
+ T4(T4 const&) = delete;
+ T4(T4&&) = default; // necessary to model view
+ T4& operator=(T4&&) = default; // necessary to model view
+};
+static_assert(std::ranges::range<T4 const&>);
+static_assert(std::ranges::view<std::remove_cvref_t<T4 const&>>);
+static_assert(!std::constructible_from<std::remove_cvref_t<T4 const&>, T4 const&>);
+static_assert(std::ranges::borrowed_range<T4 const&>);
+
+static_assert(!std::ranges::viewable_range<T4 const&>);
+
+// A type that satisfies (range=true, view=true, constructible_from=false, borrowed_range=false) can't be formed
+
+// viewable_range<T> is satisfied for (range=true, view=false, constructible_from=true, borrowed_range=true)
+struct T5 : test_range<cpp20_input_iterator> { };
+template<> constexpr bool std::ranges::enable_borrowed_range<T5> = true;
+static_assert(std::ranges::range<T5>);
+static_assert(!std::ranges::view<T5>);
+static_assert(std::constructible_from<T5, T5>);
+static_assert(std::ranges::borrowed_range<T5>);
+
+static_assert(std::ranges::viewable_range<T5>);
+
+// viewable_range<T> is not satisfied for (range=true, view=false, constructible_from=true, borrowed_range=false)
+struct T6 : test_range<cpp20_input_iterator> { };
+template<> constexpr bool std::ranges::enable_borrowed_range<T6> = false;
+static_assert(std::ranges::range<T6>);
+static_assert(!std::ranges::view<T6>);
+static_assert(std::constructible_from<T6, T6>);
+static_assert(!std::ranges::borrowed_range<T6>);
+
+static_assert(!std::ranges::viewable_range<T6>);
+
+// viewable_range<T> is satisfied for (range=true, view=false, constructible_from=false, borrowed_range=true)
+struct T7 : test_range<cpp20_input_iterator> {
+ T7(T7 const&) = delete;
+};
+static_assert(std::ranges::range<T7&>);
+static_assert(!std::ranges::view<std::remove_cvref_t<T7&>>);
+static_assert(!std::constructible_from<std::remove_cvref_t<T7&>, T7&>);
+static_assert(std::ranges::borrowed_range<T7&>);
+
+static_assert(std::ranges::viewable_range<T7&>);
+
+// A type that satisfies (range=true, view=false, constructible_from=false, borrowed_range=false) can't be formed
+struct T8 : test_range<cpp20_input_iterator> {
+ T8(T8 const&) = delete;
+};
+static_assert(std::ranges::range<T8>);
+static_assert(!std::ranges::view<T8>);
+static_assert(!std::constructible_from<T8, T8>);
+static_assert(!std::ranges::borrowed_range<T8>);
+
+static_assert(!std::ranges::viewable_range<T8>);
+
+// Test with a few degenerate types
+static_assert(!std::ranges::viewable_range<void>);
+static_assert(!std::ranges::viewable_range<int>);
+static_assert(!std::ranges::viewable_range<int (*)(char)>);
+static_assert(!std::ranges::viewable_range<int[]>);
+static_assert(!std::ranges::viewable_range<int[10]>);
+static_assert(!std::ranges::viewable_range<int(&)[]>); // unbounded array is not a range
+static_assert( std::ranges::viewable_range<int(&)[10]>);
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 de92ca20a71c..741b1ad0bcbb 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
@@ -26,6 +26,7 @@ static_assert(stdr::contiguous_range<std::cmatch>);
static_assert(!stdr::view<std::cmatch>);
static_assert(stdr::sized_range<std::cmatch>);
static_assert(!stdr::borrowed_range<std::cmatch>);
+static_assert(!stdr::viewable_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>);
@@ -34,3 +35,4 @@ static_assert(stdr::contiguous_range<std::cmatch const>);
static_assert(!stdr::view<std::cmatch const>);
static_assert(stdr::sized_range<std::cmatch const>);
static_assert(!stdr::borrowed_range<std::cmatch const>);
+static_assert(!stdr::viewable_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 398549696f53..fb1e6765c900 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
@@ -26,6 +26,7 @@ static_assert(stdr::contiguous_range<std::string>);
static_assert(!stdr::view<std::string>);
static_assert(stdr::sized_range<std::string>);
static_assert(!stdr::borrowed_range<std::string>);
+static_assert(!stdr::viewable_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>);
@@ -34,3 +35,4 @@ static_assert(stdr::contiguous_range<std::string const>);
static_assert(!stdr::view<std::string const>);
static_assert(stdr::sized_range<std::string const>);
static_assert(!stdr::borrowed_range<std::string const>);
+static_assert(!stdr::viewable_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 78a803e14f59..860de80eb981 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
@@ -26,6 +26,7 @@ static_assert(stdr::contiguous_range<std::string_view>);
static_assert(stdr::view<std::string_view> && stdr::enable_view<std::string_view>);
static_assert(stdr::sized_range<std::string_view>);
static_assert(stdr::borrowed_range<std::string_view>);
+static_assert(stdr::viewable_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>);
@@ -34,3 +35,4 @@ static_assert(stdr::contiguous_range<std::string_view const>);
static_assert(!stdr::view<std::string_view const> && !stdr::enable_view<std::string_view const>);
static_assert(stdr::sized_range<std::string_view const>);
static_assert(stdr::borrowed_range<std::string_view const>);
+static_assert(stdr::viewable_range<std::string_view const>);
More information about the libcxx-commits
mailing list