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-no-concepts 11 // UNSUPPORTED: gcc-10 12 // UNSUPPORTED: libcpp-has-no-incomplete-ranges 13 14 // constexpr auto end(); 15 // constexpr auto end() const requires range<const V>; 16 17 #include <ranges> 18 #include <cassert> 19 20 #include "test_macros.h" 21 #include "test_iterators.h" 22 #include "test_range.h" 23 24 struct CopyableView : std::ranges::view_base { 25 int *ptr_; 26 constexpr CopyableView(int* ptr) : ptr_(ptr) {} 27 friend constexpr int* begin(CopyableView& view) { return view.ptr_; } 28 friend constexpr int* begin(CopyableView const& view) { return view.ptr_; } 29 friend constexpr sentinel_wrapper<int*> end(CopyableView& view) { 30 return sentinel_wrapper<int*>{view.ptr_ + 8}; 31 } 32 friend constexpr sentinel_wrapper<int*> end(CopyableView const& view) { 33 return sentinel_wrapper<int*>{view.ptr_ + 8}; 34 } 35 }; 36 37 using ForwardIter = forward_iterator<int*>; 38 struct SizedForwardView : std::ranges::view_base { 39 int *ptr_; 40 constexpr SizedForwardView(int* ptr) : ptr_(ptr) {} 41 friend constexpr ForwardIter begin(SizedForwardView& view) { return ForwardIter(view.ptr_); } 42 friend constexpr ForwardIter begin(SizedForwardView const& view) { return ForwardIter(view.ptr_); } 43 friend constexpr sentinel_wrapper<ForwardIter> end(SizedForwardView& view) { 44 return sentinel_wrapper<ForwardIter>{ForwardIter(view.ptr_ + 8)}; 45 } 46 friend constexpr sentinel_wrapper<ForwardIter> end(SizedForwardView const& view) { 47 return sentinel_wrapper<ForwardIter>{ForwardIter(view.ptr_ + 8)}; 48 } 49 }; 50 51 constexpr auto operator-(sentinel_wrapper<ForwardIter> sent, ForwardIter iter) { 52 return sent.base().base() - iter.base(); 53 } 54 constexpr auto operator-(ForwardIter iter, sentinel_wrapper<ForwardIter> sent) { 55 return iter.base() - sent.base().base(); 56 } 57 58 using RandomAccessIter = random_access_iterator<int*>; 59 struct SizedRandomcAccessView : std::ranges::view_base { 60 int *ptr_; 61 constexpr SizedRandomcAccessView(int* ptr) : ptr_(ptr) {} 62 friend constexpr RandomAccessIter begin(SizedRandomcAccessView& view) { return RandomAccessIter(view.ptr_); } 63 friend constexpr RandomAccessIter begin(SizedRandomcAccessView const& view) { return RandomAccessIter(view.ptr_); } 64 friend constexpr sentinel_wrapper<RandomAccessIter> end(SizedRandomcAccessView& view) { 65 return sentinel_wrapper<RandomAccessIter>{RandomAccessIter(view.ptr_ + 8)}; 66 } 67 friend constexpr sentinel_wrapper<RandomAccessIter> end(SizedRandomcAccessView const& view) { 68 return sentinel_wrapper<RandomAccessIter>{RandomAccessIter(view.ptr_ + 8)}; 69 } 70 }; 71 72 constexpr auto operator-(sentinel_wrapper<RandomAccessIter> sent, RandomAccessIter iter) { 73 return sent.base().base() - iter.base(); 74 } 75 constexpr auto operator-(RandomAccessIter iter, sentinel_wrapper<RandomAccessIter> sent) { 76 return iter.base() - sent.base().base(); 77 } 78 79 constexpr bool test() { 80 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 81 82 { 83 std::ranges::common_view<SizedRandomcAccessView> comm(SizedRandomcAccessView{buffer}); 84 assert(comm.end().base() == buffer + 8); 85 // Note this should NOT be the sentinel type. 86 ASSERT_SAME_TYPE(decltype(comm.end()), RandomAccessIter); 87 } 88 89 { 90 const std::ranges::common_view<SizedRandomcAccessView> comm(SizedRandomcAccessView{buffer}); 91 assert(comm.end().base() == buffer + 8); 92 // Note this should NOT be the sentinel type. 93 ASSERT_SAME_TYPE(decltype(comm.end()), RandomAccessIter); 94 } 95 96 return true; 97 } 98 99 int main(int, char**) { 100 test(); 101 static_assert(test()); 102 103 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 104 105 using CommonForwardIter = std::common_iterator<ForwardIter, sentinel_wrapper<ForwardIter>>; 106 using CommonIntIter = std::common_iterator<int*, sentinel_wrapper<int*>>; 107 108 { 109 std::ranges::common_view<SizedForwardView> comm(SizedForwardView{buffer}); 110 assert(comm.end() == CommonForwardIter(sentinel_wrapper<ForwardIter>(ForwardIter(buffer + 8)))); 111 ASSERT_SAME_TYPE(decltype(comm.end()), CommonForwardIter); 112 } 113 114 { 115 std::ranges::common_view<CopyableView> comm(CopyableView{buffer}); 116 assert(comm.end() == CommonIntIter(sentinel_wrapper<int*>(buffer + 8))); 117 ASSERT_SAME_TYPE(decltype(comm.end()), CommonIntIter); 118 } 119 120 { 121 const std::ranges::common_view<SizedForwardView> comm(SizedForwardView{buffer}); 122 assert(comm.end() == CommonForwardIter(sentinel_wrapper<ForwardIter>(ForwardIter(buffer + 8)))); 123 ASSERT_SAME_TYPE(decltype(comm.end()), CommonForwardIter); 124 } 125 126 { 127 const std::ranges::common_view<CopyableView> comm(CopyableView{buffer}); 128 assert(comm.end() == CommonIntIter(sentinel_wrapper<int*>(buffer + 8))); 129 ASSERT_SAME_TYPE(decltype(comm.end()), CommonIntIter); 130 } 131 132 return 0; 133 } 134