[libcxx-commits] [libcxx] 597b90e - [libc++] Fix __simple_view concept in std::ranges
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jan 14 09:55:38 PST 2022
Author: Hui Xie
Date: 2022-01-14T12:55:34-05:00
New Revision: 597b90ebacafad94082c0010b74bcf2ac1a23b4f
URL: https://github.com/llvm/llvm-project/commit/597b90ebacafad94082c0010b74bcf2ac1a23b4f
DIFF: https://github.com/llvm/llvm-project/commit/597b90ebacafad94082c0010b74bcf2ac1a23b4f.diff
LOG: [libc++] Fix __simple_view concept in std::ranges
Differential Revision: https://reviews.llvm.org/D116808
Added:
Modified:
libcxx/include/__ranges/concepts.h
libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp
libcxx/test/std/ranges/range.adaptors/range.drop/begin.pass.cpp
libcxx/test/std/ranges/range.adaptors/range.join.view/begin.pass.cpp
libcxx/test/std/ranges/range.adaptors/range.take/begin.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h
index fa31074ab6581..a9cb15f9f17ce 100644
--- a/libcxx/include/__ranges/concepts.h
+++ b/libcxx/include/__ranges/concepts.h
@@ -83,11 +83,11 @@ namespace ranges {
movable<_Tp> &&
enable_view<_Tp>;
- template<class _Range>
+ template <class _Range>
concept __simple_view =
view<_Range> && range<const _Range> &&
same_as<iterator_t<_Range>, iterator_t<const _Range>> &&
- same_as<sentinel_t<_Range>, iterator_t<const _Range>>;
+ same_as<sentinel_t<_Range>, sentinel_t<const _Range>>;
// [range.refinements], other range refinements
template <class _Rp, class _Tp>
diff --git a/libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp
index 7aef1bab92a56..fd7427f25900d 100644
--- a/libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp
+++ b/libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp
@@ -39,7 +39,14 @@ struct DifferentSentinel : std::ranges::view_base {
sentinel_wrapper<int*> end() const;
};
+struct WrongConstSentinel : std::ranges::view_base {
+ int *begin() const;
+ sentinel_wrapper<int*> end();
+ sentinel_wrapper<const int*> end() const;
+};
+
static_assert( std::ranges::__simple_view<SimpleView>);
static_assert(!std::ranges::__simple_view<WrongConstView>);
static_assert(!std::ranges::__simple_view<NoConstView>);
-static_assert(!std::ranges::__simple_view<DifferentSentinel>);
+static_assert( std::ranges::__simple_view<DifferentSentinel>);
+static_assert(!std::ranges::__simple_view<WrongConstSentinel>);
diff --git a/libcxx/test/std/ranges/range.adaptors/range.drop/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.drop/begin.pass.cpp
index ca19ef2ba8023..2455eeeb47f38 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.drop/begin.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.drop/begin.pass.cpp
@@ -19,11 +19,32 @@
#include <ranges>
#include "test_macros.h"
+#include "test_iterators.h"
#include "types.h"
template<class T>
concept BeginInvocable = requires(std::ranges::drop_view<T> t) { t.begin(); };
+template <bool IsSimple>
+struct MaybeSimpleView : std::ranges::view_base {
+ int* num_of_non_const_begin_calls;
+ int* num_of_const_begin_calls;
+
+ constexpr int* begin() {
+ ++(*num_of_non_const_begin_calls);
+ return nullptr;
+ }
+ constexpr std::conditional_t<IsSimple, int*, const int*> begin() const {
+ ++(*num_of_const_begin_calls);
+ return nullptr;
+ }
+ constexpr int* end() const { return nullptr; }
+ constexpr size_t size() const { return 0; }
+};
+
+using SimpleView = MaybeSimpleView<true>;
+using NonSimpleView = MaybeSimpleView<false>;
+
constexpr bool test() {
// random_access_range<const V> && sized_range<const V>
std::ranges::drop_view dropView1(MoveOnlyView(), 4);
@@ -62,6 +83,36 @@ constexpr bool test() {
static_assert(!BeginInvocable<const ForwardView>);
+ {
+ static_assert(std::ranges::random_access_range<const SimpleView>);
+ static_assert(std::ranges::sized_range<const SimpleView>);
+ LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleView>);
+ int non_const_calls = 0;
+ int const_calls = 0;
+ std::ranges::drop_view dropView(SimpleView{{}, &non_const_calls, &const_calls}, 4);
+ assert(dropView.begin() == nullptr);
+ assert(non_const_calls == 0);
+ assert(const_calls == 1);
+ assert(std::as_const(dropView).begin() == nullptr);
+ assert(non_const_calls == 0);
+ assert(const_calls == 2);
+ }
+
+ {
+ static_assert(std::ranges::random_access_range<const NonSimpleView>);
+ static_assert(std::ranges::sized_range<const NonSimpleView>);
+ LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<NonSimpleView>);
+ int non_const_calls = 0;
+ int const_calls = 0;
+ std::ranges::drop_view dropView(NonSimpleView{{}, &non_const_calls, &const_calls}, 4);
+ assert(dropView.begin() == nullptr);
+ assert(non_const_calls == 1);
+ assert(const_calls == 0);
+ assert(std::as_const(dropView).begin() == nullptr);
+ assert(non_const_calls == 1);
+ assert(const_calls == 1);
+ }
+
return true;
}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join.view/begin.pass.cpp
index 2441f6787f2ba..25785644b10a2 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join.view/begin.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join.view/begin.pass.cpp
@@ -19,6 +19,17 @@
#include "test_macros.h"
#include "types.h"
+struct NonSimpleParentView : std::ranges::view_base {
+ ChildView* begin() { return nullptr; }
+ const ChildView* begin() const;
+ const ChildView* end() const;
+};
+
+struct SimpleParentView : std::ranges::view_base {
+ const ChildView* begin() const;
+ const ChildView* end() const;
+};
+
constexpr bool test() {
int buffer[4][4] = {{1111, 2222, 3333, 4444}, {555, 666, 777, 888}, {99, 1010, 1111, 1212}, {13, 14, 15, 16}};
@@ -86,6 +97,20 @@ constexpr bool test() {
assert(*jv.begin() == 1111);
}
+ // !simple-view<V>
+ {
+ std::ranges::join_view<NonSimpleParentView> jv;
+ static_assert(!std::same_as<decltype(jv.begin()),
+ decltype(std::as_const(jv).begin())>);
+ }
+
+ // simple-view<V> && is_reference_v<range_reference_t<V>>;
+ {
+ std::ranges::join_view<SimpleParentView> jv;
+ static_assert(std::same_as<decltype(jv.begin()),
+ decltype(std::as_const(jv).begin())>);
+ }
+
return true;
}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/begin.pass.cpp
index 056817f1e7f45..909212841e44d 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take/begin.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.take/begin.pass.cpp
@@ -21,6 +21,14 @@
#include "test_range.h"
#include "types.h"
+struct NonCommonSimpleView : std::ranges::view_base {
+ int* begin() const;
+ sentinel_wrapper<int*> end() const;
+ size_t size() { return 0; } // deliberately non-const
+};
+static_assert(std::ranges::sized_range<NonCommonSimpleView>);
+static_assert(!std::ranges::sized_range<const NonCommonSimpleView>);
+
constexpr bool test() {
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
@@ -63,6 +71,13 @@ constexpr bool test() {
ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<int*>);
}
+ // __simple_view<V> && sized_range<V> && !size_range<!V>
+ {
+ std::ranges::take_view<NonCommonSimpleView> tv{};
+ ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<int*>);
+ ASSERT_SAME_TYPE(decltype(std::as_const(tv).begin()), std::counted_iterator<int*>);
+ }
+
return true;
}
More information about the libcxx-commits
mailing list