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