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 static_assert( CountedInvocable<int*, size_t>); 52 static_assert(!CountedInvocable<int*, LvalueConvertible>); 53 static_assert( CountedInvocable<int*, LvalueConvertible&>); 54 static_assert( CountedInvocable<int*, RvalueConvertible>); 55 static_assert(!CountedInvocable<int*, RvalueConvertible&>); 56 static_assert(!CountedInvocable<int*, OnlyExplicitlyConvertible>); 57 static_assert(!CountedInvocable<int*, int*>); 58 static_assert(!CountedInvocable<int*>); 59 static_assert(!CountedInvocable<size_t>); 60 static_assert(!CountedInvocable<>); 61 } 62 63 { 64 auto c1 = std::views::counted(buffer, 3); 65 auto c2 = std::views::counted(std::as_const(buffer), 3); 66 67 ASSERT_SAME_TYPE(decltype(c1), std::span<int>); 68 ASSERT_SAME_TYPE(decltype(c2), std::span<const int>); 69 70 assert(c1.data() == buffer && c1.size() == 3); 71 assert(c2.data() == buffer && c2.size() == 3); 72 } 73 74 { 75 auto it = contiguous_iterator<int*>(buffer); 76 auto cit = contiguous_iterator<const int*>(buffer); 77 78 auto c1 = std::views::counted(it, 3); 79 auto c2 = std::views::counted(std::as_const(it), 3); 80 auto c3 = std::views::counted(std::move(it), 3); 81 auto c4 = std::views::counted(contiguous_iterator<int*>(buffer), 3); 82 auto c5 = std::views::counted(cit, 3); 83 auto c6 = std::views::counted(std::as_const(cit), 3); 84 auto c7 = std::views::counted(std::move(cit), 3); 85 auto c8 = std::views::counted(contiguous_iterator<const int*>(buffer), 3); 86 87 ASSERT_SAME_TYPE(decltype(c1), std::span<int>); 88 ASSERT_SAME_TYPE(decltype(c2), std::span<int>); 89 ASSERT_SAME_TYPE(decltype(c3), std::span<int>); 90 ASSERT_SAME_TYPE(decltype(c4), std::span<int>); 91 ASSERT_SAME_TYPE(decltype(c5), std::span<const int>); 92 ASSERT_SAME_TYPE(decltype(c6), std::span<const int>); 93 ASSERT_SAME_TYPE(decltype(c7), std::span<const int>); 94 ASSERT_SAME_TYPE(decltype(c8), std::span<const int>); 95 96 assert(c1.data() == buffer && c1.size() == 3); 97 assert(c2.data() == buffer && c2.size() == 3); 98 assert(c3.data() == buffer && c3.size() == 3); 99 assert(c4.data() == buffer && c4.size() == 3); 100 assert(c5.data() == buffer && c5.size() == 3); 101 assert(c6.data() == buffer && c6.size() == 3); 102 assert(c7.data() == buffer && c7.size() == 3); 103 assert(c8.data() == buffer && c8.size() == 3); 104 } 105 106 { 107 auto it = random_access_iterator<int*>(buffer); 108 auto cit = random_access_iterator<const int*>(buffer); 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), 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), 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 142 auto c1 = std::views::counted(it, 3); 143 auto c2 = std::views::counted(std::as_const(it), 3); 144 auto c3 = std::views::counted(std::move(it), 3); 145 auto c4 = std::views::counted(bidirectional_iterator<int*>(buffer), 3); 146 auto c5 = std::views::counted(cit, 3); 147 auto c6 = std::views::counted(std::as_const(cit), 3); 148 auto c7 = std::views::counted(std::move(cit), 3); 149 auto c8 = std::views::counted(bidirectional_iterator<const int*>(buffer), 3); 150 151 using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 152 using ConstExpected = std::ranges::subrange<std::counted_iterator<decltype(cit)>, std::default_sentinel_t>; 153 154 ASSERT_SAME_TYPE(decltype(c1), Expected); 155 ASSERT_SAME_TYPE(decltype(c2), Expected); 156 ASSERT_SAME_TYPE(decltype(c3), Expected); 157 ASSERT_SAME_TYPE(decltype(c4), Expected); 158 ASSERT_SAME_TYPE(decltype(c5), ConstExpected); 159 ASSERT_SAME_TYPE(decltype(c6), ConstExpected); 160 ASSERT_SAME_TYPE(decltype(c7), ConstExpected); 161 ASSERT_SAME_TYPE(decltype(c8), ConstExpected); 162 163 assert(c1.begin().base() == it && c1.size() == 3); 164 assert(c2.begin().base() == it && c2.size() == 3); 165 assert(c3.begin().base() == it && c3.size() == 3); 166 assert(c4.begin().base() == it && c4.size() == 3); 167 assert(c5.begin().base() == cit && c5.size() == 3); 168 assert(c6.begin().base() == cit && c6.size() == 3); 169 assert(c7.begin().base() == cit && c7.size() == 3); 170 assert(c8.begin().base() == cit && c8.size() == 3); 171 } 172 173 { 174 auto it = output_iterator<int*>(buffer); 175 176 auto c1 = std::views::counted(it, 3); 177 auto c2 = std::views::counted(std::as_const(it), 3); 178 auto c3 = std::views::counted(std::move(it), 3); 179 auto c4 = std::views::counted(output_iterator<int*>(buffer), 3); 180 181 using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 182 183 ASSERT_SAME_TYPE(decltype(c1), Expected); 184 ASSERT_SAME_TYPE(decltype(c2), Expected); 185 ASSERT_SAME_TYPE(decltype(c3), Expected); 186 ASSERT_SAME_TYPE(decltype(c4), Expected); 187 188 assert(base(c1.begin().base()) == buffer && c1.size() == 3); 189 assert(base(c2.begin().base()) == buffer && c2.size() == 3); 190 assert(base(c3.begin().base()) == buffer && c3.size() == 3); 191 assert(base(c4.begin().base()) == buffer && c4.size() == 3); 192 } 193 194 { 195 auto it = cpp17_input_iterator<int*>(buffer); 196 197 auto c1 = std::views::counted(it, 3); 198 auto c2 = std::views::counted(std::as_const(it), 3); 199 auto c3 = std::views::counted(std::move(it), 3); 200 auto c4 = std::views::counted(cpp17_input_iterator<int*>(buffer), 3); 201 202 using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 203 204 ASSERT_SAME_TYPE(decltype(c1), Expected); 205 ASSERT_SAME_TYPE(decltype(c2), Expected); 206 ASSERT_SAME_TYPE(decltype(c3), Expected); 207 ASSERT_SAME_TYPE(decltype(c4), Expected); 208 209 assert(base(c1.begin().base()) == buffer && c1.size() == 3); 210 assert(base(c2.begin().base()) == buffer && c2.size() == 3); 211 assert(base(c3.begin().base()) == buffer && c3.size() == 3); 212 assert(base(c4.begin().base()) == buffer && c4.size() == 3); 213 } 214 215 { 216 auto it = cpp20_input_iterator<int*>(buffer); 217 218 static_assert(!std::copyable<cpp20_input_iterator<int*>>); 219 static_assert(!CountedInvocable<cpp20_input_iterator<int*>&, int>); 220 static_assert(!CountedInvocable<const cpp20_input_iterator<int*>&, int>); 221 auto c3 = std::views::counted(std::move(it), 3); 222 auto c4 = std::views::counted(cpp20_input_iterator<int*>(buffer), 3); 223 224 using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 225 226 ASSERT_SAME_TYPE(decltype(c3), Expected); 227 ASSERT_SAME_TYPE(decltype(c4), Expected); 228 229 assert(base(c3.begin().base()) == buffer && c3.size() == 3); 230 assert(base(c4.begin().base()) == buffer && c4.size() == 3); 231 } 232 233 return true; 234 } 235 236 int main(int, char**) { 237 test(); 238 static_assert(test()); 239 240 return 0; 241 } 242