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 size() requires sized_range<V> 14 // constexpr auto size() const requires sized_range<const V> 15 16 #include <ranges> 17 #include <cassert> 18 19 #include "test_iterators.h" 20 #include "test_range.h" 21 22 struct CopyableView : std::ranges::view_base { 23 int *ptr_; 24 constexpr CopyableView(int* ptr) : ptr_(ptr) {} 25 friend constexpr int* begin(CopyableView& view) { return view.ptr_; } 26 friend constexpr int* begin(CopyableView const& view) { return view.ptr_; } 27 friend constexpr sentinel_wrapper<int*> end(CopyableView& view) { 28 return sentinel_wrapper<int*>{view.ptr_ + 8}; 29 } 30 friend constexpr sentinel_wrapper<int*> end(CopyableView const& view) { 31 return sentinel_wrapper<int*>{view.ptr_ + 8}; 32 } 33 }; 34 35 using ForwardIter = forward_iterator<int*>; 36 struct SizedForwardView : std::ranges::view_base { 37 int *ptr_; 38 constexpr SizedForwardView(int* ptr) : ptr_(ptr) {} 39 friend constexpr ForwardIter begin(SizedForwardView& view) { return ForwardIter(view.ptr_); } 40 friend constexpr ForwardIter begin(SizedForwardView const& view) { return ForwardIter(view.ptr_); } 41 friend constexpr sentinel_wrapper<ForwardIter> end(SizedForwardView& view) { 42 return sentinel_wrapper<ForwardIter>{ForwardIter(view.ptr_ + 8)}; 43 } 44 friend constexpr sentinel_wrapper<ForwardIter> end(SizedForwardView const& view) { 45 return sentinel_wrapper<ForwardIter>{ForwardIter(view.ptr_ + 8)}; 46 } 47 }; 48 49 constexpr auto operator-(sentinel_wrapper<ForwardIter> sent, ForwardIter iter) { 50 return sent.base().base() - iter.base(); 51 } 52 constexpr auto operator-(ForwardIter iter, sentinel_wrapper<ForwardIter> sent) { 53 return iter.base() - sent.base().base(); 54 } 55 56 template<class T> 57 concept SizeEnabled = requires(const std::ranges::common_view<T>& comm) { 58 comm.size(); 59 }; 60 61 constexpr bool test() { 62 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 63 64 { 65 static_assert( SizeEnabled<SizedForwardView>); 66 static_assert(!SizeEnabled<CopyableView>); 67 } 68 69 { 70 std::ranges::common_view<SizedForwardView> common(SizedForwardView{buffer}); 71 assert(common.size() == 8); 72 } 73 74 { 75 const std::ranges::common_view<SizedForwardView> common(SizedForwardView{buffer}); 76 assert(common.size() == 8); 77 } 78 79 return true; 80 } 81 82 int main(int, char**) { 83 test(); 84 static_assert(test()); 85 86 return 0; 87 } 88