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 // constexpr auto begin() const requires forward_range<View> && forward_range<const View>; 14 15 #include <ranges> 16 17 #include <cassert> 18 #include <utility> 19 #include "test_iterators.h" 20 #include "types.h" 21 22 template <class View> 23 concept ConstBeginDisabled = !requires (const View v) { 24 { (*v.begin()) }; 25 }; 26 27 constexpr bool test() { 28 // non-const: forward_range<View> && simple-view<View> -> outer-iterator<Const = true> 29 // const: forward_range<View> && forward_range<const View> -> outer-iterator<Const = true> 30 { 31 using V = ForwardView; 32 using P = V; 33 34 static_assert(std::ranges::forward_range<V>); 35 static_assert(std::ranges::forward_range<const V>); 36 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<V>); 37 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<P>); 38 39 { 40 std::ranges::lazy_split_view<V, P> v; 41 auto it = v.begin(); 42 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>); 43 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>); 44 } 45 46 { 47 const std::ranges::lazy_split_view<V, P> cv; 48 auto it = cv.begin(); 49 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>); 50 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>); 51 } 52 } 53 54 // non-const: forward_range<View> && !simple-view<View> -> outer-iterator<Const = false> 55 // const: forward_range<View> && forward_range<const View> -> outer-iterator<Const = true> 56 { 57 using V = ForwardDiffView; 58 using P = V; 59 60 static_assert(std::ranges::forward_range<V>); 61 static_assert(std::ranges::forward_range<const V>); 62 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<V>); 63 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<P>); 64 65 { 66 std::ranges::lazy_split_view<V, P> v; 67 auto it = v.begin(); 68 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>); 69 static_assert(std::is_same_v<decltype(*(*it).begin()), char&>); 70 } 71 72 { 73 const std::ranges::lazy_split_view<V, P> cv; 74 auto it = cv.begin(); 75 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>); 76 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>); 77 } 78 } 79 80 // non-const: forward_range<View> && !simple-view<View> -> outer-iterator<Const = false> 81 // const: forward_range<View> && !forward_range<const View> -> disabled 82 { 83 using V = ForwardOnlyIfNonConstView; 84 using P = V; 85 static_assert(std::ranges::forward_range<V>); 86 static_assert(!std::ranges::forward_range<const V>); 87 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<V>); 88 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<P>); 89 90 std::ranges::lazy_split_view<V, P> v; 91 auto it = v.begin(); 92 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>); 93 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>); 94 95 static_assert(ConstBeginDisabled<decltype(v)>); 96 } 97 98 // non-const: forward_range<View> && simple-view<View> && !simple-view<Pattern> -> outer-iterator<Const = false> 99 // const: forward_range<View> && forward_range<const View> -> outer-iterator<Const = true> 100 { 101 using V = ForwardView; 102 using P = ForwardOnlyIfNonConstView; 103 104 static_assert(std::ranges::forward_range<V>); 105 static_assert(std::ranges::forward_range<const V>); 106 LIBCPP_STATIC_ASSERT(std::ranges::__simple_view<V>); 107 LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view<P>); 108 109 { 110 std::ranges::lazy_split_view<V, P> v; 111 auto it = v.begin(); 112 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>); 113 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>); 114 } 115 116 { 117 const std::ranges::lazy_split_view<V, P> cv; 118 auto it = cv.begin(); 119 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::forward_iterator_tag>); 120 static_assert(std::is_same_v<decltype(*(*it).begin()), const char&>); 121 } 122 } 123 124 // non-const: !forward_range<View> && tiny-range<Pattern> -> outer-iterator<Const = false> 125 // const: !forward_range<View> -> disabled 126 { 127 using V = InputView; 128 using P = ForwardTinyView; 129 130 static_assert(!std::ranges::forward_range<V>); 131 static_assert(std::ranges::forward_range<P>); 132 133 std::ranges::lazy_split_view<V, P> v; 134 auto it = v.begin(); 135 static_assert(std::is_same_v<decltype(it)::iterator_concept, std::input_iterator_tag>); 136 static_assert(std::is_same_v<decltype(*(*it).begin()), char&>); 137 138 static_assert(ConstBeginDisabled<decltype(v)>); 139 } 140 141 return true; 142 } 143 144 int main(int, char**) { 145 test(); 146 static_assert(test()); 147 148 return 0; 149 } 150