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 size() requires sized_range<V> 15 // constexpr auto size() const requires sized_range<const V> 16 17 #include <ranges> 18 #include <cassert> 19 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 template<class T> 58 concept SizeEnabled = requires(const std::ranges::common_view<T>& comm) { 59 comm.size(); 60 }; 61 62 constexpr bool test() { 63 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 64 65 { 66 static_assert( SizeEnabled<SizedForwardView>); 67 static_assert(!SizeEnabled<CopyableView>); 68 } 69 70 { 71 std::ranges::common_view<SizedForwardView> common(SizedForwardView{buffer}); 72 assert(common.size() == 8); 73 } 74 75 { 76 const std::ranges::common_view<SizedForwardView> common(SizedForwardView{buffer}); 77 assert(common.size() == 8); 78 } 79 80 return true; 81 } 82 83 int main(int, char**) { 84 test(); 85 static_assert(test()); 86 87 return 0; 88 } 89