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