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