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