forked from OSchip/llvm-project
[libc++] Fix __simple_view concept in std::ranges
Differential Revision: https://reviews.llvm.org/D116808
This commit is contained in:
parent
02455bea6b
commit
597b90ebac
|
@ -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>
|
||||
|
|
|
@ -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>);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue