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 // std::views::counted; 14 15 #include <ranges> 16 #include <cassert> 17 #include <concepts> 18 #include <cstddef> 19 #include <memory> 20 #include <span> 21 #include <utility> 22 23 #include "test_macros.h" 24 #include "test_iterators.h" 25 26 struct RvalueConvertible { 27 RvalueConvertible(const RvalueConvertible&) = delete; 28 operator int() &&; 29 }; 30 31 struct LvalueConvertible { 32 LvalueConvertible(const LvalueConvertible&) = delete; 33 operator int() &; 34 }; 35 36 struct OnlyExplicitlyConvertible { 37 explicit operator int() const; 38 }; 39 40 template<class... Ts> 41 concept CountedInvocable = requires (Ts&&... ts) { 42 std::views::counted(std::forward<Ts>(ts)...); 43 }; 44 45 constexpr bool test() { 46 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 47 48 { 49 static_assert(std::addressof(std::views::counted) == std::addressof(std::ranges::views::counted)); 50 51 auto copy = std::views::counted; 52 static_assert(std::semiregular<decltype(copy)>); 53 54 static_assert( CountedInvocable<int*, size_t>); 55 static_assert(!CountedInvocable<int*, LvalueConvertible>); 56 static_assert( CountedInvocable<int*, LvalueConvertible&>); 57 static_assert( CountedInvocable<int*, RvalueConvertible>); 58 static_assert(!CountedInvocable<int*, RvalueConvertible&>); 59 static_assert(!CountedInvocable<int*, OnlyExplicitlyConvertible>); 60 static_assert(!CountedInvocable<int*, int*>); 61 static_assert(!CountedInvocable<int*>); 62 static_assert(!CountedInvocable<size_t>); 63 static_assert(!CountedInvocable<>); 64 } 65 66 { 67 auto c1 = std::views::counted(buffer, 3); 68 auto c2 = std::views::counted(std::as_const(buffer), 3); 69 70 ASSERT_SAME_TYPE(decltype(c1), std::span<int>); 71 ASSERT_SAME_TYPE(decltype(c2), std::span<const int>); 72 73 assert(c1.data() == buffer && c1.size() == 3); 74 assert(c2.data() == buffer && c2.size() == 3); 75 } 76 77 { 78 auto it = contiguous_iterator<int*>(buffer); 79 auto cit = contiguous_iterator<const int*>(buffer); 80 81 auto c1 = std::views::counted(it, 3); 82 auto c2 = std::views::counted(std::as_const(it), 3); 83 auto c3 = std::views::counted(std::move(it), 3); 84 auto c4 = std::views::counted(contiguous_iterator<int*>(buffer), 3); 85 auto c5 = std::views::counted(cit, 3); 86 auto c6 = std::views::counted(std::as_const(cit), 3); 87 auto c7 = std::views::counted(std::move(cit), 3); 88 auto c8 = std::views::counted(contiguous_iterator<const int*>(buffer), 3); 89 90 ASSERT_SAME_TYPE(decltype(c1), std::span<int>); 91 ASSERT_SAME_TYPE(decltype(c2), std::span<int>); 92 ASSERT_SAME_TYPE(decltype(c3), std::span<int>); 93 ASSERT_SAME_TYPE(decltype(c4), std::span<int>); 94 ASSERT_SAME_TYPE(decltype(c5), std::span<const int>); 95 ASSERT_SAME_TYPE(decltype(c6), std::span<const int>); 96 ASSERT_SAME_TYPE(decltype(c7), std::span<const int>); 97 ASSERT_SAME_TYPE(decltype(c8), std::span<const int>); 98 99 assert(c1.data() == buffer && c1.size() == 3); 100 assert(c2.data() == buffer && c2.size() == 3); 101 assert(c3.data() == buffer && c3.size() == 3); 102 assert(c4.data() == buffer && c4.size() == 3); 103 assert(c5.data() == buffer && c5.size() == 3); 104 assert(c6.data() == buffer && c6.size() == 3); 105 assert(c7.data() == buffer && c7.size() == 3); 106 assert(c8.data() == buffer && c8.size() == 3); 107 } 108 109 { 110 auto it = random_access_iterator<int*>(buffer); 111 auto cit = random_access_iterator<const int*>(buffer); 112 113 auto c1 = std::views::counted(it, 3); 114 auto c2 = std::views::counted(std::as_const(it), 3); 115 auto c3 = std::views::counted(std::move(it), 3); 116 auto c4 = std::views::counted(random_access_iterator<int*>(buffer), 3); 117 auto c5 = std::views::counted(cit, 3); 118 auto c6 = std::views::counted(std::as_const(cit), 3); 119 auto c7 = std::views::counted(std::move(cit), 3); 120 auto c8 = std::views::counted(random_access_iterator<const int*>(buffer), 3); 121 122 ASSERT_SAME_TYPE(decltype(c1), std::ranges::subrange<random_access_iterator<int*>>); 123 ASSERT_SAME_TYPE(decltype(c2), std::ranges::subrange<random_access_iterator<int*>>); 124 ASSERT_SAME_TYPE(decltype(c3), std::ranges::subrange<random_access_iterator<int*>>); 125 ASSERT_SAME_TYPE(decltype(c4), std::ranges::subrange<random_access_iterator<int*>>); 126 ASSERT_SAME_TYPE(decltype(c5), std::ranges::subrange<random_access_iterator<const int*>>); 127 ASSERT_SAME_TYPE(decltype(c6), std::ranges::subrange<random_access_iterator<const int*>>); 128 ASSERT_SAME_TYPE(decltype(c7), std::ranges::subrange<random_access_iterator<const int*>>); 129 ASSERT_SAME_TYPE(decltype(c8), std::ranges::subrange<random_access_iterator<const int*>>); 130 131 assert(c1.begin() == it && c1.end() == it + 3); 132 assert(c2.begin() == it && c2.end() == it + 3); 133 assert(c3.begin() == it && c3.end() == it + 3); 134 assert(c4.begin() == it && c4.end() == it + 3); 135 assert(c5.begin() == cit && c5.end() == cit + 3); 136 assert(c6.begin() == cit && c6.end() == cit + 3); 137 assert(c7.begin() == cit && c7.end() == cit + 3); 138 assert(c8.begin() == cit && c8.end() == cit + 3); 139 } 140 141 { 142 auto it = bidirectional_iterator<int*>(buffer); 143 auto cit = bidirectional_iterator<const int*>(buffer); 144 145 auto c1 = std::views::counted(it, 3); 146 auto c2 = std::views::counted(std::as_const(it), 3); 147 auto c3 = std::views::counted(std::move(it), 3); 148 auto c4 = std::views::counted(bidirectional_iterator<int*>(buffer), 3); 149 auto c5 = std::views::counted(cit, 3); 150 auto c6 = std::views::counted(std::as_const(cit), 3); 151 auto c7 = std::views::counted(std::move(cit), 3); 152 auto c8 = std::views::counted(bidirectional_iterator<const int*>(buffer), 3); 153 154 using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 155 using ConstExpected = std::ranges::subrange<std::counted_iterator<decltype(cit)>, std::default_sentinel_t>; 156 157 ASSERT_SAME_TYPE(decltype(c1), Expected); 158 ASSERT_SAME_TYPE(decltype(c2), Expected); 159 ASSERT_SAME_TYPE(decltype(c3), Expected); 160 ASSERT_SAME_TYPE(decltype(c4), Expected); 161 ASSERT_SAME_TYPE(decltype(c5), ConstExpected); 162 ASSERT_SAME_TYPE(decltype(c6), ConstExpected); 163 ASSERT_SAME_TYPE(decltype(c7), ConstExpected); 164 ASSERT_SAME_TYPE(decltype(c8), ConstExpected); 165 166 assert(c1.begin().base() == it && c1.size() == 3); 167 assert(c2.begin().base() == it && c2.size() == 3); 168 assert(c3.begin().base() == it && c3.size() == 3); 169 assert(c4.begin().base() == it && c4.size() == 3); 170 assert(c5.begin().base() == cit && c5.size() == 3); 171 assert(c6.begin().base() == cit && c6.size() == 3); 172 assert(c7.begin().base() == cit && c7.size() == 3); 173 assert(c8.begin().base() == cit && c8.size() == 3); 174 } 175 176 { 177 auto it = output_iterator<int*>(buffer); 178 179 auto c1 = std::views::counted(it, 3); 180 auto c2 = std::views::counted(std::as_const(it), 3); 181 auto c3 = std::views::counted(std::move(it), 3); 182 auto c4 = std::views::counted(output_iterator<int*>(buffer), 3); 183 184 using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 185 186 ASSERT_SAME_TYPE(decltype(c1), Expected); 187 ASSERT_SAME_TYPE(decltype(c2), Expected); 188 ASSERT_SAME_TYPE(decltype(c3), Expected); 189 ASSERT_SAME_TYPE(decltype(c4), Expected); 190 191 assert(base(c1.begin().base()) == buffer && c1.size() == 3); 192 assert(base(c2.begin().base()) == buffer && c2.size() == 3); 193 assert(base(c3.begin().base()) == buffer && c3.size() == 3); 194 assert(base(c4.begin().base()) == buffer && c4.size() == 3); 195 } 196 197 { 198 auto it = cpp17_input_iterator<int*>(buffer); 199 200 auto c1 = std::views::counted(it, 3); 201 auto c2 = std::views::counted(std::as_const(it), 3); 202 auto c3 = std::views::counted(std::move(it), 3); 203 auto c4 = std::views::counted(cpp17_input_iterator<int*>(buffer), 3); 204 205 using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 206 207 ASSERT_SAME_TYPE(decltype(c1), Expected); 208 ASSERT_SAME_TYPE(decltype(c2), Expected); 209 ASSERT_SAME_TYPE(decltype(c3), Expected); 210 ASSERT_SAME_TYPE(decltype(c4), Expected); 211 212 assert(base(c1.begin().base()) == buffer && c1.size() == 3); 213 assert(base(c2.begin().base()) == buffer && c2.size() == 3); 214 assert(base(c3.begin().base()) == buffer && c3.size() == 3); 215 assert(base(c4.begin().base()) == buffer && c4.size() == 3); 216 } 217 218 { 219 auto it = cpp20_input_iterator<int*>(buffer); 220 221 static_assert(!std::copyable<cpp20_input_iterator<int*>>); 222 static_assert(!CountedInvocable<cpp20_input_iterator<int*>&, int>); 223 static_assert(!CountedInvocable<const cpp20_input_iterator<int*>&, int>); 224 auto c3 = std::views::counted(std::move(it), 3); 225 auto c4 = std::views::counted(cpp20_input_iterator<int*>(buffer), 3); 226 227 using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 228 229 ASSERT_SAME_TYPE(decltype(c3), Expected); 230 ASSERT_SAME_TYPE(decltype(c4), Expected); 231 232 assert(base(c3.begin().base()) == buffer && c3.size() == 3); 233 assert(base(c4.begin().base()) == buffer && c4.size() == 3); 234 } 235 236 return true; 237 } 238 239 int main(int, char**) { 240 test(); 241 static_assert(test()); 242 243 return 0; 244 } 245