1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11, c++14, c++17 10 // UNSUPPORTED: libcpp-has-no-incomplete-ranges 11 12 // constexpr auto begin() 13 // requires (!(simple-view<V> && 14 // random_access_range<const V> && sized_range<const V>)); 15 // constexpr auto begin() const 16 // requires random_access_range<const V> && sized_range<const V>; 17 18 #include <ranges> 19 20 #include "test_macros.h" 21 #include "test_iterators.h" 22 #include "types.h" 23 24 template<class T> 25 concept BeginInvocable = requires(std::ranges::drop_view<T> t) { t.begin(); }; 26 27 template <bool IsSimple> 28 struct MaybeSimpleView : std::ranges::view_base { 29 int* num_of_non_const_begin_calls; 30 int* num_of_const_begin_calls; 31 32 constexpr int* begin() { 33 ++(*num_of_non_const_begin_calls); 34 return nullptr; 35 } 36 constexpr std::conditional_t<IsSimple, int*, const int*> begin() const { 37 ++(*num_of_const_begin_calls); 38 return nullptr; 39 } 40 constexpr int* end() const { return nullptr; } 41 constexpr size_t size() const { return 0; } 42 }; 43 44 using SimpleView = MaybeSimpleView<true>; 45 using NonSimpleView = MaybeSimpleView<false>; 46 47 constexpr bool test() { 48 // random_access_range<const V> && sized_range<const V> 49 std::ranges::drop_view dropView1(MoveOnlyView(), 4); 50 assert(dropView1.begin() == globalBuff + 4); 51 52 // !random_access_range<const V> 53 std::ranges::drop_view dropView2(ForwardView(), 4); 54 assert(base(dropView2.begin()) == globalBuff + 4); 55 56 // !random_access_range<const V> 57 std::ranges::drop_view dropView3(InputView(), 4); 58 assert(base(dropView3.begin()) == globalBuff + 4); 59 60 // random_access_range<const V> && sized_range<const V> 61 std::ranges::drop_view dropView4(MoveOnlyView(), 8); 62 assert(dropView4.begin() == globalBuff + 8); 63 64 // random_access_range<const V> && sized_range<const V> 65 std::ranges::drop_view dropView5(MoveOnlyView(), 0); 66 assert(dropView5.begin() == globalBuff); 67 68 // random_access_range<const V> && sized_range<const V> 69 const std::ranges::drop_view dropView6(MoveOnlyView(), 0); 70 assert(dropView6.begin() == globalBuff); 71 72 // random_access_range<const V> && sized_range<const V> 73 std::ranges::drop_view dropView7(MoveOnlyView(), 10); 74 assert(dropView7.begin() == globalBuff + 8); 75 76 CountedView view8; 77 std::ranges::drop_view dropView8(view8, 5); 78 assert(base(base(dropView8.begin())) == globalBuff + 5); 79 assert(dropView8.begin().stride_count() == 5); 80 assert(base(base(dropView8.begin())) == globalBuff + 5); 81 assert(dropView8.begin().stride_count() == 5); 82 83 static_assert(!BeginInvocable<const ForwardView>); 84 85 { 86 static_assert(std::ranges::random_access_range<const SimpleView>); 87 static_assert(std::ranges::sized_range<const SimpleView>); 88 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<SimpleView>); 89 int non_const_calls = 0; 90 int const_calls = 0; 91 std::ranges::drop_view dropView(SimpleView{{}, &non_const_calls, &const_calls}, 4); 92 assert(dropView.begin() == nullptr); 93 assert(non_const_calls == 0); 94 assert(const_calls == 1); 95 assert(std::as_const(dropView).begin() == nullptr); 96 assert(non_const_calls == 0); 97 assert(const_calls == 2); 98 } 99 100 { 101 static_assert(std::ranges::random_access_range<const NonSimpleView>); 102 static_assert(std::ranges::sized_range<const NonSimpleView>); 103 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<NonSimpleView>); 104 int non_const_calls = 0; 105 int const_calls = 0; 106 std::ranges::drop_view dropView(NonSimpleView{{}, &non_const_calls, &const_calls}, 4); 107 assert(dropView.begin() == nullptr); 108 assert(non_const_calls == 1); 109 assert(const_calls == 0); 110 assert(std::as_const(dropView).begin() == nullptr); 111 assert(non_const_calls == 1); 112 assert(const_calls == 1); 113 } 114 115 return true; 116 } 117 118 int main(int, char**) { 119 test(); 120 static_assert(test()); 121 122 return 0; 123 } 124