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, c++20 10 // UNSUPPORTED: libcpp-has-no-incomplete-ranges 11 12 // test if zip_view models input_range, forward_range, bidirectional_range, 13 // random_access_range, contiguous_range, common_range 14 // sized_range 15 16 #include <cassert> 17 #include <concepts> 18 #include <ranges> 19 #include <tuple> 20 #include <utility> 21 22 #include "types.h" 23 24 void testConceptPair() { 25 int buffer1[2] = {1, 2}; 26 int buffer2[3] = {1, 2, 3}; 27 { 28 std::ranges::zip_view v{ContiguousCommonView{buffer1}, ContiguousCommonView{buffer2}}; 29 using View = decltype(v); 30 static_assert(std::ranges::random_access_range<View>); 31 static_assert(!std::ranges::contiguous_range<View>); 32 static_assert(std::ranges::common_range<View>); 33 static_assert(std::ranges::sized_range<View>); 34 } 35 36 { 37 std::ranges::zip_view v{ContiguousNonCommonView{buffer1}, ContiguousNonCommonView{buffer2}}; 38 using View = decltype(v); 39 static_assert(std::ranges::random_access_range<View>); 40 static_assert(!std::ranges::contiguous_range<View>); 41 static_assert(!std::ranges::common_range<View>); 42 static_assert(!std::ranges::sized_range<View>); 43 } 44 45 { 46 std::ranges::zip_view v{ContiguousNonCommonSized{buffer1}, ContiguousNonCommonSized{buffer2}}; 47 using View = decltype(v); 48 static_assert(std::ranges::random_access_range<View>); 49 static_assert(!std::ranges::contiguous_range<View>); 50 static_assert(std::ranges::common_range<View>); 51 static_assert(std::ranges::sized_range<View>); 52 } 53 54 { 55 std::ranges::zip_view v{SizedRandomAccessView{buffer1}, ContiguousCommonView{buffer2}}; 56 using View = decltype(v); 57 static_assert(std::ranges::random_access_range<View>); 58 static_assert(!std::ranges::contiguous_range<View>); 59 static_assert(std::ranges::common_range<View>); 60 static_assert(std::ranges::sized_range<View>); 61 } 62 63 { 64 std::ranges::zip_view v{SizedRandomAccessView{buffer1}, SizedRandomAccessView{buffer2}}; 65 using View = decltype(v); 66 static_assert(std::ranges::random_access_range<View>); 67 static_assert(!std::ranges::contiguous_range<View>); 68 static_assert(std::ranges::common_range<View>); 69 static_assert(std::ranges::sized_range<View>); 70 } 71 72 { 73 std::ranges::zip_view v{NonSizedRandomAccessView{buffer1}, NonSizedRandomAccessView{buffer2}}; 74 using View = decltype(v); 75 static_assert(std::ranges::random_access_range<View>); 76 static_assert(!std::ranges::contiguous_range<View>); 77 static_assert(!std::ranges::common_range<View>); 78 static_assert(!std::ranges::sized_range<View>); 79 } 80 81 { 82 std::ranges::zip_view v{BidiCommonView{buffer1}, SizedRandomAccessView{buffer2}}; 83 using View = decltype(v); 84 static_assert(std::ranges::bidirectional_range<View>); 85 static_assert(!std::ranges::random_access_range<View>); 86 static_assert(!std::ranges::common_range<View>); 87 static_assert(!std::ranges::sized_range<View>); 88 } 89 90 { 91 std::ranges::zip_view v{BidiCommonView{buffer1}, BidiCommonView{buffer2}}; 92 using View = decltype(v); 93 static_assert(std::ranges::bidirectional_range<View>); 94 static_assert(!std::ranges::random_access_range<View>); 95 static_assert(!std::ranges::common_range<View>); 96 static_assert(!std::ranges::sized_range<View>); 97 } 98 99 { 100 std::ranges::zip_view v{BidiCommonView{buffer1}, ForwardSizedView{buffer2}}; 101 using View = decltype(v); 102 static_assert(std::ranges::forward_range<View>); 103 static_assert(!std::ranges::bidirectional_range<View>); 104 static_assert(std::ranges::common_range<View>); 105 static_assert(!std::ranges::sized_range<View>); 106 } 107 108 { 109 std::ranges::zip_view v{BidiNonCommonView{buffer1}, ForwardSizedView{buffer2}}; 110 using View = decltype(v); 111 static_assert(std::ranges::forward_range<View>); 112 static_assert(!std::ranges::bidirectional_range<View>); 113 static_assert(!std::ranges::common_range<View>); 114 static_assert(!std::ranges::sized_range<View>); 115 } 116 117 { 118 std::ranges::zip_view v{ForwardSizedView{buffer1}, ForwardSizedView{buffer2}}; 119 using View = decltype(v); 120 static_assert(std::ranges::forward_range<View>); 121 static_assert(!std::ranges::bidirectional_range<View>); 122 static_assert(std::ranges::common_range<View>); 123 static_assert(std::ranges::sized_range<View>); 124 } 125 126 { 127 std::ranges::zip_view v{ForwardSizedNonCommon{buffer1}, ForwardSizedView{buffer2}}; 128 using View = decltype(v); 129 static_assert(std::ranges::forward_range<View>); 130 static_assert(!std::ranges::bidirectional_range<View>); 131 static_assert(!std::ranges::common_range<View>); 132 static_assert(std::ranges::sized_range<View>); 133 } 134 135 { 136 std::ranges::zip_view v{InputCommonView{buffer1}, ForwardSizedView{buffer2}}; 137 using View = decltype(v); 138 static_assert(std::ranges::input_range<View>); 139 static_assert(!std::ranges::forward_range<View>); 140 static_assert(std::ranges::common_range<View>); 141 static_assert(!std::ranges::sized_range<View>); 142 } 143 144 { 145 std::ranges::zip_view v{InputCommonView{buffer1}, InputCommonView{buffer2}}; 146 using View = decltype(v); 147 static_assert(std::ranges::input_range<View>); 148 static_assert(!std::ranges::forward_range<View>); 149 static_assert(std::ranges::common_range<View>); 150 static_assert(!std::ranges::sized_range<View>); 151 } 152 153 { 154 std::ranges::zip_view v{InputNonCommonView{buffer1}, InputCommonView{buffer2}}; 155 using View = decltype(v); 156 static_assert(std::ranges::input_range<View>); 157 static_assert(!std::ranges::forward_range<View>); 158 static_assert(!std::ranges::common_range<View>); 159 static_assert(!std::ranges::sized_range<View>); 160 } 161 } 162 163 void testConceptTuple() { 164 int buffer1[2] = {1, 2}; 165 int buffer2[3] = {1, 2, 3}; 166 int buffer3[4] = {1, 2, 3, 4}; 167 168 // TODO: uncomment all the static_asserts once [tuple.tuple] section in P2321R2 is implemented 169 // This is because convertible_to<tuple<int&,int&,int&>&, tuple<int,int,int>> is false without 170 // the above implementation, thus the zip iterator does not model indirectly_readable 171 172 { 173 std::ranges::zip_view v{ContiguousCommonView{buffer1}, ContiguousCommonView{buffer2}, 174 ContiguousCommonView{buffer3}}; 175 using View = decltype(v); 176 // static_assert(std::ranges::random_access_range<View>); 177 static_assert(!std::ranges::contiguous_range<View>); 178 static_assert(std::ranges::common_range<View>); 179 static_assert(std::ranges::sized_range<View>); 180 } 181 182 { 183 std::ranges::zip_view v{ContiguousNonCommonView{buffer1}, ContiguousNonCommonView{buffer2}, 184 ContiguousNonCommonView{buffer3}}; 185 using View = decltype(v); 186 // static_assert(std::ranges::random_access_range<View>); 187 static_assert(!std::ranges::contiguous_range<View>); 188 static_assert(!std::ranges::common_range<View>); 189 static_assert(!std::ranges::sized_range<View>); 190 } 191 192 { 193 std::ranges::zip_view v{ContiguousNonCommonSized{buffer1}, ContiguousNonCommonSized{buffer2}, 194 ContiguousNonCommonSized{buffer3}}; 195 using View = decltype(v); 196 // static_assert(std::ranges::random_access_range<View>); 197 static_assert(!std::ranges::contiguous_range<View>); 198 static_assert(std::ranges::common_range<View>); 199 static_assert(std::ranges::sized_range<View>); 200 } 201 202 { 203 std::ranges::zip_view v{SizedRandomAccessView{buffer1}, ContiguousCommonView{buffer2}, 204 ContiguousCommonView{buffer3}}; 205 using View = decltype(v); 206 // static_assert(std::ranges::random_access_range<View>); 207 static_assert(!std::ranges::contiguous_range<View>); 208 static_assert(std::ranges::common_range<View>); 209 static_assert(std::ranges::sized_range<View>); 210 } 211 212 { 213 std::ranges::zip_view v{SizedRandomAccessView{buffer1}, SizedRandomAccessView{buffer2}, 214 SizedRandomAccessView{buffer3}}; 215 using View = decltype(v); 216 // static_assert(std::ranges::random_access_range<View>); 217 static_assert(!std::ranges::contiguous_range<View>); 218 static_assert(std::ranges::common_range<View>); 219 static_assert(std::ranges::sized_range<View>); 220 } 221 222 { 223 std::ranges::zip_view v{NonSizedRandomAccessView{buffer1}, NonSizedRandomAccessView{buffer2}, 224 NonSizedRandomAccessView{buffer3}}; 225 using View = decltype(v); 226 // static_assert(std::ranges::random_access_range<View>); 227 static_assert(!std::ranges::contiguous_range<View>); 228 static_assert(!std::ranges::common_range<View>); 229 static_assert(!std::ranges::sized_range<View>); 230 } 231 232 { 233 std::ranges::zip_view v{BidiCommonView{buffer1}, SizedRandomAccessView{buffer2}, SizedRandomAccessView{buffer3}}; 234 using View = decltype(v); 235 // static_assert(std::ranges::bidirectional_range<View>); 236 static_assert(!std::ranges::random_access_range<View>); 237 static_assert(!std::ranges::common_range<View>); 238 static_assert(!std::ranges::sized_range<View>); 239 } 240 241 { 242 std::ranges::zip_view v{BidiCommonView{buffer1}, BidiCommonView{buffer2}, BidiCommonView{buffer3}}; 243 using View = decltype(v); 244 // static_assert(std::ranges::bidirectional_range<View>); 245 static_assert(!std::ranges::random_access_range<View>); 246 static_assert(!std::ranges::common_range<View>); 247 static_assert(!std::ranges::sized_range<View>); 248 } 249 250 { 251 std::ranges::zip_view v{BidiCommonView{buffer1}, ForwardSizedView{buffer2}, ForwardSizedView{buffer3}}; 252 using View = decltype(v); 253 // static_assert(std::ranges::forward_range<View>); 254 static_assert(!std::ranges::bidirectional_range<View>); 255 static_assert(std::ranges::common_range<View>); 256 static_assert(!std::ranges::sized_range<View>); 257 } 258 259 { 260 std::ranges::zip_view v{BidiNonCommonView{buffer1}, ForwardSizedView{buffer2}, ForwardSizedView{buffer3}}; 261 using View = decltype(v); 262 // static_assert(std::ranges::forward_range<View>); 263 static_assert(!std::ranges::bidirectional_range<View>); 264 static_assert(!std::ranges::common_range<View>); 265 static_assert(!std::ranges::sized_range<View>); 266 } 267 268 { 269 std::ranges::zip_view v{ForwardSizedView{buffer1}, ForwardSizedView{buffer2}, ForwardSizedView{buffer3}}; 270 using View = decltype(v); 271 // static_assert(std::ranges::forward_range<View>); 272 static_assert(!std::ranges::bidirectional_range<View>); 273 static_assert(std::ranges::common_range<View>); 274 static_assert(std::ranges::sized_range<View>); 275 } 276 277 { 278 std::ranges::zip_view v{ForwardSizedNonCommon{buffer1}, ForwardSizedView{buffer2}, ForwardSizedView{buffer3}}; 279 using View = decltype(v); 280 // static_assert(std::ranges::forward_range<View>); 281 static_assert(!std::ranges::bidirectional_range<View>); 282 static_assert(!std::ranges::common_range<View>); 283 static_assert(std::ranges::sized_range<View>); 284 } 285 286 { 287 std::ranges::zip_view v{InputCommonView{buffer1}, ForwardSizedView{buffer2}, ForwardSizedView{buffer3}}; 288 using View = decltype(v); 289 // static_assert(std::ranges::input_range<View>); 290 static_assert(!std::ranges::forward_range<View>); 291 static_assert(std::ranges::common_range<View>); 292 static_assert(!std::ranges::sized_range<View>); 293 } 294 295 { 296 std::ranges::zip_view v{InputCommonView{buffer1}, InputCommonView{buffer2}, InputCommonView{buffer3}}; 297 using View = decltype(v); 298 // static_assert(std::ranges::input_range<View>); 299 static_assert(!std::ranges::forward_range<View>); 300 static_assert(std::ranges::common_range<View>); 301 static_assert(!std::ranges::sized_range<View>); 302 } 303 304 { 305 std::ranges::zip_view v{InputNonCommonView{buffer1}, InputCommonView{buffer2}, InputCommonView{buffer3}}; 306 using View = decltype(v); 307 // static_assert(std::ranges::input_range<View>); 308 static_assert(!std::ranges::forward_range<View>); 309 static_assert(!std::ranges::common_range<View>); 310 static_assert(!std::ranges::sized_range<View>); 311 } 312 } 313 314 using OutputIter = cpp17_output_iterator<int*>; 315 static_assert(std::output_iterator<OutputIter, int>); 316 317 struct OutputView : std::ranges::view_base { 318 OutputIter begin() const; 319 sentinel_wrapper<OutputIter> end() const; 320 }; 321 static_assert(std::ranges::output_range<OutputView, int>); 322 static_assert(!std::ranges::input_range<OutputView>); 323 324 template <class... Ts> 325 concept zippable = requires { 326 typename std::ranges::zip_view<Ts...>; 327 }; 328 329 // output_range is not supported 330 static_assert(!zippable<OutputView>); 331 static_assert(!zippable<SimpleCommon, OutputView>); 332 static_assert(zippable<SimpleCommon>); 333